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