Skip to content

Commit 03cad50

Browse files
committed
Add PyDictSetItem and PyDictDelItem nodes.
1 parent 9f074db commit 03cad50

File tree

3 files changed

+231
-18
lines changed

3 files changed

+231
-18
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVModuleBuiltins.java

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,20 @@
55
*/
66
package com.oracle.graal.python.builtins.modules.csv;
77

8+
import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.QUOTE_ALL;
9+
import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.QUOTE_MINIMAL;
10+
import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.QUOTE_NONE;
11+
import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.QUOTE_NONNUMERIC;
12+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
13+
14+
import java.util.List;
15+
816
import com.oracle.graal.python.builtins.Builtin;
917
import com.oracle.graal.python.builtins.CoreFunctions;
1018
import com.oracle.graal.python.builtins.Python3Core;
1119
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
1220
import com.oracle.graal.python.builtins.PythonBuiltins;
1321
import com.oracle.graal.python.builtins.objects.PNone;
14-
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
1522
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary;
1623
import com.oracle.graal.python.builtins.objects.dict.PDict;
1724
import com.oracle.graal.python.builtins.objects.function.PKeyword;
@@ -20,7 +27,9 @@
2027
import com.oracle.graal.python.builtins.objects.str.PString;
2128
import com.oracle.graal.python.builtins.objects.type.PythonClass;
2229
import com.oracle.graal.python.lib.PyCallableCheckNode;
30+
import com.oracle.graal.python.lib.PyDictDelItem;
2331
import com.oracle.graal.python.lib.PyDictGetItem;
32+
import com.oracle.graal.python.lib.PyDictSetItem;
2433
import com.oracle.graal.python.lib.PyLongAsIntNode;
2534
import com.oracle.graal.python.lib.PyLongAsLongNode;
2635
import com.oracle.graal.python.lib.PyLongCheckExactNode;
@@ -45,11 +54,6 @@
4554
import com.oracle.truffle.api.frame.VirtualFrame;
4655
import com.oracle.truffle.api.library.CachedLibrary;
4756

