Subj : Re: finilize & construct: call disbalance To : netscape.public.mozilla.jseng From : anton muhin Date : Tue Jul 13 2004 08:58 pm Dear Brendan, I'm joining your answers: Brendan Eich wrote: >>> When you call JS_InitClass, it creates a prototype object of your class, so that object will be finalized too. It won't be constructed, though -- you have to call the constructor yourself, if you need to. >> >> >> > Most class prototypes don't need to be constructed, but that means if >> > JSCLASS_HAS_PRIVATE, JS_GetPrivate will return null for such objects, >> > so your finalize implementation has to null-check. >> >> Does this follow the standard? > > > > The ECMA-262 standard doesn't govern the JS API. Sure, my bad wording. I just supposed that default behavior (when NULLs are passed) should mimic standard as much as possible. Maybe your note below answers this question. > Now, you might want to be able, *in JS*, to write a constructor function > whose prototype is an instance of the "class" you're trying to define in > JS. But you can't. JS 1.x is not class-ical, and it's not strong and > symmetric enough to support such a "user-level" class definition. I don't understand you. Does it mean that I cannot define a class in C/C++ whose prototype will differ from the class itself? (See a question below too) > Ok, having written all this, I've reviewed ECMA-262 again, and alas, it > does specify that even native (its sense of that word) constructors such > as RegExp have a prototype property whose value is an object whose > [[Class]] is "Object". Dammit, I missed that years ago during > standardization. > > Someone please file a bug. And again, it's my poor English showing teeth, I don't understand you: where is the bug, in standard (I don't think so) or in SpiderMonkey? Now back to class prototypes. After googling and reading sources, I ended with the following solution that is *really nasty* hack: JSObject * const proto = JS_InitClass( cx, glob, NULL, // parent_proto &kls, ctor, // constructor 3, // constructor nargs props, // proto props methods, // proto methods NULL, // cons props NULL // cons methods ); JS_VERIFY(proto); JSObject * const ctr = JS_GetConstructor(cx, proto); JSObject * const object = JS_NewObject(cx, NULL, NULL, glob); js_SetClassPrototype(cx, ctr, object, JSPROP_READONLY | JSPROP_PERMANENT); return JS_TRUE; It seems to work. Of course, I have to patch sources to export js_SetClassPrototype. Is there better way? Passing something as parent_proto seems to have no effect. Actually, only perlconnect supplies something different from NULL for parent_proto. Better solution (but maybe I just ruining some SpiderMonkey's internals) would be to extend class init prototcol to pass prototypes class. What do you think, should I start working on this patch? And the last question: I'm living under vc6.0. This compilier issues one warning about size-mismatch. I fixed it in my local copy. Should I try to check it into main SpiderMonkey's trunk? Just again, thank you for your answers, with the best regards anton. .