From b0edba434c5c5c08e2c21a7dbe07839b9a314968 Mon Sep 17 00:00:00 2001 From: ksss Date: Wed, 25 Jun 2014 13:50:06 +0900 Subject: proc.h: MRB_ASPEC_REST() macro return 1 or 0 MRB_ASPEC_REST() is macro just only checks whether truthy or falsy. And truthy means exist 1 rest argument in current proc. --- include/mruby/proc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mruby/proc.h b/include/mruby/proc.h index 39f5eca22..82b93ddef 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -37,7 +37,7 @@ struct RProc { /* aspec access */ #define MRB_ASPEC_REQ(a) (((a) >> 18) & 0x1f) #define MRB_ASPEC_OPT(a) (((a) >> 13) & 0x1f) -#define MRB_ASPEC_REST(a) ((a) & (1<<12)) +#define MRB_ASPEC_REST(a) (((a) >> 12) & 0x1) #define MRB_ASPEC_POST(a) (((a) >> 7) & 0x1f) #define MRB_ASPEC_KEY(a) (((a) >> 2) & 0x1f) #define MRB_ASPEC_KDICT(a) ((a) & (1<<1)) -- cgit v1.2.3 From f092ef6b141d0817bd76af9d9187e73029d3001b Mon Sep 17 00:00:00 2001 From: ksss Date: Wed, 25 Jun 2014 13:51:19 +0900 Subject: OP_ENTER: Rewrite split aspec use macros --- src/vm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vm.c b/src/vm.c index 9a0f03aba..d1d4b7bd4 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1364,14 +1364,14 @@ RETRY_TRY_BLOCK: /* Ax arg setup according to flags (23=5:5:1:5:5:1:1) */ /* number of optional arguments times OP_JMP should follow */ mrb_aspec ax = GETARG_Ax(i); - int m1 = (ax>>18)&0x1f; - int o = (ax>>13)&0x1f; - int r = (ax>>12)&0x1; - int m2 = (ax>>7)&0x1f; + int m1 = MRB_ASPEC_REQ(ax); + int o = MRB_ASPEC_OPT(ax); + int r = MRB_ASPEC_REST(ax); + int m2 = MRB_ASPEC_POST(ax); /* unused - int k = (ax>>2)&0x1f; - int kd = (ax>>1)&0x1; - int b = (ax>>0)& 0x1; + int k = MRB_ASPEC_KEY(ax); + int kd = MRB_ASPEC_KDICT(ax); + int b = MRB_ASPEC_BLOCK(ax); */ int argc = mrb->c->ci->argc; mrb_value *argv = regs+1; -- cgit v1.2.3 From 9cafc5e1051765d67d451f4b456996300ddf355c Mon Sep 17 00:00:00 2001 From: ksss Date: Wed, 25 Jun 2014 15:55:59 +0900 Subject: Implement Proc#parameters --- mrbgems/mruby-proc-ext/src/proc.c | 69 +++++++++++++++++++++++++++++++++++++ mrbgems/mruby-proc-ext/test/proc.rb | 12 +++++++ 2 files changed, 81 insertions(+) diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c index b105c95d7..f4a238803 100644 --- a/mrbgems/mruby-proc-ext/src/proc.c +++ b/mrbgems/mruby-proc-ext/src/proc.c @@ -1,5 +1,6 @@ #include "mruby.h" #include "mruby/proc.h" +#include "mruby/opcode.h" #include "mruby/array.h" #include "mruby/string.h" #include "mruby/debug.h" @@ -122,6 +123,73 @@ mrb_kernel_proc(mrb_state *mrb, mrb_value self) return blk; } +/* + * call-seq: + * prc.parameters -> array + * + * Returns the parameter information of this proc. + * + * prc = lambda{|x, y=42, *other|} + * prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :other]] + */ + +static mrb_value +mrb_proc_parameters(mrb_state *mrb, mrb_value self) +{ + struct parameters_type { + int size; + const char *name; + } *p, parameters_list [] = { + {0, "req"}, + {0, "opt"}, + {0, "rest"}, + {0, "req"}, + {0, "block"}, + {0, NULL} + }; + const struct RProc *proc = mrb_proc_ptr(self); + const struct mrb_irep *irep = proc->body.irep; + mrb_aspec aspec; + mrb_value parameters; + int i, j; + + if (MRB_PROC_CFUNC_P(proc)) { + // TODO cfunc aspec is not implemented yet + return mrb_ary_new(mrb); + } + if (!irep->lv) { + return mrb_ary_new(mrb); + } + if (GET_OPCODE(*irep->iseq) != OP_ENTER) { + return mrb_ary_new(mrb); + } + + if (!MRB_PROC_STRICT_P(proc)) { + parameters_list[0].name = "opt"; + parameters_list[3].name = "opt"; + } + + aspec = GETARG_Ax(*irep->iseq); + parameters_list[0].size = MRB_ASPEC_REQ(aspec); + parameters_list[1].size = MRB_ASPEC_OPT(aspec); + parameters_list[2].size = MRB_ASPEC_REST(aspec); + parameters_list[3].size = MRB_ASPEC_POST(aspec); + parameters_list[4].size = MRB_ASPEC_BLOCK(aspec); + + parameters = mrb_ary_new_capa(mrb, irep->nlocals-1); + for (i = 0, p = parameters_list; p->name; p++) { + mrb_value sname = mrb_symbol_value(mrb_intern_cstr(mrb, p->name)); + for (j = 0; j < p->size; i++, j++) { + mrb_assert(i < (irep->nlocals-1)); + mrb_ary_push(mrb, parameters, mrb_assoc_new(mrb, + sname, + mrb_symbol_value(irep->lv[i].name) + )); + } + } + return parameters; +} + void mrb_mruby_proc_ext_gem_init(mrb_state* mrb) { @@ -130,6 +198,7 @@ mrb_mruby_proc_ext_gem_init(mrb_state* mrb) mrb_define_method(mrb, p, "source_location", mrb_proc_source_location, MRB_ARGS_NONE()); mrb_define_method(mrb, p, "to_s", mrb_proc_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, p, "inspect", mrb_proc_inspect, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "parameters", mrb_proc_parameters, MRB_ARGS_NONE()); mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()); mrb_define_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()); diff --git a/mrbgems/mruby-proc-ext/test/proc.rb b/mrbgems/mruby-proc-ext/test/proc.rb index 1565873a0..bca9b463a 100644 --- a/mrbgems/mruby-proc-ext/test/proc.rb +++ b/mrbgems/mruby-proc-ext/test/proc.rb @@ -43,6 +43,18 @@ assert('Proc#curry') do assert_raise(ArgumentError) { b.curry(1) } end +assert('Proc#parameters') do + assert_equal([], Proc.new {}.parameters) + assert_equal([], Proc.new {||}.parameters) + assert_equal([[:opt, :a]], Proc.new {|a|}.parameters) + assert_equal([[:req, :a]], lambda {|a|}.parameters) + assert_equal([[:opt, :a]], lambda {|a=nil|}.parameters) + assert_equal([[:req, :a]], ->(a){}.parameters) + assert_equal([[:rest, :a]], Proc.new {|*a|}.parameters) + assert_equal([[:opt, :a], [:opt, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:opt, :f], [:opt, :g], [:block, :h]], Proc.new {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters) + assert_equal([[:req, :a], [:req, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:req, :f], [:req, :g], [:block, :h]], lambda {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters) +end + assert('Proc#to_proc') do proc = Proc.new {} assert_equal proc, proc.to_proc -- cgit v1.2.3 From 090a8889f7a740cd760c19c418bbfd2cb60b1ff1 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Wed, 25 Jun 2014 21:34:52 +0900 Subject: Add documentation of `mrb_value` config. --- doc/mrbconf/README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/mrbconf/README.md b/doc/mrbconf/README.md index f0dd50da5..e8da29e43 100644 --- a/doc/mrbconf/README.md +++ b/doc/mrbconf/README.md @@ -104,3 +104,18 @@ largest value of required alignment. `MRB_FIXED_STATE_ATEXIT_STACK_SIZE` * Default value is `5`. * If `MRB_FIXED_STATE_ATEXIT_STACK` isn't defined this macro is ignored. + +## `mrb_value` configuration. + +`MRB_ENDIAN_BIG` +* If defined compiles mruby for big endian machines. +* Used in `MRB_NAN_BOXING`. +* Some mrbgem use this mrbconf. + +`MRB_NAN_BOXING` +* If defined represent `mrb_value` in boxed `double`. +* Conflicts with `MRB_USE_FLOAT`. + +`MRB_WORD_BOXING` +* If defined represent `mrb_value` as a word. +* If defined `Float` will be a mruby object with `RBasic`. -- cgit v1.2.3 From 340279885e8f8b5dee6b47667ca1cb2d74496172 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Wed, 25 Jun 2014 21:41:54 +0900 Subject: Add notes about restriction of `DISABLE_STDIO`. --- doc/mrbconf/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/mrbconf/README.md b/doc/mrbconf/README.md index e8da29e43..698d2526f 100644 --- a/doc/mrbconf/README.md +++ b/doc/mrbconf/README.md @@ -17,6 +17,10 @@ You can use mrbconfs with following ways: `DISABLE_STDIO` * When defined `` functions won't be used. +* Some features will be disabled when this is enabled: + * `mrb_irep` load/dump from/to file. + * Compiling mruby script from file. + * Printing features in **src/print.c**. ## Debug macros. `ENABLE_DEBUG` -- cgit v1.2.3