Skip to content
This repository
Newer
Older
100644 817 lines (723 sloc) 19.917 kb
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
1 /**********************************************************************
2
3 vm_eval.c -
4
5 $Author: nobu $
6 created at: Sat May 24 16:02:32 JST 2008
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10 Copyright (C) 2000 Information-technology Promotion Agency, Japan
11
12 **********************************************************************/
13
468a2ea9 » Thibault Martin-Lagardette
2010-07-08 Move Obj-C related headers around.
14 #include "ruby/macruby.h"
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
15 #include "ruby/node.h"
16 #include "ruby/st.h"
cb654164 » Laurent Sansonetti
2009-05-23 the great schism, part I
17 #include "vm.h"
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
18 #include "objc.h"
19 #include "id.h"
311a41b1 » Laurent Sansonetti
2010-04-28 rewrote class flags to not use the version field anymore, better typi…
20 #include "class.h"
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
21
22 #include "vm_method.c"
23
24 static inline VALUE
f357c641 » Laurent Sansonetti
2009-05-11 a new implementation for storing active blocks in the VM which fixes …
25 rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, int scope,
26 bool pass_current_block)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
27 {
28 SEL sel;
29 if (mid == ID_ALLOCATOR) {
30 sel = selAlloc;
31 }
32 else {
33 const char *midstr = rb_id2name(mid);
34 if (argc > 0 && midstr[strlen(midstr) - 1] != ':') {
35 char buf[100];
36 snprintf(buf, sizeof buf, "%s:", midstr);
37 sel = sel_registerName(buf);
38 }
39 else {
40 sel = sel_registerName(midstr);
41 }
42 }
f357c641 » Laurent Sansonetti
2009-05-11 a new implementation for storing active blocks in the VM which fixes …
43
44 rb_vm_block_t *block = pass_current_block ? rb_vm_current_block() : NULL;
70ea0b5a » Laurent Sansonetti
2010-06-01 per-vm method cache + misc fixes/improvements
45 return rb_vm_call2(block, recv, CLASS_OF(recv), sel, argc, argv);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
46 }
47
48 /*
49 * call-seq:
50 * obj.method_missing(symbol [, *args] ) => result
51 *
52 * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
53 * <i>symbol</i> is the symbol for the method called, and <i>args</i>
54 * are any arguments that were passed to it. By default, the interpreter
55 * raises an error when this method is called. However, it is possible
56 * to override the method to provide more dynamic behavior.
57 * If it is decided that a particular method should not be handled, then
58 * <i>super</i> should be called, so that ancestors can pick up the
59 * missing method.
60 * The example below creates
61 * a class <code>Roman</code>, which responds to methods with names
62 * consisting of roman numerals, returning the corresponding integer
63 * values.
64 *
65 * class Roman
66 * def romanToInt(str)
67 * # ...
68 * end
69 * def method_missing(methId)
70 * str = methId.id2name
71 * romanToInt(str)
72 * end
73 * end
74 *
75 * r = Roman.new
76 * r.iv #=> 4
77 * r.xxiii #=> 23
78 * r.mm #=> 2000
79 */
80
81 static VALUE
82 rb_method_missing(VALUE obj, SEL sel, int argc, const VALUE *argv)
83 {
84 return rb_vm_method_missing(obj, argc, argv);
85 }
86
87 VALUE
88 rb_apply(VALUE recv, ID mid, VALUE args)
89 {
90 int argc;
91 VALUE *argv;
92
93 argc = RARRAY_LEN(args); /* Assigns LONG, but argc is INT */
94 argv = ALLOCA_N(VALUE, argc);
95 MEMCPY(argv, RARRAY_PTR(args), VALUE, argc);
f357c641 » Laurent Sansonetti
2009-05-11 a new implementation for storing active blocks in the VM which fixes …
96 return rb_call(recv, mid, argc, argv, CALL_FCALL, false);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
97 }
98
99 VALUE
100 rb_funcall(VALUE recv, ID mid, int n, ...)
101 {
102 VALUE *argv;
103 va_list ar;
104 va_start(ar, n);
105
106 if (n > 0) {
107 long i;
108
109 argv = ALLOCA_N(VALUE, n);
110
111 for (i = 0; i < n; i++) {
112 argv[i] = va_arg(ar, VALUE);
113 }
114 va_end(ar);
115 }
116 else {
117 argv = 0;
118 }
f357c641 » Laurent Sansonetti
2009-05-11 a new implementation for storing active blocks in the VM which fixes …
119 return rb_call(recv, mid, n, argv, CALL_FCALL, false);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
120 }
121
122 VALUE
123 rb_funcall2(VALUE recv, ID mid, int argc, const VALUE *argv)
124 {
f357c641 » Laurent Sansonetti
2009-05-11 a new implementation for storing active blocks in the VM which fixes …
125 return rb_call(recv, mid, argc, argv, CALL_FCALL, false);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
126 }
127
128 VALUE
129 rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
130 {
f357c641 » Laurent Sansonetti
2009-05-11 a new implementation for storing active blocks in the VM which fixes …
131 return rb_call(recv, mid, argc, argv, CALL_PUBLIC, false);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
132 }
133
134 static VALUE
135 send_internal(int argc, VALUE *argv, VALUE recv, int scope)
136 {
137 VALUE vid;
138
139 if (argc == 0) {
140 rb_raise(rb_eArgError, "no method name given");
141 }
142
143 vid = *argv++; argc--;
f357c641 » Laurent Sansonetti
2009-05-11 a new implementation for storing active blocks in the VM which fixes …
144 return rb_call(recv, rb_to_id(vid), argc, argv, scope, true);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
145 }
146
147 /*
148 * call-seq:
149 * obj.send(symbol [, args...]) => obj
150 * obj.__send__(symbol [, args...]) => obj
151 *
152 * Invokes the method identified by _symbol_, passing it any
153 * arguments specified. You can use <code>__send__</code> if the name
154 * +send+ clashes with an existing method in _obj_.
155 *
156 * class Klass
157 * def hello(*args)
158 * "Hello " + args.join(' ')
159 * end
160 * end
161 * k = Klass.new
162 * k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
163 */
164
165 static VALUE
166 rb_f_send(VALUE recv, SEL sel, int argc, VALUE *argv)
167 {
168 return send_internal(argc, argv, recv, NOEX_NOSUPER | NOEX_PRIVATE);
169 }
170
171 /*
172 * call-seq:
173 * obj.public_send(symbol [, args...]) => obj
174 *
175 * Invokes the method identified by _symbol_, passing it any
176 * arguments specified. Unlike send, public_send calls public
177 * methods only.
178 *
179 * 1.public_send(:puts, "hello") # causes NoMethodError
180 */
181
182 static VALUE
183 rb_f_public_send(VALUE recv, SEL sel, int argc, VALUE *argv)
184 {
185 return send_internal(argc, argv, recv, NOEX_PUBLIC);
186 }
187
188 /* yield */
189
190 VALUE
8e4c2c73 » Laurent Sansonetti
2010-06-05 moving the dispatcher bits into the kernel + misc fixes/cleanup
191 rb_yield(VALUE val)
192 {
193 if (val == Qundef) {
194 return rb_vm_yield(0, NULL);
195 }
196 return rb_vm_yield(1, &val);
197 }
198
199 VALUE
200 rb_yield_values2(int argc, const VALUE *argv)
201 {
202 return rb_vm_yield(argc, argv);
203 }
204
205 VALUE
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
206 rb_yield_values(int n, ...)
207 {
208 if (n == 0) {
dabee306 » Laurent Sansonetti
2009-11-04 rb_yield is now inlined + improved GC_WB to not emit a write barrier …
209 return rb_vm_yield(0, 0);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
210 }
211 else {
212 int i;
213 VALUE *argv;
214 va_list args;
215 argv = ALLOCA_N(VALUE, n);
216
217 va_start(args, n);
218 for (i=0; i<n; i++) {
219 argv[i] = va_arg(args, VALUE);
220 }
221 va_end(args);
222
dabee306 » Laurent Sansonetti
2009-11-04 rb_yield is now inlined + improved GC_WB to not emit a write barrier …
223 return rb_vm_yield(n, argv);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
224 }
225 }
226
227 VALUE
228 rb_yield_splat(VALUE values)
229 {
230 VALUE tmp = rb_check_array_type(values);
231 if (NIL_P(tmp)) {
232 rb_raise(rb_eArgError, "not an array");
233 }
dabee306 » Laurent Sansonetti
2009-11-04 rb_yield is now inlined + improved GC_WB to not emit a write barrier …
234 return rb_vm_yield(RARRAY_LEN(tmp), RARRAY_PTR(tmp));
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
235 }
236
237 static VALUE
238 loop_i(void)
239 {
10ef9b1d » Laurent Sansonetti
2009-08-27 testing thread cancelability is all loops wasn't a bright idea
240 int count = 0;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
241 for (;;) {
242 rb_yield(Qundef);
243 RETURN_IF_BROKEN();
a2e495be » vincentisambart
2009-08-28 fixed some of Laurent's strange code ;)
244 if (++count >= 100) {
10ef9b1d » Laurent Sansonetti
2009-08-27 testing thread cancelability is all loops wasn't a bright idea
245 TEST_THREAD_CANCEL();
246 count = 0;
247 }
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
248 }
249 return Qnil;
250 }
251
252 /*
253 * call-seq:
254 * loop {|| block }
255 *
256 * Repeatedly executes the block.
257 *
258 * loop do
259 * print "Input: "
260 * line = gets
261 * break if !line or line =~ /^qQ/
262 * # ...
263 * end
264 *
265 * StopIteration raised in the block breaks the loop.
266 */
267
268 static VALUE
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
269 rb_f_loop(VALUE rcv, SEL sel)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
270 {
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
271 RETURN_ENUMERATOR(rcv, 0, 0);
5c8cd3fe » Laurent Sansonetti
2009-04-03 fixed the return value of #loop (in case of break)
272 return rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
273 }
274
275 VALUE
70ea0b5a » Laurent Sansonetti
2010-06-01 per-vm method cache + misc fixes/improvements
276 rb_objc_block_call(VALUE obj, SEL sel, int argc, VALUE *argv,
277 VALUE (*bl_proc) (ANYARGS), VALUE data2)
38a26b8f » Laurent Sansonetti
2009-03-20 implemented NODE_IFUNC-type blocks
278 {
2c54dbd2 » Laurent Sansonetti
2009-07-01 AOT compiler: added support for blocks
279 rb_vm_block_t *b = rb_vm_create_block((IMP)bl_proc, obj, data2);
70ea0b5a » Laurent Sansonetti
2010-06-01 per-vm method cache + misc fixes/improvements
280 return rb_vm_call2(b, obj, 0, sel, argc, argv);
38a26b8f » Laurent Sansonetti
2009-03-20 implemented NODE_IFUNC-type blocks
281 }
282
283 VALUE
284 rb_block_call(VALUE obj, ID mid, int argc, VALUE *argv,
70ea0b5a » Laurent Sansonetti
2010-06-01 per-vm method cache + misc fixes/improvements
285 VALUE (*bl_proc) (ANYARGS), VALUE data2)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
286 {
38a26b8f » Laurent Sansonetti
2009-03-20 implemented NODE_IFUNC-type blocks
287 SEL sel;
288 if (argc == 0) {
289 sel = sel_registerName(rb_id2name(mid));
290 }
291 else {
292 char buf[100];
293 snprintf(buf, sizeof buf, "%s:", rb_id2name(mid));
294 sel = sel_registerName(buf);
295 }
70ea0b5a » Laurent Sansonetti
2010-06-01 per-vm method cache + misc fixes/improvements
296 return rb_objc_block_call(obj, sel, argc, argv, bl_proc, data2);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
297 }
298
299 VALUE
300 rb_each(VALUE obj)
301 {
f357c641 » Laurent Sansonetti
2009-05-11 a new implementation for storing active blocks in the VM which fixes …
302 return rb_call(obj, idEach, 0, 0, CALL_FCALL, false);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
303 }
304
cf73725a » Laurent Sansonetti
2010-01-17 experimental debugger
305 VALUE
306 rb_vm_eval_string(VALUE self, VALUE klass, VALUE src, rb_vm_binding_t *binding,
307 const char *file, const int line)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
308 {
e68823cd » Laurent Sansonetti
2010-06-19 trim the parser and command-line parsing from static
309 #if MACRUBY_STATIC
310 rb_raise(rb_eRuntimeError,
311 "evaluating strings is not supported in MacRuby static");
312 #else
40717caf » Laurent Sansonetti
2009-03-24 do not print syntax error messages while parsing code within eval
313 bool old_parse_in_eval = rb_vm_parse_in_eval();
314 rb_vm_set_parse_in_eval(true);
cf73725a » Laurent Sansonetti
2010-01-17 experimental debugger
315 if (binding != NULL) {
084a52a0 » Laurent Sansonetti
2009-04-03 a faster implementation of dvars + fixed eval bugs + preliminary impl…
316 // Binding must be added because the parser needs it.
cf73725a » Laurent Sansonetti
2010-01-17 experimental debugger
317 rb_vm_add_binding(binding);
084a52a0 » Laurent Sansonetti
2009-04-03 a faster implementation of dvars + fixed eval bugs + preliminary impl…
318 }
319
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
320 NODE *node = rb_compile_string(file, src, line);
084a52a0 » Laurent Sansonetti
2009-04-03 a faster implementation of dvars + fixed eval bugs + preliminary impl…
321
cf73725a » Laurent Sansonetti
2010-01-17 experimental debugger
322 if (binding != NULL) {
084a52a0 » Laurent Sansonetti
2009-04-03 a faster implementation of dvars + fixed eval bugs + preliminary impl…
323 // We remove the binding now but we still pass it to the VM, which
324 // will use it for compilation.
325 rb_vm_pop_binding();
326 }
40717caf » Laurent Sansonetti
2009-03-24 do not print syntax error messages while parsing code within eval
327 rb_vm_set_parse_in_eval(old_parse_in_eval);
084a52a0 » Laurent Sansonetti
2009-04-03 a faster implementation of dvars + fixed eval bugs + preliminary impl…
328
22ef83cd » Laurent Sansonetti
2009-03-21 let's raise SyntaxError exceptions when there is a parsing error inst…
329 if (node == NULL) {
40717caf » Laurent Sansonetti
2009-03-24 do not print syntax error messages while parsing code within eval
330 VALUE exc = rb_vm_current_exception();
331 if (exc != Qnil) {
7c968bd0 » Laurent Sansonetti
2009-05-12 fixing more exceptions bugs
332 rb_vm_raise_current_exception();
40717caf » Laurent Sansonetti
2009-03-24 do not print syntax error messages while parsing code within eval
333 }
334 else {
335 rb_raise(rb_eSyntaxError, "compile error");
336 }
22ef83cd » Laurent Sansonetti
2009-03-21 let's raise SyntaxError exceptions when there is a parsing error inst…
337 }
084a52a0 » Laurent Sansonetti
2009-04-03 a faster implementation of dvars + fixed eval bugs + preliminary impl…
338
cf73725a » Laurent Sansonetti
2010-01-17 experimental debugger
339 return rb_vm_run_under(klass, self, file, node, binding, true);
e68823cd » Laurent Sansonetti
2010-06-19 trim the parser and command-line parsing from static
340 #endif
cf73725a » Laurent Sansonetti
2010-01-17 experimental debugger
341 }
342
57f584cd » Laurent Sansonetti
2010-10-12 when creating a binding, keep a reference to the top one
343 #define GetBindingPtr(obj) ((rb_vm_binding_t *)DATA_PTR(obj))
344
cf73725a » Laurent Sansonetti
2010-01-17 experimental debugger
345 static VALUE
346 eval_string(VALUE self, VALUE klass, VALUE src, VALUE scope, const char *file,
347 const int line)
348 {
349 rb_vm_binding_t *binding = NULL;
350 if (scope != Qnil) {
351 if (!rb_obj_is_kind_of(scope, rb_cBinding)) {
352 rb_raise(rb_eTypeError, "wrong argument type %s (expected Binding)",
353 rb_obj_classname(scope));
354 }
57f584cd » Laurent Sansonetti
2010-10-12 when creating a binding, keep a reference to the top one
355 binding = GetBindingPtr(scope);
cf73725a » Laurent Sansonetti
2010-01-17 experimental debugger
356 }
357 return rb_vm_eval_string(self, klass, src, binding, file, line);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
358 }
359
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
360 static VALUE
361 specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self)
362 {
90a3eb64 » Laurent Sansonetti
2009-08-25 implemented module_function as a scope + fixed a couple of eval-relat…
363 VALUE retval;
364
365 // XXX: not exception-safe
366 const long old_version = RCLASS_VERSION(klass);
367
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
368 if (rb_block_given_p()) {
369 if (argc > 0) {
90a3eb64 » Laurent Sansonetti
2009-08-25 implemented module_function as a scope + fixed a couple of eval-relat…
370 rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)",
371 argc);
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
372 }
90a3eb64 » Laurent Sansonetti
2009-08-25 implemented module_function as a scope + fixed a couple of eval-relat…
373 rb_vm_set_current_scope(klass, SCOPE_PUBLIC);
374 retval = rb_vm_yield_under(klass, self, 0, NULL);
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
375 }
376 else {
4fcff256 » Laurent Sansonetti
2009-03-23 implemented #instance_eval with a string + disabled the inline #eval …
377 const char *file = "(eval)";
378 int line = 1;
379
380 if (argc == 0) {
381 rb_raise(rb_eArgError, "block not supplied");
382 }
383 if (rb_safe_level() >= 4) {
384 StringValue(argv[0]);
385 }
386 else {
387 SafeStringValue(argv[0]);
388 }
389 if (argc > 3) {
390 const char *name = rb_id2name(rb_frame_callee());
391 rb_raise(rb_eArgError,
392 "wrong number of arguments: %s(src) or %s{..}",
393 name, name);
394 }
395 if (argc > 2) {
396 line = NUM2INT(argv[2]);
397 }
398 if (argc > 1) {
399 file = StringValuePtr(argv[1]);
400 }
90a3eb64 » Laurent Sansonetti
2009-08-25 implemented module_function as a scope + fixed a couple of eval-relat…
401 rb_vm_set_current_scope(klass, SCOPE_PUBLIC);
402 retval = eval_string(self, klass, argv[0], Qnil, file, line);
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
403 }
90a3eb64 » Laurent Sansonetti
2009-08-25 implemented module_function as a scope + fixed a couple of eval-relat…
404
405 RCLASS_SET_VERSION(klass, old_version);
406
407 return retval;
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
408 }
409
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
410 /*
411 * call-seq:
412 * eval(string [, binding [, filename [,lineno]]]) => obj
413 *
414 * Evaluates the Ruby expression(s) in <em>string</em>. If
415 * <em>binding</em> is given, the evaluation is performed in its
416 * context. The binding may be a <code>Binding</code> object or a
417 * <code>Proc</code> object. If the optional <em>filename</em> and
418 * <em>lineno</em> parameters are present, they will be used when
419 * reporting syntax errors.
420 *
421 * def getBinding(str)
422 * return binding
423 * end
424 * str = "hello"
425 * eval "str + ' Fred'" #=> "hello Fred"
426 * eval "str + ' Fred'", getBinding("bye") #=> "bye Fred"
427 */
428
429 VALUE
430 rb_f_eval(VALUE self, SEL sel, int argc, VALUE *argv)
431 {
432 VALUE src, scope, vfile, vline;
433 const char *file = "(eval)";
434 int line = 1;
435
436 rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
437 if (rb_safe_level() >= 4) {
438 StringValue(src);
439 if (!NIL_P(scope) && !OBJ_TAINTED(scope)) {
440 rb_raise(rb_eSecurityError,
441 "Insecure: can't modify trusted binding");
442 }
443 }
444 else {
445 SafeStringValue(src);
446 }
447 if (argc >= 3) {
448 StringValue(vfile);
449 }
450 if (argc >= 4) {
451 line = NUM2INT(vline);
452 }
453 if (!NIL_P(vfile)) {
454 file = RSTRING_PTR(vfile);
455 }
90a3eb64 » Laurent Sansonetti
2009-08-25 implemented module_function as a scope + fixed a couple of eval-relat…
456 VALUE klass;
457 switch (TYPE(self)) {
458 case T_CLASS:
459 case T_MODULE:
460 klass = self;
461 break;
462 default:
e070527c » Laurent Sansonetti
2010-02-25 revert r3589 because it breaks irb...
463 klass = 0;
90a3eb64 » Laurent Sansonetti
2009-08-25 implemented module_function as a scope + fixed a couple of eval-relat…
464 break;
465 }
57f584cd » Laurent Sansonetti
2010-10-12 when creating a binding, keep a reference to the top one
466 #if 0
467 if (!NIL_P(scope)) {
468 rb_vm_binding_t *t = rb_vm_current_binding();
469 assert(t != NULL);
470 rb_vm_binding_t *tmp = rb_vm_create_binding(t->self,
471 t->block, GetBindingPtr(scope), 0, NULL, false);
472 GC_WB(&tmp->locals, t->locals);
473 scope = rb_binding_new_from_binding(tmp);
474 }
475 #endif
90a3eb64 » Laurent Sansonetti
2009-08-25 implemented module_function as a scope + fixed a couple of eval-relat…
476 return eval_string(self, klass, src, scope, file, line);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
477 }
478
479 VALUE
480 rb_eval_string(const char *str)
481 {
084a52a0 » Laurent Sansonetti
2009-04-03 a faster implementation of dvars + fixed eval bugs + preliminary impl…
482 return eval_string(rb_vm_top_self(), 0, rb_str_new2(str), Qnil, "(eval)", 1);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
483 }
484
485 VALUE
486 rb_eval_cmd(VALUE cmd, VALUE arg, int level)
487 {
488 VALUE val = Qnil; /* OK */
489 volatile int safe = rb_safe_level();
490
491 if (OBJ_TAINTED(cmd)) {
492 level = 4;
493 }
494
495 if (TYPE(cmd) != T_STRING) {
496 rb_set_safe_level_force(level);
497 val = rb_funcall2(cmd, rb_intern("call"), RARRAY_LEN(arg),
498 RARRAY_PTR(arg));
499 rb_set_safe_level_force(safe);
500 return val;
501 }
502
6820000e » Thibault Martin-Lagardette
2010-01-20 - Fixed the call to eval_string() in rb_eval_cmd()
503 val = eval_string(0, rb_vm_top_self(), cmd, Qnil, "(eval)", 1);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
504 rb_set_safe_level_force(safe);
505 return val;
506 }
507
508 /*
509 * call-seq:
510 * obj.instance_eval(string [, filename [, lineno]] ) => obj
511 * obj.instance_eval {| | block } => obj
512 *
513 * Evaluates a string containing Ruby source code, or the given block,
514 * within the context of the receiver (_obj_). In order to set the
515 * context, the variable +self+ is set to _obj_ while
516 * the code is executing, giving the code access to _obj_'s
517 * instance variables. In the version of <code>instance_eval</code>
518 * that takes a +String+, the optional second and third
519 * parameters supply a filename and starting line number that are used
520 * when reporting compilation errors.
521 *
522 * class KlassWithSecret
523 * def initialize
524 * @secret = 99
525 * end
526 * end
527 * k = KlassWithSecret.new
528 * k.instance_eval { @secret } #=> 99
529 */
530
531 static VALUE
a8477def » Laurent Sansonetti
2010-11-02 expose rb_obj_instance_eval() MRI API
532 rb_obj_instance_eval_imp(VALUE self, SEL sel, VALUE top, int argc, VALUE *argv)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
533 {
534 VALUE klass;
535
a834a3e6 » Laurent Sansonetti
2010-08-05 #instance_eval: don't attempt to create singleton classes on symbols
536 if (SPECIAL_CONST_P(self) || CLASS_OF(self) == rb_cSymbol) {
de8126fc » Laurent Sansonetti
2009-06-18 appropriately toggle the VM current class when #module_eval/#class_ev…
537 klass = 0;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
538 }
539 else {
a834a3e6 » Laurent Sansonetti
2010-08-05 #instance_eval: don't attempt to create singleton classes on symbols
540 klass = rb_singleton_class(self);
a8477def » Laurent Sansonetti
2010-11-02 expose rb_obj_instance_eval() MRI API
541 if (top != Qundef) {
542 switch (TYPE(top)) {
543 case T_CLASS:
544 case T_MODULE:
545 rb_vm_set_outer(klass, top);
546 break;
547 }
97e44237 » Laurent Sansonetti
2010-01-23 fix a const lookup bug in instance_eval, fix a deadlock when autoload…
548 }
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
549 }
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
550 return specific_eval(argc, argv, klass, self);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
551 }
552
a8477def » Laurent Sansonetti
2010-11-02 expose rb_obj_instance_eval() MRI API
553 VALUE
554 rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
555 {
556 // XXX: does not honor top context variable, so certain const lookups
557 // might fail.
558 return rb_obj_instance_eval_imp(self, 0, Qundef, argc, argv);
559 }
560
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
561 /*
562 * call-seq:
563 * obj.instance_exec(arg...) {|var...| block } => obj
564 *
565 * Executes the given block within the context of the receiver
566 * (_obj_). In order to set the context, the variable +self+ is set
567 * to _obj_ while the code is executing, giving the code access to
568 * _obj_'s instance variables. Arguments are passed as block parameters.
569 *
570 * class KlassWithSecret
571 * def initialize
572 * @secret = 99
573 * end
574 * end
575 * k = KlassWithSecret.new
576 * k.instance_exec(5) {|x| @secret+x } #=> 104
577 */
578
579 static VALUE
580 rb_obj_instance_exec(VALUE self, SEL sel, int argc, VALUE *argv)
581 {
582 VALUE klass;
583
584 if (SPECIAL_CONST_P(self)) {
ae48953d » Laurent Sansonetti
2009-03-24 fixed singleton class definition, when passing a non-Array object as …
585 klass = 0;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
586 }
587 else {
588 klass = rb_singleton_class(self);
589 }
12a1d67f » Laurent Sansonetti
2009-08-25 fixing bugs in instance_eval & friends + fixed some specs so that the…
590 if (!rb_block_given_p()) {
591 rb_raise(rb_eLocalJumpError, "no block given");
592 }
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
593 return rb_vm_yield_under(klass, self, argc, argv);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
594 }
595
596 /*
597 * call-seq:
598 * mod.class_eval(string [, filename [, lineno]]) => obj
599 * mod.module_eval {|| block } => obj
600 *
601 * Evaluates the string or block in the context of _mod_. This can
602 * be used to add methods to a class. <code>module_eval</code> returns
603 * the result of evaluating its argument. The optional _filename_
604 * and _lineno_ parameters set the text for error messages.
605 *
606 * class Thing
607 * end
608 * a = %q{def hello() "Hello there!" end}
609 * Thing.module_eval(a)
610 * puts Thing.new.hello()
611 * Thing.module_eval("invalid code", "dummy", 123)
612 *
613 * <em>produces:</em>
614 *
615 * Hello there!
616 * dummy:123:in `module_eval': undefined local variable
617 * or method `code' for Thing:Class
618 */
619
620 VALUE
621 rb_mod_module_eval(VALUE mod, SEL sel, int argc, VALUE *argv)
622 {
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
623 return specific_eval(argc, argv, mod, mod);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
624 }
625
626 /*
627 * call-seq:
628 * mod.module_exec(arg...) {|var...| block } => obj
629 * mod.class_exec(arg...) {|var...| block } => obj
630 *
631 * Evaluates the given block in the context of the class/module.
632 * The method defined in the block will belong to the receiver.
633 *
634 * class Thing
635 * end
636 * Thing.class_exec{
637 * def hello() "Hello there!" end
638 * }
639 * puts Thing.new.hello()
640 *
641 * <em>produces:</em>
642 *
643 * Hello there!
644 */
645
646 VALUE
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
647 rb_mod_module_exec(VALUE mod, SEL sel, int argc, VALUE *argv)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
648 {
1827cf43 » Laurent Sansonetti
2009-03-21 experimental implementation of instance_eval/instance_exec/module_eva…
649 return rb_vm_yield_under(mod, mod, argc, argv);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
650 }
651
652 /*
653 * call-seq:
654 * throw(symbol [, obj])
655 *
656 * Transfers control to the end of the active +catch+ block
657 * waiting for _symbol_. Raises +NameError+ if there
658 * is no +catch+ block for the symbol. The optional second
659 * parameter supplies a return value for the +catch+ block,
660 * which otherwise defaults to +nil+. For examples, see
661 * <code>Kernel::catch</code>.
662 */
663
664 static VALUE
665 rb_f_throw(VALUE rcv, SEL sel, int argc, VALUE *argv)
666 {
755b4642 » Laurent Sansonetti
2009-04-06 implemented catch/throw
667 VALUE tag, value;
668
669 rb_scan_args(argc, argv, "11", &tag, &value);
670
671 return rb_vm_throw(tag, value);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
672 }
673
674 void
675 rb_throw(const char *tag, VALUE val)
676 {
677 VALUE argv[2];
678
679 argv[0] = ID2SYM(rb_intern(tag));
680 argv[1] = val;
681 rb_f_throw(Qnil, 0, 2, argv);
682 }
683
684 void
685 rb_throw_obj(VALUE tag, VALUE val)
686 {
687 VALUE argv[2];
688
689 argv[0] = tag;
690 argv[1] = val;
691 rb_f_throw(Qnil, 0, 2, argv);
692 }
693
694 /*
695 * call-seq:
696 * catch(symbol) {| | block } > obj
697 *
698 * +catch+ executes its block. If a +throw+ is
699 * executed, Ruby searches up its stack for a +catch+ block
700 * with a tag corresponding to the +throw+'s
701 * _symbol_. If found, that block is terminated, and
702 * +catch+ returns the value given to +throw+. If
703 * +throw+ is not called, the block terminates normally, and
704 * the value of +catch+ is the value of the last expression
705 * evaluated. +catch+ expressions may be nested, and the
706 * +throw+ call need not be in lexical scope.
707 *
708 * def routine(n)
709 * puts n
710 * throw :done if n <= 0
711 * routine(n-1)
712 * end
713 *
714 *
715 * catch(:done) { routine(3) }
716 *
717 * <em>produces:</em>
718 *
719 * 3
720 * 2
721 * 1
722 * 0
723 */
724
725 static VALUE
755b4642 » Laurent Sansonetti
2009-04-06 implemented catch/throw
726 rb_f_catch(VALUE rcv, SEL sel, VALUE tag)
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
727 {
755b4642 » Laurent Sansonetti
2009-04-06 implemented catch/throw
728 return rb_vm_catch(tag);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
729 }
730
731 /*
732 * call-seq:
733 * caller(start=1) => array
734 *
735 * Returns the current execution stack---an array containing strings in
736 * the form ``<em>file:line</em>'' or ``<em>file:line: in
737 * `method'</em>''. The optional _start_ parameter
738 * determines the number of initial stack entries to omit from the
739 * result.
740 *
741 * def a(skip)
742 * caller(skip)
743 * end
744 * def b(skip)
745 * a(skip)
746 * end
747 * def c(skip)
748 * b(skip)
749 * end
750 * c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"]
751 * c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"]
752 * c(2) #=> ["prog:8:in `c'", "prog:12"]
753 * c(3) #=> ["prog:13"]
754 */
755
756 static VALUE
757 rb_f_caller(VALUE klass, SEL sel, int argc, VALUE *argv)
758 {
759 VALUE level;
760 rb_scan_args(argc, argv, "01", &level);
761
0849733d » Laurent Sansonetti
2010-02-14 Kernel#caller: now honor the skip argument
762 int lev;
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
763 if (NIL_P(level)) {
764 lev = 1;
765 }
766 else {
767 lev = NUM2INT(level);
768 }
769
770 if (lev < 0) {
771 rb_raise(rb_eArgError, "negative level (%d)", lev);
772 }
773
0849733d » Laurent Sansonetti
2010-02-14 Kernel#caller: now honor the skip argument
774 return rb_vm_backtrace(lev);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
775 }
776
777 void
778 rb_backtrace(void)
779 {
0849733d » Laurent Sansonetti
2010-02-14 Kernel#caller: now honor the skip argument
780 VALUE ary = rb_vm_backtrace(0);
781 for (long i = 0, count = RARRAY_LEN(ary); i < count; i++) {
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
782 printf("\tfrom %s\n", RSTRING_PTR(RARRAY_AT(ary, i)));
783 }
784 }
785
786 VALUE
787 rb_make_backtrace(void)
788 {
0849733d » Laurent Sansonetti
2010-02-14 Kernel#caller: now honor the skip argument
789 return rb_vm_backtrace(0);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
790 }
791
792 void
793 Init_vm_eval(void)
794 {
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
795 rb_objc_define_module_function(rb_mKernel, "catch", rb_f_catch, 1);
796 rb_objc_define_module_function(rb_mKernel, "throw", rb_f_throw, -1);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
797
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
798 rb_objc_define_module_function(rb_mKernel, "loop", rb_f_loop, 0);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
799
a8477def » Laurent Sansonetti
2010-11-02 expose rb_obj_instance_eval() MRI API
800 rb_objc_define_method(rb_cNSObject, "instance_eval", rb_obj_instance_eval_imp, -3);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
801 rb_objc_define_method(rb_cNSObject, "instance_exec", rb_obj_instance_exec, -1);
802 rb_objc_define_private_method(rb_cNSObject, "method_missing", rb_method_missing, -1);
803 rb_objc_define_method(rb_cNSObject, "__send__", rb_f_send, -1);
804
a8477def » Laurent Sansonetti
2010-11-02 expose rb_obj_instance_eval() MRI API
805 rb_objc_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval_imp, -3);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
806 rb_objc_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
807 rb_objc_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
808 rb_objc_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
809
810 rb_objc_define_method(rb_mKernel, "send", rb_f_send, -1);
811 rb_objc_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
812
813 rb_objc_define_method(rb_cModule, "module_exec", rb_mod_module_exec, -1);
814 rb_objc_define_method(rb_cModule, "class_exec", rb_mod_module_exec, -1);
815
cbe906ec » Laurent Sansonetti
2009-08-26 introduce rb_objc_define_module_function() which mimics the ruby spec
816 rb_objc_define_module_function(rb_mKernel, "caller", rb_f_caller, -1);
9c1d2307 » Laurent Sansonetti
2009-03-11 committing experimental branch content
817 }
818
Something went wrong with that request. Please try again.