Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ private void runFile(PythonContext context, TruffleString inputFilePath) {
Object[] arguments = PArguments.create();
PythonModule mainModule = context.getMainModule();
PDict mainDict = GetOrCreateDictNode.executeUncached(mainModule);
PArguments.setGlobals(arguments, mainModule);
PArguments.setGlobals(arguments, mainDict);
PArguments.setSpecialArgument(arguments, mainDict);
PArguments.setException(arguments, PException.NO_EXCEPTION);
context.initializeMainModule(inputFilePath);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates.
* Copyright (c) 2013, Regents of the University of California
*
* All rights reserved.
Expand All @@ -26,9 +26,11 @@
package com.oracle.graal.python.builtins.objects.function;

import com.oracle.graal.python.builtins.objects.frame.PFrame;
import com.oracle.graal.python.builtins.objects.module.PythonModule;
import com.oracle.graal.python.builtins.objects.object.PythonObject;
import com.oracle.graal.python.nodes.argument.CreateArgumentsNode;
import com.oracle.graal.python.runtime.exception.PException;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.exception.AbstractTruffleException;
import com.oracle.truffle.api.frame.Frame;

Expand Down Expand Up @@ -70,9 +72,10 @@ public static boolean isPythonFrame(Object[] frameArgs) {
return frameArgs.length >= USER_ARGUMENTS_OFFSET && frameArgs[INDEX_CURRENT_FRAME_INFO] instanceof PFrame.Reference;
}

public static Object[] withGlobals(PythonObject globals) {
public static Object[] withGlobals(PythonModule globals) {
CompilerAsserts.neverPartOfCompilation();
Object[] arguments = create();
setGlobals(arguments, globals);
setGlobals(arguments, globals.getDict());
return arguments;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates.
* Copyright (c) 2013, Regents of the University of California
*
* All rights reserved.
Expand Down Expand Up @@ -37,9 +37,12 @@
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
import com.oracle.graal.python.builtins.PythonBuiltins;
import com.oracle.graal.python.builtins.objects.PNone;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.object.PythonObject;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.object.GetDictIfExistsNode;
import com.oracle.graal.python.nodes.object.GetOrCreateDictNode;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.object.Shape;
import com.oracle.truffle.api.strings.TruffleString;
Expand All @@ -61,7 +64,7 @@ public final class PythonModule extends PythonObject {
* table reference weak in order to break possible reference cycles. This field will ever only
* be set if the module's native definition provides a traverse function (see
* {@code moduleobject.c: module_traverse}). The condition for this is:
*
*
* <pre>
* {@code
* if (m -> md_def && m -> md_def -> m_traverse && (m -> md_def -> m_size <= 0 || m -> md_state != NULL)) {
Expand Down Expand Up @@ -162,4 +165,10 @@ public void setReplicatedNativeReferences(Object[] replicatedNativeReferences) {
public Object[] getReplicatedNativeReferences() {
return this.replicatedNativeReferences;
}

public PDict getDict() {
// PythonModule always have a dict
CompilerAsserts.neverPartOfCompilation();
return GetDictIfExistsNode.getDictUncached(this);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates.
* Copyright (c) 2013, Regents of the University of California
*
* All rights reserved.
Expand Down Expand Up @@ -83,11 +83,11 @@ public void setDict(Node inliningTarget, HiddenAttr.WriteNode writeNode, PDict d
}

@NeverDefault
public Object getPythonClass() {
public final Object getPythonClass() {
return pythonClass;
}

public void setPythonClass(Object pythonClass) {
public final void setPythonClass(Object pythonClass) {
assert getShape().getDynamicType() == PNone.NO_VALUE;
this.pythonClass = pythonClass;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -42,10 +42,12 @@

import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
import static com.oracle.graal.python.nodes.SpecialMethodNames.T___CLASS_GETITEM__;
import static com.oracle.graal.python.runtime.exception.PythonErrorType.KeyError;

import com.oracle.graal.python.PythonLanguage;
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
import com.oracle.graal.python.builtins.objects.PNone;
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem;
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.list.ListBuiltins;
Expand All @@ -63,6 +65,8 @@
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.call.CallNode;
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile;
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
import com.oracle.graal.python.runtime.exception.PException;
import com.oracle.graal.python.runtime.object.PFactory;
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
import com.oracle.truffle.api.dsl.Cached;
Expand All @@ -76,6 +80,7 @@
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.strings.TruffleString;

/**
* Equivalent of CPython's {@code PyObject_GetItem}.
Expand Down Expand Up @@ -121,6 +126,38 @@ static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object object,
return genericNode.execute(frame, inliningTarget, object, slots, key);
}

/**
* A version of {@link PyObjectGetItem} optimized for builtin dictionaries and
* {@link TruffleString} keys that suppresses the {@code KeyError} and returns {@code null} if
* key was not found.
*/
@GenerateUncached
@GenerateInline
@GenerateCached(false)
public abstract static class PyObjectGetItemOrNull extends PNodeWithContext {
public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object dict, TruffleString key);

@Specialization(guards = "isBuiltinDict(dict)")
static Object doPDict(VirtualFrame frame, Node inliningTarget, PDict dict, TruffleString key,
@Cached HashingStorageGetItem getItem) {
return getItem.execute(frame, inliningTarget, dict.getDictStorage(), key);
}

@Fallback
@InliningCutoff
static Object doPDictGeneric(VirtualFrame frame, Node inliningTarget, Object object, TruffleString key,
@Cached GetObjectSlotsNode getSlotsNode,
@Cached PyObjectGetItemGeneric genericNode,
@Cached IsBuiltinObjectProfile errorProfile) {
try {
return doGeneric(frame, inliningTarget, object, key, getSlotsNode, genericNode);
} catch (PException e) {
e.expect(inliningTarget, KeyError, errorProfile);
return null;
}
}
}

@GenerateUncached
@GenerateInline
@GenerateCached(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import com.oracle.graal.python.builtins.objects.asyncio.PAsyncGenWrappedValue;
import com.oracle.graal.python.builtins.objects.cell.PCell;
import com.oracle.graal.python.builtins.objects.code.PCode;
import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage;
import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage;
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem;
Expand Down Expand Up @@ -151,6 +152,7 @@
import com.oracle.graal.python.lib.PyObjectFunctionStr;
import com.oracle.graal.python.lib.PyObjectGetAttr;
import com.oracle.graal.python.lib.PyObjectGetItem;
import com.oracle.graal.python.lib.PyObjectGetItem.PyObjectGetItemOrNull;
import com.oracle.graal.python.lib.PyObjectGetIter;
import com.oracle.graal.python.lib.PyObjectGetMethod;
import com.oracle.graal.python.lib.PyObjectHashNode;
Expand Down Expand Up @@ -178,6 +180,7 @@
import com.oracle.graal.python.nodes.argument.keywords.NonMappingException;
import com.oracle.graal.python.nodes.argument.keywords.SameDictKeyException;
import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode;
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode;
import com.oracle.graal.python.nodes.builtins.ListNodes;
import com.oracle.graal.python.nodes.bytecode.CopyDictWithoutKeysNode;
import com.oracle.graal.python.nodes.bytecode.GetAIterNode;
Expand Down Expand Up @@ -211,7 +214,6 @@
import com.oracle.graal.python.nodes.frame.ReadBuiltinNode;
import com.oracle.graal.python.nodes.frame.ReadFromLocalsNode;
import com.oracle.graal.python.nodes.frame.ReadGlobalOrBuiltinNode;
import com.oracle.graal.python.nodes.frame.ReadNameNode;
import com.oracle.graal.python.nodes.frame.WriteGlobalNode;
import com.oracle.graal.python.nodes.frame.WriteNameNode;
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
Expand Down Expand Up @@ -258,6 +260,7 @@
import com.oracle.truffle.api.bytecode.ContinuationRootNode;
import com.oracle.truffle.api.bytecode.EpilogExceptional;
import com.oracle.truffle.api.bytecode.EpilogReturn;
import com.oracle.truffle.api.bytecode.ForceQuickening;
import com.oracle.truffle.api.bytecode.GenerateBytecode;
import com.oracle.truffle.api.bytecode.Instruction;
import com.oracle.truffle.api.bytecode.Instrumentation;
Expand Down Expand Up @@ -348,6 +351,7 @@
@OperationProxy(SetupAnnotationsNode.class)
@OperationProxy(GetAIterNode.class)
@OperationProxy(GetANextNode.class)
@OperationProxy(value = ReadGlobalOrBuiltinNode.class, name = "ReadGlobal")
@OperationProxy(value = CopyDictWithoutKeysNode.class, name = "CopyDictWithoutKeys")
@OperationProxy(value = PyObjectIsTrueNode.class, name = "Yes")
@OperationProxy(value = PyObjectIsNotTrueNode.class, name = "Not")
Expand Down Expand Up @@ -1204,13 +1208,42 @@ public static void perform(VirtualFrame frame, TruffleString name, Object value,
}
}

@Operation(storeBytecodeIndex = true)
@Operation(storeBytecodeIndex = false)
@ConstantOperand(type = TruffleString.class)
@ImportStatic(PGuards.class)
public static final class ReadName {
@Specialization
public static Object perform(VirtualFrame frame, TruffleString name,
@Cached ReadNameNode readNode) {
return readNode.execute(frame, name);
static Object readFromLocalsFastPath(VirtualFrame frame, TruffleString attributeId, ReadAttributeFromPythonObjectNode readNode) {
Object specialArgument = PArguments.getSpecialArgument(frame);
if (specialArgument instanceof PDict dict && dict.getDictStorage() instanceof DynamicObjectStorage s) {
return readNode.execute(s.getStore(), attributeId, PNone.NO_VALUE);
}
return PNone.NO_VALUE;
}

@ForceQuickening
@Specialization(guards = "!isNoValue(result)", limit = "1")
public static Object doLocalFastPath(VirtualFrame frame, TruffleString name,
@Cached ReadAttributeFromPythonObjectNode readAttrNode,
@Bind("readFromLocalsFastPath(frame, name, readAttrNode)") Object result) {
return result;
}

@StoreBytecodeIndex
@Specialization(replaces = "doLocalFastPath")
public static Object doFull(VirtualFrame frame, TruffleString name,
@Bind Node inliningTarget,
@Cached PyObjectGetItemOrNull getLocal,
@Cached ReadGlobalOrBuiltinNode readGlobalOrBuiltinNode,
@Cached InlinedConditionProfile hasLocalsProfile) {
Object locals = PArguments.getSpecialArgument(frame);
Object result = null;
if (hasLocalsProfile.profile(inliningTarget, locals != null)) {
result = getLocal.execute(frame, inliningTarget, locals, name);
}
if (result == null) {
return readGlobalOrBuiltinNode.execute(frame, name);
}
return result;
}
}

Expand Down Expand Up @@ -1621,16 +1654,6 @@ public static void doWithFrame(VirtualFrame frame, Object primary, Object index,
}
}

@Operation(storeBytecodeIndex = true)
@ConstantOperand(type = TruffleString.class)
public static final class ReadGlobal {
@Specialization
public static Object perform(VirtualFrame frame, TruffleString name,
@Cached ReadGlobalOrBuiltinNode readNode) {
return readNode.execute(frame, name);
}
}

@Operation(storeBytecodeIndex = true)
@ConstantOperand(type = TruffleString.class)
public static final class WriteGlobal {
Expand Down Expand Up @@ -2657,7 +2680,7 @@ public static Object doLoadCell(VirtualFrame frame, TruffleString name, Object d
value = getItemNode.execute(frame, inliningTarget, dict, name);
} catch (PException e) {
e.expect(inliningTarget, KeyError, errorProfile);
value = readGlobal.read(frame, PArguments.getGlobals(frame), name);
value = readGlobal.execute(frame, name);
}
return value;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -323,7 +323,7 @@ private Object run(VirtualFrame frame) {
} else {
mainModule = pythonContext.getMainModule();
PDict mainDict = GetOrCreateDictNode.executeUncached(mainModule);
PArguments.setGlobals(arguments, mainModule);
PArguments.setGlobals(arguments, mainDict);
PArguments.setSpecialArgument(arguments, mainDict);
PArguments.setException(arguments, PException.NO_EXCEPTION);
}
Expand Down
Loading
Loading