Re: Object creation in SpiderMonkey 45
Mihai Dobrescu <[email protected]>
| Newsgroups | gmane.comp.mozilla.devel.jseng |
|---|---|
| Message-ID | <[email protected]> |
On Thursday, May 5, 2016 at 6:19:24 PM UTC+3, Mihai Dobrescu wrote:
> On Thursday, May 5, 2016 at 6:06:29 PM UTC+3, Boris Zbarsky wrote:
> > On 5/5/16 8:56 AM, Mihai Dobrescu wrote:
> > > but for some reason it doesn't call the custom toString when it is
> > > created this way. Any hints?
> >
> > Where does the custom toString live? In your examples:
> >
> > var ap1 = new AIRealPoint(3, 3);
> > var r = new AIReal(3);
> >
> > is it the case that Object.getPrototypeOf(r) ==
> > Object.getPrototypeOf(ap1.h)?
> >
> > Or put another way, when you say "h and v properties are defined using a
> > templated function, basically creating a custom object of type AIReal
> > (in this case) to return, using JS_NewObject", how _exactly_ are you
> > doing this? What does the JS_NewObject callsite look like?
> >
> > -Boris
>
> I have a construction as follows:
>
> const JSFunctionSpec jsAIReal::fFunctions[] = {
> JS_FN("toString", jsAIReal::ToString, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),
> ...
>
> JS_FS_END
> }
>
> passed to JS_InitClass (in a template class...):
>
> static void DefineClass(JSContext *cx, JS::Handle<JSObject*> global)
> {
> try
> {
>
> jsType::fProtoObj = JS_InitClass(cx, global,
> nullptr, &fClass,
> Constructor, jsType::fConstructorNumberOfArguments,
> jsType::fProperties, jsType::fFunctions, jsType::fStaticProperties, jsType::fStaticFunctions);
>
> if (!jsType::fProtoObj)
> {
> throw new jsEngineException("jsEngine error at definiton of %s.", fClass.name);
> }
> }
> catch (...)
> {
> throw new jsEngineException("jsEngine error at definiton of %s.", fClass.name);
> }
> }
>
> A property getter looks like:
>
> template<typename jsType, typename jsPropertyType, typename jsPropertyType::PrivateType PrivateType::*Property>
> static bool GetProperty(JSContext *cx, unsigned argc, JS::Value *vp)
> {
> JS::CallArgs args = CallArgsFromVp(argc, vp);
>
> PrivateType* data = (PrivateType*)(JS_GetPrivate(&args.thisv().toObject()));
>
> if (!data)
> return false; // +throw error...
>
> JSObject *obj = JS_NewObject(cx, &jsDataClass<jsPropertyType>::fClass);
>
> JS_SetPrivate(obj, new jsPropertyType::PrivateType(data->*Property));
>
> args.rval().setObject(*obj);
>
> return true;
> }
>
> used as follows:
>
> const JSPropertySpec jsAIRealPoint::fProperties[] = {
> CLASS_JS_PSGS_PROPERTY(jsAIRealPoint, jsAIReal, h),
> CLASS_JS_PSGS_PROPERTY(jsAIRealPoint, jsAIReal, v),
>
> JS_PS_END
> };
>
> where I have:
>
> #define CLASS_JS_PSGS_PROPERTY(JS_TYPE, JS_PROPERTY_TYPE, PROPERTY) \
> JS_PSGS(#PROPERTY, (JS_TYPE::GetProperty<JS_TYPE, JS_PROPERTY_TYPE, &JS_TYPE::PrivateType::PROPERTY>), \
> (JS_TYPE::SetProperty<JS_TYPE, JS_PROPERTY_TYPE, &JS_TYPE::PrivateType::PROPERTY>), JSPROP_PERMANENT | JSPROP_ENUMERATE)
>
> A bit hard to read this...sorry.
>
> Note, it worked fine in 38.
Initially, I have set 0 for the functions flags (now, out of curiousity, I have JSPROP_PERMANENT | JSPROP_ENUMERATE, which is just for testing).