48-
import java.util.List;
49-
50-
import static com.oracle.graal.python.builtins.modules.csv.QuoteStyle.*;
51-
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
52-
5357
@CoreFunctions(defineModule = "_csv")
5458
public class CSVModuleBuiltins extends PythonBuiltins {
5559

@@ -86,7 +90,7 @@ PNone register(VirtualFrame frame, PythonModule module, Object nameObj, Object d
8690
@Cached CastToJavaStringNode nameNode,
8791
@Cached ReadAttributeFromObjectNode readNode,
8892
@Cached CallNode callNode,
89-
@CachedLibrary(limit = "1") HashingStorageLibrary library) {
93+
@Cached PyDictSetItem setItem) {
9094

9195
String name;
9296
try {
@@ -97,10 +101,9 @@ PNone register(VirtualFrame frame, PythonModule module, Object nameObj, Object d
97101

98102
Object result = callNode.execute(frame, PythonBuiltinClassType.CSVDialect, new Object[]{dialectObj}, keywords);
99103

100-
Object dialects = readNode.execute(module, "_dialects");
101-
// TODO: Write PyDictSetItem Node?
102-
HashingStorage storage = library.setItem(((PDict) dialects).getDictStorage(), name, result);
103-
((PDict) dialects).setDictStorage(storage);
104+
PDict dialects = (PDict) readNode.execute(module, "_dialects");
105+
106+
setItem.execute(frame, dialects, name, result);
104107

105108
return PNone.NONE;
106109
}
@@ -111,15 +114,15 @@ PNone register(VirtualFrame frame, PythonModule module, Object nameObj, Object d
111114
@GenerateNodeFactory
112115
public abstract static class CSVUnregisterDialectNode extends PythonBuiltinNode {
113116
@Specialization
114-
PNone unregister(PythonModule module, Object nameObj,
117+
PNone unregister(VirtualFrame frame, PythonModule module, Object nameObj,
115118
@Cached ReadAttributeFromObjectNode readNode,
116-
@CachedLibrary(limit = "1") HashingStorageLibrary library) {
119+
@Cached PyDictDelItem delItem,
120+
@CachedLibrary(limit = "1") HashingStorageLibrary hashingStorage) {
117121

118-
Object dialects = readNode.execute(module, "_dialects");
122+
PDict dialects = (PDict) readNode.execute(module, "_dialects");
119123

120-
//TODO: Should we write a PyDict_DelItem Node?
121-
if (library.hasKey(((PDict) dialects).getDictStorage(), nameObj)) {
122-
library.delItem(((PDict) dialects).getDictStorage(), nameObj);
124+
if (hashingStorage.hasKey((dialects).getDictStorage(), nameObj)) {
125+
delItem.execute(frame, dialects, nameObj);
123126
} else {
124127
throw raise(PythonBuiltinClassType.CSVError, "unknown dialect");
125128
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.lib;
42+
43+
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
44+
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary;
45+
import com.oracle.graal.python.builtins.objects.dict.PDict;
46+
import com.oracle.truffle.api.dsl.Bind;
47+
import com.oracle.truffle.api.dsl.Cached;
48+
import com.oracle.truffle.api.dsl.GenerateUncached;
49+
import com.oracle.truffle.api.dsl.Specialization;
50+
import com.oracle.truffle.api.frame.Frame;
51+
import com.oracle.truffle.api.frame.VirtualFrame;
52+
import com.oracle.truffle.api.library.CachedLibrary;
53+
import com.oracle.truffle.api.nodes.Node;
54+
import com.oracle.truffle.api.profiles.ConditionProfile;
55+
56+
/**
57+
* Equivalent to use for PyDict_DelItem and PyDict_DelItemString functions available in CPython.
58+
* Note that these functions lead to places where there are hard casts to PyDictObject anyway, so we
59+
* just accept PDict.
60+
*/
61+
@GenerateUncached
62+
public abstract class PyDictDelItem extends Node {
63+
public abstract void execute(Frame frame, PDict dict, Object key);
64+
65+
// We never need a frame for reading string keys
66+
@Specialization(limit = "3")
67+
static final void delItemWithStringKey(@SuppressWarnings("unused") PDict dict, String key,
68+
@Bind("dict.getDictStorage()") HashingStorage dictStorage,
69+
@CachedLibrary("dictStorage") HashingStorageLibrary lib,
70+
@Cached("createCountingProfile()") ConditionProfile updateStorageProfile) {
71+
HashingStorage updatedStorage = lib.delItem(dictStorage, key);
72+
if (updateStorageProfile.profile(updatedStorage != dictStorage)) {
73+
dict.setDictStorage(updatedStorage);
74+
}
75+
}
76+
77+
@Specialization(replaces = "delItemWithStringKey", limit = "3")
78+
static final void delItemCached(VirtualFrame frame, @SuppressWarnings("unused") PDict dict, Object key,
79+
@Bind("dict.getDictStorage()") HashingStorage dictStorage,
80+
@Cached ConditionProfile frameCondition,
81+
@CachedLibrary("dictStorage") HashingStorageLibrary lib,
82+
@Cached("createCountingProfile()") ConditionProfile updateStorageProfile) {
83+
HashingStorage updatedStorage = lib.delItemWithFrame(dictStorage, key, frameCondition, frame);
84+
if (updateStorageProfile.profile(updatedStorage != dictStorage)) {
85+
dict.setDictStorage(updatedStorage);
86+
}
87+
}
88+
89+
@Specialization(replaces = "delItemCached")
90+
static final void delItem(PDict dict, Object key,
91+
@CachedLibrary(limit = "3") HashingStorageLibrary lib,
92+
@Cached("createCountingProfile()") ConditionProfile updateStorageProfile) {
93+
HashingStorage dictStorage = dict.getDictStorage();
94+
HashingStorage updatedStorage = lib.delItem(dictStorage, key);
95+
if (updateStorageProfile.profile(updatedStorage != dictStorage)) {
96+
dict.setDictStorage(updatedStorage);
97+
}
98+
}
99+
100+
public static PyDictDelItem create() {
101+
return PyDictDelItemNodeGen.create();
102+
}
103+
104+
public static PyDictDelItem getUncached() {
105+
return PyDictDelItemNodeGen.getUncached();
106+
}
107+
}
Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,107 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
141
package com.oracle.graal.python.lib;
242

3-
public class PyDictSetItem {
43+
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
44+
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary;
45+
import com.oracle.graal.python.builtins.objects.dict.PDict;
46+
import com.oracle.truffle.api.dsl.Bind;
47+
import com.oracle.truffle.api.dsl.Cached;
48+
import com.oracle.truffle.api.dsl.GenerateUncached;
49+
import com.oracle.truffle.api.dsl.Specialization;
50+
import com.oracle.truffle.api.frame.Frame;
51+
import com.oracle.truffle.api.frame.VirtualFrame;
52+
import com.oracle.truffle.api.library.CachedLibrary;
53+
import com.oracle.truffle.api.nodes.Node;
54+
import com.oracle.truffle.api.profiles.ConditionProfile;
55+
56+
/**
57+
* Equivalent to use for PyDict_SetItem and PyDict_SetItemString functions available in CPython.
58+
* Note that these functions lead to places where there are hard casts to PyDictObject anyway, so we
59+
* just accept PDict.
60+
*/
61+
@GenerateUncached
62+
public abstract class PyDictSetItem extends Node {
63+
public abstract void execute(Frame frame, PDict dict, Object key, Object item);
64+
65+
// We never need a frame for reading string keys
66+
@Specialization(limit = "3")
67+
static final void setItemWithStringKey(@SuppressWarnings("unused") PDict dict, String key, Object item,
68+
@Bind("dict.getDictStorage()") HashingStorage dictStorage,
69+
@CachedLibrary("dictStorage") HashingStorageLibrary lib,
70+
@Cached("createCountingProfile()") ConditionProfile updateStorageProfile) {
71+
HashingStorage updatedStorage = lib.setItem(dictStorage, key, item);
72+
if (updateStorageProfile.profile(updatedStorage != dictStorage)) {
73+
dict.setDictStorage(updatedStorage);
74+
}
75+
}
76+
77+
@Specialization(replaces = "setItemWithStringKey", limit = "3")
78+
static final void setItemCached(VirtualFrame frame, @SuppressWarnings("unused") PDict dict, Object key, Object item,
79+
@Bind("dict.getDictStorage()") HashingStorage dictStorage,
80+
@Cached ConditionProfile frameCondition,
81+
@CachedLibrary("dictStorage") HashingStorageLibrary lib,
82+
@Cached("createCountingProfile()") ConditionProfile updateStorageProfile) {
83+
HashingStorage updatedStorage = lib.setItemWithFrame(dictStorage, key, item, frameCondition, frame);
84+
if (updateStorageProfile.profile(updatedStorage != dictStorage)) {
85+
dict.setDictStorage(updatedStorage);
86+
}
87+
}
88+
89+
@Specialization(replaces = "setItemCached")
90+
static final void setItem(PDict dict, Object key, Object item,
91+
@CachedLibrary(limit = "3") HashingStorageLibrary lib,
92+
@Cached("createCountingProfile()") ConditionProfile updateStorageProfile) {
93+
HashingStorage dictStorage = dict.getDictStorage();
94+
HashingStorage updatedStorage = lib.setItem(dictStorage, key, item);
95+
if (updateStorageProfile.profile(updatedStorage != dictStorage)) {
96+
dict.setDictStorage(updatedStorage);
97+
}
98+
}
99+
100+
public static PyDictSetItem create() {
101+
return PyDictSetItemNodeGen.create();
102+
}
103+
104+
public static PyDictSetItem getUncached() {
105+
return PyDictSetItemNodeGen.getUncached();
106+
}
4107
}

0 commit comments

Comments
 (0)