Skip to content

HTTPS clone URL

Subversion checkout URL

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