📄 js.xs
字号:
ax = (SP - PL_stack_base) + 1; /* read value(s) */ if (cnt == 1) { SVToJSVAL(cx, obj, ST(0), rval); } else { JSObject *jsarr; jsval val; int i; jsarr = JS_NewArrayObject(cx, 0, NULL); for (i = 0; i < cnt; i++) { SVToJSVAL(cx, JS_GetGlobalObject(cx), ST(i), &val); JS_DefineElement(cx, jsarr, i, val, NULL, NULL, 0); } *rval = OBJECT_TO_JSVAL(jsarr); } PUTBACK; FREETMPS; LEAVE; /* this solution is not perfect, but usefull when nested call happens */ return(checkError(cx) && !JS_IsExceptionPending(cx));};/* __PH__END *//* Helper functions needed for most JS API routines *//*static JSRuntime *getRuntime(){ return (JSRuntime *)SvIV((SV*)SvRV(perl_get_sv("JS::Runtime::rt", FALSE)));}static JSContext *getContext(){ return (JSContext *)SvIV((SV*)SvRV(perl_get_sv("JS::Context::this", FALSE)));} */ /* commented as obsolete by __PH__ *//* The following packages are defined below: JS -- main container for all JS functionality JS::Runtime -- wrapper around JSRuntime * JS::Context -- wrapper around JSContext * JS::Object -- wrapper around JSObject * */MODULE = JS PACKAGE = JS PREFIX = JS_PROTOTYPES: DISABLE # package JS # Most of the functions below have names coinsiding with those of the # corresponding JS API functions. Thus, they are not commented.JSRuntime *JS_NewRuntime(maxbytes) int maxbytes OUTPUT: RETVALvoidJS_DestroyRuntime(rt) JSRuntime *rt CODE: /* Make sure that the reference count to the runtime is zero. O.w. this sequence of commands will cause double-deallocation: $rt = new JS::Runtime(10_000); $rt1 = $rt; [exit here] So both $rt->DESTROY and $rt1->DESTROY will cause runtime destruction. _PH_ That's not true, I guess. At least for Perl 5. */ /* warn("===> before runtime check\n"); */ if(SvREFCNT(ST(0)) == 1){ /* warn("===> really runtime destroing"); */ /* __PH__ */ /*__PH__END */ JS_DestroyRuntime(rt); } # package JS::RuntimeMODULE = JS PACKAGE = JS::Runtime PREFIX = JS_intJS_NewContext(rt, stacksize) JSRuntime *rt int stacksize PREINIT: JSContextItem *cxitem; CODE: { JSObject *obj; /* jsval v; comment out unused var __PH__*/ JSContext *cx; cx = JS_NewContext(rt, stacksize); cxitem = PCB_NewContextItem(); cxitem->cx = cx; cxitem->next = context_list; context_list = cxitem; /* __PH__ set the error reporter */ JS_SetErrorReporter(cx, PCB_ErrorReporter); obj = JS_NewObject(cx, &global_class, NULL, NULL); JS_SetGlobalObject(cx, obj); JS_InitStandardClasses(cx, obj); RETVAL = (int)cx; } OUTPUT: RETVALvoidJS_DestroyContext(cx) JSContext *cx CODE: /* See the comment about ref. count above */ /* warn("===> before context check\n"); */ if(SvREFCNT(ST(0)) == 1){ /* warn("===> really destroing context"); */ if (JS_IsExceptionPending(cx)) { JS_ClearPendingException(cx); } JS_SetErrorReporter(cx, NULL); JS_GC(cx); //important JS_DestroyContext(cx); PCB_FreeContextItem(cx); } # package JS::ContextMODULE = JS PACKAGE = JS::Context PREFIX = JS_jsvalJS_eval(cx, bytes, ...) JSContext *cx char *bytes PREINIT: JSContextItem *cxitem; char *filename = NULL; CODE: { jsval rval; if (items > 2) { filename = SvPV(ST(2), PL_na); }; /* Call on the global object */ if(!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), bytes, strlen(bytes), filename ? filename : "Perl", 0, &rval)){ cxitem = PCB_FindContextItem(cx); if (!cxitem || cxitem->dieFromErrors) croak("JS script evaluation failed"); clearException(cx); XSRETURN_UNDEF; } RETVAL = rval; } clearException(cx); OUTPUT: RETVALjsvalJS_exec_(cx, script) JSContext *cx SV *script PREINIT: JSContextItem *cxitem; JSScript *handle; CODE: { jsval rval; handle = (JSScript*)SvIV(*hv_fetch((HV*)SvRV(script), "_script", 7, 0)); /* Call on the global object */ if(!JS_ExecuteScript(cx, JS_GetGlobalObject(cx), handle, &rval)) { cxitem = PCB_FindContextItem(cx); if (!cxitem || cxitem->dieFromErrors) croak("JS script evaluation failed"); clearException(cx); XSRETURN_UNDEF; } clearException(cx); RETVAL = rval; } OUTPUT: RETVAL#void#JS_destroyScript(cx, script)# JSContext *cx# JSScript *script# CODE:# JS_DestroyScript(cx, script);# __PH__voidJS_setErrorReporter(cx, reporter) JSContext *cx SV* reporter PREINIT: JSContextItem *cxitem; CODE: cxitem = PCB_FindContextItem(cx); SvREFCNT_inc(reporter); if ( cxitem ) cxitem->errorReporter = reporter;voidJS_unsetErrorReporter(cx) JSContext *cx PREINIT: JSContextItem *cxitem; CODE: cxitem = PCB_FindContextItem(cx); if ( cxitem ) { if ( cxitem->errorReporter ) SvREFCNT_dec(cxitem->errorReporter); cxitem->errorReporter = NULL; }intJS_hasException(cx) JSContext *cx CODE: RETVAL = ! JS_IsExceptionPending(cx); OUTPUT: RETVALvoid JS_reportError(cx, msg) JSContext *cx char *msg CODE: JS_ReportError(cx, msg);void JS_errorFromPrivate(cx, msg, ex) JSContext *cx char *msg JSObject *ex PREINIT: JSErrorReport *rep; CODE: rep = (JSErrorReport*) JS_GetPrivate(cx, ex); if (rep) PCB_ErrorReporter(cx, msg, ((JSExnPrivate*)rep)->errorReport);voidJS_setDieFromErrors(cx, value) JSContext *cx int value PREINIT: JSContextItem *cxitem; CODE: cxitem = PCB_FindContextItem(cx); if ( cxitem ) cxitem->dieFromErrors = value;voidJS_createObject(cx, object, name, methods) JSContext *cx SV *object char *name SV *methods PREINIT: JSObject *jso; HV *m_hash; I32 len; HE *he; int i; PerlObjectItem *po; JSClass *object_class; PerlCallbackItem *pcbitem; CODE: if (SvTYPE(SvRV(methods)) != SVt_PVHV) { croak("Second parameter has to be HASHREF"); } /* create js object in given context */ object_class = PCB_NewStdJSClass(name); //jso = JS_NewObject(cx, object_class, NULL, 0); jso = JS_DefineObject(cx, JS_GetGlobalObject(cx), name, object_class, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); if (!jso) croak("Unable create JS object"); /* create callback info */ po = PCB_AddObject(name, object, cx, jso, object_class); m_hash = (HV*)SvRV(methods); hv_iterinit(m_hash); while ((he = hv_iternext(m_hash))) { PCB_AddCallback(po, hv_iterkey(he, &len), hv_iterval(m_hash, he), 0); } /* set js object methods */ /* HERE _PH_ */ pcbitem = po->vector; while ( pcbitem ) { if (! JS_DefineFunction(cx, jso, pcbitem->name, PCB_UniversalStub, 0, 0)) croak("Unable create JS function"); pcbitem = pcbitem->next; }# __PH__END # package JS::ObjectMODULE = JS PACKAGE = JS::Object PREFIX = JS_ # # The methods below get used when hash is tied. #SV *JS_TIEHASH(class, obj) char *class SV *obj PREINIT: JSContext* cx; CODE: RETVAL = SvREFCNT_inc(obj); OUTPUT: RETVALSV *JS_TIEARRAY(class, obj) char *class SV *obj PREINIT: JSContext* cx; CODE: RETVAL = SvREFCNT_inc(obj); OUTPUT: RETVALjsvalJS_FETCH(obj, key) JSObject *obj char *key PREINIT: JSContext* cx; jsval rval; MAGIC *magic; CODE: { /* printf("+++++++++> FETCH\n"); */ magic = mg_find(SvRV(ST(0)), '~'); if (magic) { cx = (JSContext *)SvIV(magic->mg_obj); } else { warn("Tied object has no magic\n"); } JS_GetProperty(cx, obj, key, &rval); RETVAL = rval; } OUTPUT: RETVALintJS_FETCHSIZE(obj) JSObject *obj PREINIT: JSContext* cx; MAGIC *magic; CODE: { /* printf("+++++++++> FETCHSIZE: %d\n", ST(0)); */ magic = mg_find(SvRV(ST(0)), '~'); if (magic) { cx = (JSContext *)SvIV(magic->mg_obj); } else { warn("Tied object has no magic\n"); } JS_IsArrayObject(cx, obj); JS_GetArrayLength(cx, obj, &RETVAL); } OUTPUT: RETVALvoidJS_STORE(obj, key, value) JSObject *obj char *key jsval value PREINIT: JSContext* cx; MAGIC *magic; { /* printf("+++++++++> STORE\n"); */ magic = mg_find(SvRV(ST(0)), '~'); if (magic) { cx = (JSContext *)SvIV(magic->mg_obj); } else { warn("Tied object has no magic\n"); } } CODE: { JS_SetProperty(cx, obj, key, &value); }voidJS_DELETE(obj, key) JSObject *obj char *key PREINIT: JSContext* cx; MAGIC *magic; CODE: { /* printf("+++++++++> DELETE\n"); */ magic = mg_find(SvRV(ST(0)), '~'); if (magic) { cx = (JSContext *)SvIV(magic->mg_obj); } else { warn("Tied object has no magic\n"); } JS_DeleteProperty(cx, obj, key); }voidJS_CLEAR(obj) JSObject *obj PREINIT: JSContext* cx; MAGIC *magic; CODE: { /* printf("+++++++++> CLEAR\n"); */ magic = mg_find(SvRV(ST(0)), '~'); if (magic) { cx = (JSContext *)SvIV(magic->mg_obj); } else { warn("Tied object has no magic\n"); } JS_ClearScope(cx, obj); }intJS_EXISTS(obj, key) JSObject *obj char *key PREINIT: JSContext* cx; MAGIC *magic; CODE: { jsval v; /* printf("+++++++++> EXISTS\n"); */ magic = mg_find(SvRV(ST(0)), '~'); if (magic) { cx = (JSContext *)SvIV(magic->mg_obj); } else { warn("Tied object has no magic\n"); } JS_LookupProperty(cx, obj, key, &v); RETVAL = !JSVAL_IS_VOID(v); } OUTPUT: RETVAL#scriptMODULE = JS PACKAGE = JS::Script PREFIX = JS_intJS_compileScript(object, cx, bytes, ...) SV *object JSContext *cx char *bytes PREINIT: JSContextItem *cxitem; char *filename = NULL; CODE: { if (items > 2) { filename = SvPV(ST(2), PL_na); }; /* Call on the global object */ if(!(RETVAL = (int)JS_CompileScript(cx, JS_GetGlobalObject(cx), bytes, strlen(bytes), filename ? filename : "Perl", 0))) { cxitem = PCB_FindContextItem(cx); if (!cxitem || cxitem->dieFromErrors) croak("JS script compilation failed"); XSRETURN_UNDEF; } } OUTPUT: RETVALint JS_rootScript(object, cx, name) SV *object JSContext *cx char *name PREINIT: JSObject **scrobj; JSScript *handle; CODE: handle = (JSScript*)SvIV(*hv_fetch((HV*)SvRV(object), "_script", 7, 0)); scrobj = malloc(sizeof(JSObject*)); *scrobj = JS_NewScriptObject(cx, handle); JS_AddNamedRoot(cx, scrobj, name); RETVAL = (int)scrobj; OUTPUT: RETVALvoid JS_destroyScript(object, cx) SV *object JSContext *cx PREINIT: JSObject **scrobj; JSScript *handle; CODE: handle = (JSScript*)SvIV(*hv_fetch((HV*)SvRV(object), "_script", 7, 0)); scrobj = (JSObject**)SvIV(*hv_fetch((HV*)SvRV(object), "_root", 5, 0)); JS_RemoveRoot(cx, scrobj);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -