ERB.new(<<-'end', 0, '%-', 'io')
%case RUBY_VERSION
%when "1.9.3"
#define RUBY_1_9_3 1
%when "1.9.2"
#define RUBY_1_9_2 1
%else
% raise(UnsupportedError.new("Unsupported ruby version #{RUBY_VERSION}"))
%end
#include <ruby.h>
#include <ruby/encoding.h>
#include "vm_opts.h"
#include "vm_core.h"
#include "eval_intern.h"
#include "iseq.h"
#include "gc.h"
#include <ruby/vm.h>
/* need for CHECK_STACK_OVERFLOW and vm_push_frame */
#undef GET_VM
#define GET_VM() th->vm
#include "vm_insnhelper.h"
#include "vm_insnhelper.c"
#define USE_INSN_STACK_INCREASE 1
#include "insns_info.inc"
#include "manual_update.h"
static VALUE rb_mCastOff;
static VALUE rb_eCastOffExecutionError;
static VALUE rb_mCastOffCompiler;
static VALUE rb_cCastOffSingletonClass;
static VALUE rb_cCastOffConfiguration;
static VALUE rb_cCastOffClassWrapper;
static VALUE rb_cCastOffMethodWrapper;
static VALUE oMain, cMain;
#include "vm_api.h"
#include "iter_api.h"
#include "unbox_api.h"
%if @configuration.inject_guard?
#define INJECT_GUARD 1
%end
%if @configuration.array_conservative?
#define ARRAY_CONSERVATIVE 1
%end
#include "inline_api.h"
/* FIXME */
#undef RUBY_VM_CHECK_INTS
#define RUBY_VM_CHECK_INTS(th)
/* Odd, This macro is not in any header files above... */
/* #define hide_obj(obj) do {OBJ_FREEZE(obj); RBASIC(obj)->klass = 0;} while (0) */
#define hide_obj(obj)
static VALUE sampling_table_val = Qnil;
static st_table *sampling_table = NULL;
static void register_sampling_table(VALUE hash)
{
sampling_table_val = hash;
rb_gc_register_mark_object(hash);
sampling_table = RHASH_TBL(hash);
}
static VALUE cast_off_register_sampling_table_<%= signiture() %>(VALUE dummy, VALUE hash)
{
register_sampling_table(hash);
return Qnil;
}
static void sampling_variable(VALUE val, VALUE sym)
{
/* :variable => [klass0, klass1, ...] */
VALUE klass = rb_class_of(val);
VALUE hashval;
VALUE singleton_class_or_module_obj_p = Qfalse;
st_table *hash;
if (!st_lookup(sampling_table, (st_data_t)sym, (st_data_t*)&hashval)) {
hashval = rb_hash_new();
st_insert(sampling_table, (st_data_t)sym, (st_data_t)hashval);
}
hash = RHASH_TBL(hashval);
if (FL_TEST(klass, FL_SINGLETON)) {
if (rb_obj_class(val) == rb_cClass || rb_obj_class(val) == rb_cModule || val == oMain) {
klass = val;
singleton_class_or_module_obj_p = Qtrue;
} else {
if (empty_method_table_p(klass)) {
klass = rb_obj_class(val);
} else {
klass = rb_cCastOffSingletonClass;
}
}
}
if (!st_lookup(hash, (st_data_t)klass, 0)) {
st_insert(hash, (st_data_t)klass, (st_data_t)singleton_class_or_module_obj_p);
}
return;
}
static void __sampling_poscall(VALUE val, VALUE method_klass, VALUE method_id)
{
VALUE klass;
VALUE mtblval, method_id_hashval, hashval;
VALUE singleton_class_or_module_obj_p = Qfalse;
VALUE class_method_or_module_function_p = Qfalse;
st_table *mtbl, *method_id_hash, *hash;
if (FL_TEST(method_klass, FL_SINGLETON)) {
VALUE recv = rb_ivar_get(method_klass, rb_intern("__attached__"));
if (rb_class_of(recv) == method_klass) {
if ((rb_obj_class(recv) == rb_cClass || rb_obj_class(recv) == rb_cModule) || recv == oMain) {
method_klass = recv;
class_method_or_module_function_p = Qtrue;
} else {
if (empty_method_table_p(method_klass)) {
method_klass = rb_obj_class(recv);
} else {
method_klass = rb_cCastOffSingletonClass;
}
}
} else {
method_klass = rb_cCastOffSingletonClass;
}
}
if (!st_lookup(sampling_table, (st_data_t)class_method_or_module_function_p, (st_data_t*)&mtblval)) {
mtblval = rb_hash_new();
st_insert(sampling_table, (st_data_t)class_method_or_module_function_p, (st_data_t)mtblval);
}
mtbl = RHASH_TBL(mtblval);
if (!st_lookup(mtbl, (st_data_t)method_klass, (st_data_t*)&method_id_hashval)) {
method_id_hashval = rb_hash_new();
st_insert(mtbl, (st_data_t)method_klass, (st_data_t)method_id_hashval);
}
method_id_hash = RHASH_TBL(method_id_hashval);
if (!st_lookup(method_id_hash, (st_data_t)method_id, (st_data_t*)&hashval)) {
hashval = rb_hash_new();
st_insert(method_id_hash, (st_data_t)method_id, (st_data_t)hashval);
}
hash = RHASH_TBL(hashval);
klass = rb_class_of(val);
if (FL_TEST(klass, FL_SINGLETON)) {
if (rb_obj_class(val) == rb_cClass || rb_obj_class(val) == rb_cModule) {
klass = val;
singleton_class_or_module_obj_p = Qtrue;
} else {
if (empty_method_table_p(klass)) {
klass = rb_obj_class(val);
} else {
klass = rb_cCastOffSingletonClass;
}
}
}
if (!st_lookup(hash, (st_data_t)klass, 0)) {
st_insert(hash, (st_data_t)klass, (st_data_t)singleton_class_or_module_obj_p);
}
return;
}
static void sampling_poscall(VALUE val, VALUE recv, VALUE method_id)
{
__sampling_poscall(val, rb_class_of(recv), method_id);
}
%@namespace.each_static_decls do |decl|
<%= decl %>
%end
%@fptr.each do |(k, fps)|
% name, mid, singleton, convention, argc = k
% mid = allocate_id(mid)
% fps.each do |fp|
static VALUE (*<%= fp %>)(ANYARGS);
static VALUE (*<%= function_pointer_wrapper_fptr(fp) %>)(ANYARGS);
% case convention
% when -3 # -1
% args = Array.new(argc)
% i = 0; args.map!{|a| a = "arg#{i}"; i += 1; a}
% args_d = args.empty? ? '' : ", VALUE #{args.join(', VALUE ')}"
% args_c = args.empty? ? '' : ", #{args.join(', ')}"
static VALUE <%= function_pointer_wrapper_func(fp) %>(VALUE recv, ID id, int argc<%= args_d %>)
{
return <%= function_pointer_wrapper_fptr(fp) %>(recv<%= args_c %>);
}
static VALUE <%= function_pointer_wrapper_func_complex(fp) %>(VALUE recv, ID id, int argc<%= args_d %>)
{
VALUE argv[<%= [argc, 1].max %>];
% argc.times do |i|
argv[<%= i %>] = arg<%= i %>;
% end
if (argc != <%= argc %>) {
rb_bug("<%= function_pointer_wrapper_func(fp) %>: should not be reached");
}
return <%= function_pointer_wrapper_fptr(fp) %>(<%= argc %>, argv, recv);
}
% when -2
static VALUE <%= function_pointer_wrapper_func(fp) %>(VALUE recv, VALUE ary)
{
return <%= function_pointer_wrapper_fptr(fp) %>(recv, <%= mid %>, RARRAY_LEN(ary), RARRAY_PTR(ary));
}
% when -1
static VALUE <%= function_pointer_wrapper_func(fp) %>(int argc, VALUE *argv, VALUE recv)
{
return <%= function_pointer_wrapper_fptr(fp) %>(recv, <%= mid %>, argc, argv);
}
% when 0..15
% args = Array.new(convention)
% i = 0; args.map!{|a| a = "arg#{i}"; i += 1; a}
% args_d = args.empty? ? '' : ", VALUE #{args.join(', VALUE ')}"
% args_c = args.empty? ? '' : ", #{args.join(', ')}"
static VALUE <%= function_pointer_wrapper_func(fp) %>(VALUE recv<%= args_d %>)
{
return <%= function_pointer_wrapper_fptr(fp) %>(recv, <%= mid %>, <%= convention %><%= args_c %>);
}
% else
% bug()
% end
% end
%end
%@ic.each do |(k, v)|
static struct iseq_inline_cache_entry <%= v %>;
%end
%queue = [@root_iseq]
static rb_iseq_t *<%= @root_iseq %> = NULL;
%until queue.empty?
% entry = queue.pop()
% entry.children.each do |(pc, child)|
static rb_iseq_t *<%= child %> = NULL;
% bug() if queue.include?(child)
% queue << child
% end
%end
static rb_iseq_t *cast_off_orig_iseq = NULL;
static VALUE cast_off_register_iseq_<%= signiture() %>(VALUE dummy, VALUE iseqval)
{
rb_iseq_t *iseq = DATA_PTR(iseqval);
VALUE insn;
rb_gc_register_mark_object(iseqval);
cast_off_orig_iseq = iseq;
%queue = [@root_iseq]
<%= @root_iseq %> = cast_off_orig_iseq;
%until queue.empty?
% entry = queue.pop()
% entry.children.each do |(pc, child)|
insn = <%= entry %>->iseq[<%= pc %>];
if (insn != BIN(send)) {
rb_bug("should not be reached (0), pc = %d", <%= pc %>);
}
<%= child %> = (rb_iseq_t*)<%= entry %>->iseq[<%= pc %> + 3];
if (rb_class_of(<%= child %>->self) != rb_cISeq) {
rb_bug("should not be reached (1)");
}
% bug() if queue.include?(child)
% queue << child
% end
%end
return Qnil;
}
%@declare_constants.each do |(key, value)|
static VALUE <%= key %> = Qundef;
%end
static VALUE cast_off_prefetch_constants_<%= signiture() %>(VALUE self, VALUE binding)
{
%@prefetch_constants.each do |(key, value)|
% path, singleton_p = value
<%= key %> = rb_funcall(self, rb_intern("eval"), 2, rb_str_new2("<%= path %>"), binding);
% if singleton_p
<%= key %> = rb_class_of(<%= key %>);
% end
%end
return Qnil;
}
static void *fbind = NULL;
static void *feval = NULL;
static VALUE cast_off_initialize_fptr_<%= signiture() %>(VALUE dummy)
{
rb_method_entry_t *me;
VALUE klass;
VALUE (*fptr)(ANYARGS);
me = search_method(rb_mKernel, rb_intern("binding"));
should_be_cfunc(me);
fbind = me->def->body.cfunc.func;
me = search_method(rb_mKernel, rb_intern("eval"));
should_be_cfunc(me);
feval = me->def->body.cfunc.func;
%@fptr.each do |(k, v)|
% name, mid, singleton, convention, argc = k
% mid = allocate_id(mid)
% fps = v
% case name
% when Symbol
klass = <%= name %>;
% when Array
klass = rb_cObject;
% name.each do |kid|
klass = rb_const_get(klass, rb_intern("<%= kid %>"));
% end
% else
% bug()
% end
% if singleton
should_be_singleton(klass);
me = search_method(rb_class_of(klass), <%= mid %>);
% else
me = search_method(klass, <%= mid %>);
% end
fptr = c_function_pointer(me);
if (fptr && should_be_call_directly_p(fptr)) {
int argc = c_function_argc(me);
if (fptr == fbind) {
rb_raise(rb_eCastOffExecutionError, "should not use binding in compilation target of CastOff");
}
if (fptr == feval) {
rb_raise(rb_eCastOffExecutionError, "should not use eval in compilation target of CastOff");
}
if (argc == <%= convention %>) {
% fps.each do |fp|
<%= fp %> = fptr;
% end
} else {
% case convention
% when -3
if (0 <= argc && argc <= 15) {
% fps.each do |fp|
<%= function_pointer_wrapper_fptr(fp) %> = fptr;
<%= fp %> = <%= function_pointer_wrapper_func(fp) %>;
% end
} else if (argc == -1) {
% fps.each do |fp|
<%= function_pointer_wrapper_fptr(fp) %> = fptr;
<%= fp %> = <%= function_pointer_wrapper_func_complex(fp) %>;
% end
} else if (argc == -2) {
% fps.each do |fp|
<%= function_pointer_wrapper_fptr(fp) %> = fptr;
<%= fp %> = (void*)rb_funcall;
% end
} else {
rb_raise(rb_eCastOffExecutionError, "unexpected method(0)");
}
% when -1, -2
% fps.each do |fp|
<%= function_pointer_wrapper_fptr(fp) %> = (void*)rb_funcall2;
<%= fp %> = <%= function_pointer_wrapper_func(fp) %>;
% end
% when 0..15
% fps.each do |fp|
<%= function_pointer_wrapper_fptr(fp) %> = (void*)rb_funcall;
<%= fp %> = <%= function_pointer_wrapper_func(fp) %>;
% end
% else
% bug("convention = #{convention}")
% end
}
} else {
% case convention
% when -3 # rb_funcall
% fps.each do |fp|
<%= fp %> = (void*)rb_funcall;
% end
% when -1, -2
% fps.each do |fp|
<%= function_pointer_wrapper_fptr(fp) %> = (void*)rb_funcall2;
<%= fp %> = <%= function_pointer_wrapper_func(fp) %>;
% end
% when 0..15 # cfunc
% fps.each do |fp|
<%= function_pointer_wrapper_fptr(fp) %> = (void*)rb_funcall;
<%= fp %> = <%= function_pointer_wrapper_func(fp) %>;
% end
% else
% bug("convention = #{convention}")
% end
}
%end
return Qnil;
}
%@throw_exception_functions.each do |(func, name)|
<%= func.gsub(/<THROW_EXCEPTION_FUNCTION_NAME>/, name) %>
%end
%@class_check_functions.each do |(func, name)|
<%= func.gsub(/<CLASS_CHECK_FUNCTION_NAME>/, name) %>
%end
%@recompilation_functions.each do |(func, name)|
<%= func.gsub(/<RECOMPILATION_FUNCTION_NAME>/, name) %>
%end
%if !inline_block?
static inline void expand_dframe(rb_thread_t *th, long size, rb_iseq_t *iseq, int root_p)
{
rb_control_frame_t *cfp = th->cfp;
VALUE *sp = cfp->sp;
VALUE *dfp = cfp->dfp;
int i;
if ((void *)(sp + size + 2) >= (void *)cfp) {
rb_exc_raise(sysstack_error);
}
for (i = 0; i < size; i++) {
*sp++ = Qnil;
}
*sp++ = dfp[-1]; /* cref */
*sp = dfp[0]; /* specval */
if (root_p) {
cfp->lfp = sp;
}
cfp->dfp = sp;
cfp->sp = sp + 1;
cfp->bp = sp + 1;
cfp->iseq = iseq;
}
static rb_thread_t *current_thread()
{
VALUE thval = rb_thread_current();
rb_thread_t * th = DATA_PTR(thval);
return th;
}
static VALUE get_self(rb_thread_t *th)
{
return th->cfp->self;
}
static inline VALUE* fetch_dfp(rb_thread_t *th, int level)
{
VALUE *dfp;
int i;
dfp = th->cfp->dfp;
for (i = 0; i < level; i++) {
dfp = GET_PREV_DFP(dfp);
}
return dfp;
}
static inline int cast_off_lambda_p(VALUE arg, int argc, VALUE *argv)
{
VALUE *ptr;
int i;
if (rb_class_of(arg) != rb_cArray) {
return 0;
}
ptr = RARRAY_PTR(arg);
for (i = 0; i < argc; i++) {
if (ptr[i] != argv[i]) {
return 0;
}
}
return 1;
}
%if false # for instance_exec, instance_eval, ...
static inline void check_cref(rb_thread_t *th)
{
rb_control_frame_t *cfp = th->cfp;
rb_iseq_t *iseq = cfp->iseq;
VALUE *lfp = cfp->lfp;
VALUE *dfp = cfp->dfp;
NODE *cref;
while (1) {
if (lfp == dfp) {
if (!RUBY_VM_NORMAL_ISEQ_P(iseq)) {
cref = NULL;
break;
} else {
cref = iseq->cref_stack;
break;
}
} else if (dfp[-1] != Qnil) {
cref = (NODE *)dfp[-1];
break;
}
dfp = GET_PREV_DFP(dfp);
}
if (cref && cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) {
rb_raise(rb_eCastOffExecutionError, "Currently, CastOff cannot handle constant reference with object(e.g. reciever of BasicObject#instance_exec) context.");
}
}
%end
static void cast_off_set_block(rb_block_t *block)
{
VALUE thval = rb_thread_current();
rb_thread_t * th = DATA_PTR(thval);
th->passed_block = block;
}
% @root_iseq.iterate_all_iseq do |iseq|
% next if iseq.root?
<%= iseq.declare_ifunc_node() %>;
<%= iseq.declare_block_generator() %>;
<%= iseq.declare_ifunc() %>;
% end
% @root_iseq.iterate_all_iseq do |iseq|
/* iseq is <%= iseq %> */
% next if iseq.root?
<%= iseq.define_ifunc_node_generator() %>
<%= iseq.define_block_generator() %>
<%= iseq.define_ifunc() %>
% end
%end
static VALUE cast_off_register_ifunc_<%= signiture() %>(VALUE dummy)
{
%if !inline_block?
% @root_iseq.iterate_all_iseq do |iseq|
% next if iseq.root?
<%= iseq.ifunc_node_generator() %>();
% end
%end
return Qnil;
}
%if @mid
% if @complex_call
static VALUE <%= this_function_name() %>(int argc, VALUE *argv, VALUE self)
% else
static VALUE <%= this_function_name() %>(VALUE self<%= @arg_size > 0 ? ", #{arguments.join(", ")}" : "" %>)
% end
%else
static VALUE <%= this_function_name() %>(VALUE dummy, VALUE self)
%end
{
%if @configuration.enable_trace?
#ifdef CAST_OFF_ENABLE_TRACE
/* VALUE thval = rb_thread_current(); */
/* rb_thread_t *th = DATA_PTR(thval); */
/* VALUE trace_recv, trace_klass; */
#endif
%end
/* decl variables */
VALUE cast_off_argv[<%= @root_iseq.all_argv_size() %>];
VALUE cast_off_tmp;
VALUE sampling_tmp;
rb_thread_t *th;
%if inline_block?
VALUE thval;
VALUE specval;
VALUE *lfp, *dfp;
%else
<%= @root_iseq.declare_dfp %>
%end
%if use_fast_ivar?
static VALUE __klass = Qundef;
VALUE *iv_table_ptr = NULL;
%end
%@ivar_index.each do |(iv_id, iv_var)|
static int <%= iv_var %>_cache;
int <%= iv_var %>;
%end
%if inline_block?
<%= @loopkey.map{|(k, v)| v.decl? ? " #{v.decl};" : nil}.compact.join("\n") %>
<%= (@root_iseq.all_local_variable_declarations - arguments).map{|v| " #{v};"}.join("\n") %>
%else
<%= (@root_iseq.own_local_variable_declarations - arguments).map{|v| " #{v};"}.join("\n") %>
%end
%if @complex_call
% arguments.each do |arg|
<%= arg %> = Qnil;
% end
%end
%if !inline_block?
th = current_thread();
expand_dframe(th, <%= @root_iseq.lvars.size %>, <%= @root_iseq %>, 1);
<%= @root_iseq.update_dfp() %>
%end
%if inline_block?
% inits = @root_iseq.all_initializations_for_guards()
%else
% inits = @root_iseq.own_initializations_for_guards()
%end
%bug() if inits.uniq!
<%= inits.join("\n") %>
%if use_fast_ivar?
if (UNLIKELY(TYPE(self) != T_OBJECT)) rb_bug("should not be reached"); /* FIXME should be check compile time */
if (UNLIKELY((RBASIC(self)->klass) != __klass)) {
/* iv index cache miss */
struct st_table *iv_index_tbl = cast_off_get_iv_index_tbl(self);
% @ivar_index.each do |(iv_id, iv_var)|
<%= iv_var %>_cache = cast_off_get_iv_index(iv_index_tbl, <%= iv_id %>);
% end
__klass = RBASIC(self)->klass;
}
% @ivar_index.each do |(iv_id, iv_var)|
<%= iv_var %> = <%= iv_var %>_cache;
% end
iv_table_ptr = cast_off_get_iv_table_ptr(self);
%end
<%= @root_iseq.enclose_begin %>
/* body */
%if inline_block?
<%= @root_iseq.all_c_function_body() %>
%else
<%= @root_iseq.own_c_function_body() %>
%end
%iterator = inline_block? ? :iterate_all_guards : :iterate_own_guards
%@root_iseq.__send__(iterator) do |code, insns|
{
long pc;
<%= @root_iseq.enclose_end_deoptimize %>
%code_label = "deoptimize_#{code.hash.to_s.gsub(/-/, "_")}"
% insns.uniq.each do |insn|
<%= insn.guard_label %>:
pc = <%= insn.pc %>;
goto <%= code_label %>;
% end
<%= code_label %>:
%if @mid
/* override this method (if this method has not redefined yet) */
/* rb_define_method(...); */
%end
<%= code %>
}
%end
<%= @root_iseq.enclose_end %>
}
%['', '_singleton'].each do |str|
static VALUE cast_off_register<%= str %>_method_<%= signiture() %>(VALUE dummy, VALUE self)
{
% if @complex_call
rb_define<%= str %>_method(self, "<%= @mid %>", <%= this_function_name() %>, -1);
% else
rb_define<%= str %>_method(self, "<%= @mid %>", <%= this_function_name() %>, <%= @arg_size %>);
% end
return Qnil;
}
%end
static VALUE cast_off_generate_proc_<%= signiture() %>(VALUE self, VALUE source_procval)
{
rb_proc_t *source_procptr = DATA_PTR(source_procval);
return rb_proc_new(<%= this_function_name() %>, source_procptr->block.self);
}
void Init_<%= signiture() %>(void)
{
%@namespace.each_nonstatic_decls do |decl|
<%= decl %>
%end
%@namespace.each do |nam|
% if /\Astatic VALUE\b/.match nam.declaration
rb_gc_register_address(&<%= nam.name %>);
% end
%end
%@namespace.each_initializers do |init|
<%= init %>
%end
/* finish up */
#define reg(n) \
rb_gc_register_mark_object(n); \
switch(BUILTIN_TYPE(n)) { \
case T_STRING: \
case T_ARRAY: \
hide_obj(n); \
break; \
}
#define bye(n) \
n = Qundef
%@namespace.each do |i|
% if /\bVALUE\b/.match i.declaration
% if /\Astatic\b/.match i.declaration
reg(<%= i.name %>);
% else
bye(<%= i.name %>);
% end
% end
%end
#undef reg
%@ic.each do |(k, v)|
MEMZERO(&<%= v %>, struct iseq_inline_cache_entry, 1);
%end
rb_mCastOff = rb_const_get(rb_cObject, rb_intern("CastOff"));
rb_eCastOffExecutionError = rb_const_get(rb_mCastOff, rb_intern("ExecutionError"));
rb_mCastOffCompiler = rb_const_get(rb_mCastOff, rb_intern("Compiler"));
rb_cCastOffSingletonClass = rb_const_get(rb_mCastOffCompiler, rb_intern("SingletonClass"));
rb_cCastOffConfiguration = rb_const_get(rb_mCastOffCompiler, rb_intern("Configuration"));
rb_cCastOffClassWrapper = rb_const_get(rb_mCastOffCompiler, rb_intern("ClassWrapper"));
rb_cCastOffMethodWrapper = rb_const_get(rb_mCastOffCompiler, rb_intern("MethodWrapper"));
oMain = rb_const_get(rb_mCastOffCompiler, rb_intern("MAIN"));
cMain = rb_class_of(oMain);
%if !@mid
rb_define_method(rb_mCastOffCompiler, "<%= signiture() %>", <%= this_function_name() %>, 1);
%end
% ['', '_singleton'].each do |str|
rb_define_method(rb_mCastOffCompiler, "register<%= str %>_method_<%= signiture() %>", cast_off_register<%= str %>_method_<%= signiture() %>, 1);
% end
rb_define_method(rb_mCastOffCompiler, "register_iseq_<%= signiture() %>", cast_off_register_iseq_<%= signiture() %>, 1);
rb_define_method(rb_mCastOffCompiler, "register_ifunc_<%= signiture() %>", cast_off_register_ifunc_<%= signiture() %>, 0);
rb_define_method(rb_mCastOffCompiler, "register_sampling_table_<%= signiture() %>", cast_off_register_sampling_table_<%= signiture() %>, 1);
rb_define_method(rb_mCastOffCompiler, "initialize_fptr_<%= signiture() %>", cast_off_initialize_fptr_<%= signiture() %>, 0);
rb_define_method(rb_mCastOffCompiler, "prefetch_constants_<%= signiture() %>", cast_off_prefetch_constants_<%= signiture() %>, 1);
}
end
{
ClassWrapper.new(Fixnum, true) => :rb_cFixnum,
ClassWrapper.new(Bignum, true) => :rb_cBignum,
ClassWrapper.new(String, true) => :rb_cString,
ClassWrapper.new(Array, true) => :rb_cArray,
ClassWrapper.new(Hash, true) => :rb_cHash,
ClassWrapper.new(Float, true) => :rb_cFloat,
ClassWrapper.new(Object, true) => :rb_cObject,
ClassWrapper.new(IO, true) => :rb_cIO,
ClassWrapper.new(Module, true) => :rb_cModule,
ClassWrapper.new(Proc, true) => :rb_cProc,
ClassWrapper.new(RubyVM, true) => :rb_cRubyVM,
ClassWrapper.new(Time, true) => :rb_cTime,
ClassWrapper.new(Symbol, true) => :rb_cSymbol,
ClassWrapper.new(Thread, true) => :rb_cThread,
ClassWrapper.new(Struct, true) => :rb_cStruct,
ClassWrapper.new(Regexp, true) => :rb_cRegexp,
ClassWrapper.new(Rational, true) => :rb_cRational,
ClassWrapper.new(Range, true) => :rb_cRange,
ClassWrapper.new(NilClass, true) => :rb_cNilClass,
ClassWrapper.new(Random, true) => :rb_cRandom,
ClassWrapper.new(Numeric, true) => :rb_cNumeric,
ClassWrapper.new(Integer, true) => :rb_cInteger,
ClassWrapper.new(Binding, true) => :rb_cBinding,
ClassWrapper.new(Method, true) => :rb_cMethod,
ClassWrapper.new(File, true) => :rb_cFile,
ClassWrapper.new(FalseClass, true) => :rb_cFalseClass,
ClassWrapper.new(TrueClass, true) => :rb_cTrueClass,
ClassWrapper.new(Class, true) => :rb_cClass,
ClassWrapper.new(Encoding, true) => :rb_cEncoding,
ClassWrapper.new(Complex, true) => :rb_cComplex,
ClassWrapper.new(Dir, true) => :rb_cDir,
ClassWrapper.new(Enumerator, true) => :rb_cEnumerator,
ClassWrapper.new(Fiber, true) => :rb_cFiber,
ClassWrapper.new(Data, true) => :rb_cData,
ClassWrapper.new(MAIN, false) => :cMain,
}