diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java index 9f16f990d2..eff267bc02 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java @@ -980,10 +980,7 @@ private void emitNameFastOperation(String mangled, NameOperation op, Builder b) BytecodeLocal local = locals.get(mangled); switch (op) { case Read: - b.beginBlock(); - b.emitCheckUnboundLocal(local, varnames.get(mangled)); - b.emitLoadLocal(local); - b.endBlock(); + b.emitCheckAndLoadLocal(local, varnames.get(mangled)); break; case Delete: b.emitDeleteLocal(local, varnames.get(mangled)); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java index 6bbae56f71..04366c9386 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java @@ -3952,12 +3952,45 @@ private static void handleException(VirtualFrame frame, PException e, Node inlin } } + /** + * Loads a user-defined local variable. Unlike a built-in LoadLocal, this operation raises an + * unbound local error if the local has not been set. + *

+ * This operation makes use of Truffle's boxing overloads. When an operation tries to quicken + * this one for boxing elimination, the correct overload will be selected. + */ @Operation @ConstantOperand(type = LocalAccessor.class) @ConstantOperand(type = int.class) - public static final class CheckUnboundLocal { - @Specialization - public static void doObject(VirtualFrame frame, LocalAccessor accessor, int index, + public static final class CheckAndLoadLocal { + @Specialization(rewriteOn = UnexpectedResultException.class) + public static int doInt(VirtualFrame frame, LocalAccessor accessor, int index, + @Bind PBytecodeDSLRootNode rootNode, + @Bind BytecodeNode bytecodeNode, + @Bind Node inliningTarget, + @Shared @Cached InlinedBranchProfile localUnboundProfile) throws UnexpectedResultException { + if (accessor.isCleared(bytecodeNode, frame)) { + localUnboundProfile.enter(inliningTarget); + throw raiseUnbound(rootNode, inliningTarget, index); + } + return accessor.getInt(bytecodeNode, frame); + } + + @Specialization(rewriteOn = UnexpectedResultException.class) + public static boolean doBoolean(VirtualFrame frame, LocalAccessor accessor, int index, + @Bind PBytecodeDSLRootNode rootNode, + @Bind BytecodeNode bytecodeNode, + @Bind Node inliningTarget, + @Shared @Cached InlinedBranchProfile localUnboundProfile) throws UnexpectedResultException { + if (accessor.isCleared(bytecodeNode, frame)) { + localUnboundProfile.enter(inliningTarget); + throw raiseUnbound(rootNode, inliningTarget, index); + } + return accessor.getBoolean(bytecodeNode, frame); + } + + @Specialization(replaces = {"doInt", "doBoolean"}) + public static Object doObject(VirtualFrame frame, LocalAccessor accessor, int index, @Bind PBytecodeDSLRootNode rootNode, @Bind BytecodeNode bytecodeNode, @Bind Node inliningTarget, @@ -3966,6 +3999,7 @@ public static void doObject(VirtualFrame frame, LocalAccessor accessor, int inde localUnboundProfile.enter(inliningTarget); throw raiseUnbound(rootNode, inliningTarget, index); } + return accessor.getObject(bytecodeNode, frame); } }