|
89 | 89 | import org.jruby.internal.runtime.methods.UndefinedMethod;
|
90 | 90 | import org.jruby.ir.IRClosure;
|
91 | 91 | import org.jruby.ir.IRMethod;
|
| 92 | +import org.jruby.ir.instructions.CallBase; |
| 93 | +import org.jruby.ir.instructions.ClassSuperInstr; |
| 94 | +import org.jruby.ir.instructions.InstanceSuperInstr; |
| 95 | +import org.jruby.ir.instructions.Instr; |
| 96 | +import org.jruby.ir.instructions.ModuleSuperInstr; |
| 97 | +import org.jruby.ir.instructions.UnresolvedSuperInstr; |
| 98 | +import org.jruby.ir.interpreter.InterpreterContext; |
| 99 | +import org.jruby.ir.representations.BasicBlock; |
92 | 100 | import org.jruby.ir.targets.indy.Bootstrap;
|
| 101 | +import org.jruby.ir.transformations.inlining.SimpleCloneInfo; |
93 | 102 | import org.jruby.javasupport.JavaClass;
|
94 | 103 | import org.jruby.javasupport.binding.MethodGatherer;
|
95 | 104 | import org.jruby.parser.StaticScope;
|
|
102 | 111 | import org.jruby.runtime.IRBlockBody;
|
103 | 112 | import org.jruby.runtime.MethodFactory;
|
104 | 113 | import org.jruby.runtime.MethodIndex;
|
| 114 | +import org.jruby.runtime.MixedModeIRBlockBody; |
105 | 115 | import org.jruby.runtime.ObjectAllocator;
|
106 | 116 | import org.jruby.runtime.ThreadContext;
|
107 | 117 | import org.jruby.runtime.Visibility;
|
@@ -1616,7 +1626,7 @@ private CacheEntry refinedMethodOriginalMethodEntry(Map<RubyModule, RubyModule>
|
1616 | 1626 | * failed to return a result. Cache superclass definitions in this class.
|
1617 | 1627 | *
|
1618 | 1628 | * MRI: method_entry_get_without_cache
|
1619 |
| - * |
| 1629 | + * |
1620 | 1630 | * @param id The name of the method to search for
|
1621 | 1631 | * @param cacheUndef Flag for caching UndefinedMethod. This should normally be true.
|
1622 | 1632 | * @return The method, or UndefinedMethod if not found
|
@@ -2386,19 +2396,57 @@ public IRubyObject defineMethodFromBlock(ThreadContext context, IRubyObject arg0
|
2386 | 2396 |
|
2387 | 2397 | // If we know it comes from IR we can convert this directly to a method and
|
2388 | 2398 | // avoid overhead of invoking it as a block
|
2389 |
| - if (block.getBody() instanceof IRBlockBody && |
2390 |
| - runtime.getInstanceConfig().getCompileMode().shouldJIT()) { // FIXME: Once Interp and Mixed Methods are one class we can fix this to work in interp mode too. |
| 2399 | + if (block.getBody() instanceof IRBlockBody) { |
2391 | 2400 | IRBlockBody body = (IRBlockBody) block.getBody();
|
2392 | 2401 | IRClosure closure = body.getScope();
|
2393 | 2402 |
|
2394 |
| - // closure may be null from AOT scripts |
2395 |
| - if (closure != null) { |
2396 |
| - // Ask closure to give us a method equivalent. |
2397 |
| - IRMethod method = closure.convertToMethod(name.getBytes()); |
2398 |
| - if (method != null) { |
2399 |
| - newMethod = new DefineMethodMethod(method, visibility, this, context.getFrameBlock()); |
2400 |
| - Helpers.addInstanceMethod(this, name, newMethod, visibility, context, runtime); |
2401 |
| - return name; |
| 2403 | + // clone for rewriting and optimization specific to define_method |
| 2404 | + closure = closure.cloneForInlining(new SimpleCloneInfo(closure, false)); |
| 2405 | + body = new MixedModeIRBlockBody(closure, body.getSignature()); |
| 2406 | + block = new Block(body, block.getBinding(), block.type); |
| 2407 | + |
| 2408 | + InterpreterContext ic = closure.prepareFullBuild(); |
| 2409 | + for (BasicBlock bb : ic.getCFG().getBasicBlocks()) { |
| 2410 | + ArrayList<Instr> newList = new ArrayList<>(); |
| 2411 | + for (Instr i : bb.getInstrs()) { |
| 2412 | + if (i instanceof CallBase) { |
| 2413 | + CallBase cb = (CallBase) i; |
| 2414 | + |
| 2415 | + if (cb instanceof UnresolvedSuperInstr) { |
| 2416 | + newList.add( |
| 2417 | + new ModuleSuperInstr( |
| 2418 | + closure, |
| 2419 | + cb.getResult(), |
| 2420 | + name, |
| 2421 | + cb.getReceiver(), |
| 2422 | + cb.getCallArgs(), |
| 2423 | + cb.getClosureArg(), |
| 2424 | + cb.isPotentiallyRefined())); |
| 2425 | + continue; |
| 2426 | + } |
| 2427 | + |
| 2428 | + if (cb instanceof InstanceSuperInstr || |
| 2429 | + cb instanceof ClassSuperInstr || |
| 2430 | + cb instanceof ModuleSuperInstr) { |
| 2431 | + cb.setName(name); |
| 2432 | + } |
| 2433 | + } |
| 2434 | + |
| 2435 | + newList.add(i); |
| 2436 | + } |
| 2437 | + } |
| 2438 | + |
| 2439 | + if (runtime.getInstanceConfig().getCompileMode().shouldJIT()) { // FIXME: Once Interp and Mixed Methods are one class we can fix this to work in interp mode too. |
| 2440 | + |
| 2441 | + // closure may be null from AOT scripts |
| 2442 | + if (closure != null) { |
| 2443 | + // Ask closure to give us a method equivalent. |
| 2444 | + IRMethod method = closure.convertToMethod(name.getBytes()); |
| 2445 | + if (method != null) { |
| 2446 | + newMethod = new DefineMethodMethod(method, visibility, this, context.getFrameBlock()); |
| 2447 | + Helpers.addInstanceMethod(this, name, newMethod, visibility, context, runtime); |
| 2448 | + return name; |
| 2449 | + } |
2402 | 2450 | }
|
2403 | 2451 | }
|
2404 | 2452 | }
|
|
0 commit comments