static JSBool PushObject(JSContext *cx, JSONParser *jp, JSObject *obj) { jsuint len; if (!js_GetLengthProperty(cx, jp->objectStack, &len)) return JS_FALSE; if (len >= JSON_MAX_DEPTH) return JS_FALSE; // decoding error jsval v = OBJECT_TO_JSVAL(obj); JSAutoTempValueRooter tvr(cx, v); // Check if this is the root object if (len == 0) { *jp->rootVal = v; // This property must be enumerable to keep the array dense if (!OBJ_DEFINE_PROPERTY(cx, jp->objectStack, INT_TO_JSID(0), *jp->rootVal, NULL, NULL, JSPROP_ENUMERATE, NULL)) { return JS_FALSE; } return JS_TRUE; } jsval p; if (!OBJ_GET_PROPERTY(cx, jp->objectStack, INT_TO_JSID(len - 1), &p)) return JS_FALSE; JS_ASSERT(JSVAL_IS_OBJECT(p)); JSObject *parent = JSVAL_TO_OBJECT(p); if (!PushValue(cx, jp, parent, OBJECT_TO_JSVAL(obj))) return JS_FALSE; // This property must be enumerable to keep the array dense if (!OBJ_DEFINE_PROPERTY(cx, jp->objectStack, INT_TO_JSID(len), v, NULL, NULL, JSPROP_ENUMERATE, NULL)) { return JS_FALSE; } return JS_TRUE; }
static JSBool InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector) { jsval v; jsid id; if (!IndexToValue(cx, length, &v)) return JS_FALSE; id = (jsid) cx->runtime->atomState.lengthAtom; if (!OBJ_DEFINE_PROPERTY(cx, obj, id, v, array_length_getter, array_length_setter, JSPROP_PERMANENT, NULL)) { return JS_FALSE; } if (!vector) return JS_TRUE; return InitArrayElements(cx, obj, length, vector); }
static JSBool PushValue(JSContext *cx, JSONParser *jp, JSObject *parent, jsval value) { JSAutoTempValueRooter tvr(cx, 1, &value); JSBool ok; if (OBJ_IS_ARRAY(cx, parent)) { jsuint len; ok = js_GetLengthProperty(cx, parent, &len); if (ok) { ok = OBJ_DEFINE_PROPERTY(cx, parent, INT_TO_JSID(len), value, NULL, NULL, JSPROP_ENUMERATE, NULL); } } else { ok = JS_DefineUCProperty(cx, parent, jp->objectKey->base, STRING_BUFFER_OFFSET(jp->objectKey), value, NULL, NULL, JSPROP_ENUMERATE); js_FinishStringBuffer(jp->objectKey); js_InitStringBuffer(jp->objectKey); } return ok; }
JSBool XPCIDispatchExtension::DefineProperty(XPCCallContext & ccx, JSObject *obj, jsval idval, XPCWrappedNative* wrapperToReflectInterfaceNames, uintN propFlags, JSBool* resolved) { if(!JSVAL_IS_STRING(idval)) return JS_FALSE; // Look up the native interface for IDispatch and then find a tearoff XPCNativeInterface* iface = XPCNativeInterface::GetNewOrUsed(ccx, "IDispatch"); // The native interface isn't defined so just exit with an error if(iface == nsnull) return JS_FALSE; XPCWrappedNativeTearOff* to = wrapperToReflectInterfaceNames->LocateTearOff(ccx, iface); // This object has no IDispatch interface so bail. if(to == nsnull) return JS_FALSE; // Look up the member in the interface const XPCDispInterface::Member * member = to->GetIDispatchInfo()->FindMember(idval); if(!member) { // IDispatch is case insensitive, so if we don't find a case sensitive // match, we'll try a more expensive case-insensisitive search // TODO: We need to create cleaner solution that doesn't create // multiple properties of different case on the JS Object member = to->GetIDispatchInfo()->FindMemberCI(ccx, idval); if(!member) return JS_FALSE; } // Get the function object jsval funval; if(!member->GetValue(ccx, iface, &funval)) return JS_FALSE; // Protect the jsval AUTO_MARK_JSVAL(ccx, funval); // clone a function we can use for this object JSObject* funobj = xpc_CloneJSFunction(ccx, JSVAL_TO_OBJECT(funval), obj); if(!funobj) return JS_FALSE; jsid id; // If this is a function or a parameterized property if(member->IsFunction() || member->IsParameterizedProperty()) { // define the function on the object AutoResolveName arn(ccx, idval); if(resolved) *resolved = JS_TRUE; return JS_ValueToId(ccx, idval, &id) && OBJ_DEFINE_PROPERTY(ccx, obj, id, OBJECT_TO_JSVAL(funobj), nsnull, nsnull, propFlags, nsnull); } // Define the property on the object NS_ASSERTION(member->IsProperty(), "way broken!"); propFlags |= JSPROP_GETTER | JSPROP_SHARED; if(member->IsSetter()) { propFlags |= JSPROP_SETTER; propFlags &= ~JSPROP_READONLY; } AutoResolveName arn(ccx, idval); if(resolved) *resolved = JS_TRUE; return JS_ValueToId(ccx, idval, &id) && OBJ_DEFINE_PROPERTY(ccx, obj, id, JSVAL_VOID, (JSPropertyOp) funobj, (JSPropertyOp) funobj, propFlags, nsnull); }