Skip to content

Commit 59cc778

Browse files
committed
update CompileNode to coerce arguments in the generic case
1 parent ab8c9de commit 59cc778

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

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

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@
8282
import com.oracle.graal.python.builtins.modules.BuiltinFunctionsFactory.GetAttrNodeFactory;
8383
import com.oracle.graal.python.builtins.modules.BuiltinFunctionsFactory.GlobalsNodeFactory;
8484
import com.oracle.graal.python.builtins.objects.PNone;
85-
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
8685
import com.oracle.graal.python.builtins.objects.bytes.BytesUtils;
8786
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
8887
import com.oracle.graal.python.builtins.objects.bytes.PIBytesLike;
@@ -183,6 +182,7 @@
183182
import com.oracle.truffle.api.dsl.TypeSystemReference;
184183
import com.oracle.truffle.api.frame.Frame;
185184
import com.oracle.truffle.api.frame.VirtualFrame;
185+
import com.oracle.truffle.api.interop.InteropLibrary;
186186
import com.oracle.truffle.api.interop.UnsupportedMessageException;
187187
import com.oracle.truffle.api.library.CachedLibrary;
188188
import com.oracle.truffle.api.nodes.ExplodeLoop;
@@ -747,26 +747,6 @@ public CompileNode() {
747747

748748
public abstract PCode execute(VirtualFrame frame, Object source, String filename, String mode, Object kwFlags, Object kwDontInherit, Object kwOptimize);
749749

750-
@Specialization
751-
PCode compile(VirtualFrame frame, PBytes pBytes, String filename, String mode, Object kwFlags, Object kwDontInherit, Object kwOptimize,
752-
@Cached("create()") BytesNodes.ToBytesNode toBytesNode) {
753-
try {
754-
byte[] bytes = toBytesNode.execute(frame, pBytes);
755-
Charset charset = PythonFileDetector.findEncodingStrict(bytes);
756-
return compile(createString(bytes, charset), filename, mode, kwFlags, kwDontInherit, kwOptimize);
757-
} catch (PythonFileDetector.InvalidEncodingException e) {
758-
throw handleInvalidEncoding(filename, e);
759-
}
760-
}
761-
762-
@TruffleBoundary
763-
private RuntimeException handleInvalidEncoding(String filename, PythonFileDetector.InvalidEncodingException e) {
764-
PythonContext context = getContext();
765-
// Create non-empty source to avoid overwriting the message with "unexpected EOF"
766-
Source source = PythonLanguage.newSource(context, " ", filename, mayBeFromFile);
767-
throw getCore().raiseInvalidSyntax(source, source.createUnavailableSection(), "encoding problem: %s", e.getEncodingName());
768-
}
769-
770750
@SuppressWarnings("unused")
771751
@Specialization
772752
@TruffleBoundary
@@ -805,10 +785,59 @@ PCode compile(String expression, String filename, String mode, Object kwFlags, O
805785
return factory().createCode(ct);
806786
}
807787

808-
@SuppressWarnings("unused")
809-
@Specialization
810-
PCode compile(PCode code, String filename, String mode, Object flags, Object dontInherit, Object optimize) {
811-
return code;
788+
@Specialization(limit = "3")
789+
PCode generic(VirtualFrame frame, Object wSource, Object wFilename, Object wMode, Object kwFlags, Object kwDontInherit, Object kwOptimize,
790+
@Cached CastToJavaStringNode castStr,
791+
@CachedLibrary("wSource") InteropLibrary interopLib,
792+
@CachedLibrary(limit = "3") PythonObjectLibrary lib) {
793+
if (wSource instanceof PCode) {
794+
return (PCode) wSource;
795+
}
796+
String filename = lib.asPathWithState(wFilename, PArguments.getThreadState(frame));
797+
String mode;
798+
try {
799+
mode = castStr.execute(wMode);
800+
} catch (CannotCastException e) {
801+
throw raise(TypeError, ErrorMessages.ARG_S_MUST_BE_S_NOT_P, "compile()", "mode", "str", wMode);
802+
}
803+
String source = sourceAsString(wSource, filename, interopLib, lib);
804+
return compile(source, filename, mode, kwFlags, kwDontInherit, kwOptimize);
805+
}
806+
807+
// modeled after _Py_SourceAsString
808+
String sourceAsString(Object source, String filename, InteropLibrary interopLib, PythonObjectLibrary pyLib) {
809+
if (interopLib.isString(source)) {
810+
try {
811+
return interopLib.asString(source);
812+
} catch (UnsupportedMessageException e) {
813+
throw CompilerDirectives.shouldNotReachHere(e);
814+
}
815+
} else if (pyLib.isBuffer(source)) {
816+
// cpython checks for bytes and bytearray separately, but we deal with it as
817+
// buffers, since that's fast for us anyway
818+
try {
819+
byte[] bytes;
820+
try {
821+
bytes = pyLib.getBufferBytes(source);
822+
} catch (UnsupportedMessageException e) {
823+
throw CompilerDirectives.shouldNotReachHere(e);
824+
}
825+
Charset charset = PythonFileDetector.findEncodingStrict(bytes);
826+
return createString(bytes, charset);
827+
} catch (PythonFileDetector.InvalidEncodingException e) {
828+
throw handleInvalidEncoding(filename, e);
829+
}
830+
} else {
831+
throw raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S, "compile()", 1, "string, bytes or AST object");
832+
}
833+
}
834+
835+
@TruffleBoundary
836+
private RuntimeException handleInvalidEncoding(String filename, PythonFileDetector.InvalidEncodingException e) {
837+
PythonContext context = getContext();
838+
// Create non-empty source to avoid overwriting the message with "unexpected EOF"
839+
Source source = PythonLanguage.newSource(context, " ", filename, mayBeFromFile);
840+
throw getCore().raiseInvalidSyntax(source, source.createUnavailableSection(), "encoding problem: %s", e.getEncodingName());
812841
}
813842

814843
@TruffleBoundary

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public abstract class ErrorMessages {
4646
public static final String ARG_CONVERTED_NOT_EXECUTABLE = "argument converted is not executable";
4747
public static final String ARG_D_MUST_BE_S = "%s arg %d must be a %s";
4848
public static final String ARG_D_MUST_BE_S_NOT_P = "%s argument %d must be %s, not %p";
49+
public static final String ARG_S_MUST_BE_S_NOT_P = "%s argument %s must be %s, not %p";
4950
public static final String ARG_D_MUST_BE_S_OR_S = "%s argument %d must be '%s' or '%s'";
5051
public static final String ARG_D_MUST_NOT_BE_EMPTY = "arg %d must not be empty";
5152
public static final String ARG_EXPECTED_GOT = "%s argument expected, got %p";

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToJavaStringNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
@ImportStatic(PGuards.class)
6666
public abstract class CastToJavaStringNode extends PNodeWithContext {
6767

68-
public abstract String execute(Object x);
68+
public abstract String execute(Object x) throws CannotCastException;
6969

7070
@Specialization
7171
static String doString(String x) {

0 commit comments

Comments
 (0)