Subj : JS_InitClass segfaults in my JS/Python bridge To : netscape.public.mozilla.jseng From : jjl@pobox.com (John J. Lee) Date : Fri Aug 01 2003 04:07 pm I'm making a JavaScript / Python bridge, and I'm having trouble dynamically creating proxy JS classes for Python classes that get bound to JS. I'm embedding JS in Python rather than the other way round. I've looked at both perlconnect (both halves) and Claes Jacobssen's Javascript.xs, and stared at the docs, and I'm none the wiser. I think I must be doing something really stupid, but I can't see it. I'm a complete JS newbie. (I'm using spidermonkey 1.5-rc5, libjs.so, on linux.) JS and Python are pretty similar in many ways (JS property <--> Python attribute; also, methods are just properties/attributes in both languages), so the idea is not to define any methods or properties at JS_InitClass time, but instead use my own setProperty / getProperty functions to look up the corresponding Python attributes. Now, the JS_InitClass docs say: | If you provide a constructor for the class, then you should also pass | an object to parent_proto. but I've seen several people do (note third and fifth args): // set up my_class, then JSObject *obj = JS_InitClass( cx, global_obj, NULL, &my_class, my_constructor, 0, NULL, NULL, NULL, NULL); apparently without harm. That's what I'm trying to do (I don't see any need ATM for the proxies to have a special prototype), but I get a segfault or illegal instruction inside JS_InitClass. In fact, I get that no matter what I do -- I've tried using a prototype object of my own created with JS_NewObject, using the global object, and using NULL. They all segfault or cause illegal instructions. Any clues? I've reduced the problem to the boilerplate setting up of runtime and context, then setting up a JSClass and calling JS_InitClass, so I'm fairly confident the problem is in the function below. [In case anybody feels like looking at it, the complete code ( stripped down to minimal 120 lines + extern type declarations that causes the segfault) is here: http://wwwsearch.sourceforge.net/spidermonkey.tar.gz Unfortunately, the test.py in there doesn't happen to trigger the segfault... In the unlikely event that anyone who wants to try building it and getting the segfault, let me know and I'll put up the code that triggers it.] This is Pyrex code -- essentially Python with C types, compiles to C. But don't panic! The cdef class is really just a C struct (as far as C is concerned), '->' operators are written as '.', casts (type)object are written as object, there are no semicolons and comments start with a '#'. Pyrex does treat python objects specially, but there's nothing too tricky there: it compiles len(name), klass.__name__, the use of name in strcpy etc. into appropriate Python C API calls (including refcounting, but there's no refcounting worthy of note in the function below). cdef class Class: # struct members cdef Context context # another struct, containing the JSContext * etc. cdef JSClass *jsc cdef JSObject *base_obj cdef object klass # Python class (PyObject *) -- not relevant here # Define a special Python method (don't worry your pretty head about it ;). # It's just a C function that gets called from Python. def __new__(self, Context context, flags, klass): self.jsc = xmalloc(sizeof(JSClass)) name = klass.__name__ self.jsc.name = xmalloc((len(name)+1)*sizeof(char)) strcpy(self.jsc.name, name) self.jsc.flags = flags self.jsc.addProperty = JS_PropertyStub self.jsc.delProperty = JS_PropertyStub self.jsc.getProperty = JS_PropertyStub # will implement later self.jsc.setProperty = JS_PropertyStub # ditto self.jsc.enumerate = JS_EnumerateStub self.jsc.resolve = JS_ResolveStub self.jsc.convert = JS_ConvertStub self.jsc.finalize = JS_FinalizeStub # context.cx is the JSContext *, context.globj is the global object self.base_obj = JS_InitClass( context.cx, context.globj, NULL, # !!! no matter what this is, JS_InitClass crashes self.jsc, constructor_stub, 0, NULL, NULL, NULL, NULL) Since Python constructors have variable numbers of arguments, I'm not sure what that 0 should be, but that can't be causing the problems I'm having ATM. Heeeelllp... John .