Skip to content

Commit aee45c2

Browse files
committed
Fix PyUnicode_InternInPlace
1 parent e8cdea8 commit aee45c2

File tree

3 files changed

+33
-34
lines changed

3 files changed

+33
-34
lines changed

graalpython/com.oracle.graal.python.cext/src/unicodeobject.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -819,10 +819,9 @@ PyUnicode_InternInPlace(PyObject **p)
819819
}
820820

821821
if (t != s) {
822-
Py_INCREF(t);
823-
Py_SETREF(*p, t);
824-
return;
822+
*p = t;
825823
}
824+
Py_DECREF(s);
826825
}
827826

828827
// 15940

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_unicode.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,18 +1030,21 @@ def compile_module(self, name):
10301030
cmpfunc=unhandled_error_compare
10311031
)
10321032

1033+
10331034
class TestUnicodeObject(object):
10341035
def test_intern(self):
10351036
TestIntern = CPyExtType(
10361037
"TestIntern",
10371038
'''
10381039
static PyObject* set_intern_str(PyObject* self, PyObject* str) {
1040+
Py_INCREF(str);
10391041
PyUnicode_InternInPlace(&str);
10401042
((TestInternObject*)self)->str = str;
10411043
return str;
10421044
}
10431045
10441046
static PyObject* check_is_same_str_ptr(PyObject* self, PyObject* str) {
1047+
Py_INCREF(str);
10451048
PyUnicode_InternInPlace(&str);
10461049
if (str == ((TestInternObject*)self)->str) {
10471050
Py_RETURN_TRUE;
@@ -1057,6 +1060,7 @@ def test_intern(self):
10571060
''',
10581061
)
10591062
tester = TestIntern()
1060-
s = 'some text'
1061-
assert tester.set_intern_str(s) == s
1062-
assert tester.check_is_same_str_ptr(s)
1063+
s1 = b'some text'.decode('ascii')
1064+
s2 = b'some text'.decode('ascii')
1065+
assert tester.set_intern_str(s1) == s2
1066+
assert tester.check_is_same_str_ptr(s2)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextUnicodeBuiltins.java

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@
132132
import com.oracle.graal.python.nodes.PGuards;
133133
import com.oracle.graal.python.nodes.PRaiseNode;
134134
import com.oracle.graal.python.nodes.StringLiterals;
135-
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromDynamicObjectNode;
136135
import com.oracle.graal.python.nodes.call.CallNode;
137136
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
138137
import com.oracle.graal.python.nodes.object.GetClassNode;
@@ -298,45 +297,42 @@ static Object doGeneric(Object obj, Object encodingObj, Object errorsObj,
298297
}
299298
}
300299

301-
@CApiBuiltin(ret = PyObject, args = {PyObject}, call = Ignored)
300+
@CApiBuiltin(ret = PyObjectTransfer, args = {PyObject}, call = Ignored)
302301
abstract static class PyTruffleUnicode_LookupAndIntern extends CApiUnaryBuiltinNode {
303-
@Specialization
304-
static Object withTS(TruffleString str,
305-
@Bind("this") Node inliningTarget,
306-
@Exclusive @Cached StringNodes.InternStringNode internNode,
307-
@Exclusive @Cached HashingStorageGetItem getItem,
308-
@Exclusive @Cached HashingStorageSetItem setItem,
309-
@Exclusive @Cached PythonObjectFactory.Lazy factory) {
310-
PDict dict = getCApiContext(inliningTarget).getInternedUnicode();
311-
if (dict == null) {
312-
dict = factory.get(inliningTarget).createDict();
313-
getCApiContext(inliningTarget).setInternedUnicode(dict);
314-
}
315-
Object interned = getItem.execute(inliningTarget, dict.getDictStorage(), str);
316-
if (interned == null) {
317-
interned = internNode.execute(inliningTarget, str);
318-
dict.setDictStorage(setItem.execute(inliningTarget, dict.getDictStorage(), str, interned));
319-
}
320-
return interned;
321-
}
322302

323303
@Specialization
324304
static Object withPString(PString str,
325305
@Bind("this") Node inliningTarget,
326306
@Cached PyUnicodeCheckExactNode unicodeCheckExactNode,
327-
@Cached ReadAttributeFromDynamicObjectNode readNode,
328-
@Exclusive @Cached StringNodes.InternStringNode internNode,
329-
@Exclusive @Cached HashingStorageGetItem getItem,
330-
@Exclusive @Cached HashingStorageSetItem setItem,
331-
@Exclusive @Cached PythonObjectFactory.Lazy factory) {
307+
@Cached CastToTruffleStringNode cast,
308+
@Cached StringNodes.IsInternedStringNode isInternedStringNode,
309+
@Cached StringNodes.InternStringNode internNode,
310+
@Cached HashingStorageGetItem getItem,
311+
@Cached HashingStorageSetItem setItem,
312+
@Cached PythonObjectFactory.Lazy factory) {
332313
if (!unicodeCheckExactNode.execute(inliningTarget, str)) {
333314
return getNativeNull(inliningTarget);
334315
}
335-
boolean isInterned = readNode.execute(str, PString.INTERNED) != PNone.NO_VALUE;
316+
/*
317+
* TODO this is not integrated with str.intern, pointer comparisons of two str.intern'ed
318+
* string may still yield failse
319+
*/
320+
boolean isInterned = isInternedStringNode.execute(inliningTarget, str);
336321
if (isInterned) {
337322
return str;
338323
}
339-
return withTS(str.getValueUncached(), inliningTarget, internNode, getItem, setItem, factory);
324+
TruffleString ts = cast.execute(inliningTarget, str);
325+
PDict dict = getCApiContext(inliningTarget).getInternedUnicode();
326+
if (dict == null) {
327+
dict = factory.get(inliningTarget).createDict();
328+
getCApiContext(inliningTarget).setInternedUnicode(dict);
329+
}
330+
Object interned = getItem.execute(inliningTarget, dict.getDictStorage(), ts);
331+
if (interned == null) {
332+
interned = internNode.execute(inliningTarget, str);
333+
dict.setDictStorage(setItem.execute(inliningTarget, dict.getDictStorage(), ts, interned));
334+
}
335+
return interned;
340336
}
341337

342338
@Fallback

0 commit comments

Comments
 (0)