X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.pythonlink.win32.x86_64%2Fsrc%2Fsclpy.c;fp=org.simantics.pythonlink.win32.x86_64%2Fsrc%2Fsclpy.c;h=b2308bcdd3b4af57192c0fbd5a3dfa1ad6801e9f;hb=d556dfd2739c43551c894dd636bf8e0735fbad55;hp=762df28e988aaee4b451efe8dfe5f788ccbf304e;hpb=c8a7033eeec2a8a4dd99a8738a7685e8d51b19fd;p=simantics%2Fpython.git diff --git a/org.simantics.pythonlink.win32.x86_64/src/sclpy.c b/org.simantics.pythonlink.win32.x86_64/src/sclpy.c index 762df28..b2308bc 100644 --- a/org.simantics.pythonlink.win32.x86_64/src/sclpy.c +++ b/org.simantics.pythonlink.win32.x86_64/src/sclpy.c @@ -1,14 +1,15 @@ -/////////////////////////////////////////////////////// -// // -// VTT Technical Research Centre of Finland LTD // -// For internal use only. Do not redistribute. // -// // -// Authors: // -// Antton Tapani ext-antton.tapani@vtt.fi // -// // -// Last modified by Antton Tapani 9.2016 // -// // -/////////////////////////////////////////////////////// +/******************************************************************************* + * Copyright (c) 2017-2019 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre - Initial API and implementation + * Semantum Oy - Improvements + *******************************************************************************/ #include "sclpy.h" @@ -49,7 +50,7 @@ static PyObject * writeToSCL(PyObject *self, PyObject *args) { if (currentEnv != NULL && sclWriter != NULL) { - Py_UNICODE *what; + wchar_t *what; Py_ssize_t length; JNIEnv *env = currentEnv; @@ -109,7 +110,7 @@ static PyMethodDef sclWriterMethods[] = { JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_initializePython( JNIEnv *env, jobject thisObj, jobject writer) { - Py_Initialize(); + Py_InitializeEx(0); { static struct PyModuleDef moduledef = { @@ -988,9 +989,12 @@ static PyObject *getExceptionMessage(PyObject *exceptionType, PyObject *exceptio PyObject *formatExc = NULL, *args = NULL; PyObject *tracebackModule = PyImport_ImportModule("traceback"); if (!tracebackModule) { + fputs("Python: No traceback module\n", stderr); return NULL; } + PyErr_NormalizeException(&exceptionType, &exception, &traceback); + if (exception && traceback) { formatExc = PyDict_GetItemString(PyModule_GetDict(tracebackModule), "format_exception"); args = PyTuple_Pack(3, exceptionType, exception, traceback); @@ -1000,21 +1004,40 @@ static PyObject *getExceptionMessage(PyObject *exceptionType, PyObject *exceptio args = PyTuple_Pack(2, exceptionType, exception); } - Py_DECREF(tracebackModule); - if (formatExc != NULL && args != NULL) { PyObject *result = PyObject_CallObject(formatExc, args); + if (!result) { + fputs("Python: No result from format_exception\n", stderr); + // Fallback to a direct string representation of the exception object + result = PyObject_Str(exception); + } Py_XDECREF(args); - Py_XDECREF(formatExc); + // Py_XDECREF(formatExc) - Borrowed reference + Py_DECREF(tracebackModule); + return result; } else { + if (!formatExc) fputs("Python: No format_exception\n", stderr); + Py_XDECREF(args); - Py_XDECREF(formatExc); + // Py_XDECREF(formatExc) - Borrowed reference + Py_DECREF(tracebackModule); + return NULL; } } +static void throwExceptionType(JNIEnv *env, PyObject *exceptionType) { + PyObject *ty_name = exceptionType ? PyObject_GetAttrString(exceptionType, "__name__") : NULL; + PyObject *str = ty_name ? PyUnicode_AsEncodedString(ty_name, "utf-8", "ignore") : NULL; + + throwPythonException(env, str ? PyBytes_AsString(str) : "Internal error - no exception type"); + + Py_XDECREF(str); + Py_XDECREF(ty_name); +} + JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl( JNIEnv *env, jobject thisObj, jlong contextID, jstring statement) { @@ -1032,7 +1055,9 @@ Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl( currentEnv = env; { - PyObject *result = PyRun_String(utfchars, Py_file_input, globals, globals); + // PyObject *result = PyRun_String(utfchars, Py_file_input, globals, globals); - Not available in Py_LIMITED_API + PyObject *code = Py_CompileString(utfchars, "SCL_INPUT", Py_file_input); + PyObject *result = code ? PyEval_EvalCode(code,globals, globals) : NULL; PyObject *exceptionType = PyErr_Occurred(); if (exceptionType != NULL) { @@ -1041,27 +1066,46 @@ Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl( message = getExceptionMessage(exceptionType, exception, traceback); if (message != NULL) { - PyObject *emptyStr = PyUnicode_FromString(""); - PyObject *joined = PyUnicode_Join(emptyStr, message); - char *messageStr = PyUnicode_AsUTF8(joined); - throwPythonException(env, messageStr); - Py_DECREF(joined); - Py_DECREF(emptyStr); + if (PyList_Check(message)) { + PyObject *emptyStr = PyUnicode_FromString(""); + PyObject *temp = PyUnicode_Join(emptyStr, message); + if (temp) { + Py_DECREF(message); + message = temp; + } + + Py_DECREF(emptyStr); + } + + if (!PyUnicode_Check(message)) { + PyObject *temp = PyObject_Str(message); + if (temp) { + Py_DECREF(message); + message = temp; + } + } + + PyObject* str = PyUnicode_AsEncodedString(message, "utf-8", "ignore"); Py_DECREF(message); + + if (str != NULL) { + throwPythonException(env, PyBytes_AsString(str)); + Py_DECREF(str); + } + else { + fputs("Python: Encoding message string failed\n", stderr); + throwExceptionType(env, exceptionType); + } } else { - PyTypeObject - *ty = (PyTypeObject *)exceptionType; - throwPythonException( - env, ty ? ty->tp_name - : "Internal error, null exception type"); + fputs("Python: No exception message\n", stderr); + throwExceptionType(env, exceptionType); } - - Py_XDECREF(exceptionType); - Py_XDECREF(exception); - Py_XDECREF(traceback); } + Py_XDECREF(result); + Py_XDECREF(code); + PyEval_SaveThread(); (*env)->ReleaseStringUTFChars(env, statement, utfchars);