Created
August 26, 2012 02:03
-
-
Save wanabe/3473112 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/include/mruby/irep.h b/include/mruby/irep.h | |
| index af3346c..3dec0fd 100644 | |
| --- a/include/mruby/irep.h | |
| +++ b/include/mruby/irep.h | |
| @@ -29,6 +29,7 @@ typedef struct mrb_irep { | |
| #define MRB_ISEQ_NOFREE 1 | |
| void mrb_add_irep(mrb_state *mrb, int n); | |
| +mrb_irep *mrb_irep_new(mrb_state *mrb, int ilen, mrb_code *iseq, int plen, mrb_value *pool, int slen, mrb_sym *syms); | |
| #if defined(__cplusplus) | |
| } /* extern "C" { */ | |
| diff --git a/mrblib/class.rb b/mrblib/class.rb | |
| index 4f268b6..64ee163 100644 | |
| --- a/mrblib/class.rb | |
| +++ b/mrblib/class.rb | |
| @@ -1,19 +1,4 @@ | |
| class Module | |
| - # 15.2.2.4.13 | |
| - def attr_reader(*names) | |
| - names.each{|name| | |
| - name2 = ('@'+name.to_s).intern | |
| - define_method(name){self.instance_variable_get(name2)} | |
| - } | |
| - end | |
| - # 15.2.2.4.14 | |
| - def attr_writer(*names) | |
| - names.each{|name| | |
| - name2 = ('@'+name.to_s).intern | |
| - name = (name.to_s+"=").intern | |
| - define_method(name){|v|self.instance_variable_set(name2,v)} | |
| - } | |
| - end | |
| # 15.2.2.4.12 | |
| def attr_accessor(*names) | |
| attr_reader(*names) | |
| diff --git a/src/class.c b/src/class.c | |
| index 0c0c6a3..291e671 100644 | |
| --- a/src/class.c | |
| +++ b/src/class.c | |
| @@ -9,10 +9,13 @@ | |
| #include <stdio.h> | |
| #include "mruby/class.h" | |
| #include "mruby/proc.h" | |
| +#include "mruby/irep.h" | |
| +#include "mruby/compile.h" | |
| #include "mruby/string.h" | |
| #include "mruby/numeric.h" | |
| #include "mruby/variable.h" | |
| #include "mruby/array.h" | |
| +#include "opcode.h" | |
| #include "error.h" | |
| KHASH_DEFINE(mt, mrb_sym, struct RProc*, 1, kh_int_hash_func, kh_int_hash_equal); | |
| @@ -1355,6 +1358,92 @@ mrb_mod_const_set(mrb_state *mrb, mrb_value mod) | |
| return value; | |
| } | |
| +static const char * | |
| +mrb_cstr_len(mrb_state *mrb, mrb_value val, int *lenp) | |
| +{ | |
| + const char *cstr; | |
| + | |
| + if(mrb_type(val) == MRB_TT_SYMBOL) { | |
| + return mrb_sym2name_len(mrb, SYM2ID(val), lenp); | |
| + } | |
| + else if(mrb_type(val) != MRB_TT_STRING) { | |
| + mrb_value obj = mrb_funcall(mrb, val, "inspect", 0); | |
| + mrb_raise(mrb, E_TYPE_ERROR, "%s is not a symbol", | |
| + mrb_string_value_ptr(mrb, obj)); | |
| + } | |
| + cstr = mrb_string_value_cstr(mrb, &val); | |
| + *lenp = strlen(cstr); | |
| + return cstr; | |
| +} | |
| + | |
| +static mrb_value | |
| +mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod) | |
| +{ | |
| + mrb_value *argv; | |
| + int argc, len, i; | |
| + char *vname; | |
| + const char *name; | |
| + mrb_sym sym, vsym; | |
| + mrb_irep *irep; | |
| + struct RProc *proc; | |
| + mrb_code iseq[3] = { | |
| + MKOP_Ax(OP_ENTER, 0<<18), | |
| + MKOP_ABx(OP_GETIV, 0, 0), | |
| + MKOP_AB(OP_RETURN, 0, OP_R_NORMAL) | |
| + }; | |
| + | |
| + mrb_get_args(mrb, "*", &argv, &argc); | |
| + for (i=0; i<argc; i++) { | |
| + name = mrb_cstr_len(mrb, argv[i], &len); | |
| + vname = mrb_malloc(mrb, len + 2); | |
| + *vname = '@'; | |
| + memcpy(vname + 1, name, len + 1); | |
| + vsym = mrb_intern(mrb, vname); | |
| + free(vname); | |
| + irep = mrb_irep_new(mrb, sizeof(iseq) / sizeof(mrb_code), iseq, 0, NULL, 1, &vsym); | |
| + sym = mrb_sym_value(mrb, argv[i]); | |
| + proc = mrb_proc_new(mrb, irep); | |
| + proc->flags |= MRB_PROC_STRICT; | |
| + mrb_define_method_raw(mrb, mrb_class_ptr(mod), sym, proc); | |
| + } | |
| + return mrb_nil_value(); | |
| +} | |
| + | |
| +static mrb_value | |
| +mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod) | |
| +{ | |
| + mrb_value *argv; | |
| + int argc, len, i; | |
| + char *vname; | |
| + const char *name; | |
| + mrb_sym sym, vsym; | |
| + mrb_irep *irep; | |
| + struct RProc *proc; | |
| + mrb_code iseq[3] = { | |
| + MKOP_Ax(OP_ENTER, 1<<18), | |
| + MKOP_ABx(OP_SETIV, 1, 0), | |
| + MKOP_AB(OP_RETURN, 1, OP_R_NORMAL) | |
| + }; | |
| + | |
| + mrb_get_args(mrb, "*", &argv, &argc); | |
| + for (i=0; i<argc; i++) { | |
| + name = mrb_cstr_len(mrb, argv[i], &len); | |
| + vname = mrb_malloc(mrb, len + 2); | |
| + *vname = '@'; | |
| + memcpy(vname + 1, name, len + 1); | |
| + vsym = mrb_intern(mrb, vname); | |
| + irep = mrb_irep_new(mrb, sizeof(iseq) / sizeof(mrb_code), iseq, 0, NULL, 1, &vsym); | |
| + memcpy(vname, name, len); | |
| + vname[len] = '='; | |
| + sym = mrb_intern(mrb, vname); | |
| + free(vname); | |
| + proc = mrb_proc_new(mrb, irep); | |
| + proc->flags |= MRB_PROC_STRICT; | |
| + mrb_define_method_raw(mrb, mrb_class_ptr(mod), sym, proc); | |
| + } | |
| + return mrb_nil_value(); | |
| +} | |
| + | |
| static mrb_value | |
| mrb_mod_eqq(mrb_state *mrb, mrb_value mod) | |
| @@ -1424,6 +1513,8 @@ mrb_init_class(mrb_state *mrb) | |
| mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, ARGS_REQ(1)); /* 15.2.2.4.21 */ | |
| mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, ARGS_REQ(2)); /* 15.2.2.4.23 */ | |
| mrb_define_method(mrb, mod, "define_method", mod_define_method, ARGS_REQ(1)); | |
| + mrb_define_method(mrb, mod, "attr_reader", mrb_mod_attr_reader, ARGS_ANY()); | |
| + mrb_define_method(mrb, mod, "attr_writer", mrb_mod_attr_writer, ARGS_ANY()); | |
| mrb_define_method(mrb, mod, "===", mrb_mod_eqq, ARGS_REQ(1)); | |
| mrb_undef_method(mrb, cls, "append_features"); | |
| diff --git a/src/codegen.c b/src/codegen.c | |
| index 38d57d5..d9ab00d 100644 | |
| --- a/src/codegen.c | |
| +++ b/src/codegen.c | |
| @@ -2474,6 +2474,26 @@ mrb_generate_code(mrb_state *mrb, node *tree) | |
| return start; | |
| } | |
| +mrb_irep * | |
| +mrb_irep_new(mrb_state *mrb, int ilen, mrb_code *iseq, int plen, mrb_value *pool, int slen, mrb_sym *syms) | |
| +{ | |
| + mrb_irep *irep; | |
| + | |
| + mrb_add_irep(mrb, mrb->irep_len + 1); | |
| + irep = (mrb_irep *)mrb_calloc(mrb, sizeof(mrb_irep), 1); | |
| + | |
| +#define COPY_IREP_ITEM(item, type, len) \ | |
| + irep->item = (type *)mrb_malloc(mrb, sizeof(type) * len); \ | |
| + memcpy(irep->item, item, sizeof(type) * len); \ | |
| + irep->len = len; | |
| + | |
| + COPY_IREP_ITEM(iseq, mrb_code , ilen); | |
| + COPY_IREP_ITEM(pool, mrb_value, plen); | |
| + COPY_IREP_ITEM(syms, mrb_sym , slen); | |
| + mrb->irep[mrb->irep_len++] = irep; | |
| + return irep; | |
| +} | |
| + | |
| #ifdef CODEGEN_TEST | |
| int | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment