Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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