diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-02-04 19:17:33 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-02-04 19:17:33 +0000 |
commit | 44133346923781aaa1022d9b881aeb4e58dd5940 (patch) | |
tree | 3f74f159fcc7abf2e87ff7295e6400651a26a8c4 /parse.y | |
parent | 11703607ac25a15def2197bb91e53b4b0d7cf84d (diff) | |
download | ruby-44133346923781aaa1022d9b881aeb4e58dd5940.tar.gz ruby-44133346923781aaa1022d9b881aeb4e58dd5940.tar.xz ruby-44133346923781aaa1022d9b881aeb4e58dd5940.zip |
* parse.y (rb_compose_ivar2): function to create a new ivar2
symbol from a symbol and a class. back-ported from matzruby.
* parse.y (rb_decompose_ivar2): reverse function of
rb_compose_ivar2().
* marshal.c (w_symbol): support class local instance variables.
* marshal.c (r_object0): ditto.
* compile.c (defined_expr): ditto.
* compile.c (iseq_compile_each): ditto.
* insns.def: add two new instructions: getinstancevariable2 and
setinstancevariable2.
git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@11630 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 97 |
1 files changed, 89 insertions, 8 deletions
@@ -35,19 +35,21 @@ #define ID_SCOPE_SHIFT 3 #define ID_SCOPE_MASK 0x07 -#define ID_LOCAL 0x01 -#define ID_INSTANCE 0x02 -#define ID_GLOBAL 0x03 -#define ID_ATTRSET 0x04 -#define ID_CONST 0x05 -#define ID_CLASS 0x06 -#define ID_JUNK 0x07 -#define ID_INTERNAL ID_JUNK +#define ID_LOCAL 0x00 +#define ID_INSTANCE 0x01 +#define ID_INSTANCE2 0x02 +#define ID_GLOBAL 0x03 +#define ID_ATTRSET 0x04 +#define ID_CONST 0x05 +#define ID_CLASS 0x06 +#define ID_JUNK 0x07 +#define ID_INTERNAL ID_JUNK #define is_notop_id(id) ((id)>tLAST_TOKEN) #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL) #define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL) #define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE) +#define is_instance2_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE2) #define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET) #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST) #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS) @@ -7245,6 +7247,9 @@ gettable_gen(struct parser_params *parser, ID id) else if (is_instance_id(id)) { return NEW_IVAR(id); } + else if (is_instance2_id(id)) { + return NEW_IVAR2(id); + } else if (is_const_id(id)) { return NEW_CONST(id); } @@ -7298,6 +7303,9 @@ assignable_gen(struct parser_params *parser, ID id, NODE *val) else if (is_instance_id(id)) { return NEW_IASGN(id, val); } + else if (is_instance2_id(id)) { + return NEW_IASGN2(id, val); + } else if (is_const_id(id)) { if (in_def || in_single) yyerror("dynamic constant assignment"); @@ -7432,6 +7440,7 @@ node_assign_gen(struct parser_params *parser, NODE *lhs, NODE *rhs) switch (nd_type(lhs)) { case NODE_GASGN: case NODE_IASGN: + case NODE_IASGN2: case NODE_LASGN: case NODE_DASGN: case NODE_DASGN_CURR: @@ -8319,6 +8328,8 @@ static struct symbols { ID last_id; st_table *sym_id; st_table *id_str; + st_table *ivar2_id; + st_table *id_ivar2; VALUE op_sym[tLAST_TOKEN]; } global_symbols = {tLAST_TOKEN}; @@ -8327,11 +8338,38 @@ static struct st_hash_type symhash = { rb_str_hash, }; +struct ivar2_key { + ID id; + VALUE klass; +}; + +static int +ivar2_cmp(struct ivar2_key *key1, struct ivar2_key *key2) +{ + if (key1->id == key2->id && key1->klass == key2->klass) { + return 0; + } + return 1; +} + +static int +ivar2_hash(struct ivar2_key *key) +{ + return (key->id << 8) ^ (key->klass >> 2); +} + +static struct st_hash_type ivar2_hash_type = { + ivar2_cmp, + ivar2_hash, +}; + void Init_sym(void) { global_symbols.sym_id = st_init_table_with_size(&symhash, 1000); global_symbols.id_str = st_init_numtable_with_size(1000); + global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000); + global_symbols.id_ivar2 = st_init_numtable_with_size(1000); } void @@ -8466,6 +8504,9 @@ rb_intern2(const char *name, long len) m++; id |= ID_CLASS; } + else if (name[1] == '_') { + id |= ID_INSTANCE2; + } else { id |= ID_INSTANCE; } @@ -8527,6 +8568,39 @@ rb_intern(const char *name) return rb_intern2(name, strlen(name)); } +ID +rb_compose_ivar2(ID oid, VALUE klass) +{ + struct ivar2_key key, *kp; + ID id; + + key.id = oid; + key.klass = klass; + if (st_lookup(global_symbols.ivar2_id, (st_data_t)&key, (st_data_t *)&id)) + return id; + + kp = ALLOC_N(struct ivar2_key, 1); + kp->id = oid; kp->klass = klass; + id = ID_INSTANCE2; + id |= ++global_symbols.last_id << ID_SCOPE_SHIFT; + st_add_direct(global_symbols.ivar2_id, (st_data_t)kp, (st_data_t)id); + st_add_direct(global_symbols.id_ivar2, (st_data_t)id, (st_data_t)kp); + return id; +} + +ID +rb_decompose_ivar2(ID id, VALUE *klassp) +{ + struct ivar2_key *kp; + ID oid; + + if (!st_lookup(global_symbols.id_ivar2, (st_data_t)id, (st_data_t *)&kp)) { + return id; + } + if (klassp) *klassp = kp->klass; + return kp->id; +} + VALUE rb_id2str(ID id) { @@ -8636,6 +8710,13 @@ rb_is_instance_id(ID id) } int +rb_is_instance2_id(ID id) +{ + if (is_instance2_id(id)) return Qtrue; + return Qfalse; +} + +int rb_is_local_id(ID id) { if (is_local_id(id)) return Qtrue; |