PyObject* Context_execute(Context* self, PyObject* args, PyObject* kwargs) { PyObject* obj = NULL; PyObject* ret = NULL; JSContext* cx = NULL; JSObject* root = NULL; JSString* script = NULL; jschar* schars = NULL; JSBool started_counter = JS_FALSE; size_t slen; jsval rval; JS_BeginRequest(self->cx); if(!PyArg_ParseTuple(args, "O", &obj)) goto error; script = py2js_string_obj(self, obj); if(script == NULL) goto error; schars = JS_GetStringChars(script); slen = JS_GetStringLength(script); cx = self->cx; root = self->root; // Mark us for time consumption if(self->start_time == 0) { started_counter = JS_TRUE; self->start_time = time(NULL); } if(!JS_EvaluateUCScript(cx, root, schars, slen, "<JavaScript>", 1, &rval)) { if(!PyErr_Occurred()) { PyErr_SetString(PyExc_RuntimeError, "Failed to execute script."); } goto error; } if(PyErr_Occurred()) goto error; ret = js2py(self, rval); JS_EndRequest(self->cx); JS_MaybeGC(self->cx); goto success; error: JS_EndRequest(self->cx); success: if(started_counter) { self->start_time = 0; } return ret; }
JSBool resolve(JSContext* jscx, JSObject* jsobj, jsval key) { Context* pycx = NULL; PyObject* pykey = NULL; jsid pid; JSBool ret = JS_FALSE; pycx = (Context*) JS_GetContextPrivate(jscx); if(pycx == NULL) { JS_ReportError(jscx, "Failed to get Python context."); goto done; } // Bail if there's no registered global handler. if(pycx->global == NULL) { ret = JS_TRUE; goto done; } pykey = js2py(pycx, key); if(pykey == NULL) goto done; if(Context_has_access(pycx, jscx, pycx->global, pykey) <= 0) goto done; if(!PyMapping_HasKey(pycx->global, pykey)) { ret = JS_TRUE; goto done; } if(!JS_ValueToId(jscx, key, &pid)) { JS_ReportError(jscx, "Failed to convert property id."); goto done; } if(!js_DefineProperty(jscx, pycx->root, pid, JSVAL_VOID, NULL, NULL, JSPROP_SHARED, NULL)) { JS_ReportError(jscx, "Failed to define property."); goto done; } ret = JS_TRUE; done: Py_XDECREF(pykey); return ret; }
JSBool set_prop(JSContext* jscx, JSObject* jsobj, jsval key, jsval* rval) { Context* pycx = NULL; PyObject* pykey = NULL; PyObject* pyval = NULL; JSBool ret = JS_FALSE; pycx = (Context*) JS_GetContextPrivate(jscx); if(pycx == NULL) { JS_ReportError(jscx, "Failed to get Python context."); goto done; } // Bail if there's no registered global handler. if(pycx->global == NULL) { ret = JS_TRUE; goto done; } pykey = js2py(pycx, key); if(pykey == NULL) goto done; if(Context_has_access(pycx, jscx, pycx->global, pykey) <= 0) goto done; pyval = js2py(pycx, *rval); if(pyval == NULL) goto done; if(PyObject_SetItem(pycx->global, pykey, pyval) < 0) goto done; ret = JS_TRUE; done: Py_XDECREF(pykey); Py_XDECREF(pyval); return ret; }
JSBool get_prop(JSContext* jscx, JSObject* jsobj, jsval key, jsval* rval) { Context* pycx = NULL; PyObject* pykey = NULL; PyObject* pyval = NULL; JSBool ret = JS_FALSE; pycx = (Context*) JS_GetContextPrivate(jscx); if(pycx == NULL) { JS_ReportError(jscx, "Failed to get Python context."); goto done; } // Bail if there's no registered global handler. if(pycx->global == NULL) { ret = JS_TRUE; goto done; } pykey = js2py(pycx, key); if(pykey == NULL) goto done; if(Context_has_access(pycx, jscx, pycx->global, pykey) <= 0) goto done; pyval = PyObject_GetItem(pycx->global, pykey); if(pyval == NULL) { if(PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_KeyError)) { PyErr_Clear(); ret = JS_TRUE; } goto done; } *rval = py2js(pycx, pyval); if(*rval == JSVAL_VOID) goto done; ret = JS_TRUE; done: Py_XDECREF(pykey); Py_XDECREF(pyval); return ret; }
PyObject* Context_rem_global(Context* self, PyObject* args, PyObject* kwargs) { PyObject* pykey = NULL; PyObject* ret = NULL; jsval jsk; jsid kid; jsval jsv; JS_BeginRequest(self->cx); if(!PyArg_ParseTuple(args, "O", &pykey)) goto error; jsk = py2js(self, pykey); if(jsk == JSVAL_VOID) goto error; if(!JS_ValueToId(self->cx, jsk, &kid)) { PyErr_SetString(JSError, "Failed to create key id."); } if(!js_GetProperty(self->cx, self->root, kid, &jsv)) { PyErr_SetString(JSError, "Failed to get global property."); goto error; } ret = js2py(self, jsv); if(ret == NULL) goto error; if(!js_DeleteProperty(self->cx, self->root, kid, &jsv)) { PyErr_SetString(JSError, "Failed to remove global property."); goto error; } JS_MaybeGC(self->cx); goto success; error: success: JS_EndRequest(self->cx); return ret; }
JSBool del_prop(JSContext* jscx, JSObject* jsobj, jsval key, jsval* rval) { Context* pycx = NULL; PyObject* pykey = NULL; PyObject* pyval = NULL; JSBool ret = JS_FALSE; pycx = (Context*) JS_GetContextPrivate(jscx); if(pycx == NULL) { JS_ReportError(jscx, "Failed to get Python context."); goto done; } // Bail if there's no registered global handler. if(pycx->global == NULL) { ret = JS_TRUE; goto done; } // Check access to python land. if(Context_has_access(pycx, jscx, pycx->global, pykey) <= 0) goto done; // Bail if the global doesn't have a __delitem__ if(!PyObject_HasAttrString(pycx->global, "__delitem__")) { ret = JS_TRUE; goto done; } pykey = js2py(pycx, key); if(pykey == NULL) goto done; if(PyObject_DelItem(pycx->global, pykey) < 0) goto done; ret = JS_TRUE; done: Py_XDECREF(pykey); Py_XDECREF(pyval); return ret; }
PyObject* Context_execute(Context* self, PyObject* args, PyObject* kwargs) { PyObject* obj = NULL; PyObject* ret = NULL; JSContext* cx = NULL; JSObject* root = NULL; JSString* script = NULL; jschar* schars = NULL; JSBool started_counter = JS_FALSE; char *fname = "<anonymous JavaScript>"; unsigned int lineno = 1; size_t slen; jsval rval; char *keywords[] = {"code", "filename", "lineno", NULL}; if(!PyArg_ParseTupleAndKeywords(args, kwargs, "O|sI", keywords, &obj, &fname, &lineno)) goto error; JS_BeginRequest(self->cx); script = py2js_string_obj(self, obj); if(script == NULL) goto error; schars = JS_GetStringChars(script); slen = JS_GetStringLength(script); cx = self->cx; root = self->root; // Mark us for time consumption if(self->start_time == 0) { started_counter = JS_TRUE; self->start_time = time(NULL); } if(!JS_EvaluateUCScript(cx, root, schars, slen, fname, lineno, &rval)) { if(!PyErr_Occurred()) { PyErr_SetString(PyExc_RuntimeError, "Script execution failed and no exception was set"); } goto error; } if(PyErr_Occurred()) goto error; ret = js2py(self, rval); JS_EndRequest(self->cx); JS_MaybeGC(self->cx); goto success; error: JS_EndRequest(self->cx); success: if(started_counter) { self->start_time = 0; } return ret; }
PyObject* Function_call(Function* self, PyObject* args, PyObject* kwargs) { PyObject* item = NULL; PyObject* ret = NULL; Py_ssize_t argc; Py_ssize_t idx; JSContext* cx; JSObject* parent; jsval func; jsval* argv = NULL; jsval rval; JSBool started_counter = JS_FALSE; JS_BeginRequest(self->obj.cx->cx); argc = PySequence_Length(args); if(argc < 0) goto error; argv = malloc(sizeof(jsval) * argc); if(argv == NULL) { PyErr_NoMemory(); goto error; } for(idx = 0; idx < argc; idx++) { item = PySequence_GetItem(args, idx); if(item == NULL) goto error; argv[idx] = py2js(self->obj.cx, item); if(argv[idx] == JSVAL_VOID) goto error; Py_DECREF(item); item = NULL; // Prevent double decref. } func = self->obj.val; cx = self->obj.cx->cx; parent = JSVAL_TO_OBJECT(self->parent); // Mark us for execution time if not already marked if(self->obj.cx->start_time == 0) { started_counter = JS_TRUE; self->obj.cx->start_time = time(NULL); } if(!JS_CallFunctionValue(cx, parent, func, argc, argv, &rval)) { if(!PyErr_Occurred()) { PyErr_SetString(PyExc_RuntimeError, "JavaScript Function failed to execute"); } goto error; } ret = js2py(self->obj.cx, rval); JS_EndRequest(self->obj.cx->cx); JS_MaybeGC(cx); goto success; error: if(argv != NULL) free(argv); JS_EndRequest(self->obj.cx->cx); success: // Reset the time counter if we started it. if(started_counter) { self->obj.cx->start_time = 0; } Py_XDECREF(item); return ret; }