summaryrefslogtreecommitdiff
path: root/insns.def
diff options
context:
space:
mode:
authorshugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-20 08:13:53 +0000
committershugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-20 08:13:53 +0000
commitea01ffa56951724708858b982d7aa64504cc412c (patch)
tree8196c9203f6fe953f5bba9ccc81be26e179b5ab5 /insns.def
parenta1580347899f1fb6fd85d82828db3f372e5ec86d (diff)
* vm_core.h (rb_vm_defineclass_type_t),
compile.c (iseq_compile_each), insns.def (defineclass): change the meaning of the third operand of defineclass as follows: lower 3bits: the type of the defineclass 0 = class, 1 = singleton class, 2 = module 4th bit: a flag represents whether the defineclass is scoped 0 = not scoped (e.g., class Foo) 1 = scoped (e.g., class Bar::Baz) 5th bit: a flag represents whether the superclass is specified 0 = not specified (e.g., class Foo) 1 = specified (e.g., class Bar < Foo) If the superclass is specified and is not a class, a TypeError should be raised. [ruby-dev:46747] [Bug #7572] * test/ruby/test_class.rb: related test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38495 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'insns.def')
-rw-r--r--insns.def27
1 files changed, 17 insertions, 10 deletions
diff --git a/insns.def b/insns.def
index 7ada586d0a..c339180589 100644
--- a/insns.def
+++ b/insns.def
@@ -885,17 +885,23 @@ trace
*/
DEFINE_INSN
defineclass
-(ID id, ISEQ class_iseq, rb_num_t define_type)
+(ID id, ISEQ class_iseq, rb_num_t flags)
(VALUE cbase, VALUE super)
(VALUE val)
{
VALUE klass;
+ rb_vm_defineclass_type_t type = VM_DEFINECLASS_TYPE(flags);
- switch ((int)define_type) {
- case 0: /* scoped: class Foo::Bar */
- case 3: /* no scope: class Bar */
+ switch (type) {
+ case VM_DEFINECLASS_TYPE_CLASS:
/* val is dummy. classdef returns class scope value */
+ if (VM_DEFINECLASS_HAS_SUPERCLASS_P(flags) &&
+ !RB_TYPE_P(super, T_CLASS)) {
+ rb_raise(rb_eTypeError, "superclass must be a Class (%s given)",
+ rb_obj_classname(super));
+ }
+
if (super == Qnil) {
super = rb_cObject;
}
@@ -906,7 +912,8 @@ defineclass
rb_autoload_load(cbase, id);
if ((klass = vm_search_const_defined_class(cbase, id)) != 0) {
/* already exist */
- klass = define_type == 0 ? rb_public_const_get_at(klass, id) : rb_const_get_at(klass, id);
+ klass = VM_DEFINECLASS_SCOPED_P(flags) ?
+ rb_public_const_get_at(klass, id) : rb_const_get_at(klass, id);
if (!RB_TYPE_P(klass, T_CLASS)) {
rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
}
@@ -929,13 +936,12 @@ defineclass
rb_class_inherited(super, klass);
}
break;
- case 1:
+ case VM_DEFINECLASS_TYPE_SINGLETON_CLASS:
/* val is dummy. classdef returns class scope value */
/* super is dummy */
klass = rb_singleton_class(cbase);
break;
- case 2: /* scoped: module Foo::Bar or module ::Bar */
- case 5: /* no scope: module Bar */
+ case VM_DEFINECLASS_TYPE_MODULE:
/* val is dummy. classdef returns class scope value */
/* super is dummy */
@@ -943,7 +949,8 @@ defineclass
/* find klass */
if ((klass = vm_search_const_defined_class(cbase, id)) != 0) {
- klass = define_type == 2 ? rb_public_const_get_at(klass, id) : rb_const_get_at(klass, id);
+ klass = VM_DEFINECLASS_SCOPED_P(flags) ?
+ rb_const_get_at(klass, id) : rb_public_const_get_at(klass, id);
/* already exist */
if (!RB_TYPE_P(klass, T_MODULE)) {
rb_raise(rb_eTypeError, "%s is not a module", rb_id2name(id));
@@ -957,7 +964,7 @@ defineclass
}
break;
default:
- rb_bug("unknown defineclass type: %d", (int)define_type);
+ rb_bug("unknown defineclass type: %d", (int)type);
}
COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC, NULL));