PyObject* Context_add_global(Context* self, PyObject* args, PyObject* kwargs) { PyObject* pykey = NULL; PyObject* pyval = NULL; jsval jsk; jsid kid; jsval jsv; JS_BeginRequest(self->cx); if(!PyArg_ParseTuple(args, "OO", &pykey, &pyval)) goto error; jsk = py2js(self, pykey); if(jsk == JSVAL_VOID) goto error; if(!JS_ValueToId(self->cx, jsk, &kid)) { PyErr_SetString(PyExc_AttributeError, "Failed to create key id."); goto error; } jsv = py2js(self, pyval); if(jsv == JSVAL_VOID) goto error; if(!js_SetProperty(self->cx, self->root, kid, &jsv)) { PyErr_SetString(PyExc_AttributeError, "Failed to set global property."); goto error; } goto success; error: success: JS_EndRequest(self->cx); Py_RETURN_NONE; }
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; }
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; }