int to_erl_object(ErlNifEnv* env, JSContext* cx, JSObject* obj, ERL_NIF_TERM* term) { ERL_NIF_TERM* array = NULL; ERL_NIF_TERM list; ERL_NIF_TERM keyterm; ERL_NIF_TERM valterm; JSObject* iter; jsid idp; jsval val; int length; int index; int ret = ERROR; iter = JS_NewPropertyIterator(cx, obj); if(iter == NULL) goto done; length = 0; while(JS_NextProperty(cx, iter, &idp)) { if(idp == JSID_VOID) break; length += 1; } array = enif_alloc(length * sizeof(ERL_NIF_TERM)); if(array == NULL) goto done; iter = JS_NewPropertyIterator(cx, obj); if(iter == NULL) goto done; index = 0; while(JS_NextProperty(cx, iter, &idp)) { if(idp == JSID_VOID) { list = enif_make_list_from_array(env, array, length); *term = enif_make_tuple1(env, list); ret = OK; goto done; } if(!JS_IdToValue(cx, idp, &val)) goto done; if(!to_erl_string(env, cx, val, &keyterm)) goto done; if(!JS_GetPropertyById(cx, obj, idp, &val)) goto done; if(!to_erl_intern(env, cx, val, &valterm)) goto done; array[index] = enif_make_tuple2(env, keyterm, valterm); index += 1; } done: if(array != NULL) enif_free(array); return ret; }
static JSBool syck_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { JSObject *iterator; JSBool ok = JS_FALSE; if (_debug) fprintf(stderr, "==> %s(%p,%p,%d,%p,%p)\n", __FUNCTION__, cx, obj, op, statep, idp); switch (op) { case JSENUMERATE_INIT: if ((iterator = JS_NewPropertyIterator(cx, obj)) == NULL) goto exit; *statep = OBJECT_TO_JSVAL(iterator); if (idp) *idp = JSVAL_ZERO; break; case JSENUMERATE_NEXT: iterator = (JSObject *) JSVAL_TO_OBJECT(*statep); if (!JS_NextProperty(cx, iterator, idp)) goto exit; if (*idp != JSVAL_VOID) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: /* Allow our iterator object to be GC'd. */ *statep = JSVAL_NULL; break; } ok = JS_TRUE; exit: return ok; }
static PyObject *to_python_dict(JSContext *context, JSObject *obj) { JSObject *iter = JS_NewPropertyIterator(context, obj); if (iter) { PyObject *dict = PyDict_New(); jsid propid; while (JS_NextProperty(context, iter, &propid) == JS_TRUE) { if (propid == JSID_VOID) { break; } jsval key, value; if (JS_IdToValue(context, propid, &key)) { PyObject *pykey = to_python_object(context, key); if (pykey != Py_None) { if (JS_GetPropertyById(context, obj, propid, &value)) { PyObject *pyvalue = to_python_object(context, value); PyDict_SetItem(dict, pykey, pyvalue); Py_DECREF(pykey); Py_DECREF(pyvalue); } } } } return dict; } else { Py_INCREF(Py_None); return Py_None; } }
JSBool jsval_to_TProductInfo(JSContext *cx, jsval v, TProductInfo* ret) { JSObject* tmp = JSVAL_TO_OBJECT(v); if (!tmp) { LOGD("jsval_to_TProductInfo: the jsval is not an object."); return JS_FALSE; } JSObject* it = JS_NewPropertyIterator(cx, tmp); while (true) { jsid idp; jsval key; if (! JS_NextProperty(cx, it, &idp) || ! JS_IdToValue(cx, idp, &key)) return JS_FALSE; // error if (key == JSVAL_VOID) break; // end of iteration if (! JSVAL_IS_STRING(key)) continue; // ignore integer properties jsval value; JS_GetPropertyById(cx, tmp, idp, &value); if (! JSVAL_IS_STRING(value)) continue; // ignore integer properties JSStringWrapper strWrapper(JSVAL_TO_STRING(key), cx); JSStringWrapper strWrapper2(JSVAL_TO_STRING(value), cx); (*ret)[strWrapper.get()] = strWrapper2.get(); LOGD("iterate object: key = %s, value = %s", strWrapper.get().c_str(), strWrapper2.get().c_str()); } return JS_TRUE; }
int to_erl_object(emonk_buf_t* buf, JSContext* cx, JSObject* obj) { JSObject* iter; JSString* key; jsid idp; jsval val; jschar* keyname; size_t keylen; int count = 0; int lengthpos; REQUEST(7); BUFPTR[0] = SMALL_TUPLE; BUFPTR[1] = (char) 1; BUFPTR[2] = LIST; // Remember the byte offset where length goes so we can write it // after enumerating the properties. lengthpos = buf->used + 3; buf->used += 7; iter = JS_NewPropertyIterator(cx, obj); if(iter == NULL) return ERROR; while(JS_NextProperty(cx, iter, &idp)) { // Done iterating, write length and bail. if(idp == JSVAL_VOID) { count = htonl(count); memcpy(buf->buf+lengthpos, &count, 4); REQUEST(1); BUFPTR[0] = NIL; buf->used += 1; return OK; } REQUEST(2); BUFPTR[0] = SMALL_TUPLE; BUFPTR[1] = 2; buf->used += 2; if(!JS_IdToValue(cx, idp, &val)) return ERROR; if(!to_erl_string(buf, cx, val)) return ERROR; key = JS_ValueToString(cx, val); keyname = JS_GetStringChars(key); keylen = JS_GetStringLength(key); if(!JS_GetUCProperty(cx, obj, keyname, keylen, &val)) return ERROR; if(!to_erl_intern(buf, cx, val)) return ERROR; count += 1; } return ERROR; }
bool jsval_to_FBInfo(JSContext *cx, jsval v, StringMap* ret) { JSObject* tmp = JSVAL_TO_OBJECT(v); if (!tmp) { LOGD("jsval_to_TProductInfo: the jsval is not an object."); return false; } JSObject* it = JS_NewPropertyIterator(cx, tmp); while (true) { jsid idp; jsval key; if (! JS_NextProperty(cx, it, &idp) || ! JS_IdToValue(cx, idp, &key)) return false; // error if (key == JSVAL_VOID) break; // end of iteration if (! JSVAL_IS_STRING(key)) continue; // ignore integer properties JS::RootedValue value(cx); JS_GetPropertyById(cx, tmp, idp, &value); // if (! JSVAL_IS_STRING(value)) // continue; // ignore integer properties if(JSVAL_IS_STRING(value)) { JSStringWrapper strWrapper(JSVAL_TO_STRING(key), cx); JSStringWrapper strWrapper2(JSVAL_TO_STRING(value), cx); ret->insert(std::map<std::string, std::string>::value_type(strWrapper.get(), strWrapper2.get())); } else if(JSVAL_IS_NUMBER(value)) { double number = 0.0; JS::ToNumber(cx, value, &number); std::stringstream ss; ss << number; JSStringWrapper strWrapper(JSVAL_TO_STRING(key), cx); //JSStringWrapper strWrapper2(JSVAL_TO_STRING(value), cx); ret->insert(std::map<std::string, std::string>::value_type(strWrapper.get(), ss.str())); } else if(JSVAL_IS_BOOLEAN(value)) { bool boolVal = JS::ToBoolean(value); JSStringWrapper strWrapper(JSVAL_TO_STRING(key), cx); //JSStringWrapper strWrapper2(JSVAL_TO_STRING(value), cx); std::string boolstring = boolVal ? "true" : "false"; ret->insert(std::map<std::string, std::string>::value_type(strWrapper.get(), boolstring)); } } return true; }
void gjs_log_object_props(JSContext *context, JSObject *obj, GjsDebugTopic topic, const char *prefix) { JSObject *props_iter; jsid prop_id; JS_BeginRequest(context); /* We potentially create new strings, plus the property iterator, * that could get collected as we go through this process. So * create a local root scope. */ JS_EnterLocalRootScope(context); props_iter = JS_NewPropertyIterator(context, obj); if (props_iter == NULL) { gjs_debug(GJS_DEBUG_ERROR, "Failed to create property iterator for object props"); goto done; } prop_id = JSVAL_VOID; if (!JS_NextProperty(context, props_iter, &prop_id)) goto done; while (prop_id != JSVAL_VOID) { jsval nameval; const char *name; jsval propval; if (!JS_IdToValue(context, prop_id, &nameval)) goto next; if (!gjs_get_string_id(nameval, &name)) goto next; if (!gjs_object_get_property(context, obj, name, &propval)) goto next; gjs_debug(topic, "%s%s = '%s'", prefix, name, gjs_value_debug_string(context, propval)); next: prop_id = JSVAL_VOID; if (!JS_NextProperty(context, props_iter, &prop_id)) break; } done: JS_LeaveLocalRootScope(context); JS_EndRequest(context); }
bool ScriptInterface::EnumeratePropertyNamesWithPrefix(JS::HandleValue objVal, const char* prefix, std::vector<std::string>& out) { JSAutoRequest rq(m->m_cx); if (!objVal.isObjectOrNull()) { LOGERROR("EnumeratePropertyNamesWithPrefix expected object type!"); return false; } if(objVal.isNull()) return true; // reached the end of the prototype chain JS::RootedObject obj(m->m_cx, &objVal.toObject()); JS::RootedObject it(m->m_cx, JS_NewPropertyIterator(m->m_cx, obj)); if (!it) return false; while (true) { JS::RootedId idp(m->m_cx); JS::RootedValue val(m->m_cx); if (! JS_NextProperty(m->m_cx, it, idp.address()) || ! JS_IdToValue(m->m_cx, idp, &val)) return false; if (val.isUndefined()) break; // end of iteration if (!val.isString()) continue; // ignore integer properties JS::RootedString name(m->m_cx, val.toString()); size_t len = strlen(prefix)+1; std::vector<char> buf(len); size_t prefixLen = strlen(prefix) * sizeof(char); JS_EncodeStringToBuffer(m->m_cx, name, &buf[0], prefixLen); buf[len-1]= '\0'; if(0 == strcmp(&buf[0], prefix)) { size_t len; const jschar* chars = JS_GetStringCharsAndLength(m->m_cx, name, &len); out.push_back(std::string(chars, chars+len)); } } // Recurse up the prototype chain JS::RootedObject prototype(m->m_cx); if (JS_GetPrototype(m->m_cx, obj, &prototype)) { JS::RootedValue prototypeVal(m->m_cx, JS::ObjectOrNullValue(prototype)); if (! EnumeratePropertyNamesWithPrefix(prototypeVal, prefix, out)) return false; } return true; }
static JSBool rpmps_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { _ENUMERATE_DEBUG_ENTRY(_debug); #ifdef DYING switch (op) { case JSENUMERATE_INIT: case JSENUMERATE_INIT_ALL: if ((iterator = JS_NewPropertyIterator(cx, obj)) == NULL) goto exit; *statep = OBJECT_TO_JSVAL(iterator); if (idp) *idp = JSVAL_ZERO; break; case JSENUMERATE_NEXT: iterator = (JSObject *) JSVAL_TO_OBJECT(*statep); if (!JS_NextProperty(cx, iterator, idp)) goto exit; if (!JSID_IS_VOID(*idp)) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: /* Allow our iterator object to be GC'd. */ *statep = JSVAL_NULL; break; } #else { static const char hex[] = "0123456789abcdef"; const char * s; char name[2]; JSString * valstr; char value[5]; for (s = "AaBbCc"; *s != '\0'; s++) { name[0] = s[0]; name[1] = '\0'; value[0] = '0'; value[1] = 'x'; value[2] = hex[(name[0] >> 4) & 0xf]; value[3] = hex[(name[0] ) & 0xf]; value[4] = '\0'; if ((valstr = JS_NewStringCopyZ(cx, value)) == NULL || !JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr), NULL, NULL, JSPROP_ENUMERATE)) goto exit; } } #endif exit: return JS_TRUE; }
bool jsval_to_std_map_string_string(JSContext *cx, jsval v, std::map<std::string, std::string>* ret) { if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) { return true; } JSObject* tmp = JSVAL_TO_OBJECT(v); if (!tmp) { CCLOG("%s", "jsval_to_ccvaluemap: the jsval is not an object."); return false; } JSObject* it = JS_NewPropertyIterator(cx, tmp); while (true) { jsid idp; jsval key; if (! JS_NextProperty(cx, it, &idp) || ! JS_IdToValue(cx, idp, &key)) { return false; // error } if (key == JSVAL_VOID) { break; // end of iteration } if (!JSVAL_IS_STRING(key)) { continue; // ignore integer properties } JSStringWrapper keyWrapper(JSVAL_TO_STRING(key), cx); JS::RootedValue value(cx); JS_GetPropertyById(cx, tmp, idp, &value); if (value.isString()) { JSStringWrapper valueWapper(JSVAL_TO_STRING(value), cx); ret->insert(std::make_pair(keyWrapper.get(), valueWapper.get())); } else { CCASSERT(false, "not a string"); } } return true; }
JSBool JsGlobal::event_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp) { static log4cplus::Logger log = log4cplus::Logger::getInstance("fsm.JsContext.enumerate"); JSObject *iterator; //fsm::env::Js::ToString objString(cx,OBJECT_TO_JSVAL(obj)); LOG4CPLUS_ERROR(log,"[_event] enumerate."); switch (enum_op) { case JSENUMERATE_INIT: case JSENUMERATE_INIT_ALL: LOG4CPLUS_TRACE(log, "enumerate [_event] Init properties."); iterator = JS_NewPropertyIterator(cx, obj); if (!iterator) return JS_FALSE; *statep = OBJECT_TO_JSVAL(iterator); if (idp) *idp = INT_TO_JSID(0); break; case JSENUMERATE_NEXT: /*if (its_enum_fail) { JS_ReportError(cx, "its enumeration failed"); return JS_FALSE; }*/ LOG4CPLUS_TRACE(log, "enumerate [_event] next properties."); iterator = (JSObject *) JSVAL_TO_OBJECT(*statep); if (!JS_NextProperty(cx, iterator, idp)) return JS_FALSE; if (!JSID_IS_VOID(*idp)) break; /* Fall through. */ case JSENUMERATE_DESTROY: /* Allow our iterator object to be GC'd. */ LOG4CPLUS_TRACE(log, "enumerate [_event] destroy properties."); *statep = JSVAL_NULL; break; } return JS_TRUE; }
bool ScriptInterface::EnumeratePropertyNamesWithPrefix(jsval obj, const char* prefix, std::vector<std::string>& out) { utf16string prefix16 (prefix, prefix+strlen(prefix)); if (! JSVAL_IS_OBJECT(obj)) return false; // TODO: log error messages JSObject* it = JS_NewPropertyIterator(m->m_cx, JSVAL_TO_OBJECT(obj)); if (!it) return false; while (true) { jsid idp; jsval val; if (! JS_NextProperty(m->m_cx, it, &idp) || ! JS_IdToValue(m->m_cx, idp, &val)) return false; if (val == JSVAL_VOID) break; // end of iteration if (! JSVAL_IS_STRING(val)) continue; // ignore integer properties JSString* name = JSVAL_TO_STRING(val); size_t len; const jschar* chars = JS_GetStringCharsAndLength(m->m_cx, name, &len); if (chars && len >= prefix16.size() && memcmp(chars, prefix16.c_str(), prefix16.size()*2) == 0) out.push_back(std::string(chars, chars+len)); // handles Unicode poorly } // Recurse up the prototype chain JSObject* prototype = JS_GetPrototype(m->m_cx, JSVAL_TO_OBJECT(obj)); if (prototype) { if (! EnumeratePropertyNamesWithPrefix(OBJECT_TO_JSVAL(prototype), prefix, out)) return false; } return true; }
static void load_module_elements(JSContext *context, JSObject *in_object, ImporterIterator *iter, const char *init_path) { JSObject *module_obj; JSObject *jsiter; module_obj = load_module_init(context, in_object, init_path); if (module_obj != NULL) { jsid idp; jsiter = JS_NewPropertyIterator(context, module_obj); if (jsiter == NULL) { return; } if (!JS_NextProperty(context, jsiter, &idp)) { return; } while (!JSID_IS_VOID(idp)) { char *name; if (!gjs_get_string_id(context, idp, &name)) { continue; } /* Pass ownership of name */ g_ptr_array_add(iter->elements, name); if (!JS_NextProperty(context, jsiter, &idp)) { break; } } } }
// Convert from a jsval to an AtNode static AtSmartPtr<AtNode> ConvertNode(JSContext* cx, jsval node) { AtSmartPtr<AtNode> obj (new AtNode()); // Non-objects get converted into strings if (!JSVAL_IS_OBJECT(node)) { JSString* str = JS_ValueToString(cx, node); if (!str) return obj; // error size_t valueLen; const jschar* valueChars = JS_GetStringCharsAndLength(cx, str, &valueLen); if (!valueChars) return obj; // error wxString valueWx(reinterpret_cast<const char*>(valueChars), wxMBConvUTF16(), valueLen*2); obj->value = valueWx.c_str(); // Annotate numbers/booleans specially, to allow round-tripping if (JSVAL_IS_NUMBER(node)) { obj->children.insert(AtNode::child_pairtype( "@number", AtSmartPtr<AtNode>(new AtNode()) )); } else if (JSVAL_IS_BOOLEAN(node)) { obj->children.insert(AtNode::child_pairtype( "@boolean", AtSmartPtr<AtNode>(new AtNode()) )); } return obj; } JSObject* it = JS_NewPropertyIterator(cx, JSVAL_TO_OBJECT(node)); if (!it) return obj; // error while (true) { jsid idp; jsval val; if (! JS_NextProperty(cx, it, &idp) || ! JS_IdToValue(cx, idp, &val)) return obj; // error if (val == JSVAL_VOID) break; // end of iteration if (! JSVAL_IS_STRING(val)) continue; // ignore integer properties JSString* name = JSVAL_TO_STRING(val); size_t len; const jschar* chars = JS_GetStringCharsAndLength(cx, name, &len); wxString nameWx(reinterpret_cast<const char*>(chars), wxMBConvUTF16(), len*2); std::string nameStr(nameWx.ToUTF8().data()); jsval vp; if (!JS_GetPropertyById(cx, JSVAL_TO_OBJECT(node), idp, &vp)) return obj; // error // Unwrap arrays into a special format like <$name><item>$i0</item><item>... // (This assumes arrays aren't nested) if (JSVAL_IS_OBJECT(vp) && JS_IsArrayObject(cx, JSVAL_TO_OBJECT(vp))) { AtSmartPtr<AtNode> child(new AtNode()); child->children.insert(AtNode::child_pairtype( "@array", AtSmartPtr<AtNode>(new AtNode()) )); jsuint arrayLength; if (!JS_GetArrayLength(cx, JSVAL_TO_OBJECT(vp), &arrayLength)) return obj; // error for (jsuint i = 0; i < arrayLength; ++i) { jsval val; if (!JS_GetElement(cx, JSVAL_TO_OBJECT(vp), i, &val)) return obj; // error child->children.insert(AtNode::child_pairtype( "item", ConvertNode(cx, val) )); } obj->children.insert(AtNode::child_pairtype( nameStr, child )); } else { obj->children.insert(AtNode::child_pairtype( nameStr, ConvertNode(cx, vp) )); } } return obj; }
/* Initialize a newly created Boxed from an object that is a "hash" of * properties to set as fieds of the object. We don't require that every field * of the object be set. */ static JSBool boxed_init_from_props(JSContext *context, JSObject *obj, Boxed *priv, jsval props_value) { JSObject *props; JSObject *iter; jsid prop_id; GHashTable *field_map; gboolean success; success = FALSE; if (!JSVAL_IS_OBJECT(props_value)) { gjs_throw(context, "argument should be a hash with fields to set"); return JS_FALSE; } props = JSVAL_TO_OBJECT(props_value); iter = JS_NewPropertyIterator(context, props); if (iter == NULL) { gjs_throw(context, "Failed to create property iterator for fields hash"); return JS_FALSE; } field_map = get_field_map(priv->info); prop_id = JSID_VOID; if (!JS_NextProperty(context, iter, &prop_id)) goto out; while (!JSID_IS_VOID(prop_id)) { GIFieldInfo *field_info; char *name; jsval value; if (!gjs_get_string_id(context, prop_id, &name)) goto out; field_info = g_hash_table_lookup(field_map, name); if (field_info == NULL) { gjs_throw(context, "No field %s on boxed type %s", name, g_base_info_get_name((GIBaseInfo *)priv->info)); g_free(name); goto out; } if (!gjs_object_require_property(context, props, "property list", name, &value)) { g_free(name); goto out; } g_free(name); if (!boxed_set_field_from_value(context, priv, field_info, value)) goto out; prop_id = JSID_VOID; if (!JS_NextProperty(context, iter, &prop_id)) goto out; } success = TRUE; out: g_hash_table_destroy(field_map); return success; }
nsresult leakmonJSObjectInfo::Init(leakmonObjectsInReportTable &aObjectsInReport) { mIsInitialized = PR_TRUE; JSContext *cx = leakmonService::GetJSContext(); NS_ENSURE_TRUE(cx, NS_ERROR_UNEXPECTED); JSAutoRequest ar(cx); if (!JSVAL_IS_PRIMITIVE(mJSValue)) { JSObject *obj = JSVAL_TO_OBJECT(mJSValue); // All of the objects in obj's prototype chain, and all // objects reachable from JS_NewPropertyIterator should // (I think?) be in the same compartment. JSAutoEnterCompartment ac; if (!ac.enter(cx, obj)) { return NS_ERROR_FAILURE; } JSObject *p; for (p = obj; p; p = JS_GetPrototype(cx, p)) { // Stack-scanning protects newly-created objects // (etor) from GC. (And protecting |etor| // should in turn protect |id|.) // JS_NewPropertyIterator has the nice property that it // avoids JS_Enumerate on native objects (where it can // execute code) and uses the scope properties, but doesn't // require this code to use the unstable OBJ_IS_NATIVE API. JSObject *etor = JS_NewPropertyIterator(cx, p); if (!etor) return NS_ERROR_OUT_OF_MEMORY; jsid id; while (JS_NextProperty(cx, etor, &id) && !JSID_IS_VOID(id)) { nsresult rv = AppendProperty(id, cx, aObjectsInReport); NS_ENSURE_SUCCESS(rv, rv); } } if (JS_ObjectIsFunction(cx, obj)) { JSFunction *fun = JS_ValueToFunction(cx, mJSValue); NS_ENSURE_TRUE(fun, NS_ERROR_UNEXPECTED); JSScript *script = JS_GetFunctionScript(cx, fun); if (script) { // null for native code const char *fname = JS_GetScriptFilename(cx, script); // XXX Do we know the encoding of this file name? mFileName = NS_ConvertUTF8toUTF16(fname); mLineStart = JS_GetScriptBaseLineNumber(cx, script); mLineEnd = mLineStart + JS_GetScriptLineExtent(cx, script) - 1; } } } ValueToString(cx, mJSValue, mString); return NS_OK; }