|
13 | 13 | import com.oracle.truffle.api.interop.InteropLibrary;
|
14 | 14 | import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
15 | 15 | import com.oracle.truffle.api.object.Shape;
|
| 16 | +import com.oracle.truffle.api.profiles.BranchProfile; |
16 | 17 | import com.oracle.truffle.api.strings.AbstractTruffleString;
|
17 | 18 | import org.truffleruby.Layouts;
|
18 | 19 | import org.truffleruby.builtins.CoreMethod;
|
|
23 | 24 | import org.truffleruby.core.basicobject.BasicObjectNodesFactory.ReferenceEqualNodeFactory;
|
24 | 25 | import org.truffleruby.core.cast.BooleanCastNode;
|
25 | 26 | import org.truffleruby.core.cast.NameToJavaStringNode;
|
| 27 | +import org.truffleruby.core.cast.ToIntNode; |
| 28 | +import org.truffleruby.core.cast.ToStrNode; |
26 | 29 | import org.truffleruby.core.encoding.RubyEncoding;
|
27 | 30 | import org.truffleruby.core.exception.ExceptionOperations.ExceptionFormatter;
|
28 | 31 | import org.truffleruby.core.exception.RubyException;
|
|
44 | 47 | import org.truffleruby.language.RubyNode;
|
45 | 48 | import org.truffleruby.language.RubySourceNode;
|
46 | 49 | import org.truffleruby.language.Visibility;
|
47 |
| -import org.truffleruby.language.arguments.ReadCallerFrameNode; |
48 | 50 | import org.truffleruby.language.arguments.RubyArguments;
|
49 | 51 | import org.truffleruby.language.control.RaiseException;
|
50 | 52 | import org.truffleruby.language.dispatch.DispatchNode;
|
@@ -316,94 +318,66 @@ protected Object initialize(Frame callerFrame, Object self, Object[] rubyArgs, R
|
316 | 318 | }
|
317 | 319 | }
|
318 | 320 |
|
319 |
| - @CoreMethod(names = "instance_eval", needsBlock = true, optional = 3, lowerFixnum = 3) |
320 |
| - public abstract static class InstanceEvalNode extends CoreMethodArrayArgumentsNode { |
321 |
| - |
322 |
| - @Specialization(guards = { "strings.isRubyString(string)", "stringsFileName.isRubyString(fileName)" }, |
323 |
| - limit = "1") |
324 |
| - protected Object instanceEval( |
325 |
| - VirtualFrame frame, Object receiver, Object string, Object fileName, int line, Nil block, |
326 |
| - @Cached RubyStringLibrary strings, |
327 |
| - @Cached RubyStringLibrary stringsFileName, |
328 |
| - @Cached ToJavaStringNode toJavaStringNode, |
329 |
| - @Cached ReadCallerFrameNode callerFrameNode, |
330 |
| - @Cached IndirectCallNode callNode) { |
331 |
| - final MaterializedFrame callerFrame = callerFrameNode.execute(frame); |
| 321 | + @GenerateUncached |
| 322 | + @CoreMethod(names = "instance_eval", needsBlock = true, optional = 3, alwaysInlined = true) |
| 323 | + public abstract static class InstanceEvalNode extends AlwaysInlinedMethodNode { |
| 324 | + |
| 325 | + @Specialization(guards = "isBlockProvided(rubyArgs)") |
| 326 | + protected Object evalWithBlock(Frame callerFrame, Object self, Object[] rubyArgs, RootCallTarget target, |
| 327 | + @Cached(allowUncached = true) InstanceExecNode instanceExecNode, |
| 328 | + @Cached BranchProfile errorProfile) { |
| 329 | + final int count = RubyArguments.getPositionalArgumentsCount(rubyArgs, false); |
| 330 | + |
| 331 | + if (count > 0) { |
| 332 | + errorProfile.enter(); |
| 333 | + throw new RaiseException(getContext(), coreExceptions().argumentError(count, 0, this)); |
| 334 | + } |
332 | 335 |
|
333 |
| - return instanceEvalHelper( |
334 |
| - callerFrame, |
335 |
| - receiver, |
336 |
| - strings.getTString(string), |
337 |
| - strings.getEncoding(string), |
338 |
| - toJavaStringNode.executeToJavaString(fileName), |
339 |
| - line, |
340 |
| - callNode); |
| 336 | + final Object block = RubyArguments.getBlock(rubyArgs); |
| 337 | + return instanceExecNode.executeInstanceExec(callerFrame.materialize(), self, new Object[]{ self }, |
| 338 | + (RubyProc) block); |
341 | 339 | }
|
342 | 340 |
|
343 |
| - @Specialization(guards = { "strings.isRubyString(string)", "stringsFileName.isRubyString(fileName)" }, |
344 |
| - limit = "1") |
345 |
| - protected Object instanceEval( |
346 |
| - VirtualFrame frame, Object receiver, Object string, Object fileName, NotProvided line, Nil block, |
| 341 | + @Specialization(guards = "!isBlockProvided(rubyArgs)") |
| 342 | + protected Object evalWithString(Frame callerFrame, Object self, Object[] rubyArgs, RootCallTarget target, |
| 343 | + @Cached BranchProfile errorProfile, |
347 | 344 | @Cached RubyStringLibrary strings,
|
348 |
| - @Cached RubyStringLibrary stringsFileName, |
349 | 345 | @Cached ToJavaStringNode toJavaStringNode,
|
350 |
| - @Cached ReadCallerFrameNode callerFrameNode, |
| 346 | + @Cached ToStrNode toStrNode, |
| 347 | + @Cached ToIntNode toIntNode, |
351 | 348 | @Cached IndirectCallNode callNode) {
|
352 |
| - final MaterializedFrame callerFrame = callerFrameNode.execute(frame); |
| 349 | + final Object sourceCode; |
| 350 | + String fileName = coreStrings().EVAL_FILENAME_STRING.toString(); |
| 351 | + int line = 1; |
| 352 | + int count = RubyArguments.getPositionalArgumentsCount(rubyArgs, false); |
| 353 | + |
| 354 | + if (count == 0) { |
| 355 | + errorProfile.enter(); |
| 356 | + throw new RaiseException(getContext(), coreExceptions().argumentError(0, 1, 2, this)); |
| 357 | + } |
353 | 358 |
|
354 |
| - return instanceEvalHelper( |
355 |
| - callerFrame, |
356 |
| - receiver, |
357 |
| - strings.getTString(string), |
358 |
| - strings.getEncoding(string), |
359 |
| - toJavaStringNode.executeToJavaString(fileName), |
360 |
| - 1, |
361 |
| - callNode); |
362 |
| - } |
| 359 | + sourceCode = toStrNode.execute(RubyArguments.getArgument(rubyArgs, 0)); |
363 | 360 |
|
364 |
| - @Specialization(guards = "strings.isRubyString(string)", limit = "1") |
365 |
| - protected Object instanceEval( |
366 |
| - VirtualFrame frame, Object receiver, Object string, NotProvided fileName, NotProvided line, Nil block, |
367 |
| - @Cached RubyStringLibrary strings, |
368 |
| - @Cached ReadCallerFrameNode callerFrameNode, |
369 |
| - @Cached IndirectCallNode callNode) { |
370 |
| - final MaterializedFrame callerFrame = callerFrameNode.execute(frame); |
| 361 | + if (count >= 2) { |
| 362 | + fileName = toJavaStringNode |
| 363 | + .executeToJavaString(toStrNode.execute(RubyArguments.getArgument(rubyArgs, 1))); |
| 364 | + } |
| 365 | + |
| 366 | + if (count >= 3) { |
| 367 | + line = toIntNode.execute(RubyArguments.getArgument(rubyArgs, 2)); |
| 368 | + } |
371 | 369 |
|
| 370 | + needCallerFrame(callerFrame, target); |
372 | 371 | return instanceEvalHelper(
|
373 |
| - callerFrame, |
374 |
| - receiver, |
375 |
| - strings.getTString(string), |
376 |
| - strings.getEncoding(string), |
377 |
| - coreStrings().EVAL_FILENAME_STRING.toString(), |
378 |
| - 1, |
| 372 | + callerFrame.materialize(), |
| 373 | + self, |
| 374 | + strings.getTString(sourceCode), |
| 375 | + strings.getEncoding(sourceCode), |
| 376 | + fileName, |
| 377 | + line, |
379 | 378 | callNode);
|
380 | 379 | }
|
381 | 380 |
|
382 |
| - @Specialization |
383 |
| - protected Object instanceEval( |
384 |
| - VirtualFrame frame, |
385 |
| - Object receiver, |
386 |
| - NotProvided string, |
387 |
| - NotProvided fileName, |
388 |
| - NotProvided line, |
389 |
| - RubyProc block, |
390 |
| - @Cached InstanceExecNode instanceExecNode) { |
391 |
| - return instanceExecNode.executeInstanceExec(frame, receiver, new Object[]{ receiver }, block); |
392 |
| - } |
393 |
| - |
394 |
| - @Specialization |
395 |
| - protected Object noArgsNoBlock( |
396 |
| - Object receiver, NotProvided string, NotProvided fileName, NotProvided line, Nil block) { |
397 |
| - throw new RaiseException(getContext(), coreExceptions().argumentError(0, 1, 2, this)); |
398 |
| - } |
399 |
| - |
400 |
| - @Specialization(guards = "wasProvided(string)") |
401 |
| - protected Object argsAndBlock( |
402 |
| - Object receiver, Object string, Object maybeFileName, Object maybeLine, RubyProc block) { |
403 |
| - final int passed = RubyGuards.wasProvided(maybeLine) ? 3 : RubyGuards.wasProvided(maybeFileName) ? 2 : 1; |
404 |
| - throw new RaiseException(getContext(), coreExceptions().argumentError(passed, 0, this)); |
405 |
| - } |
406 |
| - |
407 | 381 | @TruffleBoundary
|
408 | 382 | private Object instanceEvalHelper(MaterializedFrame callerFrame, Object receiver, AbstractTruffleString code,
|
409 | 383 | RubyEncoding encoding,
|
|
0 commit comments