Skip to content

Commit b084104

Browse files
committed
[GR-71765] Replace CheckAndLoadLocal with illegalLocalException.
PullRequest: graalpython/4177
2 parents cae4d1e + f45eaed commit b084104

5 files changed

Lines changed: 25 additions & 42 deletions

File tree

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,7 @@ private void emitNameFastOperation(String mangled, NameOperation op, Builder b)
14571457
BytecodeLocal local = locals.get(mangled);
14581458
switch (op) {
14591459
case Read:
1460-
b.emitCheckAndLoadLocal(local, varnames.get(mangled));
1460+
b.emitLoadLocal(local);
14611461
break;
14621462
case Delete:
14631463
b.emitDeleteLocal(local, varnames.get(mangled));
@@ -1612,7 +1612,9 @@ public void setUpFrame(ArgumentsTy args, Builder b) {
16121612
if (scope.isFunction()) {
16131613
String[] regularVariables = orderedKeys(varnames, new String[0]);
16141614
for (int i = 0; i < regularVariables.length; i++) {
1615-
locals.put(regularVariables[i], b.createLocal());
1615+
// For user locals, store a varnames table index in the "info" field.
1616+
int index = varnames.get(regularVariables[i]);
1617+
locals.put(regularVariables[i], b.createLocal(null, index));
16161618
}
16171619
}
16181620

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -285,14 +285,12 @@
285285
import com.oracle.truffle.api.exception.AbstractTruffleException;
286286
import com.oracle.truffle.api.frame.Frame;
287287
import com.oracle.truffle.api.frame.FrameDescriptor;
288-
import com.oracle.truffle.api.frame.FrameSlotTypeException;
289288
import com.oracle.truffle.api.frame.MaterializedFrame;
290289
import com.oracle.truffle.api.frame.VirtualFrame;
291290
import com.oracle.truffle.api.nodes.DirectCallNode;
292291
import com.oracle.truffle.api.nodes.ExplodeLoop;
293292
import com.oracle.truffle.api.nodes.Node;
294293
import com.oracle.truffle.api.nodes.RootNode;
295-
import com.oracle.truffle.api.nodes.UnexpectedResultException;
296294
import com.oracle.truffle.api.object.DynamicObject;
297295
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
298296
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
@@ -304,6 +302,8 @@
304302

305303
@GenerateBytecode(//
306304
languageClass = PythonLanguage.class, //
305+
illegalLocalException = PException.class, //
306+
illegalLocalExceptionFactory = "raiseUnboundLocalException", //
307307
enableBlockScoping = false, //
308308
enableYield = true, //
309309
enableSerialization = true, //
@@ -3623,40 +3623,6 @@ static void doInteropException(AbstractTruffleException exception) {
36233623
}
36243624
}
36253625

3626-
/**
3627-
* Loads a user-defined local variable. Unlike a built-in LoadLocal, this operation raises an
3628-
* unbound local error if the local has not been set.
3629-
* <p>
3630-
* This operation makes use of Truffle's boxing overloads. When an operation tries to quicken
3631-
* this one for boxing elimination, the correct overload will be selected.
3632-
*/
3633-
@Operation(storeBytecodeIndex = false)
3634-
@ConstantOperand(type = LocalAccessor.class)
3635-
@ConstantOperand(type = int.class)
3636-
public static final class CheckAndLoadLocal {
3637-
@Specialization(rewriteOn = {FrameSlotTypeException.class, UnexpectedResultException.class})
3638-
public static int doInt(VirtualFrame frame, LocalAccessor accessor, int index,
3639-
@Bind BytecodeNode bytecodeNode) throws UnexpectedResultException {
3640-
return accessor.getInt(bytecodeNode, frame);
3641-
}
3642-
3643-
@Specialization(replaces = "doInt", rewriteOn = FrameSlotTypeException.class)
3644-
public static Object doObject(VirtualFrame frame, LocalAccessor accessor, int index,
3645-
@Bind BytecodeNode bytecodeNode) {
3646-
return accessor.getObject(bytecodeNode, frame);
3647-
}
3648-
3649-
@StoreBytecodeIndex
3650-
@Specialization(replaces = "doObject")
3651-
public static Object doObjectOrUnbound(VirtualFrame frame, LocalAccessor accessor, int index,
3652-
@Bind BytecodeNode bytecodeNode) {
3653-
if (accessor.isCleared(bytecodeNode, frame)) {
3654-
throw raiseUnbound(bytecodeNode, index);
3655-
}
3656-
return accessor.getObject(bytecodeNode, frame);
3657-
}
3658-
}
3659-
36603626
@Operation(storeBytecodeIndex = false)
36613627
@ConstantOperand(type = LocalAccessor.class)
36623628
@ConstantOperand(type = int.class)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/exception/PException.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -51,15 +51,19 @@
5151
import com.oracle.graal.python.builtins.objects.traceback.MaterializeLazyTracebackNode;
5252
import com.oracle.graal.python.builtins.objects.traceback.PTraceback;
5353
import com.oracle.graal.python.lib.PyExceptionInstanceCheckNode;
54+
import com.oracle.graal.python.nodes.ErrorMessages;
55+
import com.oracle.graal.python.nodes.PRaiseNode;
5456
import com.oracle.graal.python.nodes.PRootNode;
5557
import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode;
5658
import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode;
5759
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
5860
import com.oracle.graal.python.runtime.GilNode;
5961
import com.oracle.graal.python.runtime.PythonOptions;
6062
import com.oracle.truffle.api.CompilerAsserts;
63+
import com.oracle.truffle.api.CompilerDirectives;
6164
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
6265
import com.oracle.truffle.api.bytecode.BytecodeNode;
66+
import com.oracle.truffle.api.bytecode.LocalVariable;
6367
import com.oracle.truffle.api.dsl.Bind;
6468
import com.oracle.truffle.api.dsl.Cached;
6569
import com.oracle.truffle.api.dsl.Cached.Exclusive;
@@ -75,6 +79,7 @@
7579
import com.oracle.truffle.api.nodes.Node;
7680
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
7781
import com.oracle.truffle.api.source.SourceSection;
82+
import com.oracle.truffle.api.strings.TruffleString;
7883

7984
/**
8085
* Serves both as a throwable carrier of the python exception object ({@link PBaseException}) and as
@@ -583,4 +588,14 @@ public boolean getShouldTrace() {
583588
public void dontTraceOnReraise() {
584589
shouldTrace = true;
585590
}
591+
592+
@TruffleBoundary
593+
public static PException raiseUnboundLocalException(BytecodeNode bytecodeNode, LocalVariable localVariable) {
594+
Object info = localVariable.getInfo();
595+
if (info == null || !(info instanceof Integer i)) {
596+
throw CompilerDirectives.shouldNotReachHere("User locals must have their info field set to a varnames index.");
597+
}
598+
TruffleString localName = ((PBytecodeDSLRootNode) bytecodeNode.getRootNode()).getCodeUnit().varnames[i];
599+
throw PRaiseNode.raiseStatic(bytecodeNode, PythonBuiltinClassType.UnboundLocalError, ErrorMessages.LOCAL_VAR_REFERENCED_BEFORE_ASSIGMENT, localName);
600+
}
586601
}

mx.graalpython/suite.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@
5353
},
5454
{
5555
"name": "tools",
56-
"version": "560591a86456e570b6f089a41fc9aa358f9f7fb5",
56+
"version": "b9735919ef1c105c97260207f62f656ab8f960a1",
5757
"subdir": True,
5858
"urls": [
5959
{"url": "https://github.com/oracle/graal", "kind": "git"},
6060
],
6161
},
6262
{
6363
"name": "regex",
64-
"version": "560591a86456e570b6f089a41fc9aa358f9f7fb5",
64+
"version": "b9735919ef1c105c97260207f62f656ab8f960a1",
6565
"subdir": True,
6666
"urls": [
6767
{"url": "https://github.com/oracle/graal", "kind": "git"},

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ required-version = '23'
88
# Disables the black formatter in this repository
99
# If individual suites want to enable the formatter, they can create a
1010
# pyproject.toml with their own configuration in their suite folder
11-
force-exclude = '.*graalpy.*|.*scripts/[^w].*py|benchmarks/*'
11+
force-exclude = '.*graalpy.*|.*scripts/.*py|benchmarks/*'

0 commit comments

Comments
 (0)