Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 172 lines (145 sloc) 4.107 kb
8354436 @mimaki add file header
mimaki authored
1 /*
2 ** proc.c - Proc class
4ec6d41 rm whitespace
roco authored
3 **
8354436 @mimaki add file header
mimaki authored
4 ** See Copyright Notice in mruby.h
5 */
6
e0d6430 @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 @matz cast style consistency
matz authored
17 p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
e0d6430 @mimaki add mruby sources
mimaki authored
18 p->target_class = (mrb->ci) ? mrb->ci->target_class : 0;
472d214 @matz super look-up scheme fixed; close #415
matz authored
19 p->body.irep = irep;
e0d6430 @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 @matz cast style consistency
matz authored
32 e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->ci->proc->env);
300f97a @matz mrb_closure_new uses current irep's nlocals instead of blocks; a patc…
matz authored
33 e->flags= (unsigned int)mrb->ci->proc->body.irep->nlocals;
e0d6430 @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 @matz cast style consistency
matz authored
51 p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
e0d6430 @mimaki add mruby sources
mimaki authored
52 p->body.func = func;
53 p->flags |= MRB_PROC_CFUNC;
54
55 return p;
56 }
57
730f530 @matz define_method to copy block body
matz authored
58 void
59 mrb_proc_copy(struct RProc *a, struct RProc *b)
e9231bc @matz allow lambda duplication
matz authored
60 {
b11d464 @matz ISO conforming lambda
matz authored
61 a->flags = b->flags;
e9231bc @matz 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 @k-tsj 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 @k-tsj Use mrb_get_args instead of direct stack access
k-tsj authored
70 mrb_value blk;
5859a20 @k-tsj Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
71
8ce5893 @k-tsj Use mrb_get_args instead of direct stack access
k-tsj authored
72 mrb_get_args(mrb, "&", &blk);
e9231bc @matz allow lambda duplication
matz authored
73 if (mrb_nil_p(blk)) {
5859a20 @k-tsj 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 @matz allow lambda duplication
matz authored
77 else {
730f530 @matz define_method to copy block body
matz authored
78 mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(blk));
e9231bc @matz 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 @k-tsj Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
87
e9231bc @matz 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 @matz define_method to copy block body
matz authored
92 mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc));
5859a20 @k-tsj Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
93 return self;
94 }
95
e0d6430 @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 @matz 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 @matz define_method to copy block body
matz authored
136 mrb_proc_copy(p2, p);
b11d464 @matz 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 @matz ISO conforming lambda
matz authored
141 }
142
e0d6430 @mimaki add mruby sources
mimaki authored
143 void
144 mrb_init_proc(mrb_state *mrb)
145 {
146 struct RProc *m;
4f7a1a1 @matz 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 @mimaki add mruby sources
mimaki authored
149
150 if ( call_iseq == NULL || call_irep == NULL )
151 return;
152
4f7a1a1 @matz remove memleaks using linked allocator
matz authored
153 memset(call_irep, 0, sizeof(mrb_irep));
e0d6430 @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 @matz allow lambda duplication
matz authored
160 MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC);
e0d6430 @mimaki add mruby sources
mimaki authored
161
5859a20 @k-tsj 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 @matz allow lambda duplication
matz authored
163 mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, ARGS_REQ(1));
5859a20 @k-tsj Fix SEGV when calling Proc object created by Proc.new
k-tsj authored
164
e0d6430 @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 @matz 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 @mimaki add mruby sources
mimaki authored
171 }
Something went wrong with that request. Please try again.