NPT_Result GPAC_GenericController::OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata) { #ifdef GPAC_HAS_SPIDERMONKEY u32 i, count; GPAC_DeviceItem *item = NULL; GPAC_ServiceItem *serv = NULL; GPAC_ActionArgListener *argl, *act_l; PLT_Service* service = action->GetActionDesc().GetService(); NPT_String uuid; GPAC_ActionUDTA *act_udta = (GPAC_ActionUDTA *)userdata; /*this is NOT an actionResponse to an action triggered on a generic device*/ if (act_udta && act_udta->m_Reserved) act_udta = NULL; GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Receive %s Response - error code %d\n", (char *) action->GetActionDesc().GetName(), res)); gf_mx_p(m_ControlPointLock); /*get our device*/ uuid = service->GetDevice()->GetUUID(); count = gf_list_count(m_Devices); for (i=0; i<count; i++) { item = (GPAC_DeviceItem *) gf_list_get(m_Devices, i); if (item->m_UUID == uuid ) { break; } item = NULL; } gf_mx_v(m_ControlPointLock); if (!item) { GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] Receive %s Response on unknown device (uuid %s)\n", (char *) action->GetActionDesc().GetName(), (char *) uuid)); goto exit; } /*get our service*/ count = gf_list_count(item->m_Services); for (i=0; i<count; i++) { serv = (GPAC_ServiceItem *)gf_list_get(item->m_Services, i); if (serv->m_service == service) break; } if (!serv) { GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] Receive %s Response on unknown service %s\n", (char *) action->GetActionDesc().GetName(), (char *) service->GetServiceType())); goto exit; } /*locate our listeners*/ act_l = NULL; i=0; while ((argl = (GPAC_ActionArgListener *)gf_list_enum(serv->m_ArgListeners, &i))) { NPT_String value; GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] checking argument %s\n", (char *) argl->action->GetName() )); if (argl->action->GetName() != action->GetActionDesc().GetName() ) continue; /*global action listener*/ if (argl->arg==NULL) { act_l = argl; continue; } /*if error don't trigger listeners*/ if (res != NPT_SUCCESS) { GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[UPnP] Receive %s Response: error on remote device %d\n", (char *) action->GetActionDesc().GetName(), res)); continue; } /*action arg listener*/ if (action->GetArgumentValue(argl->arg->GetName(), value) == NPT_SUCCESS) { jsval argv[1], rval; GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling handler for response %s argument %s\n", (char *) action->GetActionDesc().GetName(), (char *) argl->arg->GetName() )); m_pUPnP->LockJavascript(1); argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(serv->js_ctx, value) ); JS_CallFunctionValue(serv->js_ctx, serv->obj, argl->on_event, 1, argv, &rval); m_pUPnP->LockJavascript(0); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] %s Response: couldn't get argument %s value\n", (char *) action->GetActionDesc().GetName(), (char *) argl->arg->GetName() )); } } if (act_l) { jsval rval; m_pUPnP->LockJavascript(1); if (act_l->is_script) { JSObject *act_obj; jsval argv[2]; GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling handler for response %s\n", (char *) action->GetActionDesc().GetName())); act_obj = JS_NewObject(serv->js_ctx, &item->m_pUPnP->upnpDeviceClass._class, 0, item->obj); SMJS_SET_PRIVATE(serv->js_ctx, act_obj, (void *)action.AsPointer() ); JS_DefineFunction(serv->js_ctx, act_obj, "GetArgumentValue", upnp_action_get_argument_value, 1, 0); JS_DefineFunction(serv->js_ctx, act_obj, "GetErrorCode", upnp_action_get_error_code, 1, 0); JS_DefineFunction(serv->js_ctx, act_obj, "GetError", upnp_action_get_error, 1, 0); gf_js_add_root(serv->js_ctx, &act_obj, GF_JSGC_OBJECT); argv[0] = OBJECT_TO_JSVAL(act_obj); if (act_udta) { argv[1] = act_udta->udta; JS_CallFunctionValue(serv->js_ctx, serv->obj, act_l->on_event, 2, argv, &rval); } else { JS_CallFunctionValue(serv->js_ctx, serv->obj, act_l->on_event, 1, argv, &rval); } gf_js_remove_root(serv->js_ctx, &act_obj, GF_JSGC_OBJECT); } /*if error don't trigger listeners*/ else if (res == NPT_SUCCESS) { GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling handler for response %s\n", (char *) action->GetActionDesc().GetName())); JS_CallFunctionValue(serv->js_ctx, serv->obj, act_l->on_event, 0, 0, &rval); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] response %s has error %d\n", (char *) action->GetActionDesc().GetName(), res )); } m_pUPnP->LockJavascript(0); } GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Done processing response %s\n", (char *) action->GetActionDesc().GetName())); exit: if (act_udta) { gf_js_remove_root(serv->js_ctx, &act_udta->udta, GF_JSGC_VAL); delete act_udta; } return NPT_SUCCESS; #else return NPT_SUCCESS; #endif }
NS_IMETHODIMP TelemetryImpl::GetChromeHangs(JSContext *cx, jsval *ret) { MutexAutoLock hangReportMutex(mHangReportsMutex); JSObject *reportArray = JS_NewArrayObject(cx, 0, nsnull); if (!reportArray) { return NS_ERROR_FAILURE; } *ret = OBJECT_TO_JSVAL(reportArray); // Each hang report is an object in the 'chromeHangs' array for (size_t i = 0; i < mHangReports.Length(); ++i) { JSObject *reportObj = JS_NewObject(cx, NULL, NULL, NULL); if (!reportObj) { return NS_ERROR_FAILURE; } jsval reportObjVal = OBJECT_TO_JSVAL(reportObj); if (!JS_SetElement(cx, reportArray, i, &reportObjVal)) { return NS_ERROR_FAILURE; } // Record the hang duration (expressed in seconds) JSBool ok = JS_DefineProperty(cx, reportObj, "duration", INT_TO_JSVAL(mHangReports[i].duration), NULL, NULL, JSPROP_ENUMERATE); if (!ok) { return NS_ERROR_FAILURE; } // Represent call stack PCs as strings // (JS can't represent all 64-bit integer values) JSObject *pcArray = JS_NewArrayObject(cx, 0, nsnull); if (!pcArray) { return NS_ERROR_FAILURE; } ok = JS_DefineProperty(cx, reportObj, "stack", OBJECT_TO_JSVAL(pcArray), NULL, NULL, JSPROP_ENUMERATE); if (!ok) { return NS_ERROR_FAILURE; } const PRUint32 pcCount = mHangReports[i].callStack.Length(); for (size_t pcIndex = 0; pcIndex < pcCount; ++pcIndex) { nsCAutoString pcString; pcString.AppendPrintf("0x%p", mHangReports[i].callStack[pcIndex]); JSString *str = JS_NewStringCopyZ(cx, pcString.get()); if (!str) { return NS_ERROR_FAILURE; } jsval v = STRING_TO_JSVAL(str); if (!JS_SetElement(cx, pcArray, pcIndex, &v)) { return NS_ERROR_FAILURE; } } // Record memory map info JSObject *moduleArray = JS_NewArrayObject(cx, 0, nsnull); if (!moduleArray) { return NS_ERROR_FAILURE; } ok = JS_DefineProperty(cx, reportObj, "memoryMap", OBJECT_TO_JSVAL(moduleArray), NULL, NULL, JSPROP_ENUMERATE); if (!ok) { return NS_ERROR_FAILURE; } const PRUint32 moduleCount = mHangReports[i].moduleMap.GetSize(); for (size_t moduleIndex = 0; moduleIndex < moduleCount; ++moduleIndex) { // Current module const SharedLibrary &module = mHangReports[i].moduleMap.GetEntry(moduleIndex); JSObject *moduleInfoArray = JS_NewArrayObject(cx, 0, nsnull); if (!moduleInfoArray) { return NS_ERROR_FAILURE; } jsval val = OBJECT_TO_JSVAL(moduleInfoArray); if (!JS_SetElement(cx, moduleArray, moduleIndex, &val)) { return NS_ERROR_FAILURE; } // Start address nsCAutoString addressString; addressString.AppendPrintf("0x%p", module.GetStart()); JSString *str = JS_NewStringCopyZ(cx, addressString.get()); if (!str) { return NS_ERROR_FAILURE; } val = STRING_TO_JSVAL(str); if (!JS_SetElement(cx, moduleInfoArray, 0, &val)) { return NS_ERROR_FAILURE; } // Module name str = JS_NewStringCopyZ(cx, module.GetName()); if (!str) { return NS_ERROR_FAILURE; } val = STRING_TO_JSVAL(str); if (!JS_SetElement(cx, moduleInfoArray, 1, &val)) { return NS_ERROR_FAILURE; } // Module size in memory val = INT_TO_JSVAL(int32_t(module.GetEnd() - module.GetStart())); if (!JS_SetElement(cx, moduleInfoArray, 2, &val)) { return NS_ERROR_FAILURE; } // "PDB Age" identifier val = INT_TO_JSVAL(0); #if defined(MOZ_PROFILING) && defined(XP_WIN) val = INT_TO_JSVAL(module.GetPdbAge()); #endif if (!JS_SetElement(cx, moduleInfoArray, 3, &val)) { return NS_ERROR_FAILURE; } // "PDB Signature" GUID char guidString[NSID_LENGTH] = { 0 }; #if defined(MOZ_PROFILING) && defined(XP_WIN) module.GetPdbSignature().ToProvidedString(guidString); #endif str = JS_NewStringCopyZ(cx, guidString); if (!str) { return NS_ERROR_FAILURE; } val = STRING_TO_JSVAL(str); if (!JS_SetElement(cx, moduleInfoArray, 4, &val)) { return NS_ERROR_FAILURE; } } } return NS_OK; }
static void * create_map(void *opaque) { return JS_NewObject(opaque, NULL, NULL, NULL); }
void* vm_run(void* arg) { vm_ptr vm = (vm_ptr) arg; JSContext* cx; JSObject* gl; job_ptr job; ENTERM resp; int flags; cx = JS_NewContext(vm->runtime, vm->stack_size); if(cx == NULL) { fprintf(stderr, "Failed to create context.\n"); goto done; } JS_BeginRequest(cx); flags = 0; flags |= JSOPTION_VAROBJFIX; flags |= JSOPTION_STRICT; flags |= JSVERSION_LATEST; flags |= JSOPTION_COMPILE_N_GO; flags |= JSOPTION_XML; JS_SetOptions(cx, JS_GetOptions(cx) | flags); gl = JS_NewObject(cx, &global_class, NULL, NULL); if(gl == NULL) { fprintf(stderr, "Failed to create global object.\n"); goto done; } if(!JS_InitStandardClasses(cx, gl)) { fprintf(stderr, "Failed to initialize classes.\n"); goto done; } if(!install_jserl(cx, gl)) { fprintf(stderr, "Failed to install erlang object."); goto done; } JS_SetErrorReporter(cx, vm_report_error); JS_SetContextPrivate(cx, (void*) vm); JS_EndRequest(cx); while(1) { job = queue_pop(vm->jobs); if(job->type == job_close) { job_destroy(job); break; } JS_BeginRequest(cx); assert(vm->curr_job == NULL && "vm already has a job set."); vm->curr_job = job; if(job->type == job_eval) { resp = vm_eval(cx, gl, job); } else if(job->type == job_call) { resp = vm_call(cx, gl, job); } else { assert(0 && "Invalid job type."); } vm->curr_job = NULL; JS_EndRequest(cx); JS_MaybeGC(cx); // XXX: If pid is not alive, we just ignore it. enif_send(NULL, &(job->pid), job->env, resp); job_destroy(job); } done: JS_BeginRequest(cx); if(cx != NULL) JS_DestroyContext(cx); return NULL; }
static JSBool import_file(JSContext *context, JSObject *obj, const char *name, const char *full_path) { char *script; gsize script_len; JSObject *module_obj; GError *error; jsval script_retval; JSBool retval = JS_FALSE; gjs_debug(GJS_DEBUG_IMPORTER, "Importing '%s'", full_path); module_obj = JS_NewObject(context, NULL, NULL, NULL); if (module_obj == NULL) { return JS_FALSE; } if (!define_import(context, obj, module_obj, name)) return JS_FALSE; if (!define_meta_properties(context, module_obj, full_path, name, obj)) goto out; script_len = 0; error = NULL; if (!(g_file_get_contents(full_path, &script, &script_len, &error))) { if (!g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_ISDIR) && !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR) && !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) gjs_throw_g_error(context, error); else g_error_free(error); goto out; } g_assert(script != NULL); if (!JS_EvaluateScript(context, module_obj, script, script_len, full_path, 1, /* line number */ &script_retval)) { g_free(script); /* If JSOPTION_DONT_REPORT_UNCAUGHT is set then the exception * would be left set after the evaluate and not go to the error * reporter function. */ if (JS_IsExceptionPending(context)) { gjs_debug(GJS_DEBUG_IMPORTER, "Module '%s' left an exception set", name); gjs_log_and_keep_exception(context, NULL); } else { gjs_throw(context, "JS_EvaluateScript() returned FALSE but did not set exception"); } goto out; } g_free(script); if (!finish_import(context, name)) goto out; if (!seal_import(context, obj, name)) goto out; retval = JS_TRUE; out: if (!retval) cancel_import(context, obj, name); return retval; }
JSObject* gjs_keep_alive_new(JSContext *context) { KeepAlive *priv; JSObject *keep_alive = NULL; JSObject *global; JSBool found; /* This function creates an unattached KeepAlive object; following our * general strategy, we have a single KeepAlive class with a constructor * stored on our single "load global" pseudo-global object, and we create * instances with the load global as parent. */ g_assert(context != NULL); JS_BeginRequest(context); global = gjs_get_import_global(context); g_assert(global != NULL); if (!JS_HasProperty(context, global, gjs_keep_alive_class.name, &found)) goto out; if (!found) { JSObject *prototype; gjs_debug(GJS_DEBUG_KEEP_ALIVE, "Initializing keep-alive class in context %p global %p", context, global); prototype = JS_InitClass(context, global, /* parent prototype JSObject* for * prototype; NULL for * Object.prototype */ NULL, &gjs_keep_alive_class, /* constructor for instances (NULL for * none - just name the prototype like * Math - rarely correct) */ gjs_keep_alive_constructor, /* number of constructor args */ 0, /* props of prototype */ &gjs_keep_alive_proto_props[0], /* funcs of prototype */ &gjs_keep_alive_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ NULL); if (prototype == NULL) g_error("Can't init class %s", gjs_keep_alive_class.name); gjs_debug(GJS_DEBUG_KEEP_ALIVE, "Initialized class %s prototype %p", gjs_keep_alive_class.name, prototype); } gjs_debug(GJS_DEBUG_KEEP_ALIVE, "Creating new keep-alive object for context %p global %p", context, global); keep_alive = JS_NewObject(context, &gjs_keep_alive_class, NULL, global); if (keep_alive == NULL) { gjs_log_exception(context); g_error("Failed to create keep_alive object"); } priv = g_slice_new0(KeepAlive); priv->children = g_hash_table_new_full(child_hash, child_equal, NULL, child_free); g_assert(priv_from_js(context, keep_alive) == NULL); JS_SetPrivate(keep_alive, priv); gjs_debug_lifecycle(GJS_DEBUG_KEEP_ALIVE, "keep_alive constructor, obj %p priv %p", keep_alive, priv); out: JS_EndRequest(context); return keep_alive; }
JSObject* Library::Create(JSContext* cx, Value path_, const JSCTypesCallbacks* callbacks) { RootedValue path(cx, path_); RootedObject libraryObj(cx, JS_NewObject(cx, &sLibraryClass)); if (!libraryObj) return nullptr; // initialize the library JS_SetReservedSlot(libraryObj, SLOT_LIBRARY, PrivateValue(nullptr)); // attach API functions if (!JS_DefineFunctions(cx, libraryObj, sLibraryFunctions)) return nullptr; if (!path.isString()) { JS_ReportError(cx, "open takes a string argument"); return nullptr; } PRLibSpec libSpec; RootedFlatString pathStr(cx, JS_FlattenString(cx, path.toString())); if (!pathStr) return nullptr; AutoStableStringChars pathStrChars(cx); if (!pathStrChars.initTwoByte(cx, pathStr)) return nullptr; #ifdef XP_WIN // On Windows, converting to native charset may corrupt path string. // So, we have to use Unicode path directly. char16ptr_t pathChars = pathStrChars.twoByteChars(); libSpec.value.pathname_u = pathChars; libSpec.type = PR_LibSpec_PathnameU; #else // Convert to platform native charset if the appropriate callback has been // provided. char* pathBytes; if (callbacks && callbacks->unicodeToNative) { pathBytes = callbacks->unicodeToNative(cx, pathStrChars.twoByteChars(), pathStr->length()); if (!pathBytes) return nullptr; } else { // Fallback: assume the platform native charset is UTF-8. This is true // for Mac OS X, Android, and probably Linux. size_t nbytes = GetDeflatedUTF8StringLength(cx, pathStrChars.twoByteChars(), pathStr->length()); if (nbytes == (size_t) -1) return nullptr; pathBytes = static_cast<char*>(JS_malloc(cx, nbytes + 1)); if (!pathBytes) return nullptr; ASSERT_OK(DeflateStringToUTF8Buffer(cx, pathStrChars.twoByteChars(), pathStr->length(), pathBytes, &nbytes)); pathBytes[nbytes] = 0; } libSpec.value.pathname = pathBytes; libSpec.type = PR_LibSpec_Pathname; #endif PRLibrary* library = PR_LoadLibraryWithFlags(libSpec, 0); if (!library) { char* error = (char*) JS_malloc(cx, PR_GetErrorTextLength() + 1); if (error) PR_GetErrorText(error); #ifdef XP_WIN JS_ReportError(cx, "couldn't open library %hs: %s", pathChars, error); #else JS_ReportError(cx, "couldn't open library %s: %s", pathBytes, error); JS_free(cx, pathBytes); #endif JS_free(cx, error); return nullptr; } #ifndef XP_WIN JS_free(cx, pathBytes); #endif // stash the library JS_SetReservedSlot(libraryObj, SLOT_LIBRARY, PrivateValue(library)); return libraryObj; }
jsval toval( const BSONElement& e ) { switch( e.type() ) { case EOO: case jstNULL: case Undefined: return JSVAL_NULL; case NumberDouble: case NumberInt: return toval( e.number() ); case Symbol: // TODO: should we make a special class for this case String: return toval( e.valuestr() ); case Bool: return e.boolean() ? JSVAL_TRUE : JSVAL_FALSE; case Object: { BSONObj embed = e.embeddedObject().getOwned(); return toval( &embed ); } case Array: { BSONObj embed = e.embeddedObject().getOwned(); if ( embed.isEmpty() ) { return OBJECT_TO_JSVAL( JS_NewArrayObject( _context , 0 , 0 ) ); } int n = embed.nFields(); JSObject * array = JS_NewArrayObject( _context , n , 0 ); assert( array ); jsval myarray = OBJECT_TO_JSVAL( array ); for ( int i=0; i<n; i++ ) { jsval v = toval( embed[i] ); assert( JS_SetElement( _context , array , i , &v ) ); } return myarray; } case jstOID: { OID oid = e.__oid(); JSObject * o = JS_NewObject( _context , &object_id_class , 0 , 0 ); setProperty( o , "str" , toval( oid.str().c_str() ) ); return OBJECT_TO_JSVAL( o ); } case RegEx: { const char * flags = e.regexFlags(); uintN flagNumber = 0; while ( *flags ) { switch ( *flags ) { case 'g': flagNumber |= JSREG_GLOB; break; case 'i': flagNumber |= JSREG_FOLD; break; case 'm': flagNumber |= JSREG_MULTILINE; break; //case 'y': flagNumber |= JSREG_STICKY; break; default: log() << "warning: unknown regex flag:" << *flags << endl; } flags++; } JSObject * r = JS_NewRegExpObject( _context , (char*)e.regex() , strlen( e.regex() ) , flagNumber ); assert( r ); return OBJECT_TO_JSVAL( r ); } case Code: { JSFunction * func = compileFunction( e.valuestr() ); return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) ); } case CodeWScope: { JSFunction * func = compileFunction( e.codeWScopeCode() ); BSONObj extraScope = e.codeWScopeObject(); if ( ! extraScope.isEmpty() ) { log() << "warning: CodeWScope doesn't transfer to db.eval" << endl; } return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) ); } case Date: return OBJECT_TO_JSVAL( js_NewDateObjectMsec( _context , (jsdouble) e.date().millis ) ); case MinKey: return OBJECT_TO_JSVAL( JS_NewObject( _context , &minkey_class , 0 , 0 ) ); case MaxKey: return OBJECT_TO_JSVAL( JS_NewObject( _context , &maxkey_class , 0 , 0 ) ); case Timestamp: { JSObject * o = JS_NewObject( _context , ×tamp_class , 0 , 0 ); setProperty( o , "t" , toval( (double)(e.timestampTime()) ) ); setProperty( o , "i" , toval( (double)(e.timestampInc()) ) ); return OBJECT_TO_JSVAL( o ); } case NumberLong: { boost::uint64_t val = (boost::uint64_t)e.numberLong(); JSObject * o = JS_NewObject( _context , &numberlong_class , 0 , 0 ); setProperty( o , "floatApprox" , toval( (double)(boost::int64_t)( val ) ) ); if ( (boost::int64_t)val != (boost::int64_t)(double)(boost::int64_t)( val ) ) { // using 2 doubles here instead of a single double because certain double // bit patterns represent undefined values and sm might trash them setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) ); setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) ); } return OBJECT_TO_JSVAL( o ); } case DBRef: { JSObject * o = JS_NewObject( _context , &dbpointer_class , 0 , 0 ); setProperty( o , "ns" , toval( e.dbrefNS() ) ); JSObject * oid = JS_NewObject( _context , &object_id_class , 0 , 0 ); setProperty( oid , "str" , toval( e.dbrefOID().str().c_str() ) ); setProperty( o , "id" , OBJECT_TO_JSVAL( oid ) ); return OBJECT_TO_JSVAL( o ); } case BinData: { JSObject * o = JS_NewObject( _context , &bindata_class , 0 , 0 ); int len; const char * data = e.binData( len ); assert( JS_SetPrivate( _context , o , new BinDataHolder( data ) ) ); setProperty( o , "len" , toval( len ) ); setProperty( o , "type" , toval( (int)e.binDataType() ) ); return OBJECT_TO_JSVAL( o ); } }
static JSBool fade( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { *rval = JSVAL_FALSE ; if( ( 5 == argc ) && JSVAL_IS_OBJECT( argv[0] ) && JSVAL_IS_OBJECT( argv[1] ) && JSVAL_IS_INT( argv[2] ) && JSVAL_IS_INT( argv[3] ) && JSVAL_IS_INT( argv[4] ) ) { JSObject *thisObj = JS_NewObject( cx, &jsFadeClass_, NULL, NULL ); if( thisObj ) { *rval = OBJECT_TO_JSVAL( thisObj ); // root JSObject *const src = JSVAL_TO_OBJECT( argv[0] ); JSObject *const dest = JSVAL_TO_OBJECT( argv[1] ); jsval lhWidth, lhHeight, rhWidth, rhHeight ; if( JS_GetProperty( cx, src, "width", &lhWidth ) && JS_GetProperty( cx, src, "height", &lhHeight ) && JS_GetProperty( cx, dest, "width", &rhWidth ) && JS_GetProperty( cx, dest, "height", &rhHeight ) ) { if( ( JSVAL_TO_INT( lhWidth ) == JSVAL_TO_INT( rhWidth ) ) && ( JSVAL_TO_INT( lhHeight ) == JSVAL_TO_INT( rhHeight ) ) ) { int const duration = JSVAL_TO_INT( argv[2] ); if( 0 < duration ) { int const x = JSVAL_TO_INT( argv[3] ); int const y = JSVAL_TO_INT( argv[4] ); fbDevice_t &fbDev = getFB(); if( ( 0 <= x ) && ( 0 <= y ) && ( fbDev.getWidth() > x ) && ( fbDev.getHeight() > y ) ) { for( int i = 0 ; i < argc ; i++ ) JS_DefineProperty( cx, thisObj, fadeProperties_[i].name, argv[i], 0, 0, JSPROP_ENUMERATE|JSPROP_PERMANENT|JSPROP_READONLY ); unsigned long const tickNow = now_ms(); JS_DefineProperty( cx, thisObj, fadeProperties_[argc].name, INT_TO_JSVAL( tickNow ), 0, 0, JSPROP_ENUMERATE|JSPROP_PERMANENT|JSPROP_READONLY ); } } else JS_ReportError( cx, "duration must be > 0" ); } else JS_ReportError( cx, "fade: images must be the same size\n" "%d/%d, %d/%d\n", JSVAL_TO_INT( lhWidth ), JSVAL_TO_INT( rhWidth ), JSVAL_TO_INT( lhHeight ), JSVAL_TO_INT( rhHeight ) ); } else JS_ReportError( cx, "fade: getting image sizes" ); } else JS_ReportError( cx, "Error allocating fade" ); } else JS_ReportError( cx, "Usage : new fade( srcImg, destImg, durationMs );" ); return JS_TRUE ; }
static JSObject * create_module_object(JSContext *context) { return JS_NewObject(context, NULL, NULL, NULL); }
static JSObject* importer_new(JSContext *context, gboolean is_root) { JSObject *importer; Importer *priv; JSObject *global; JSBool found; global = gjs_get_import_global(context); if (!JS_HasProperty(context, global, gjs_importer_class.name, &found)) g_error("HasProperty call failed creating importer class"); if (!found) { JSObject *prototype; prototype = JS_InitClass(context, global, /* parent prototype JSObject* for * prototype; NULL for * Object.prototype */ NULL, &gjs_importer_class, /* constructor for instances (NULL for * none - just name the prototype like * Math - rarely correct) */ gjs_importer_constructor, /* number of constructor args */ 0, /* props of prototype */ &gjs_importer_proto_props[0], /* funcs of prototype */ &gjs_importer_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ NULL); if (prototype == NULL) g_error("Can't init class %s", gjs_importer_class.name); gjs_debug(GJS_DEBUG_IMPORTER, "Initialized class %s prototype %p", gjs_importer_class.name, prototype); } importer = JS_NewObject(context, &gjs_importer_class, NULL, global); if (importer == NULL) g_error("No memory to create importer importer"); priv = g_slice_new0(Importer); priv->is_root = is_root; GJS_INC_COUNTER(importer); g_assert(priv_from_js(context, importer) == NULL); JS_SetPrivate(importer, priv); gjs_debug_lifecycle(GJS_DEBUG_IMPORTER, "importer constructor, obj %p priv %p", importer, priv); return importer; }
nsresult WebCL_imageFormatToVariant (JSContext *cx, cl_image_format const& aImageFormat, nsIVariant** aResultOut) { D_METHOD_START; NS_ENSURE_ARG_POINTER (aResultOut); nsresult rv = NS_OK; nsCOMPtr<nsIVariant> res; if (!cx) { nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv); NS_ENSURE_SUCCESS (rv, rv); cx = stack->GetSafeJSContext (); NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE); } nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv); NS_ENSURE_SUCCESS (rv, rv); JS_BeginRequest (cx); JSBool ignored = JS_EnterLocalRootScope (cx); (void)ignored; // ignored is there to avoid gcc warnings.. JSObject* jsObj = JS_NewObject (cx, NULL, NULL, NULL); if (jsObj) { js::Value propChannelOrder; propChannelOrder.setInt32 (aImageFormat.image_channel_order); js::Value propChannelDataType; propChannelDataType.setInt32 (aImageFormat.image_channel_data_type); if ( JS_SetProperty(cx, jsObj, "channelOrder", &propChannelOrder) && JS_SetProperty(cx, jsObj, "channelDataType", &propChannelDataType) && JS_SetProperty(cx, jsObj, "image_channel_order", &propChannelOrder) && JS_SetProperty(cx, jsObj, "image_channel_data_type", &propChannelDataType) ) { js::Value objVal; objVal.setObjectOrNull (jsObj); rv = xpc->JSToVariant (cx, objVal, getter_AddRefs (res)); } else { D_LOG (LOG_LEVEL_ERROR, "Failed to set JSObject properties for image format."); rv = NS_ERROR_FAILURE; } } else { D_LOG (LOG_LEVEL_ERROR, "Failed to create JSObject for image format."); rv = NS_ERROR_FAILURE; } JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); NS_ENSURE_SUCCESS (rv, rv); NS_ADDREF (*aResultOut = res); return NS_OK; }
nsresult WebCL_convertVectorToJSArrayInVariant(JSContext *cx, nsTArray<cl_image_format> const& aVector, nsIVariant** aResultOut, WebCL_LibCLWrapper*) { D_METHOD_START; NS_ENSURE_ARG_POINTER (aResultOut); nsresult rv; if (!cx) { nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv); NS_ENSURE_SUCCESS (rv, rv); cx = stack->GetSafeJSContext (); NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE); } nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv); NS_ENSURE_SUCCESS (rv, rv); JS_BeginRequest (cx); JSBool ignored = JS_EnterLocalRootScope (cx); (void)ignored; // ignored is there to avoid gcc warnings.. JSObject* jsArr = JS_NewArrayObject (cx, aVector.Length (), NULL); if (!jsArr) { JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } size_t cnt = 0; for (nsTArray<cl_image_format>::index_type i = 0; i < aVector.Length(); ++i) { JSObject* jsObj = JS_NewObject (cx, NULL, NULL, NULL); if (jsObj) { js::Value propChannelOrder; propChannelOrder.setInt32 (aVector[i].image_channel_order); js::Value propChannelDataType; propChannelDataType.setInt32 (aVector[i].image_channel_data_type); JS_SetProperty(cx, jsObj, "channelOrder", &propChannelOrder); JS_SetProperty(cx, jsObj, "channelDataType", &propChannelDataType); JS_SetProperty(cx, jsObj, "image_channel_order", &propChannelOrder); JS_SetProperty(cx, jsObj, "image_channel_data_type", &propChannelDataType); js::Value objVal; objVal.setObjectOrNull (jsObj); JS_SetElement (cx, jsArr, cnt++, &objVal); } } JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); if (NS_FAILED (rv)) return rv; // Wrap the JSArray in an nsIVariant nsCOMPtr<nsIVariant> value; js::Value jsValue; jsValue.setObjectOrNull (jsArr); rv = xpc->JSValToVariant(cx, &jsValue, getter_AddRefs(value)); NS_ENSURE_SUCCESS (rv, rv); NS_ADDREF (*aResultOut = value); return NS_OK; }
nsresult WebCL_createTypesObject (JSContext *cx, nsIVariant** aResultOut) { D_METHOD_START; NS_ENSURE_ARG_POINTER (aResultOut); nsresult rv; nsCOMPtr<nsIVariant> res; static struct { char const* name; int value; } types[] = { { "BYTE", types::BYTE }, { "CHAR", types::CHAR }, { "UCHAR", types::UCHAR }, { "SHORT", types::SHORT }, { "USHORT", types::USHORT }, { "INT", types::INT }, { "UINT", types::UINT }, { "LONG", types::LONG }, { "ULONG", types::ULONG }, { "BOOL", types::BOOL }, { "SIZE_T", types::SIZE_T }, { "HALF", types::HALF }, { "FLOAT", types::FLOAT }, { "DOUBLE", types::DOUBLE }, { "STRING", types::STRING }, { "PLATFORM", types::PLATFORM }, { "DEVICE", types::DEVICE }, { "CONTEXT", types::CONTEXT }, { "COMMAND_QUEUE", types::COMMAND_QUEUE }, { "MEMORY_OBJECT", types::MEMORY_OBJECT }, { "PROGRAM", types::PROGRAM }, { "KERNEL", types::KERNEL }, { "EVENT", types::EVENT }, { "SAMPLER", types::SAMPLER }, { "IMAGE_FORMAT", types::IMAGE_FORMAT }, { "ADRESSING_MODE", types::ADRESSING_MODE }, { "BUILD_STATUS", types::BUILD_STATUS }, { "CHANNEL_ORDER", types::CHANNEL_ORDER }, { "CHANNEL_TYPE", types::CHANNEL_TYPE }, { "COMMAND_QUEUE_PROPERTIES", types::COMMAND_QUEUE_PROPERTIES }, { "COMMAND_TYPE", types::COMMAND_TYPE }, { "CONTEXT_PROPERTIES", types::CONTEXT_PROPERTIES }, { "DEVICE_EXEC_CAPABILITIES", types::DEVICE_EXEC_CAPABILITIES }, { "DEVICE_FP_CONFIG", types::DEVICE_FP_CONFIG }, { "DEVICE_LOCAL_MEM_TYPE", types::DEVICE_LOCAL_MEM_TYPE }, { "DEVICE_MEM_CACHE_TYPE", types::DEVICE_MEM_CACHE_TYPE }, { "DEVICE_TYPE", types::DEVICE_TYPE }, { "FILTER_MODE", types::FILTER_MODE }, { "GL_OBJECT_TYPE", types::GL_OBJECT_TYPE }, { "MAP_FLAGS", types::MAP_FLAGS }, { "MEM_FENCE_FLAGS", types::MEM_FENCE_FLAGS }, { "MEM_FLAGS", types::MEM_FLAGS }, { "MEM_OBJECT_TYPE", types::MEM_OBJECT_TYPE }, { "BYTE_V", types::BYTE_V }, { "CHAR_V", types::CHAR_V }, { "UCHAR_V", types::UCHAR_V }, { "SHORT_V", types::SHORT_V }, { "USHORT_V", types::USHORT_V }, { "INT_V", types::INT_V }, { "UINT_V", types::UINT_V }, { "LONG_V", types::LONG_V }, { "ULONG_V", types::ULONG_V }, { "BOOL_V", types::BOOL_V }, { "SIZE_T_V", types::SIZE_T_V }, { "HALF_V", types::HALF_V }, { "FLOAT_V", types::FLOAT_V }, { "DOUBLE_V", types::DOUBLE_V }, { "STRING_V", types::STRING_V }, { "PLATFORM_V", types::PLATFORM_V }, { "DEVICE_V", types::DEVICE_V }, { "CONTEXT_V", types::CONTEXT_V }, { "COMMAND_QUEUE_V", types::COMMAND_QUEUE_V }, { "MEMORY_OBJECT_V", types::MEMORY_OBJECT_V }, { "PROGRAM_V", types::PROGRAM_V }, { "KERNEL_V", types::KERNEL_V }, { "EVENT_V", types::EVENT_V }, { "SAMPLER_V", types::SAMPLER_V } }; if (!cx) { nsCOMPtr<nsIThreadJSContextStack> stack = do_GetService ("@mozilla.org/js/xpc/ContextStack;1", &rv); NS_ENSURE_SUCCESS (rv, rv); cx = stack->GetSafeJSContext (); NS_ENSURE_TRUE (cx, NS_ERROR_FAILURE); } nsCOMPtr<nsIXPConnect> xpc = do_GetService (nsIXPConnect::GetCID (), &rv); NS_ENSURE_SUCCESS (rv, rv); JS_BeginRequest (cx); JSBool ignored = JS_EnterLocalRootScope (cx); (void)ignored; // ignored is there to avoid gcc warnings.. JSObject* jsObj = JS_NewObject (cx, NULL, NULL, NULL); if (jsObj) { for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i) { js::Value val; val.setInt32 (types[i].value); if (!JS_SetProperty(cx, jsObj, types[i].name, &val)) { D_LOG (LOG_LEVEL_ERROR, "Failed to set types object property \"%s\" = %d", types[i].name, types[i].value); break; } } js::Value objVal; objVal.setObjectOrNull (jsObj); rv = xpc->JSToVariant (cx, objVal, getter_AddRefs (res)); } else { D_LOG (LOG_LEVEL_ERROR, "Failed to create JSObject for types property."); rv = NS_ERROR_FAILURE; } JS_LeaveLocalRootScope (cx); JS_EndRequest(cx); NS_ENSURE_SUCCESS (rv, rv); NS_ADDREF (*aResultOut = res); return NS_OK; }
JSObject * LM_ReflectNamedAnchor(MWContext *context, lo_NameList *name_rec, PA_Tag * tag, int32 layer_id, uint index) { JSObject *obj, *array_obj, *document; MochaDecoder *decoder; JSContext *cx; JSObjectArray *array; JSAnchor *named_anchor; lo_TopState *top_state; PRHashTable *map; JSString *str; obj = name_rec->mocha_object; if (obj) return obj; decoder = LM_GetMochaDecoder(context); if (!decoder) return NULL; cx = decoder->js_context; top_state = lo_GetMochaTopState(context); if (top_state->resize_reload) { map = lm_GetIdToObjectMap(decoder); if (map) obj = (JSObject *)PR_HashTableLookup(map, LM_GET_MAPPING_KEY(LM_NAMEDANCHORS, layer_id, index)); if (obj) { name_rec->mocha_object = obj; LM_PutMochaDecoder(decoder); return obj; } } /* Get the document object that will hold this anchor */ document = lm_GetDocumentFromLayerId(decoder, layer_id); if (!document) { LM_PutMochaDecoder(decoder); return NULL; } array_obj = lm_GetNameArray(decoder, document); if (!array_obj) { LM_PutMochaDecoder(decoder); return NULL; } array = JS_GetPrivate(cx, array_obj); if (!array) { LM_PutMochaDecoder(decoder); return NULL; } named_anchor = JS_malloc(cx, sizeof *named_anchor); if (!named_anchor) { LM_PutMochaDecoder(decoder); return NULL; } XP_BZERO(named_anchor, sizeof *named_anchor); obj = JS_NewObject(cx, &lm_anchor_class, decoder->anchor_prototype, document); if (!obj || !JS_SetPrivate(cx, obj, named_anchor)) { JS_free(cx, named_anchor); LM_PutMochaDecoder(decoder); return NULL; } /* Put obj into the document.anchors array. */ JS_DefineProperty(cx, array_obj, (char *) name_rec->name, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE|JSPROP_READONLY); JS_AliasElement(cx, array_obj, (char *) name_rec->name, index); /* Put it in the index to object hash table */ map = lm_GetIdToObjectMap(decoder); if (map) { PR_HashTableAdd(map, LM_GET_MAPPING_KEY(LM_NAMEDANCHORS, layer_id, index), obj); } if ((jsint) index >= array->length) array->length = index + 1; named_anchor->decoder = HOLD_BACK_COUNT(decoder); named_anchor->layer_id = layer_id; named_anchor->index = index; if (name_rec->element && name_rec->element->type == LO_TEXT) { str = lm_LocalEncodingToStr(context, (char *) name_rec->element->lo_text.text); if (!str || !JS_LockGCThing(cx, str)) { LM_PutMochaDecoder(decoder); return NULL; } named_anchor->text = str; } str = JS_NewStringCopyZ(cx, (char *) name_rec->name); if (!str || !JS_LockGCThing(cx, str)) { LM_PutMochaDecoder(decoder); return NULL; } named_anchor->name = str; name_rec->mocha_object = obj; /* see if there are any attributes for event handlers */ if(tag) { PA_Block onlocate, id; /* don't hold the layout lock across compiles */ LO_UnlockLayout(); onlocate = lo_FetchParamValue(context, tag, PARAM_ONLOCATE); id = lo_FetchParamValue(context, tag, PARAM_ID); if (onlocate) { (void) lm_CompileEventHandler(decoder, id, tag->data, tag->newline_count, obj, PARAM_ONLOCATE, onlocate); PA_FREE(onlocate); } if (id) PA_FREE(id); LO_LockLayout(); } LM_PutMochaDecoder(decoder); return obj; }
template<> void ScriptInterface::ToJSVal<SDL_Event_>(JSContext* cx, JS::Value& ret, SDL_Event_ const& val) { JSAutoRequest rq(cx); const char* typeName; switch (val.ev.type) { #if SDL_VERSION_ATLEAST(2, 0, 0) case SDL_WINDOWEVENT: typeName = "windowevent"; break; #else case SDL_ACTIVEEVENT: typeName = "activeevent"; break; case SDL_VIDEOEXPOSE: typeName = "videoexpose"; break; case SDL_VIDEORESIZE: typeName = "videoresize"; break; #endif case SDL_KEYDOWN: typeName = "keydown"; break; case SDL_KEYUP: typeName = "keyup"; break; case SDL_MOUSEMOTION: typeName = "mousemotion"; break; case SDL_MOUSEBUTTONDOWN: typeName = "mousebuttondown"; break; case SDL_MOUSEBUTTONUP: typeName = "mousebuttonup"; break; case SDL_QUIT: typeName = "quit"; break; case SDL_HOTKEYDOWN: typeName = "hotkeydown"; break; case SDL_HOTKEYUP: typeName = "hotkeyup"; break; default: typeName = "(unknown)"; break; } JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL); if (! obj) { ret = JSVAL_VOID; return; } SET(obj, "type", typeName); switch (val.ev.type) { #if !SDL_VERSION_ATLEAST(2, 0, 0) case SDL_ACTIVEEVENT: { SET(obj, "gain", (int)val.ev.active.gain); SET(obj, "state", (int)val.ev.active.state); break; } #endif case SDL_KEYDOWN: case SDL_KEYUP: { // SET(obj, "which", (int)val.ev.key.which); // (not in wsdl.h) // SET(obj, "state", (int)val.ev.key.state); // (not in wsdl.h) JSObject* keysym = JS_NewObject(cx, NULL, NULL, NULL); if (! keysym) { ret = JSVAL_VOID; return; } JS::RootedValue keysymVal(cx, JS::ObjectValue(*keysym)); JS_SetProperty(cx, obj, "keysym", keysymVal.address()); // SET(keysym, "scancode", (int)val.ev.key.keysym.scancode); // (not in wsdl.h) SET(keysym, "sym", (int)val.ev.key.keysym.sym); // SET(keysym, "mod", (int)val.ev.key.keysym.mod); // (not in wsdl.h) if (val.ev.key.keysym.unicode) { std::wstring unicode(1, (wchar_t)val.ev.key.keysym.unicode); SET(keysym, "unicode", unicode); } else { SET(keysym, "unicode", CScriptVal(JSVAL_VOID)); } // TODO: scripts have no idea what all the key/mod enum values are; // we should probably expose them as constants if we expect scripts to use them break; } case SDL_MOUSEMOTION: { // SET(obj, "which", (int)val.ev.motion.which); // (not in wsdl.h) // SET(obj, "state", (int)val.ev.motion.state); // (not in wsdl.h) SET(obj, "x", (int)val.ev.motion.x); SET(obj, "y", (int)val.ev.motion.y); // SET(obj, "xrel", (int)val.ev.motion.xrel); // (not in wsdl.h) // SET(obj, "yrel", (int)val.ev.motion.yrel); // (not in wsdl.h) break; } case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { // SET(obj, "which", (int)val.ev.button.which); // (not in wsdl.h) SET(obj, "button", (int)val.ev.button.button); SET(obj, "state", (int)val.ev.button.state); SET(obj, "x", (int)val.ev.button.x); SET(obj, "y", (int)val.ev.button.y); break; } case SDL_HOTKEYDOWN: case SDL_HOTKEYUP: { SET(obj, "hotkey", static_cast<const char*>(val.ev.user.data1)); break; } } ret = JS::ObjectValue(*obj); }
JSBool js_CrossApp_extension_WebSocket_constructor(JSContext *cx, uint32_t argc, jsval *vp) { jsval *argv = JS_ARGV(cx, vp); if (argc == 1 || argc == 2) { std::string url; do { JSBool ok = jsval_to_std_string(cx, argv[0], &url); JSB_PRECONDITION2( ok, cx, JS_FALSE, "Error processing arguments"); } while (0); JSObject *obj = JS_NewObject(cx, js_CrossApp_websocket_class, js_CrossApp_websocket_prototype, NULL); extension::WebSocket* cobj = new extension::WebSocket(); JSB_WebSocketDelegate* delegate = new JSB_WebSocketDelegate(); delegate->setJSDelegate(obj); if (argc == 2) { std::vector<std::string> protocols; if (JSVAL_IS_STRING(argv[1])) { std::string protocol; do { JSBool ok = jsval_to_std_string(cx, argv[1], &protocol); JSB_PRECONDITION2( ok, cx, JS_FALSE, "Error processing arguments"); } while (0); protocols.push_back(protocol); } else if (argv[1].isObject()) { JSBool ok = JS_TRUE; JSObject* arg2 = JSVAL_TO_OBJECT(argv[1]); JSB_PRECONDITION(JS_IsArrayObject( cx, arg2 ), "Object must be an array"); uint32_t len = 0; JS_GetArrayLength(cx, arg2, &len); for( uint32_t i=0; i< len;i++ ) { jsval valarg; JS_GetElement(cx, arg2, i, &valarg); std::string protocol; do { ok = jsval_to_std_string(cx, valarg, &protocol); JSB_PRECONDITION2( ok, cx, JS_FALSE, "Error processing arguments"); } while (0); protocols.push_back(protocol); } } cobj->init(*delegate, url, &protocols); } else { cobj->init(*delegate, url); } JS_DefineProperty(cx, obj, "URL", argv[0] , NULL, NULL, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY); //protocol not support yet (always return "") JS_DefineProperty(cx, obj, "protocol", c_string_to_jsval(cx, "") , NULL, NULL, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY); // link the native object with the javascript object js_proxy_t *p = jsb_new_proxy(cobj, obj); JS_AddNamedObjectRoot(cx, &p->obj, "WebSocket"); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); return JS_TRUE; } JS_ReportError(cx, "wrong number of arguments: %d, was expecting %d", argc, 0); return JS_FALSE; }
/* Wrap a JS value to export into perl * Returns a new SV, REFCNT_dec is caller's responsability */ JSBool PJS_ReflectJS2Perl( pTHX_ JSContext *cx, jsval value, SV** sv, int full ) { if(JSVAL_IS_PRIMITIVE(value)) { *sv = PrimJSVALToSV(aTHX_ cx, value); if(*sv) return JS_TRUE; } else if(JSVAL_IS_OBJECT(value)) { PJS_Context *pcx = PJS_GET_CONTEXT(cx); JSObject *object = JSVAL_TO_OBJECT(value); JSClass *clasp = PJS_GET_CLASS(cx, object); const char *classname = clasp->name; JSObject *passport; SV *wrapper; SV *box; char hkey[32]; jsval temp = JSVAL_VOID; snprintf(hkey, 32, "%p", (void *)object); PJS_DEBUG2("Wrapping a %s(%s)\n", classname, hkey); if(PJS_getFlag(pcx, "ConvertRegExp") && strEQ(classname, "RegExp")) { jsval src; char *str; if(JS_CallFunctionName(cx, object, "toSource", 0, NULL, &src) && (str = JS_GetStringBytes(JS_ValueToString(cx, src))) ) { dSP; SV *tmp = newSVpvf("qr%s", str); eval_sv(tmp, G_SCALAR); sv_free(tmp); // Don't leak SPAGAIN; tmp = POPs; PUTBACK; if(!SvTRUE(ERRSV)) { *sv = SvREFCNT_inc_simple_NN(tmp); return JS_TRUE; } } return JS_FALSE; } if(IS_PERL_CLASS(clasp)) { /* IS_PERL_CLASS means actual perl object is there */ SV *priv = (SV *)JS_GetPrivate(cx, object); if(priv && SvOK(priv) && SvROK(priv)) { *sv = SvREFCNT_inc_simple_NN(priv); return JS_TRUE; } croak("A private %s?!\n", classname); return JS_FALSE; } /* Common JSObject case */ /* Check registered perl visitors */ JS_LookupProperty(cx, pcx->pvisitors, hkey, &temp); if(temp != JSVAL_VOID) { /* Already registered, so exits a reference in perl space * _must_ hold a PASSPORT */ assert(JSVAL_TO_OBJECT(temp) == object); box = PJS_GetPassport(aTHX_ cx, object); SvREFCNT_inc_void_NN(box); /* In perl should be one more */ PJS_DEBUG1("Cached!: %s\n", hkey); } else { /* Check if with a PASSPORT */ JS_LookupPropertyWithFlags(cx, object, PJS_PASSPORT_PROP, 0, &temp); if(JSVAL_IS_OBJECT(temp) && (passport = JSVAL_TO_OBJECT(temp)) && PJS_GET_CLASS(cx, passport) == &passport_class && JS_GetReservedSlot(cx, passport, 0, &temp) && object == (JSObject *)JSVAL_TO_PRIVATE(temp) ) { /* Yes, reentering perl */ box = (SV *)JS_GetPrivate(cx, passport); /* Here we don't increment refcount, the ownership in passport is * transferred to perl land. */ PJS_DEBUG1("Reenter: %s\n", hkey); } else { /* No, first time, must wrap the object */ SV *boxref; const char *package; SV *robj = newSV(0); SV *rjsv = newSV(0); if (JS_ObjectIsFunction(cx, object)) package = PJS_FUNCTION_PACKAGE; else if(JS_IsArrayObject(cx, object)) package = PJS_ARRAY_PACKAGE; else if(strEQ(classname, PJS_PACKAGE_CLASS_NAME)) package = PJS_STASH_PACKAGE; #if JS_HAS_XML_SUPPORT else if(strEQ(classname, "XML")) package = PJS_XMLOBJ_PACKAGE; #endif else if(strEQ(classname, "Error")) package = PJS_ERROR_PACKAGE; else { SV **sv = hv_fetch(get_hv(NAMESPACE"ClassMap", 1), classname, strlen(classname), 0); if(sv) package = SvPV_nolen(*sv); else package = PJS_OBJECT_PACKAGE; } sv_setref_pv(robj, PJS_RAW_OBJECT, (void*)object); sv_setref_iv(rjsv, PJS_RAW_JSVAL, (IV)value); boxref = PJS_CallPerlMethod(aTHX_ cx, "__new", sv_2mortal(newSVpv(package, 0)), // package sv_2mortal(robj), // content sv_2mortal(rjsv), // jsval NULL ); if(!boxref) return JS_FALSE; if(!SvOK(boxref) || !sv_derived_from(boxref, PJS_BOXED_PACKAGE)) croak("PJS_Assert: Contructor must return a "NAMESPACE"Boxed"); /* Create a new PASSPORT */ passport = JS_NewObject(cx, &passport_class, NULL, object); if(!passport || !JS_DefineProperty(cx, object, PJS_PASSPORT_PROP, OBJECT_TO_JSVAL(passport), NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT)) return JS_FALSE; box = SvRV(boxref); /* boxref is mortal, so we need to increment its rc, at end of * scope, PASSPORT owns created box */ JS_SetPrivate(cx, passport, (void *)SvREFCNT_inc_simple_NN(box)); JS_SetReservedSlot(cx, passport, 0, PRIVATE_TO_JSVAL(object)); PJS_DEBUG2("New boxed: %s brc: %d\n", hkey, SvREFCNT(box)); } /* Root object adding it to pvisitors list, will be unrooted by * jsc_free_root at Boxed DESTROY time */ JS_DefineProperty(cx, pcx->pvisitors, hkey, value, NULL, NULL, 0); } /* Here the RC of box in PASSPORT reflects wrapper's ownership */ if(full && PJS_getFlag(pcx, "AutoTie") && (strEQ(classname, "Object") || strEQ(classname, "Array")) ) { /* Return tied */ AV *avbox = (AV *)SvRV(box); SV **last; SV *tied; SV *tier; if(strEQ(classname, "Array")) { last = av_fetch(avbox, 6, 1); if(last && SvOK(*last) && SvROK(*last)) { // Cached *sv = newSVsv(*last); sv_free(box); /* Hard copy 'sv' owns the reference */ return JS_TRUE; } tied = (SV *)newAV(); } else { // Object last = av_fetch(avbox, 5, 1); if(last && SvOK(*last) && SvROK(*last)) { // Cached *sv = newSVsv(*last); sv_free(box); /* Hard copy 'sv' owns the reference */ return JS_TRUE; } tied = (SV *)newHV(); } /* hv_magic below own a reference to box, we use an explicit path, * to make clear that to perl land only one reference is given */ tier = newRV_inc(box); hv_magic((HV *)tied, (GV *)tier, PERL_MAGIC_tied); sv_free(tier); wrapper = newRV_noinc(tied); /* Don't leak the hidden tied variable */ /* Save in cache a weaken copy, the cache itself dosn't hold a reference */ sv_setsv(*last, wrapper); sv_rvweaken(*last); PJS_DEBUG1("Return tied for %s\n", SvPV_nolen(tier)); } else { wrapper = newRV_noinc(box); /* Transfer ownership to wrapper */ #if PERL_VERSION < 9 sv_bless(wrapper, SvSTASH(box)); #endif } *sv = wrapper; return JS_TRUE; } return JS_FALSE; }
void SG_vc_hooks__execute( SG_context* pCtx, const char* psz_js, SG_vhash* pvh_params, SG_vhash** ppvh_result ) { jsval rval; JSContext* cx = NULL; JSObject* glob = NULL; SG_vhash* pvh_result = NULL; JSObject* jso_params = NULL; SG_NULLARGCHECK_RETURN(psz_js); SG_jscore__new_runtime(pCtx, NULL, global_functions, SG_FALSE, NULL); SG_ERR_CHECK_CURRENT_DISREGARD(SG_ERR_ALREADY_INITIALIZED); SG_ERR_CHECK( SG_jscore__new_context(pCtx, &cx, &glob, NULL) ); //This should tell the javascript engine how to report javascript errors to our jsglue. JS_SetErrorReporter(cx,SG_jsglue__error_reporter); if(!JS_EvaluateScript(cx, glob, psz_js, (uintN) strlen(psz_js), "hook_script", 1, &rval)) { SG_ERR_CHECK_CURRENT; SG_ERR_THROW2(SG_ERR_UNSPECIFIED, (pCtx, "An error occurred evaluating hook")); } // note that we don't care about the rval from eval of the script { jsval params; jsval rval; if (pvh_params) { jso_params = JS_NewObject(cx, NULL, NULL, NULL); if(!jso_params) SG_ERR_THROW2(SG_ERR_MALLOCFAILED, (pCtx, "Failed to create new JS object for params to vc hook.")); params = OBJECT_TO_JSVAL(jso_params); SG_ERR_CHECK( sg_jsglue__copy_vhash_into_jsobject(pCtx, cx, pvh_params, jso_params) ); } else { params = JSVAL_NULL; } if(!JS_CallFunctionName(cx, glob, "hook", 1, ¶ms, &rval)) { SG_ERR_CHECK_CURRENT; SG_ERR_THROW2(SG_ERR_UNSPECIFIED, (pCtx, "An error occurred calling JS hook")); } if (JSVAL_IS_OBJECT(rval)) { SG_ERR_CHECK( sg_jsglue__jsobject_to_vhash(pCtx, cx, JSVAL_TO_OBJECT(rval), &pvh_result) ); } } if (ppvh_result) { *ppvh_result = pvh_result; pvh_result = NULL; } fail: if (cx) { SG_ERR_IGNORE( SG_jsglue__set_sg_context(NULL, cx) ); JS_EndRequest(cx); JS_DestroyContext(cx); } SG_VHASH_NULLFREE(pCtx, pvh_result); }
JSBool JSI_Console::getConsole(JSContext* cx, JSObject* UNUSED(obj), jsid UNUSED(id), jsval* vp) { JSObject* console = JS_NewObject(cx, &JSI_Console::JSI_class, NULL, NULL); *vp = OBJECT_TO_JSVAL(console); return JS_TRUE; }
void SmsRequest::NotifyThreadList(const InfallibleTArray<ThreadListItem>& aItems) { MOZ_ASSERT(!mParent); MOZ_ASSERT(GetOwner()); nsresult rv; nsIScriptContext* sc = GetContextForEventHandlers(&rv); NS_ENSURE_SUCCESS_VOID(rv); NS_ENSURE_TRUE_VOID(sc); JSContext* cx = sc->GetNativeContext(); MOZ_ASSERT(cx); nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetOwner()); JSObject* ownerObj = sgo->GetGlobalJSObject(); NS_ENSURE_TRUE_VOID(ownerObj); nsCxPusher pusher; NS_ENSURE_TRUE_VOID(pusher.Push(cx, false)); JSAutoRequest ar(cx); JSAutoCompartment ac(cx, ownerObj); JSObject* array = JS_NewArrayObject(cx, aItems.Length(), nullptr); NS_ENSURE_TRUE_VOID(array); bool ok; for (uint32_t i = 0; i < aItems.Length(); i++) { const ThreadListItem& source = aItems[i]; nsString temp = source.senderOrReceiver(); jsval senderOrReceiver; ok = xpc::StringToJsval(cx, temp, &senderOrReceiver); NS_ENSURE_TRUE_VOID(ok); JSObject* timestampObj = JS_NewDateObjectMsec(cx, source.timestamp()); NS_ENSURE_TRUE_VOID(timestampObj); jsval timestamp = OBJECT_TO_JSVAL(timestampObj); temp = source.body(); jsval body; ok = xpc::StringToJsval(cx, temp, &body); NS_ENSURE_TRUE_VOID(ok); jsval unreadCount = JS_NumberValue(double(source.unreadCount())); JSObject* elementObj = JS_NewObject(cx, nullptr, nullptr, nullptr); NS_ENSURE_TRUE_VOID(elementObj); ok = JS_SetProperty(cx, elementObj, "senderOrReceiver", &senderOrReceiver); NS_ENSURE_TRUE_VOID(ok); ok = JS_SetProperty(cx, elementObj, "timestamp", ×tamp); NS_ENSURE_TRUE_VOID(ok); ok = JS_SetProperty(cx, elementObj, "body", &body); NS_ENSURE_TRUE_VOID(ok); ok = JS_SetProperty(cx, elementObj, "unreadCount", &unreadCount); NS_ENSURE_TRUE_VOID(ok); jsval element = OBJECT_TO_JSVAL(elementObj); ok = JS_SetElement(cx, array, i, &element); NS_ENSURE_TRUE_VOID(ok); } NotifyThreadList(OBJECT_TO_JSVAL(array), cx); }
static JSObject* CreateInterfaceObject(JSContext* cx, JSObject* global, JSObject* receiver, JSClass* constructorClass, JSNative constructorNative, unsigned ctorNargs, JSObject* proto, Prefable<JSFunctionSpec>* staticMethods, Prefable<ConstantSpec>* constants, const char* name) { JSObject* constructor; if (constructorClass) { JSObject* functionProto = JS_GetFunctionPrototype(cx, global); if (!functionProto) { return NULL; } constructor = JS_NewObject(cx, constructorClass, functionProto, global); } else { MOZ_ASSERT(constructorNative); JSFunction* fun = JS_NewFunction(cx, constructorNative, ctorNargs, JSFUN_CONSTRUCTOR, global, name); if (!fun) { return NULL; } constructor = JS_GetFunctionObject(fun); } if (!constructor) { return NULL; } if (staticMethods && !DefinePrefable(cx, constructor, staticMethods)) { return NULL; } if (constructorClass) { JSFunction* toString = js::DefineFunctionWithReserved(cx, constructor, "toString", InterfaceObjectToString, 0, 0); if (!toString) { return NULL; } JSObject* toStringObj = JS_GetFunctionObject(toString); js::SetFunctionNativeReserved(toStringObj, TOSTRING_CLASS_RESERVED_SLOT, PRIVATE_TO_JSVAL(constructorClass)); JSString *str = ::JS_InternString(cx, name); if (!str) { return NULL; } js::SetFunctionNativeReserved(toStringObj, TOSTRING_NAME_RESERVED_SLOT, STRING_TO_JSVAL(str)); } if (constants && !DefinePrefable(cx, constructor, constants)) { return NULL; } if (proto && !JS_LinkConstructorAndPrototype(cx, constructor, proto)) { return NULL; } JSBool alreadyDefined; if (!JS_AlreadyHasOwnProperty(cx, receiver, name, &alreadyDefined)) { return NULL; } // This is Enumerable: False per spec. if (!alreadyDefined && !JS_DefineProperty(cx, receiver, name, OBJECT_TO_JSVAL(constructor), NULL, NULL, 0)) { return NULL; } return constructor; }
static JSObject * load_module_init(JSContext *context, JSObject *in_object, const char *full_path) { char *script; gsize script_len; jsval script_retval; JSObject *module_obj; GError *error; /* First we check if js module has already been loaded */ if (gjs_object_has_property(context, in_object, MODULE_INIT_PROPERTY)) { jsval module_obj_val; if (gjs_object_get_property(context, in_object, MODULE_INIT_PROPERTY, &module_obj_val)) { return JSVAL_TO_OBJECT(module_obj_val); } } module_obj = JS_NewObject(context, NULL, NULL, NULL); if (module_obj == NULL) { return JS_FALSE; } /* https://bugzilla.mozilla.org/show_bug.cgi?id=599651 means we * can't just pass in the global as the parent */ JS_SetParent(context, module_obj, gjs_get_import_global (context)); /* Define module in importer for future use and to avoid module_obj * object to be garbage collected during the evaluation of the script */ JS_DefineProperty(context, in_object, MODULE_INIT_PROPERTY, OBJECT_TO_JSVAL(module_obj), NULL, NULL, GJS_MODULE_PROP_FLAGS & ~JSPROP_PERMANENT); script_len = 0; error = NULL; if (!g_file_get_contents(full_path, &script, &script_len, &error)) { if (!g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_ISDIR) && !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR) && !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) gjs_throw_g_error(context, error); else g_error_free(error); return NULL; } g_assert(script != NULL); gjs_debug(GJS_DEBUG_IMPORTER, "Importing %s", full_path); if (!JS_EvaluateScript(context, module_obj, script, script_len, full_path, 1, /* line number */ &script_retval)) { g_free(script); /* If JSOPTION_DONT_REPORT_UNCAUGHT is set then the exception * would be left set after the evaluate and not go to the error * reporter function. */ if (JS_IsExceptionPending(context)) { gjs_debug(GJS_DEBUG_IMPORTER, "Module " MODULE_INIT_FILENAME " left an exception set"); gjs_log_and_keep_exception(context, NULL); } else { gjs_throw(context, "JS_EvaluateScript() returned FALSE but did not set exception"); } return NULL; } g_free(script); return module_obj; }
static void js_sub_query(subtitle_provider_t *SP, sub_scanner_t *ss, int score, int autosel) { js_subprovider_t *sp = (js_subprovider_t *)SP; JSContext *cx = js_newctx(NULL); JS_BeginRequest(cx); if(ss != NULL) { JSObject *obj = JS_NewObject(cx, &subreq_class, NULL, NULL); JS_AddNamedRoot(cx, &obj, "subscanner"); if(sp->sp_jsp != NULL) usage_inc_plugin_counter(sp->sp_jsp->jsp_id, "subsearch", 1); js_sub_job_t *jsj = malloc(sizeof(js_sub_job_t)); jsj->jsj_ss = ss; jsj->jsj_score = score; jsj->jsj_autosel = autosel; sub_scanner_retain(ss); JS_SetPrivate(cx, obj, jsj); JS_DefineFunctions(cx, obj, sub_functions); js_set_prop_rstr(cx, obj, "title", ss->ss_title); js_set_prop_rstr(cx, obj, "imdb", ss->ss_imdbid); if(ss->ss_season > 0) js_set_prop_int(cx, obj, "season", ss->ss_season); if(ss->ss_year > 0) js_set_prop_int(cx, obj, "year", ss->ss_year); if(ss->ss_episode > 0) js_set_prop_int(cx, obj, "episode", ss->ss_episode); if(ss->ss_fsize > 0) js_set_prop_dbl(cx, obj, "filesize", ss->ss_fsize); if(ss->ss_hash_valid) { char str[64]; snprintf(str, sizeof(str), "%016" PRIx64, ss->ss_opensub_hash); js_set_prop_str(cx, obj, "opensubhash", str); bin2hex(str, sizeof(str), ss->ss_subdbhash, 16); js_set_prop_str(cx, obj, "subdbhash", str); } if(ss->ss_duration > 0) js_set_prop_int(cx, obj, "duration", ss->ss_duration); jsval result; jsval arg = OBJECT_TO_JSVAL(obj); JS_CallFunctionValue(cx, NULL, sp->sp_func, 1, &arg, &result); JS_RemoveRoot(cx, &obj); } js_subprovider_release(cx, sp); JS_DestroyContext(cx); }
jsval CStdDeserializer::ReadScriptVal(JSObject* appendParent) { JSContext* cx = m_ScriptInterface.GetContext(); uint8_t type; NumberU8_Unbounded("type", type); switch (type) { case SCRIPT_TYPE_VOID: return JSVAL_VOID; case SCRIPT_TYPE_NULL: return JSVAL_NULL; case SCRIPT_TYPE_ARRAY: case SCRIPT_TYPE_OBJECT: { JSObject* obj; if (appendParent) obj = appendParent; else if (type == SCRIPT_TYPE_ARRAY) obj = JS_NewArrayObject(cx, 0, NULL); else obj = JS_NewObject(cx, NULL, NULL, NULL); if (!obj) throw PSERROR_Deserialize_ScriptError(); CScriptValRooted objRoot(cx, OBJECT_TO_JSVAL(obj)); AddScriptBackref(obj); uint32_t numProps; NumberU32_Unbounded("num props", numProps); for (uint32_t i = 0; i < numProps; ++i) { utf16string propname; ReadStringUTF16(propname); jsval propval = ReadScriptVal(NULL); CScriptValRooted propvalRoot(cx, propval); if (!JS_SetUCProperty(cx, obj, (const jschar*)propname.data(), propname.length(), &propval)) throw PSERROR_Deserialize_ScriptError(); } return OBJECT_TO_JSVAL(obj); } case SCRIPT_TYPE_STRING: { JSString* str; ScriptString("string", str); return STRING_TO_JSVAL(str); } case SCRIPT_TYPE_INT: { int32_t value; NumberI32("value", value, JSVAL_INT_MIN, JSVAL_INT_MAX); return INT_TO_JSVAL(value); } case SCRIPT_TYPE_DOUBLE: { double value; NumberDouble_Unbounded("value", value); jsval rval; if (!JS_NewNumberValue(cx, value, &rval)) throw PSERROR_Deserialize_ScriptError("JS_NewNumberValue failed"); return rval; } case SCRIPT_TYPE_BOOLEAN: { uint8_t value; NumberU8("value", value, 0, 1); return BOOLEAN_TO_JSVAL(value ? JS_TRUE : JS_FALSE); } case SCRIPT_TYPE_BACKREF: { u32 tag; NumberU32_Unbounded("tag", tag); JSObject* obj = GetScriptBackref(tag); if (!obj) throw PSERROR_Deserialize_ScriptError("Invalid backref tag"); return OBJECT_TO_JSVAL(obj); } default: throw PSERROR_Deserialize_OutOfBounds(); } }
static JSObject* ns_new(JSContext *context, const char *ns_name) { JSObject *ns; JSObject *global; Ns *priv; JSBool found; /* put constructor in the global namespace */ global = gjs_get_import_global(context); if (!JS_HasProperty(context, global, gjs_ns_class.name, &found)) return NULL; if (!found) { JSObject *prototype; prototype = JS_InitClass(context, global, /* parent prototype JSObject* for * prototype; NULL for * Object.prototype */ NULL, &gjs_ns_class, /* constructor for instances (NULL for * none - just name the prototype like * Math - rarely correct) */ gjs_ns_constructor, /* number of constructor args */ 0, /* props of prototype */ &gjs_ns_proto_props[0], /* funcs of prototype */ &gjs_ns_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ NULL); if (prototype == NULL) g_error("Can't init class %s", gjs_ns_class.name); gjs_debug(GJS_DEBUG_GNAMESPACE, "Initialized class %s prototype %p", gjs_ns_class.name, prototype); } ns = JS_NewObject(context, &gjs_ns_class, NULL, global); if (ns == NULL) g_error("No memory to create ns object"); priv = g_slice_new0(Ns); GJS_INC_COUNTER(ns); g_assert(priv_from_js(context, ns) == NULL); JS_SetPrivate(ns, priv); gjs_debug_lifecycle(GJS_DEBUG_GNAMESPACE, "ns constructor, obj %p priv %p", ns, priv); priv = priv_from_js(context, ns); priv->gi_namespace = g_strdup(ns_name); return ns; }
JSObject* JsIndexer::jsInstance(JSContext *cx,JSObject *obj) { return JS_NewObject(cx,JsIndexer::getJsClass(),NULL,obj); }
static JSBool rpmxar_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmxarClass, NULL); rpmxar xar = ptr; int ix = 0; _ENUMERATE_DEBUG_ENTRY(_debug < 0); switch (op) { case JSENUMERATE_INIT: case JSENUMERATE_INIT_ALL: if (idp) *idp = JSVAL_ZERO; *statep = INT_TO_JSVAL(ix); if (_debug) fprintf(stderr, "\tINIT xar %p\n", xar); break; case JSENUMERATE_NEXT: ix = JSVAL_TO_INT(*statep); if (!rpmxarNext(xar)) { const char * path = rpmxarPath(xar); struct stat * st = xmalloc(sizeof(*st)); JSObject * arr = JS_NewArrayObject(cx, 0, NULL); JSBool ok = JS_AddRoot(cx, &arr); JSObject * o; jsval v; v = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, path)); ok = JS_SetElement(cx, arr, 0, &v); if (!rpmxarStat(xar, st) && (o = JS_NewObject(cx, &rpmstClass, NULL, NULL)) != NULL && JS_SetPrivate(cx, o, (void *)st)) v = OBJECT_TO_JSVAL(o); else { st = _free(st); v = JSVAL_NULL; } ok = JS_SetElement(cx, arr, 1, &v); v = OBJECT_TO_JSVAL(arr); ok = JS_DefineElement(cx, obj, ix, v, NULL, NULL, JSPROP_ENUMERATE); (void) JS_RemoveRoot(cx, &arr); if (_debug) fprintf(stderr, "\tNEXT xar %p[%u] \"%s\"\n", xar, ix, path); path = _free(path); JS_ValueToId(cx, *statep, idp); *statep = INT_TO_JSVAL(ix+1); } else *idp = JSVAL_VOID; if (!JSID_IS_VOID(*idp)) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: ix = JSVAL_TO_INT(*statep); (void) JS_DefineProperty(cx, obj, "length", INT_TO_JSVAL(ix), NULL, NULL, JSPROP_ENUMERATE); if (_debug) fprintf(stderr, "\tFINI xar %p[%u]\n", xar, ix); *statep = JSVAL_NULL; break; } return JS_TRUE; }