Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 886 lines (771 sloc) 19.073 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 *
4aca101 @drernie Added 2010 Copyrights
drernie authored
6 * Copyright (C) 2007-2010, 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
482f2b7 implement Module.nesting
Laurent Sansonetti authored
232 rb_mod_nesting(VALUE rcv, SEL sel, VALUE top, int argc, VALUE *argv)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
233 {
482f2b7 implement Module.nesting
Laurent Sansonetti authored
234 rb_scan_args(argc, argv, "00");
9c1d230 committing experimental branch content
Laurent Sansonetti authored
235
482f2b7 implement Module.nesting
Laurent Sansonetti authored
236 switch (TYPE(top)) {
237 case T_CLASS:
238 case T_MODULE:
239 return rb_vm_module_nesting(top);
240
241 default:
aca6ea4 Module.nesting: return an empty array instead of nil in case the top …
Laurent Sansonetti authored
242 return rb_ary_new();
9c1d230 committing experimental branch content
Laurent Sansonetti authored
243 }
244 }
245
246 /*
247 * call-seq:
248 * Module.constants => array
249 *
250 * Returns an array of the names of all constants defined in the
251 * system. This list includes the names of all modules and classes.
252 *
253 * p Module.constants.sort[1..5]
254 *
255 * <em>produces:</em>
256 *
257 * ["ARGV", "ArgumentError", "Array", "Bignum", "Binding"]
258 */
259
260 VALUE rb_mod_constants(VALUE, SEL, int, VALUE *);
261
262 static VALUE
263 rb_mod_s_constants(VALUE mod, SEL sel, int argc, VALUE *argv)
264 {
265 if (argc > 0) {
266 return rb_mod_constants(rb_cModule, 0, argc, argv);
267 }
268
269 #if 0 // TODO
270 const NODE *cref = vm_cref();
271 VALUE klass;
272 VALUE cbase = 0;
273 void *data = 0;
274
275 while (cref) {
276 klass = cref->nd_clss;
277 if (!NIL_P(klass)) {
278 data = rb_mod_const_at(cref->nd_clss, data);
279 if (!cbase) {
280 cbase = klass;
281 }
282 }
283 cref = cref->nd_next;
284 }
285
286 if (cbase) {
287 data = rb_mod_const_of(cbase, data);
288 }
289 return rb_const_list(data);
290 #endif
291 return Qnil;
292 }
293
294 void
295 rb_frozen_class_p(VALUE klass)
296 {
297 const char *desc = "something(?!)";
298
299 if (OBJ_FROZEN(klass)) {
300 if (RCLASS_SINGLETON(klass))
301 desc = "object";
302 else {
303 switch (TYPE(klass)) {
304 case T_MODULE:
305 case T_ICLASS:
306 desc = "module";
307 break;
308 case T_CLASS:
309 desc = "class";
310 break;
311 }
312 }
313 rb_error_frozen(desc);
314 }
315 }
316
317 VALUE rb_make_backtrace(void);
318
319 void
320 rb_exc_raise(VALUE mesg)
321 {
322 rb_vm_raise(mesg);
323 abort();
324 }
325
326 void
327 rb_exc_fatal(VALUE mesg)
328 {
329 rb_vm_raise(mesg);
330 abort();
331 }
332
333 void
334 rb_interrupt(void)
335 {
336 static const char fmt[1] = {'\0'};
337 rb_raise(rb_eInterrupt, "%s", fmt);
338 }
339
340 static VALUE get_errinfo(void);
341
342 /*
343 * call-seq:
344 * raise
345 * raise(string)
346 * raise(exception [, string [, array]])
347 * fail
348 * fail(string)
349 * fail(exception [, string [, array]])
350 *
351 * With no arguments, raises the exception in <code>$!</code> or raises
352 * a <code>RuntimeError</code> if <code>$!</code> is +nil+.
353 * With a single +String+ argument, raises a
354 * +RuntimeError+ with the string as a message. Otherwise,
355 * the first parameter should be the name of an +Exception+
356 * class (or an object that returns an +Exception+ object when sent
357 * an +exception+ message). The optional second parameter sets the
358 * message associated with the exception, and the third parameter is an
359 * array of callback information. Exceptions are caught by the
360 * +rescue+ clause of <code>begin...end</code> blocks.
361 *
362 * raise "Failed to create socket"
363 * raise ArgumentError, "No parameters", caller
364 */
365
366 static VALUE
367 rb_f_raise(VALUE klass, SEL sel, int argc, VALUE *argv)
368 {
369 VALUE err;
370 if (argc == 0) {
371 err = get_errinfo();
372 if (!NIL_P(err)) {
373 argc = 1;
374 argv = &err;
375 }
376 }
377 rb_vm_raise(rb_make_exception(argc, argv));
378 return Qnil; /* not reached */
379 }
380
381 VALUE
382 rb_make_exception(int argc, VALUE *argv)
383 {
384 VALUE mesg;
385 ID exception;
386 int n;
387
388 mesg = Qnil;
389 switch (argc) {
390 case 0:
391 //mesg = Qnil;
392 mesg = rb_exc_new2(rb_eRuntimeError, "");
393 break;
394 case 1:
20cb61a fixed #define_method with a Proc to compile a stub with the same arit…
Laurent Sansonetti authored
395 if (NIL_P(argv[0])) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
396 break;
20cb61a fixed #define_method with a Proc to compile a stub with the same arit…
Laurent Sansonetti authored
397 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
398 if (TYPE(argv[0]) == T_STRING) {
399 mesg = rb_exc_new3(rb_eRuntimeError, argv[0]);
400 break;
401 }
402 n = 0;
403 goto exception_call;
404
405 case 2:
406 case 3:
407 n = 1;
408 exception_call:
409 exception = rb_intern("exception");
410 if (!rb_respond_to(argv[0], exception)) {
411 rb_raise(rb_eTypeError, "exception class/object expected");
412 }
413 mesg = rb_funcall(argv[0], exception, n, argv[1]);
414 break;
415 default:
416 rb_raise(rb_eArgError, "wrong number of arguments");
417 break;
418 }
419 if (argc > 0) {
420 if (!rb_obj_is_kind_of(mesg, rb_eException))
421 rb_raise(rb_eTypeError, "exception object expected");
422 if (argc > 2)
423 set_backtrace(mesg, argv[2]);
424 }
425
426 return mesg;
427 }
428
429 int
430 rb_iterator_p()
431 {
432 return rb_block_given_p();
433 }
434
435 /*
436 * call-seq:
437 * block_given? => true or false
438 * iterator? => true or false
439 *
440 * Returns <code>true</code> if <code>yield</code> would execute a
441 * block in the current context. The <code>iterator?</code> form
442 * is mildly deprecated.
443 *
444 * def try
445 * if block_given?
446 * yield
447 * else
448 * "no block"
449 * end
450 * end
451 * try #=> "no block"
452 * try { "hello" } #=> "hello"
453 * try do "hello" end #=> "hello"
454 */
455
456
457 static VALUE
458 rb_f_block_given_p(VALUE self, SEL sel)
459 {
364fc04 more block fixes
Laurent Sansonetti authored
460 return rb_vm_block_saved() ? Qtrue : Qfalse;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
461 }
462
463 VALUE rb_eThreadError;
464
465 void
466 rb_need_block()
467 {
468 if (!rb_block_given_p()) {
469 // TODO
470 //vm_localjump_error("no block given", Qnil, 0);
471 rb_raise(rb_eRuntimeError, "no block given");
472 }
473 }
474
475 VALUE
476 rb_rescue(VALUE (* b_proc)(ANYARGS), VALUE data1,
477 VALUE (* r_proc)(ANYARGS), VALUE data2)
478 {
479 return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError,
480 (VALUE)0);
481 }
482
303814f fix conformance bugs in rb_protect() and add rb_jump_tag()
Laurent Sansonetti authored
483 // XXX not thread-safe, but it doesn't matter, since clients are C extensions
484 // which are not reentrant anyways.
485 static VALUE protect_exc = Qnil;
486
487 static VALUE
488 protect_rescue(VALUE obj, VALUE exc)
489 {
490 *(int *)obj = 1;
491 GC_RETAIN(exc);
492 protect_exc = exc;
493 return Qnil;
494 }
495
9c1d230 committing experimental branch content
Laurent Sansonetti authored
496 VALUE
303814f fix conformance bugs in rb_protect() and add rb_jump_tag()
Laurent Sansonetti authored
497 rb_protect(VALUE (*proc) (VALUE), VALUE data, int *state)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
498 {
ed119a4 fixed Dir.glob() & co
Laurent Sansonetti authored
499 if (state != NULL) {
500 *state = 0;
501 }
303814f fix conformance bugs in rb_protect() and add rb_jump_tag()
Laurent Sansonetti authored
502 return rb_rescue2(proc, data, protect_rescue, (VALUE)state,
503 rb_eStandardError, (VALUE)0);
504 }
505
506 void
507 rb_jump_tag(int state)
508 {
509 assert(state > 0);
510 VALUE exc = protect_exc;
511 assert(exc != Qnil);
512 protect_exc = Qnil;
513 GC_RELEASE(exc);
514 rb_exc_raise(exc);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
515 }
516
517 ID
518 rb_frame_this_func(void)
519 {
520 // TODO
521 return 0;
522 }
523
524 ID
525 rb_frame_callee(void)
526 {
527 // TODO
528 return 0;
529 }
530
531 /*
532 * call-seq:
533 * append_features(mod) => mod
534 *
535 * When this module is included in another, Ruby calls
536 * <code>append_features</code> in this module, passing it the
537 * receiving module in _mod_. Ruby's default implementation is
538 * to add the constants, methods, and module variables of this module
539 * to _mod_ if this module has not already been added to
540 * _mod_ or one of its ancestors. See also <code>Module#include</code>.
541 */
542
543 static VALUE
544 rb_mod_append_features(VALUE module, SEL sel, VALUE include)
545 {
86da889 when including a module that defines a special method (currently -ini…
Laurent Sansonetti authored
546 VALUE orig = include;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
547 switch (TYPE(include)) {
97822b2 fixed several bugs in module mixin
Laurent Sansonetti authored
548 case T_CLASS:
549 case T_MODULE:
550 break;
551 default:
552 Check_Type(include, T_CLASS);
553 break;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
554 }
97822b2 fixed several bugs in module mixin
Laurent Sansonetti authored
555 if (RCLASS_RUBY(include)) {
556 VALUE sinclude = rb_make_singleton_class(RCLASS_SUPER(include));
557 RCLASS_SET_SUPER(include, sinclude);
558 include = sinclude;
559 }
86da889 when including a module that defines a special method (currently -ini…
Laurent Sansonetti authored
560 rb_include_module2(include, orig, module, true, true);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
561
97822b2 fixed several bugs in module mixin
Laurent Sansonetti authored
562 VALUE m = module;
563 do {
564 VALUE ary = rb_attr_get(m, idIncludedModules);
565 if (ary != Qnil) {
566 for (int i = 0, count = RARRAY_LEN(ary); i < count; i++) {
567 VALUE mod = RARRAY_AT(ary, i);
568 rb_mod_append_features(mod, sel, include);
569 }
570 }
571 m = RCLASS_SUPER(m);
572 }
573 while (m == 0 || RCLASS_SINGLETON(m));
574
9c1d230 committing experimental branch content
Laurent Sansonetti authored
575 return module;
576 }
577
578 /*
579 * call-seq:
580 * include(module, ...) => self
581 *
582 * Invokes <code>Module.append_features</code> on each parameter in turn.
583 */
584
585 static VALUE
586 rb_mod_include(VALUE module, SEL sel, int argc, VALUE *argv)
587 {
588 int i;
589
590 for (i = 0; i < argc; i++) {
591 Check_Type(argv[i], T_MODULE);
592 }
593 while (argc--) {
594 rb_funcall(argv[argc], rb_intern("append_features"), 1, module);
595 rb_funcall(argv[argc], rb_intern("included"), 1, module);
596 }
597 return module;
598 }
599
600 VALUE
601 rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
602 {
603 return rb_funcall2(obj, idInitialize, argc, argv);
604 }
605
606 void
607 rb_extend_object(VALUE obj, VALUE module)
608 {
97822b2 fixed several bugs in module mixin
Laurent Sansonetti authored
609 VALUE klass;
610 if (TYPE(obj) == T_CLASS && RCLASS_RUBY(obj)) {
611 VALUE sklass = rb_make_singleton_class(RCLASS_SUPER(obj));
612 RCLASS_SET_SUPER(obj, sklass);
613 klass = *(VALUE *)sklass;
614 }
615 else {
616 klass = rb_singleton_class(obj);
ddd550f #extend_object: honor nested modules
Laurent Sansonetti authored
617 }
618
97822b2 fixed several bugs in module mixin
Laurent Sansonetti authored
619 rb_include_module(klass, module);
ddd550f #extend_object: honor nested modules
Laurent Sansonetti authored
620
621 VALUE m = module;
622 do {
623 VALUE ary = rb_attr_get(m, idIncludedModules);
624 if (ary != Qnil) {
625 for (int i = 0, count = RARRAY_LEN(ary); i < count; i++) {
626 VALUE mod = RARRAY_AT(ary, i);
627 rb_extend_object(obj, mod);
628 }
629 }
630 m = RCLASS_SUPER(m);
631 }
632 while (m == 0 || RCLASS_SINGLETON(m));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
633 }
634
635 /*
636 * call-seq:
637 * extend_object(obj) => obj
638 *
639 * Extends the specified object by adding this module's constants and
640 * methods (which are added as singleton methods). This is the callback
641 * method used by <code>Object#extend</code>.
642 *
643 * module Picky
644 * def Picky.extend_object(o)
645 * if String === o
646 * puts "Can't add Picky to a String"
647 * else
648 * puts "Picky added to #{o.class}"
649 * super
650 * end
651 * end
652 * end
653 * (s = Array.new).extend Picky # Call Object.extend
654 * (s = "quick brown fox").extend Picky
655 *
656 * <em>produces:</em>
657 *
658 * Picky added to Array
659 * Can't add Picky to a String
660 */
661
662 static VALUE
663 rb_mod_extend_object(VALUE mod, SEL sel, VALUE obj)
664 {
665 rb_extend_object(obj, mod);
666 return obj;
667 }
668
669 /*
670 * call-seq:
671 * obj.extend(module, ...) => obj
672 *
673 * Adds to _obj_ the instance methods from each module given as a
674 * parameter.
675 *
676 * module Mod
677 * def hello
678 * "Hello from Mod.\n"
679 * end
680 * end
681 *
682 * class Klass
683 * def hello
684 * "Hello from Klass.\n"
685 * end
686 * end
687 *
688 * k = Klass.new
689 * k.hello #=> "Hello from Klass.\n"
690 * k.extend(Mod) #=> #<Klass:0x401b3bc8>
691 * k.hello #=> "Hello from Mod.\n"
692 */
693
694 static VALUE
695 rb_obj_extend(VALUE obj, SEL sel, int argc, VALUE *argv)
696 {
8789583 fixed indentation and coding style
Laurent Sansonetti authored
697 if (OBJ_FROZEN(obj)) {
698 rb_raise(rb_eRuntimeError, "cannot extend a frozen object");
699 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
700 if (argc == 0) {
701 rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
702 }
8789583 fixed indentation and coding style
Laurent Sansonetti authored
703 for (int i = 0; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
704 Check_Type(argv[i], T_MODULE);
8789583 fixed indentation and coding style
Laurent Sansonetti authored
705 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
706 while (argc--) {
707 rb_funcall(argv[argc], rb_intern("extend_object"), 1, obj);
708 rb_funcall(argv[argc], rb_intern("extended"), 1, obj);
709 }
710 return obj;
711 }
712
713 /*
714 * call-seq:
715 * include(module, ...) => self
716 *
717 * Invokes <code>Module.append_features</code>
718 * on each parameter in turn. Effectively adds the methods and constants
719 * in each module to the receiver.
720 */
721
722 static VALUE
723 top_include(VALUE self, SEL sel, int argc, VALUE *argv)
724 {
725 #if 0
726 rb_thread_t *th = GET_THREAD();
727
728 rb_secure(4);
729 if (th->top_wrapper) {
730 rb_warning
731 ("main#include in the wrapped load is effective only in wrapper module");
732 return rb_mod_include(argc, argv, th->top_wrapper);
733 }
734 #endif
735 return rb_mod_include(rb_cObject, 0, argc, argv);
736 }
737
738 VALUE rb_f_trace_var();
739 VALUE rb_f_untrace_var();
740
741 static VALUE
742 get_errinfo(void)
743 {
c9a4acf implement $! + fixed a bug in the way we save+pop the current VM exce…
Laurent Sansonetti authored
744 VALUE exc = rb_vm_current_exception();
745 if (NIL_P(exc)) {
746 exc = rb_errinfo();
747 }
748 return exc;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
749 }
750
751 static VALUE
752 errinfo_getter(ID id)
753 {
c9a4acf implement $! + fixed a bug in the way we save+pop the current VM exce…
Laurent Sansonetti authored
754 return get_errinfo();
9c1d230 committing experimental branch content
Laurent Sansonetti authored
755 }
756
757 VALUE
758 rb_rubylevel_errinfo(void)
759 {
760 return get_errinfo();
761 }
762
763 static VALUE
764 errat_getter(ID id)
765 {
766 VALUE err = get_errinfo();
767 if (!NIL_P(err)) {
768 return get_backtrace(err);
769 }
770 else {
771 return Qnil;
772 }
773 }
774
775 static void
776 errat_setter(VALUE val, ID id, VALUE *var)
777 {
778 VALUE err = get_errinfo();
779 if (NIL_P(err)) {
780 rb_raise(rb_eArgError, "$! not set");
781 }
782 set_backtrace(err, val);
783 }
784
785 /*
786 * call-seq:
787 * local_variables => array
788 *
789 * Returns the names of the current local variables.
790 *
791 * fred = 1
792 * for i in 1..10
793 * # ...
794 * end
795 * local_variables #=> ["fred", "i"]
796 */
797
798 static VALUE
799 rb_f_local_variables(VALUE rcv, SEL sel)
800 {
57f584c when creating a binding, keep a reference to the top one
Laurent Sansonetti authored
801 rb_vm_binding_t *b = rb_vm_current_binding();
084a52a a faster implementation of dvars + fixed eval bugs + preliminary impl…
Laurent Sansonetti authored
802 VALUE ary = rb_ary_new();
57f584c when creating a binding, keep a reference to the top one
Laurent Sansonetti authored
803 while (b != NULL) {
804 rb_vm_local_t *l;
805 for (l = b->locals; l != NULL; l = l->next) {
806 rb_ary_push(ary, ID2SYM(l->name));
807 }
808 b = b->next;
084a52a a faster implementation of dvars + fixed eval bugs + preliminary impl…
Laurent Sansonetti authored
809 }
810 return ary;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
811 }
812
813
814 /*
815 * call-seq:
816 * __method__ => symbol
817 * __callee__ => symbol
818 *
819 * Returns the name of the current method as a Symbol.
820 * If called outside of a method, it returns <code>nil</code>.
821 *
822 */
823
824 static VALUE
825 rb_f_method_name(VALUE rcv, SEL sel)
826 {
00b147f add basic support for __method__ and __callee__
Laurent Sansonetti authored
827 return Qnil;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
828 }
829
830 void Init_vm_eval(void);
831 void Init_eval_method(void);
832
833 VALUE rb_f_eval(VALUE self, SEL sel, int argc, VALUE *argv);
834 VALUE rb_f_global_variables(VALUE rcv, SEL sel);
835 VALUE rb_mod_module_eval(VALUE mod, SEL sel, int argc, VALUE *argv);
836 VALUE rb_f_trace_var(VALUE rcv, SEL sel, int argc, VALUE *argv);
837 VALUE rb_f_untrace_var(VALUE rcv, SEL sel, int argc, VALUE *argv);
838
839 void
840 Init_eval(void)
841 {
842 rb_define_virtual_variable("$@", errat_getter, errat_setter);
843 rb_define_virtual_variable("$!", errinfo_getter, 0);
844
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
845 rb_objc_define_module_function(rb_mKernel, "eval", rb_f_eval, -1);
846 rb_objc_define_module_function(rb_mKernel, "iterator?", rb_f_block_given_p, 0);
847 rb_objc_define_module_function(rb_mKernel, "block_given?", rb_f_block_given_p, 0);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
848
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
849 rb_objc_define_module_function(rb_mKernel, "fail", rb_f_raise, -1);
b376fc9 more backtracing love
Laurent Sansonetti authored
850 rb_objc_define_module_function(rb_mKernel, "raise", rb_f_raise, -1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
851
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
852 rb_objc_define_module_function(rb_mKernel, "global_variables", rb_f_global_variables, 0); /* in variable.c */
853 rb_objc_define_module_function(rb_mKernel, "local_variables", rb_f_local_variables, 0);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
854
855 rb_objc_define_method(rb_mKernel, "__method__", rb_f_method_name, 0);
856 rb_objc_define_method(rb_mKernel, "__callee__", rb_f_method_name, 0);
857
858 rb_objc_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
859 rb_objc_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
860 rb_objc_define_private_method(rb_cModule, "include", rb_mod_include, -1);
861 rb_objc_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
862 rb_objc_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
863
864 rb_undef_method(rb_cClass, "module_function");
865
866 Init_vm_eval();
867 Init_eval_method();
868
482f2b7 implement Module.nesting
Laurent Sansonetti authored
869 rb_objc_define_method(*(VALUE *)rb_cModule, "nesting", rb_mod_nesting, -3);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
870 rb_objc_define_method(*(VALUE *)rb_cModule, "constants", rb_mod_s_constants, -1);
871
872 VALUE cTopLevel = *(VALUE *)rb_vm_top_self();
873 rb_objc_define_method(cTopLevel, "include", top_include, -1);
874
875 rb_objc_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
876
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
877 rb_objc_define_module_function(rb_mKernel, "trace_var", rb_f_trace_var, -1); /* in variable.c */
878 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
879
880 rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
881
882 exception_error = rb_exc_new2(rb_eFatal, "exception reentered");
883 //rb_ivar_set(exception_error, idThrowState, INT2FIX(TAG_FATAL));
59746d9 cleaning up a few things
Laurent Sansonetti authored
884 GC_RETAIN(exception_error);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
885 }
Something went wrong with that request. Please try again.