Skip to content

Commit ed0a801

Browse files
committed
Move logic for 'encodeAs*' to node.
1 parent 7fd8de6 commit ed0a801

File tree

3 files changed

+80
-10
lines changed

3 files changed

+80
-10
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PythonCextBuiltins.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
import java.nio.charset.CharacterCodingException;
5555
import java.nio.charset.Charset;
5656
import java.nio.charset.CharsetDecoder;
57-
import java.nio.charset.CharsetEncoder;
5857
import java.nio.charset.CoderResult;
5958
import java.nio.charset.CodingErrorAction;
6059
import java.nio.charset.StandardCharsets;
@@ -81,7 +80,6 @@
8180
import com.oracle.graal.python.builtins.objects.bytes.PIBytesLike;
8281
import com.oracle.graal.python.builtins.objects.cext.CArrayWrappers.CByteArrayWrapper;
8382
import com.oracle.graal.python.builtins.objects.cext.CArrayWrappers.CStringWrapper;
84-
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode;
8583
import com.oracle.graal.python.builtins.objects.cext.CExtNodes;
8684
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.CastToJavaDoubleNode;
8785
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.GetNativeNullNode;
@@ -111,10 +109,12 @@
111109
import com.oracle.graal.python.builtins.objects.cext.PythonNativeWrapper;
112110
import com.oracle.graal.python.builtins.objects.cext.PythonNativeWrapperLibrary;
113111
import com.oracle.graal.python.builtins.objects.cext.UnicodeObjectNodes.UnicodeAsWideCharNode;
114-
import com.oracle.graal.python.builtins.objects.cext.common.VaListWrapper;
115112
import com.oracle.graal.python.builtins.objects.cext.common.CExtAsPythonObjectNode;
113+
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.EncodeNativeStringNode;
116114
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.PCallCExtFunction;
117115
import com.oracle.graal.python.builtins.objects.cext.common.CExtContext;
116+
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode;
117+
import com.oracle.graal.python.builtins.objects.cext.common.VaListWrapper;
118118
import com.oracle.graal.python.builtins.objects.code.PCode;
119119
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
120120
import com.oracle.graal.python.builtins.objects.common.IndexNodes.NormalizeIndexNode;
@@ -1268,19 +1268,19 @@ protected NativeEncoderNode(Charset charset) {
12681268
}
12691269

