Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 872 lines (760 sloc) 18.891 kb
c9a4acf implement $! + fixed a bug in the way we save+pop the current VM exce…
Laurent Sansonetti authored
1 /*
2 * MacRuby implementation of Ruby 1.9's eval.c.
3 *
4 * This file is covered by the Ruby license. See COPYING for more details.
5 *
9595725 update copyrights to 2011
Laurent Sansonetti authored
6 * Copyright (C) 2007-2011, Apple Inc. All rights reserved.
c9a4acf implement $! + fixed a bug in the way we save+pop the current VM exce…
Laurent Sansonetti authored
7 * Copyright (C) 1993-2007 Yukihiro Matsumoto
8 * Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
9 * Copyright (C) 2000 Information-technology Promotion Agency, Japan
10 */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
11
d0898dd include/ruby/macruby.h -> macruby_internal.h
Laurent Sansonetti authored
12 #include "macruby_internal.h"
9c1d230 committing experimental branch content
Laurent Sansonetti authored
13 #include "ruby/node.h"
cb65416 the great schism, part I
Laurent Sansonetti authored
14 #include "vm.h"
9c1d230 committing experimental branch content
Laurent Sansonetti authored
15 #include "dtrace.h"
16 #include "id.h"
311a41b rewrote class flags to not use the version field anymore, better typi…
Laurent Sansonetti authored
17 #include "class.h"
9c1d230 committing experimental branch content
Laurent Sansonetti authored
18
19 VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
20
21 ID rb_frame_callee(void);
22 VALUE rb_eLocalJumpError;
23 VALUE rb_eSysStackError;
24 VALUE sysstack_error;
25
26 static VALUE exception_error;
27
28 #include "eval_error.c"
29 #include "eval_safe.c"
30 #include "eval_jump.c"
31
32 /* initialize ruby */
33
34 extern char ***_NSGetEnviron(void);
35 #define environ (*_NSGetEnviron())
36 char **rb_origenviron;
37
38 void rb_call_inits(void);
39 void Init_ext(void);
40 void Init_PreGC(void);
41 void Init_PreVM(void);
f82d58b a more efficient class flags mechanism, reduced the number of default…
Laurent Sansonetti authored
42 void Init_PreClass(void);
bf1a54a unregister VM objects created from GCD pthreads
Laurent Sansonetti authored
43 void Init_PreGCD(void);
ae4da82 more work
Laurent Sansonetti authored
44 void Init_PreEncoding(void);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
45
21174f3 remove historical dlog variables + misc cleanup
Laurent Sansonetti authored
46 bool ruby_initialized = false;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
47
48 void
49 ruby_init(void)
50 {
51 if (ruby_initialized) {
52 return;
53 }
21174f3 remove historical dlog variables + misc cleanup
Laurent Sansonetti authored
54 ruby_initialized = true;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
55
56 rb_origenviron = environ;
57
f82d58b a more efficient class flags mechanism, reduced the number of default…
Laurent Sansonetti authored
58 Init_PreClass(); // requires nothing
ae4da82 more work
Laurent Sansonetti authored
59 Init_PreGC(); // requires nothing
60 Init_PreVM(); // requires nothing
61 Init_PreGCD(); // requires nothing
62 Init_PreEncoding(); // requires rb_cEncoding, GC
9c1d230 committing experimental branch content
Laurent Sansonetti authored
63
64 rb_call_inits();
65 ruby_prog_init();
66 }
67
68 void *
69 ruby_options(int argc, char **argv)
70 {
e68823c trim the parser and command-line parsing from static
Laurent Sansonetti authored
71 #if MACRUBY_STATIC
72 printf("command-line options are not supported in MacRuby static\n");
73 abort();
74 #else
9c1d230 committing experimental branch content
Laurent Sansonetti authored
75 return ruby_process_options(argc, argv);
e68823c trim the parser and command-line parsing from static
Laurent Sansonetti authored
76 #endif
9c1d230 committing experimental branch content
Laurent Sansonetti authored
77 }
78
79 static void
80 ruby_finalize_0(void)
81 {
82 rb_trap_exit();
83 rb_exec_end_proc();
84 }
85
86 static void
87 ruby_finalize_1(void)
88 {
084a52a a faster implementation of dvars + fixed eval bugs + preliminary impl…
Laurent Sansonetti authored
89 rb_vm_finalize();
9c1d230 committing experimental branch content
Laurent Sansonetti authored
90 ruby_sig_finalize();
91 //GET_THREAD()->errinfo = Qnil;
92 }
93
94 void
95 ruby_finalize(void)
96 {
97 ruby_finalize_0();
98 ruby_finalize_1();
99 }
100
101 int
102 ruby_cleanup(int ex)
103 {
104 #if 1
105 return 0;
106 #else
107 int state;
108 volatile VALUE errs[2];
109 rb_thread_t *th = GET_THREAD();
110 int nerr;
111
112 errs[1] = th->errinfo;
113 th->safe_level = 0;
114
115 ruby_finalize_0();
116
117 errs[0] = th->errinfo;
118 PUSH_TAG();
119 if ((state = EXEC_TAG()) == 0) {
120 //SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all());
121 }
122 else if (ex == 0) {
123 ex = state;
124 }
125 GC_WB(&th->errinfo, errs[1]);
126 ex = error_handle(ex);
127 ruby_finalize_1();
128 POP_TAG();
129 //rb_thread_stop_timer_thread();
130
131 for (nerr = 0; nerr < sizeof(errs) / sizeof(errs[0]); ++nerr) {
132 VALUE err = errs[nerr];
133
134 if (!RTEST(err)) continue;
135
136 /* th->errinfo contains a NODE while break'ing */
137 if (TYPE(err) == T_NODE) continue;
138
139 if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
140 return sysexit_status(err);
141 }
142 else if (rb_obj_is_kind_of(err, rb_eSignal)) {
143 VALUE sig = rb_iv_get(err, "signo");
144 ruby_default_signal(NUM2INT(sig));
145 }
146 else if (ex == 0) {
147 ex = 1;
148 }
149 }
150
151 #if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1
152 switch (ex) {
153 #if EXIT_SUCCESS != 0
154 case 0: return EXIT_SUCCESS;
155 #endif
156 #if EXIT_FAILURE != 1
157 case 1: return EXIT_FAILURE;
158 #endif
159 }
160 #endif
161
162 return ex;
163 #endif
164 }
165
166 void
167 ruby_stop(int ex)
168 {
169 exit(ruby_cleanup(ex));
170 }
171
172 extern VALUE rb_progname;
173
61b9753 delay the require of -r libs until the compiler is available
Laurent Sansonetti authored
174 void rb_require_libraries(void);
175
9c1d230 committing experimental branch content
Laurent Sansonetti authored
176 int
6d62a32 Do not run node if node is not executable. (Backport from 1.9)
Thibault Martin-Lagardette authored
177 ruby_executable_node(void *n, int *status)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
178 {
6d62a32 Do not run node if node is not executable. (Backport from 1.9)
Thibault Martin-Lagardette authored
179 VALUE v = (VALUE)n;
180 int s;
181
182 switch (v) {
183 case Qtrue:
184 s = EXIT_SUCCESS;
185 break;
186 case Qfalse:
187 s = EXIT_FAILURE;
188 break;
189 default:
190 if (!FIXNUM_P(v)) {
191 return TRUE;
192 }
193 s = FIX2INT(v);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
194 }
6d62a32 Do not run node if node is not executable. (Backport from 1.9)
Thibault Martin-Lagardette authored
195 if (status) {
196 *status = s;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
197 }
6d62a32 Do not run node if node is not executable. (Backport from 1.9)
Thibault Martin-Lagardette authored
198 return FALSE;
199 }
200
e68823c trim the parser and command-line parsing from static
Laurent Sansonetti authored
201 #if !defined(MACRUBY_STATIC)
6d62a32 Do not run node if node is not executable. (Backport from 1.9)
Thibault Martin-Lagardette authored
202 int
203 ruby_run_node(void *n)
204 {
205 int status;
206 if (!ruby_executable_node(n, &status)) {
207 ruby_cleanup(0);
208 return status;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
209 }
6d62a32 Do not run node if node is not executable. (Backport from 1.9)
Thibault Martin-Lagardette authored
210 rb_require_libraries();
ab4212c experiment with the LLVM interpreter for #eval (disabled for now)
Laurent Sansonetti authored
211 rb_vm_run(RSTRING_PTR(rb_progname), (NODE *)n, NULL, false);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
212 return ruby_cleanup(0);
213 }
e68823c trim the parser and command-line parsing from static
Laurent Sansonetti authored
214 #endif
9c1d230 committing experimental branch content
Laurent Sansonetti authored
215
216 /*
217 * call-seq:
218 * Module.nesting => array
219 *
220 * Returns the list of +Modules+ nested at the point of call.
221 *
222 * module M1
223 * module M2
224 * $a = Module.nesting
225 * end
226 * end
227 * $a #=> [M1::M2, M1]
228 * $a[0].name #=> "M1::M2"
229 */
230
231 static VALUE
6b101bd @takaokouji supported lexical const lookup. (fixes #619, #626, #1167, #1192) (ref…
takaokouji authored
232 rb_mod_nesting(VALUE self, SEL sel)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
233 {
6b101bd @takaokouji supported lexical const lookup. (fixes #619, #626, #1167, #1192) (ref…
takaokouji authored
234 return rb_vm_module_nesting();
9c1d230 committing experimental branch content
Laurent Sansonetti authored
235 }
236
237 /*
238 * call-seq:
239 * Module.constants => array
240 *
241 * Returns an array of the names of all constants defined in the
242 * system. This list includes the names of all modules and classes.
243 *
244 * p Module.constants.sort[1..5]
245 *
246 * <em>produces:</em>
247 *
248 * ["ARGV", "ArgumentError", "Array", "Bignum", "Binding"]
249 */
250
251 VALUE rb_mod_constants(VALUE, SEL, int, VALUE *);
252
253 static VALUE
254 rb_mod_s_constants(VALUE mod, SEL sel, int argc, VALUE *argv)
255 {
256 if (argc > 0) {
257 return rb_mod_constants(rb_cModule, 0, argc, argv);
258 }
6b101bd @takaokouji supported lexical const lookup. (fixes #619, #626, #1167, #1192) (ref…
takaokouji authored
259 return rb_vm_module_constants();
9c1d230 committing experimental branch content
Laurent Sansonetti authored
260 }
261
262 void
263 rb_frozen_class_p(VALUE klass)
264 {
265 const char *desc = "something(?!)";
266
267 if (OBJ_FROZEN(klass)) {
268 if (RCLASS_SINGLETON(klass))
269 desc = "object";
270 else {
271 switch (TYPE(klass)) {
272 case T_MODULE:
273 case T_ICLASS:
274 desc = "module";
275 break;
276 case T_CLASS:
277 desc = "class";
278 break;
279 }
280 }
281 rb_error_frozen(desc);
282 }
283 }
284
285 VALUE rb_make_backtrace(void);
286
287 void
288 rb_exc_raise(VALUE mesg)
289 {
290 rb_vm_raise(mesg);
291 abort();
292 }
293
294 void
295 rb_exc_fatal(VALUE mesg)
296 {
297 rb_vm_raise(mesg);
298 abort();
299 }
300
301 void
302 rb_interrupt(void)
303 {
304 static const char fmt[1] = {'\0'};
305 rb_raise(rb_eInterrupt, "%s", fmt);
306 }
307
308 static VALUE get_errinfo(void);
309
310 /*
311 * call-seq:
312 * raise
313 * raise(string)
314 * raise(exception [, string [, array]])
315 * fail
316 * fail(string)
317 * fail(exception [, string [, array]])
318 *
319 * With no arguments, raises the exception in <code>$!</code> or raises
320 * a <code>RuntimeError</code> if <code>$!</code> is +nil+.
321 * With a single +String+ argument, raises a
322 * +RuntimeError+ with the string as a message. Otherwise,
323 * the first parameter should be the name of an +Exception+
324 * class (or an object that returns an +Exception+ object when sent
325 * an +exception+ message). The optional second parameter sets the
326 * message associated with the exception, and the third parameter is an
327 * array of callback information. Exceptions are caught by the
328 * +rescue+ clause of <code>begin...end</code> blocks.
329 *
330 * raise "Failed to create socket"
331 * raise ArgumentError, "No parameters", caller
332 */
333
334 static VALUE
335 rb_f_raise(VALUE klass, SEL sel, int argc, VALUE *argv)
336 {
337 VALUE err;
338 if (argc == 0) {
339 err = get_errinfo();
340 if (!NIL_P(err)) {
341 argc = 1;
342 argv = &err;
343 }
344 }
345 rb_vm_raise(rb_make_exception(argc, argv));
346 return Qnil; /* not reached */
347 }
348
349 VALUE
350 rb_make_exception(int argc, VALUE *argv)
351 {
352 VALUE mesg;
353 ID exception;
354 int n;
355
356 mesg = Qnil;
357 switch (argc) {
358 case 0:
359 //mesg = Qnil;
360 mesg = rb_exc_new2(rb_eRuntimeError, "");
361 break;
362 case 1:
20cb61a fixed #define_method with a Proc to compile a stub with the same arit…
Laurent Sansonetti authored
363 if (NIL_P(argv[0])) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
364 break;
20cb61a fixed #define_method with a Proc to compile a stub with the same arit…
Laurent Sansonetti authored
365 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
366 if (TYPE(argv[0]) == T_STRING) {
367 mesg = rb_exc_new3(rb_eRuntimeError, argv[0]);
368 break;
369 }
370 n = 0;
371 goto exception_call;
372
373 case 2:
374 case 3:
375 n = 1;
376 exception_call:
377 exception = rb_intern("exception");
378 if (!rb_respond_to(argv[0], exception)) {
379 rb_raise(rb_eTypeError, "exception class/object expected");
380 }
381 mesg = rb_funcall(argv[0], exception, n, argv[1]);
382 break;
383 default:
384 rb_raise(rb_eArgError, "wrong number of arguments");
385 break;
386 }
387 if (argc > 0) {
388 if (!rb_obj_is_kind_of(mesg, rb_eException))
389 rb_raise(rb_eTypeError, "exception object expected");
390 if (argc > 2)
391 set_backtrace(mesg, argv[2]);
392 }
393
394 return mesg;
395 }
396
397 int
398 rb_iterator_p()
399 {
400 return rb_block_given_p();
401 }
402
403 /*
404 * call-seq:
405 * block_given? => true or false
406 * iterator? => true or false
407 *
408 * Returns <code>true</code> if <code>yield</code> would execute a
409 * block in the current context. The <code>iterator?</code> form
410 * is mildly deprecated.
411 *
412 * def try
413 * if block_given?
414 * yield
415 * else
416 * "no block"
417 * end
418 * end
419 * try #=> "no block"
420 * try { "hello" } #=> "hello"
421 * try do "hello" end #=> "hello"
422 */
423
424
425 static VALUE
426 rb_f_block_given_p(VALUE self, SEL sel)
427 {
364fc04 more block fixes
Laurent Sansonetti authored
428 return rb_vm_block_saved() ? Qtrue : Qfalse;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
429 }
430
431 VALUE rb_eThreadError;
432
433 void
434 rb_need_block()
435 {
436 if (!rb_block_given_p()) {
437 // TODO
438 //vm_localjump_error("no block given", Qnil, 0);
439 rb_raise(rb_eRuntimeError, "no block given");
440 }
441 }
442
443 VALUE
444 rb_rescue(VALUE (* b_proc)(ANYARGS), VALUE data1,
445 VALUE (* r_proc)(ANYARGS), VALUE data2)
446 {
447 return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError,
448 (VALUE)0);
449 }
450
303814f fix conformance bugs in rb_protect() and add rb_jump_tag()
Laurent Sansonetti authored
451 // XXX not thread-safe, but it doesn't matter, since clients are C extensions
452 // which are not reentrant anyways.
453 static VALUE protect_exc = Qnil;
454
455 static VALUE
456 protect_rescue(VALUE obj, VALUE exc)
457 {
8cb9d03 fix a bug where we would crash when protecting an internal call durin…
Laurent Sansonetti authored
458 int *state = (int *)obj;
459 if (state != NULL) {
460 *state = 1;
461 }
303814f fix conformance bugs in rb_protect() and add rb_jump_tag()
Laurent Sansonetti authored
462 GC_RETAIN(exc);
463 protect_exc = exc;
464 return Qnil;
465 }
466
9c1d230 committing experimental branch content
Laurent Sansonetti authored
467 VALUE
303814f fix conformance bugs in rb_protect() and add rb_jump_tag()
Laurent Sansonetti authored
468 rb_protect(VALUE (*proc) (VALUE), VALUE data, int *state)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
469 {
ed119a4 fixed Dir.glob() & co
Laurent Sansonetti authored
470 if (state != NULL) {
471 *state = 0;
472 }
303814f fix conformance bugs in rb_protect() and add rb_jump_tag()
Laurent Sansonetti authored
473 return rb_rescue2(proc, data, protect_rescue, (VALUE)state,
474 rb_eStandardError, (VALUE)0);
475 }
476
477 void
478 rb_jump_tag(int state)
479 {
480 assert(state > 0);
481 VALUE exc = protect_exc;
482 assert(exc != Qnil);
483 protect_exc = Qnil;
484 GC_RELEASE(exc);
485 rb_exc_raise(exc);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
486 }
487
488 ID
489 rb_frame_this_func(void)
490 {
491 // TODO
492 return 0;
493 }
494
495 ID
496 rb_frame_callee(void)
497 {
498 // TODO
499 return 0;
500 }
501
502 /*
503 * call-seq:
504 * append_features(mod) => mod
505 *
506 * When this module is included in another, Ruby calls
507 * <code>append_features</code> in this module, passing it the
508 * receiving module in _mod_. Ruby's default implementation is
509 * to add the constants, methods, and module variables of this module
510 * to _mod_ if this module has not already been added to
511 * _mod_ or one of its ancestors. See also <code>Module#include</code>.
512 */
513
b2a7f15 @lrz avoid cyclic module inclusions
lrz authored
514 static void
515 check_cyclic_include(VALUE klass, VALUE mod)
516 {
517 VALUE m = mod;
518 do {
519 if (m == klass) {
520 rb_raise(rb_eArgError, "cyclic include detected");
521 }
522 m = RCLASS_SUPER(m);
523 }
524 while (RCLASS_SINGLETON(m));
525 }
526
9c1d230 committing experimental branch content
Laurent Sansonetti authored
527 static VALUE
528 rb_mod_append_features(VALUE module, SEL sel, VALUE include)
529 {
86da889 when including a module that defines a special method (currently -ini…
Laurent Sansonetti authored
530 VALUE orig = include;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
531 switch (TYPE(include)) {
97822b2 fixed several bugs in module mixin
Laurent Sansonetti authored
532 case T_CLASS:
533 case T_MODULE:
534 break;
535 default:
536 Check_Type(include, T_CLASS);
537 break;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
538 }
b2a7f15 @lrz avoid cyclic module inclusions
lrz authored
539 check_cyclic_include(include, module);
540
b367258 @takaokouji supported including a module into class Class or class Module.
takaokouji authored
541 if (include != rb_cClass && include != rb_cModule && RCLASS_RUBY(include)) {
97822b2 fixed several bugs in module mixin
Laurent Sansonetti authored
542 VALUE sinclude = rb_make_singleton_class(RCLASS_SUPER(include));
543 RCLASS_SET_SUPER(include, sinclude);
544 include = sinclude;
545 }
86da889 when including a module that defines a special method (currently -ini…
Laurent Sansonetti authored
546 rb_include_module2(include, orig, module, true, true);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
547
97822b2 fixed several bugs in module mixin
Laurent Sansonetti authored
548 VALUE m = module;
549 do {
550 VALUE ary = rb_attr_get(m, idIncludedModules);
551 if (ary != Qnil) {
552 for (int i = 0, count = RARRAY_LEN(ary); i < count; i++) {
553 VALUE mod = RARRAY_AT(ary, i);
554 rb_mod_append_features(mod, sel, include);
555 }
556 }
557 m = RCLASS_SUPER(m);
558 }
559 while (m == 0 || RCLASS_SINGLETON(m));
560
9c1d230 committing experimental branch content
Laurent Sansonetti authored
561 return module;
562 }
563
564 /*
565 * call-seq:
566 * include(module, ...) => self
567 *
568 * Invokes <code>Module.append_features</code> on each parameter in turn.
569 */
570
571 static VALUE
572 rb_mod_include(VALUE module, SEL sel, int argc, VALUE *argv)
573 {
574 int i;
575
576 for (i = 0; i < argc; i++) {
577 Check_Type(argv[i], T_MODULE);
578 }
579 while (argc--) {
580 rb_funcall(argv[argc], rb_intern("append_features"), 1, module);
581 rb_funcall(argv[argc], rb_intern("included"), 1, module);
582 }
583 return module;
584 }
585
586 VALUE
587 rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
588 {
589 return rb_funcall2(obj, idInitialize, argc, argv);
590 }
591
592 void
593 rb_extend_object(VALUE obj, VALUE module)
594 {
97822b2 fixed several bugs in module mixin
Laurent Sansonetti authored
595 VALUE klass;
596 if (TYPE(obj) == T_CLASS && RCLASS_RUBY(obj)) {
597 VALUE sklass = rb_make_singleton_class(RCLASS_SUPER(obj));
598 RCLASS_SET_SUPER(obj, sklass);
599 klass = *(VALUE *)sklass;
600 }
601 else {
602 klass = rb_singleton_class(obj);
ddd550f #extend_object: honor nested modules
Laurent Sansonetti authored
603 }
604
97822b2 fixed several bugs in module mixin
Laurent Sansonetti authored
605 rb_include_module(klass, module);
ddd550f #extend_object: honor nested modules
Laurent Sansonetti authored
606
607 VALUE m = module;
608 do {
609 VALUE ary = rb_attr_get(m, idIncludedModules);
610 if (ary != Qnil) {
611 for (int i = 0, count = RARRAY_LEN(ary); i < count; i++) {
612 VALUE mod = RARRAY_AT(ary, i);
613 rb_extend_object(obj, mod);
614 }
615 }
616 m = RCLASS_SUPER(m);
617 }
618 while (m == 0 || RCLASS_SINGLETON(m));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
619 }
620
621 /*
622 * call-seq:
623 * extend_object(obj) => obj
624 *
625 * Extends the specified object by adding this module's constants and
626 * methods (which are added as singleton methods). This is the callback
627 * method used by <code>Object#extend</code>.
628 *
629 * module Picky
630 * def Picky.extend_object(o)
631 * if String === o
632 * puts "Can't add Picky to a String"
633 * else
634 * puts "Picky added to #{o.class}"
635 * super
636 * end
637 * end
638 * end
639 * (s = Array.new).extend Picky # Call Object.extend
640 * (s = "quick brown fox").extend Picky
641 *
642 * <em>produces:</em>
643 *
644 * Picky added to Array
645 * Can't add Picky to a String
646 */
647
648 static VALUE
649 rb_mod_extend_object(VALUE mod, SEL sel, VALUE obj)
650 {
651 rb_extend_object(obj, mod);
652 return obj;
653 }
654
655 /*
656 * call-seq:
657 * obj.extend(module, ...) => obj
658 *
659 * Adds to _obj_ the instance methods from each module given as a
660 * parameter.
661 *
662 * module Mod
663 * def hello
664 * "Hello from Mod.\n"
665 * end
666 * end
667 *
668 * class Klass
669 * def hello
670 * "Hello from Klass.\n"
671 * end
672 * end
673 *
674 * k = Klass.new
675 * k.hello #=> "Hello from Klass.\n"
676 * k.extend(Mod) #=> #<Klass:0x401b3bc8>
677 * k.hello #=> "Hello from Mod.\n"
678 */
679
680 static VALUE
681 rb_obj_extend(VALUE obj, SEL sel, int argc, VALUE *argv)
682 {
8789583 fixed indentation and coding style
Laurent Sansonetti authored
683 if (OBJ_FROZEN(obj)) {
684 rb_raise(rb_eRuntimeError, "cannot extend a frozen object");
685 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
686 if (argc == 0) {
687 rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
688 }
8789583 fixed indentation and coding style
Laurent Sansonetti authored
689 for (int i = 0; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
690 Check_Type(argv[i], T_MODULE);
8789583 fixed indentation and coding style
Laurent Sansonetti authored
691 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
692 while (argc--) {
693 rb_funcall(argv[argc], rb_intern("extend_object"), 1, obj);
694 rb_funcall(argv[argc], rb_intern("extended"), 1, obj);
695 }
696 return obj;
697 }
698
699 /*
700 * call-seq:
701 * include(module, ...) => self
702 *
703 * Invokes <code>Module.append_features</code>
704 * on each parameter in turn. Effectively adds the methods and constants
705 * in each module to the receiver.
706 */
707
708 static VALUE
709 top_include(VALUE self, SEL sel, int argc, VALUE *argv)
710 {
711 #if 0
712 rb_thread_t *th = GET_THREAD();
713
714 rb_secure(4);
715 if (th->top_wrapper) {
716 rb_warning
717 ("main#include in the wrapped load is effective only in wrapper module");
718 return rb_mod_include(argc, argv, th->top_wrapper);
719 }
720 #endif
721 return rb_mod_include(rb_cObject, 0, argc, argv);
722 }
723
724 VALUE rb_f_trace_var();
725 VALUE rb_f_untrace_var();
726
727 static VALUE
728 get_errinfo(void)
729 {
c9a4acf implement $! + fixed a bug in the way we save+pop the current VM exce…
Laurent Sansonetti authored
730 VALUE exc = rb_vm_current_exception();
731 if (NIL_P(exc)) {
732 exc = rb_errinfo();
733 }
734 return exc;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
735 }
736
737 static VALUE
738 errinfo_getter(ID id)
739 {
c9a4acf implement $! + fixed a bug in the way we save+pop the current VM exce…
Laurent Sansonetti authored
740 return get_errinfo();
9c1d230 committing experimental branch content
Laurent Sansonetti authored
741 }
742
743 VALUE
744 rb_rubylevel_errinfo(void)
745 {
746 return get_errinfo();
747 }
748
749 static VALUE
750 errat_getter(ID id)
751 {
752 VALUE err = get_errinfo();
753 if (!NIL_P(err)) {
754 return get_backtrace(err);
755 }
756 else {
757 return Qnil;
758 }
759 }
760
761 static void
762 errat_setter(VALUE val, ID id, VALUE *var)
763 {
764 VALUE err = get_errinfo();
765 if (NIL_P(err)) {
766 rb_raise(rb_eArgError, "$! not set");
767 }
768 set_backtrace(err, val);
769 }
770
771 /*
772 * call-seq:
773 * local_variables => array
774 *
775 * Returns the names of the current local variables.
776 *
777 * fred = 1
778 * for i in 1..10
779 * # ...
780 * end
781 * local_variables #=> ["fred", "i"]
782 */
783
784 static VALUE
785 rb_f_local_variables(VALUE rcv, SEL sel)
786 {
57f584c when creating a binding, keep a reference to the top one
Laurent Sansonetti authored
787 rb_vm_binding_t *b = rb_vm_current_binding();
084a52a a faster implementation of dvars + fixed eval bugs + preliminary impl…
Laurent Sansonetti authored
788 VALUE ary = rb_ary_new();
57f584c when creating a binding, keep a reference to the top one
Laurent Sansonetti authored
789 while (b != NULL) {
790 rb_vm_local_t *l;
791 for (l = b->locals; l != NULL; l = l->next) {
792 rb_ary_push(ary, ID2SYM(l->name));
793 }
794 b = b->next;
084a52a a faster implementation of dvars + fixed eval bugs + preliminary impl…
Laurent Sansonetti authored
795 }
796 return ary;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
797 }
798
799
800 /*
801 * call-seq:
802 * __method__ => symbol
803 * __callee__ => symbol
804 *
805 * Returns the name of the current method as a Symbol.
806 * If called outside of a method, it returns <code>nil</code>.
807 *
808 */
809
810 static VALUE
811 rb_f_method_name(VALUE rcv, SEL sel)
812 {
00b147f add basic support for __method__ and __callee__
Laurent Sansonetti authored
813 return Qnil;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
814 }
815
816 void Init_vm_eval(void);
817 void Init_eval_method(void);
818
819 VALUE rb_f_eval(VALUE self, SEL sel, int argc, VALUE *argv);
820 VALUE rb_f_global_variables(VALUE rcv, SEL sel);
821 VALUE rb_mod_module_eval(VALUE mod, SEL sel, int argc, VALUE *argv);
822 VALUE rb_f_trace_var(VALUE rcv, SEL sel, int argc, VALUE *argv);
823 VALUE rb_f_untrace_var(VALUE rcv, SEL sel, int argc, VALUE *argv);
824
825 void
826 Init_eval(void)
827 {
828 rb_define_virtual_variable("$@", errat_getter, errat_setter);
829 rb_define_virtual_variable("$!", errinfo_getter, 0);
830
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
831 rb_objc_define_module_function(rb_mKernel, "eval", rb_f_eval, -1);
832 rb_objc_define_module_function(rb_mKernel, "iterator?", rb_f_block_given_p, 0);
833 rb_objc_define_module_function(rb_mKernel, "block_given?", rb_f_block_given_p, 0);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
834
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
835 rb_objc_define_module_function(rb_mKernel, "fail", rb_f_raise, -1);
b376fc9 more backtracing love
Laurent Sansonetti authored
836 rb_objc_define_module_function(rb_mKernel, "raise", rb_f_raise, -1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
837
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
838 rb_objc_define_module_function(rb_mKernel, "global_variables", rb_f_global_variables, 0); /* in variable.c */
839 rb_objc_define_module_function(rb_mKernel, "local_variables", rb_f_local_variables, 0);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
840
841 rb_objc_define_method(rb_mKernel, "__method__", rb_f_method_name, 0);
842 rb_objc_define_method(rb_mKernel, "__callee__", rb_f_method_name, 0);
843
844 rb_objc_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
845 rb_objc_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
846 rb_objc_define_private_method(rb_cModule, "include", rb_mod_include, -1);
847 rb_objc_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
848 rb_objc_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
849
850 rb_undef_method(rb_cClass, "module_function");
851
852 Init_vm_eval();
853 Init_eval_method();
854
6b101bd @takaokouji supported lexical const lookup. (fixes #619, #626, #1167, #1192) (ref…
takaokouji authored
855 rb_objc_define_method(*(VALUE *)rb_cModule, "nesting", rb_mod_nesting, 0);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
856 rb_objc_define_method(*(VALUE *)rb_cModule, "constants", rb_mod_s_constants, -1);
857
858 VALUE cTopLevel = *(VALUE *)rb_vm_top_self();
859 rb_objc_define_method(cTopLevel, "include", top_include, -1);
860
861 rb_objc_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
862
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
863 rb_objc_define_module_function(rb_mKernel, "trace_var", rb_f_trace_var, -1); /* in variable.c */
864 rb_objc_define_module_function(rb_mKernel, "untrace_var", rb_f_untrace_var, -1); /* in variable.c */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
865
866 rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
867
868 exception_error = rb_exc_new2(rb_eFatal, "exception reentered");
869 //rb_ivar_set(exception_error, idThrowState, INT2FIX(TAG_FATAL));
59746d9 cleaning up a few things
Laurent Sansonetti authored
870 GC_RETAIN(exception_error);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
871 }
Something went wrong with that request. Please try again.