static VALUE specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self) { VALUE retval; // XXX: not exception-safe const long old_version = RCLASS_VERSION(klass); if (rb_block_given_p()) { if (argc > 0) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc); } rb_vm_set_current_scope(klass, SCOPE_PUBLIC); retval = rb_vm_yield_under(klass, self, 1, &self); } else { const char *file = "(eval)"; int line = 1; if (argc == 0) { rb_raise(rb_eArgError, "block not supplied"); } if (rb_safe_level() >= 4) { StringValue(argv[0]); } else { SafeStringValue(argv[0]); } if (argc > 3) { const char *name = rb_id2name(rb_frame_callee()); rb_raise(rb_eArgError, "wrong number of arguments: %s(src) or %s{..}", name, name); } if (argc > 2) { line = NUM2INT(argv[2]); } if (argc > 1) { file = StringValuePtr(argv[1]); } rb_vm_set_current_scope(klass, SCOPE_PUBLIC); retval = eval_under(self, klass, argv[0], Qnil, file, line); } RCLASS_SET_VERSION(klass, old_version); return retval; }
static VALUE rb_mod_modfunc(VALUE module, SEL sel, int argc, VALUE *argv) { if (TYPE(module) != T_MODULE) { rb_raise(rb_eTypeError, "module_function must be called for modules"); } secure_visibility(module); if (argc == 0) { rb_vm_set_current_scope(module, SCOPE_MODULE_FUNC); return module; } set_method_visibility(module, argc, argv, NOEX_PRIVATE); for (int i = 0; i < argc; i++) { ID id = rb_to_id(argv[i]); IMP imp = NULL; rb_vm_method_node_t *node = NULL; SEL sel = 0; if (rb_vm_lookup_method2((Class)module, id, &sel, &imp, &node) || (TYPE(module) == T_MODULE && rb_vm_lookup_method2((Class)rb_cObject, id, &sel, &imp, &node))) { rb_vm_define_method2(*(Class *)module, sel, node, -1, false); } else { rb_bug("undefined method `%s'; can't happen", rb_id2name(id)); } } return module; }
static VALUE rb_mod_private(VALUE module, SEL sel, int argc, VALUE *argv) { secure_visibility(module); if (argc == 0) { rb_vm_set_current_scope(module, SCOPE_PRIVATE); } else { set_method_visibility(module, argc, argv, NOEX_PRIVATE); } return module; }
PRIMITIVE void vm_set_current_scope(VALUE mod, int scope) { rb_vm_set_current_scope(mod, (rb_vm_scope_t)scope); }