12701270
@Specialization(guards = "isNoValue(errors)")
1271-
Object doUnicode(VirtualFrame frame, PString s, @SuppressWarnings("unused") PNone errors, Object error_marker) {
1272-
return doUnicode(frame, s, "strict", error_marker);
1271+
Object doUnicode(VirtualFrame frame, PString s, @SuppressWarnings("unused") PNone errors, Object error_marker,
1272+
@Shared("encodeNode") @Cached EncodeNativeStringNode encodeNativeStringNode) {
1273+
return doUnicode(frame, s, "strict", error_marker, encodeNativeStringNode);
12731274
}
12741275

12751276
@Specialization
1276-
Object doUnicode(VirtualFrame frame, PString s, String errors, Object error_marker) {
1277+
Object doUnicode(VirtualFrame frame, PString s, String errors, Object error_marker,
1278+
@Shared("encodeNode") @Cached EncodeNativeStringNode encodeNativeStringNode) {
12771279
try {
1278-
return factory().createBytes(doEncode(s, errors));
1280+
return encodeNativeStringNode.execute(charset, s, errors);
12791281
} catch (PException e) {
12801282
transformToNative(frame, e);
12811283
return error_marker;
1282-
} catch (CharacterCodingException e) {
1283-
return raiseNative(frame, error_marker, PythonErrorType.UnicodeEncodeError, "%m", e);
12841284
}
12851285
}
12861286

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import com.oracle.graal.python.builtins.objects.iterator.PSequenceIterator;
6262
import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView;
6363
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
64+
import com.oracle.graal.python.nodes.PRaiseNode;
6465
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
6566
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
6667
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
@@ -84,7 +85,7 @@
8485
@CoreFunctions(extendClasses = PythonBuiltinClassType.PBytes)
8586
public class BytesBuiltins extends PythonBuiltins {
8687

87-
public static CodingErrorAction toCodingErrorAction(String errors, PythonBuiltinBaseNode n) {
88+
public static CodingErrorAction toCodingErrorAction(String errors) {
8889
switch (errors) {
8990
case "strict":
9091
return CodingErrorAction.REPORT;
@@ -93,6 +94,22 @@ public static CodingErrorAction toCodingErrorAction(String errors, PythonBuiltin
9394
case "replace":
9495
return CodingErrorAction.REPLACE;
9596
}
97+
return null;
98+
}
99+
100+
public static CodingErrorAction toCodingErrorAction(String errors, PRaiseNode n) {
101+
CodingErrorAction action = toCodingErrorAction(errors);
102+
if (action != null) {
103+
return action;
104+
}
105+
throw n.raise(PythonErrorType.LookupError, "unknown error handler name '%s'", errors);
106+
}
107+
108+
public static CodingErrorAction toCodingErrorAction(String errors, PythonBuiltinBaseNode n) {
109+
CodingErrorAction action = toCodingErrorAction(errors);
110+
if (action != null) {
111+
return action;
112+
}
96113
throw n.raise(PythonErrorType.LookupError, "unknown error handler name '%s'", errors);
97114
}
98115

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtCommonNodes.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,25 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.cext.common;
4242

43+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.UnicodeEncodeError;
44+
45+
import java.nio.ByteBuffer;
46+
import java.nio.CharBuffer;
47+
import java.nio.charset.CharacterCodingException;
48+
import java.nio.charset.Charset;
49+
import java.nio.charset.CharsetEncoder;
50+
import java.nio.charset.CodingErrorAction;
51+
4352
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
53+
import com.oracle.graal.python.builtins.objects.bytes.BytesBuiltins;
54+
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
4455
import com.oracle.graal.python.nodes.PNodeWithContext;
4556
import com.oracle.graal.python.nodes.PRaiseNode;
57+
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
58+
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
59+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4660
import com.oracle.truffle.api.dsl.Cached;
61+
import com.oracle.truffle.api.dsl.Cached.Shared;
4762
import com.oracle.truffle.api.dsl.GenerateUncached;
4863
import com.oracle.truffle.api.dsl.Specialization;
4964
import com.oracle.truffle.api.interop.ArityException;
@@ -137,4 +152,42 @@ static Object doIt(CExtContext nativeContext, String name, Object[] args,
137152
}
138153
}
139154

155+
@GenerateUncached
156+
public abstract static class EncodeNativeStringNode extends PNodeWithContext {
157+
158+
public abstract PBytes execute(Charset charset, Object string, String errors);
159+
160+
@Specialization
161+
static PBytes doJavaString(Charset charset, String s, String errors,
162+
@Shared("factory") @Cached PythonObjectFactory factory,
163+
@Shared("raiseNode") @Cached PRaiseNode raiseNode) {
164+
try {
165+
CodingErrorAction action = BytesBuiltins.toCodingErrorAction(errors, raiseNode);
166+
return factory.createBytes(doEncode(charset, s, action));
167+
} catch (CharacterCodingException e) {
168+
throw raiseNode.raise(UnicodeEncodeError, "%m", e);
169+
}
170+
}
171+
172+
@Specialization(replaces = "doJavaString")
173+
static PBytes doGeneric(Charset charset, Object stringObj, String errors,
174+
@Cached CastToJavaStringNode castToJavaStringNode,
175+
@Shared("factory") @Cached PythonObjectFactory factory,
176+
@Shared("raiseNode") @Cached PRaiseNode raiseNode) {
177+
return doJavaString(charset, castToJavaStringNode.execute(stringObj), errors, factory, raiseNode);
178+
}
179+
180+
@TruffleBoundary
181+
private static byte[] doEncode(Charset charset, String string, CodingErrorAction action) throws CharacterCodingException {
182+
CharsetEncoder encoder = charset.newEncoder();
183+
encoder.onMalformedInput(action).onUnmappableCharacter(action);
184+
CharBuffer buf = CharBuffer.allocate(string.length());
185+
buf.put(string);
186+
buf.flip();
187+
ByteBuffer encoded = encoder.encode(buf);
188+
byte[] barr = new byte[encoded.remaining()];
189+
encoded.get(barr);
190+
return barr;
191+
}
192+
}
140193
}

0 commit comments

Comments
 (0)