Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 172 lines (145 sloc) 4.107 kb
8354436 Hiroshi Mimaki add file header
mimaki authored
1 /*
2 ** proc.c - Proc class
4ec6d41 rm whitespace
roco authored
3 **
8354436 Hiroshi Mimaki add file header
mimaki authored
4 ** See Copyright Notice in mruby.h
5 */
6
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
7 #include "mruby.h"
8 #include "mruby/proc.h"
9 #include "mruby/class.h"
10 #include "opcode.h"
11
12 struct RProc *
13 mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
14 {
15 struct RProc *p;
16
4523bee Yukihiro "Matz" Matsumoto cast style consistency
matz authored
17 p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
18 p->target_class = (mrb->ci) ? mrb->ci->target_class : 0;
472d214 Yukihiro "Matz" Matsumoto super look-up scheme fixed; close #415
matz authored
19 p->body.irep = irep;
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
20 p->env = 0;
21
22 return p;
23 }
24
25 struct RProc *
26 mrb_closure_new(mrb_state *mrb, mrb_irep *irep)
27 {
28 struct RProc *p = mrb_proc_new(mrb, irep);
29 struct REnv *e;
30
31 if (!mrb->ci->env) {
4523bee Yukihiro "Matz" Matsumoto cast style consistency
matz authored
32 e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->ci->proc->env);
300f97a Yukihiro "Matz" Matsumoto mrb_closure_new uses current irep's nlocals instead of blocks; a patch f...
matz authored
33 e->flags= (unsigned int)mrb->ci->proc->body.irep->nlocals;
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
34 e->mid = mrb->ci->mid;
35 e->cioff = mrb->ci - mrb->cibase;
36 e->stack = mrb->stack;
37 mrb->ci->env = e;
38 }
39 else {
40 e = mrb->ci->env;
41 }
42 p->env = e;
43 return p;
44 }
45
46 struct RProc *
47 mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func)
48 {
49 struct RProc *p;
50
4523bee Yukihiro "Matz" Matsumoto cast style consistency
matz authored
51 p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
52 p->body.func = func;
53 p->flags |= MRB_PROC_CFUNC;
54
55 return p;
56 }
57
730f530 Yukihiro "Matz" Matsumoto define_method to copy block body
matz authored
58 void
59 mrb_proc_copy(struct RProc *a, struct RProc *b)
e9231bc Yukihiro "Matz" Matsumoto allow lambda duplication
matz authored
60 {
b11d464 Yukihiro "Matz" Matsumoto ISO conforming lambda
matz authored
61 a->flags = b->flags;
e9231bc Yukihiro "Matz" Matsumoto allow lambda duplication
matz authored
62 a->body = b->body;
63 a->target_class = b->target_class;
64 a->env = b->env;
65 }
66
5859a20 Kazuki Tsujimoto Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
67 static mrb_value
68 mrb_proc_initialize(mrb_state *mrb, mrb_value self)
69 {
8ce5893 Kazuki Tsujimoto Use mrb_get_args instead of direct stack access
k-tsj authored
70 mrb_value blk;
5859a20 Kazuki Tsujimoto Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
71
8ce5893 Kazuki Tsujimoto Use mrb_get_args instead of direct stack access
k-tsj authored
72 mrb_get_args(mrb, "&", &blk);
e9231bc Yukihiro "Matz" Matsumoto allow lambda duplication
matz authored
73 if (mrb_nil_p(blk)) {
5859a20 Kazuki Tsujimoto Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
74 /* Calling Proc.new without a block is not implemented yet */
75 mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
76 }
e9231bc Yukihiro "Matz" Matsumoto allow lambda duplication
matz authored
77 else {
730f530 Yukihiro "Matz" Matsumoto define_method to copy block body
matz authored
78 mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(blk));
e9231bc Yukihiro "Matz" Matsumoto allow lambda duplication
matz authored
79 }
80 return self;
81 }
82
83 static mrb_value
84 mrb_proc_init_copy(mrb_state *mrb, mrb_value self)
85 {
86 mrb_value proc;
5859a20 Kazuki Tsujimoto Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
87
e9231bc Yukihiro "Matz" Matsumoto allow lambda duplication
matz authored
88 mrb_get_args(mrb, "o", &proc);
89 if (mrb_type(proc) != MRB_TT_PROC) {
90 mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
91 }
730f530 Yukihiro "Matz" Matsumoto define_method to copy block body
matz authored
92 mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc));
5859a20 Kazuki Tsujimoto Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
93 return self;
94 }
95
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
96 int
97 mrb_proc_cfunc_p(struct RProc *p)
98 {
99 return MRB_PROC_CFUNC_P(p);
100 }
101
102 mrb_value
103 mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self)
104 {
105 return (p->body.func)(mrb, self);
106 }
107
108 mrb_code*
109 mrb_proc_iseq(mrb_state *mrb, struct RProc *p)
110 {
111 return p->body.irep->iseq;
112 }
113
b11d464 Yukihiro "Matz" Matsumoto ISO conforming lambda
matz authored
114 /* 15.3.1.2.6 */
115 /* 15.3.1.3.27 */
116 /*
117 * call-seq:
118 * lambda { |...| block } -> a_proc
119 *
120 * Equivalent to <code>Proc.new</code>, except the resulting Proc objects
121 * check the number of parameters passed when called.
122 */
123 static mrb_value
124 proc_lambda(mrb_state *mrb, mrb_value self)
125 {
126 mrb_value blk;
127 struct RProc *p;
128
129 mrb_get_args(mrb, "&", &blk);
130 if (mrb_nil_p(blk)) {
131 mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
132 }
133 p = mrb_proc_ptr(blk);
134 if (!MRB_PROC_STRICT_P(p)) {
135 struct RProc *p2 = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, p->c);
730f530 Yukihiro "Matz" Matsumoto define_method to copy block body
matz authored
136 mrb_proc_copy(p2, p);
b11d464 Yukihiro "Matz" Matsumoto ISO conforming lambda
matz authored
137 p2->flags |= MRB_PROC_STRICT;
138 return mrb_obj_value(p2);
139 }
2936ba1 Masamitsu MURASE proc_lambda should return blk instead of self.
masamitsu-murase authored
140 return blk;
b11d464 Yukihiro "Matz" Matsumoto ISO conforming lambda
matz authored
141 }
142
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
143 void
144 mrb_init_proc(mrb_state *mrb)
145 {
146 struct RProc *m;
4f7a1a1 Yukihiro "Matz" Matsumoto remove memleaks using linked allocator
matz authored
147 mrb_code *call_iseq = (mrb_code *)mrb_alloca(mrb, sizeof(mrb_code));
148 mrb_irep *call_irep = (mrb_irep *)mrb_alloca(mrb, sizeof(mrb_irep));
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
149
150 if ( call_iseq == NULL || call_irep == NULL )
151 return;
152
4f7a1a1 Yukihiro "Matz" Matsumoto remove memleaks using linked allocator
matz authored
153 memset(call_irep, 0, sizeof(mrb_irep));
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
154 *call_iseq = MKOP_A(OP_CALL, 0);
155 call_irep->idx = -1;
156 call_irep->iseq = call_iseq;
157 call_irep->ilen = 1;
158
159 mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class);
e9231bc Yukihiro "Matz" Matsumoto allow lambda duplication
matz authored
160 MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC);
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
161
5859a20 Kazuki Tsujimoto Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
162 mrb_define_method(mrb, mrb->proc_class, "initialize", mrb_proc_initialize, ARGS_NONE());
e9231bc Yukihiro "Matz" Matsumoto allow lambda duplication
matz authored
163 mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, ARGS_REQ(1));
5859a20 Kazuki Tsujimoto Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
164
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
165 m = mrb_proc_new(mrb, call_irep);
166 mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m);
167 mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "[]"), m);
b11d464 Yukihiro "Matz" Matsumoto ISO conforming lambda
matz authored
168
169 mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.2.6 */
170 mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.3.27 */
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
171 }
Something went wrong with that request. Please try again.