|
29 | 29 | package org.jruby; |
30 | 30 |
|
31 | 31 | import org.jcodings.Encoding; |
| 32 | +import org.jruby.api.JRubyAPI; |
32 | 33 | import org.jruby.ast.util.ArgsUtil; |
33 | 34 | import org.jruby.ir.interpreter.Interpreter; |
34 | 35 | import org.jruby.java.proxies.JavaProxy; |
|
75 | 76 | import static org.jruby.api.Error.typeError; |
76 | 77 | import static org.jruby.api.Warn.warn; |
77 | 78 | import static org.jruby.ir.runtime.IRRuntimeHelpers.dupIfKeywordRestAtCallsite; |
| 79 | +import static org.jruby.ir.runtime.IRRuntimeHelpers.getCurrentClassBase; |
78 | 80 | import static org.jruby.runtime.Helpers.invokeChecked; |
79 | 81 | import static org.jruby.runtime.ThreadContext.*; |
80 | 82 | import static org.jruby.runtime.Visibility.*; |
@@ -460,16 +462,22 @@ public static RubyClass getMetaClass(IRubyObject arg) { |
460 | 462 | return ((RubyBasicObject) arg).metaClass; |
461 | 463 | } |
462 | 464 |
|
463 | | - /** rb_singleton_class |
464 | | - * |
465 | | - * Note: this method is specialized for RubyFixnum, RubySymbol, |
466 | | - * RubyNil and RubyBoolean |
467 | | - * |
468 | | - * Will either return the existing singleton class for this |
469 | | - * object, or create a new one and return that. |
470 | | - */ |
471 | 465 | @Override |
472 | 466 | public RubyClass getSingletonClass() { |
| 467 | + return singletonClass(getCurrentContext()); |
| 468 | + } |
| 469 | + |
| 470 | + /** |
| 471 | + * Will either return the existing singleton class for this object, or create a new one and return that. |
| 472 | + * For a few types a singleton class is not possible so it will throw an error. |
| 473 | + * |
| 474 | + * @param context the current thread context |
| 475 | + * @return the singleton of this type |
| 476 | + */ |
| 477 | + |
| 478 | + // MRI: rb_singleton_class |
| 479 | + @JRubyAPI |
| 480 | + public RubyClass singletonClass(ThreadContext context) { |
473 | 481 | RubyClass klass = metaClass.toSingletonClass(this); |
474 | 482 |
|
475 | 483 | if (isFrozen()) klass.setFrozen(true); |
@@ -1874,12 +1882,15 @@ public IRubyObject specificEval(ThreadContext context, RubyModule mod, IRubyObje |
1874 | 1882 | return evalUnder(context, mod, evalStr, file, line, evalType); |
1875 | 1883 | } |
1876 | 1884 |
|
| 1885 | + @Deprecated(since = "10.0") |
1877 | 1886 | protected RubyModule getInstanceEvalClass() { |
1878 | | - if (isImmediate()) { |
1879 | | - // Ruby uses Qnil here, we use "dummy" because we need a class |
1880 | | - return getRuntime().getDummy(); |
1881 | | - } |
1882 | | - return getSingletonClass(); |
| 1887 | + return getInstanceEvalClass(getCurrentContext()); |
| 1888 | + } |
| 1889 | + |
| 1890 | + protected RubyModule getInstanceEvalClass(ThreadContext context) { |
| 1891 | + return isImmediate() ? |
| 1892 | + context.runtime.getDummy() : // MRI uses Qnil here, we use "dummy" because we need a class |
| 1893 | + singletonClass(context); |
1883 | 1894 | } |
1884 | 1895 |
|
1885 | 1896 | /** |
@@ -2535,25 +2546,25 @@ public RubyArray to_a(ThreadContext context) { |
2535 | 2546 | reads = {LASTLINE, BACKREF, VISIBILITY, BLOCK, SELF, METHODNAME, LINE, CLASS, FILENAME, SCOPE}, |
2536 | 2547 | writes = {LASTLINE, BACKREF, VISIBILITY, BLOCK, SELF, METHODNAME, LINE, CLASS, FILENAME, SCOPE}) |
2537 | 2548 | public IRubyObject instance_eval(ThreadContext context, Block block) { |
2538 | | - return specificEval(context, getInstanceEvalClass(), block, EvalType.INSTANCE_EVAL); |
| 2549 | + return specificEval(context, getInstanceEvalClass(context), block, EvalType.INSTANCE_EVAL); |
2539 | 2550 | } |
2540 | 2551 | @JRubyMethod(name = "instance_eval", |
2541 | 2552 | reads = {LASTLINE, BACKREF, VISIBILITY, BLOCK, SELF, METHODNAME, LINE, CLASS, FILENAME, SCOPE}, |
2542 | 2553 | writes = {LASTLINE, BACKREF, VISIBILITY, BLOCK, SELF, METHODNAME, LINE, CLASS, FILENAME, SCOPE}) |
2543 | 2554 | public IRubyObject instance_eval(ThreadContext context, IRubyObject arg0, Block block) { |
2544 | | - return specificEval(context, getInstanceEvalClass(), arg0, block, EvalType.INSTANCE_EVAL); |
| 2555 | + return specificEval(context, getInstanceEvalClass(context), arg0, block, EvalType.INSTANCE_EVAL); |
2545 | 2556 | } |
2546 | 2557 | @JRubyMethod(name = "instance_eval", |
2547 | 2558 | reads = {LASTLINE, BACKREF, VISIBILITY, BLOCK, SELF, METHODNAME, LINE, CLASS, FILENAME, SCOPE}, |
2548 | 2559 | writes = {LASTLINE, BACKREF, VISIBILITY, BLOCK, SELF, METHODNAME, LINE, CLASS, FILENAME, SCOPE}) |
2549 | 2560 | public IRubyObject instance_eval(ThreadContext context, IRubyObject arg0, IRubyObject arg1, Block block) { |
2550 | | - return specificEval(context, getInstanceEvalClass(), arg0, arg1, block, EvalType.INSTANCE_EVAL); |
| 2561 | + return specificEval(context, getInstanceEvalClass(context), arg0, arg1, block, EvalType.INSTANCE_EVAL); |
2551 | 2562 | } |
2552 | 2563 | @JRubyMethod(name = "instance_eval", |
2553 | 2564 | reads = {LASTLINE, BACKREF, VISIBILITY, BLOCK, SELF, METHODNAME, LINE, CLASS, FILENAME, SCOPE}, |
2554 | 2565 | writes = {LASTLINE, BACKREF, VISIBILITY, BLOCK, SELF, METHODNAME, LINE, CLASS, FILENAME, SCOPE}) |
2555 | 2566 | public IRubyObject instance_eval(ThreadContext context, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, Block block) { |
2556 | | - return specificEval(context, getInstanceEvalClass(), arg0, arg1, arg2, block, EvalType.INSTANCE_EVAL); |
| 2567 | + return specificEval(context, getInstanceEvalClass(context), arg0, arg1, arg2, block, EvalType.INSTANCE_EVAL); |
2557 | 2568 | } |
2558 | 2569 |
|
2559 | 2570 | // This is callable and will work but the rest = true is put so we can match the expected arity error message |
@@ -2593,19 +2604,9 @@ public IRubyObject instance_eval(ThreadContext context, IRubyObject[] args, Bloc |
2593 | 2604 | reads = {LASTLINE, BACKREF, VISIBILITY, BLOCK, SELF, METHODNAME, LINE, CLASS, FILENAME, SCOPE}, |
2594 | 2605 | writes = {LASTLINE, BACKREF, VISIBILITY, BLOCK, SELF, METHODNAME, LINE, CLASS, FILENAME, SCOPE}) |
2595 | 2606 | public IRubyObject instance_exec(ThreadContext context, IRubyObject[] args, Block block) { |
2596 | | - if (!block.isGiven()) { |
2597 | | - throw context.runtime.newLocalJumpErrorNoBlock(); |
2598 | | - } |
2599 | | - |
2600 | | - RubyModule klazz; |
2601 | | - if (isImmediate()) { |
2602 | | - // Ruby uses Qnil here, we use "dummy" because we need a class |
2603 | | - klazz = context.runtime.getDummy(); |
2604 | | - } else { |
2605 | | - klazz = getSingletonClass(); |
2606 | | - } |
| 2607 | + if (!block.isGiven()) throw context.runtime.newLocalJumpErrorNoBlock(); |
2607 | 2608 |
|
2608 | | - return yieldUnder(context, klazz, args, block, EvalType.INSTANCE_EVAL); |
| 2609 | + return yieldUnder(context, getInstanceEvalClass(context), args, block, EvalType.INSTANCE_EVAL); |
2609 | 2610 | } |
2610 | 2611 |
|
2611 | 2612 | /** rb_obj_extend |
|
0 commit comments