Some JS_FooBarBaz() functions in -lmozjs185 are presented/used directly,
others are wrapped by GPSEE (like gpsee_getStringBytes).
All I'm tryying to say/suggest is that you might want to wrap a few
more routineswith gpsee_fooBarBaz().
JS_DestroyRuntime(JS_NewRuntime(1024));
I'm not sure ABI matters a bit, but "hybrid" leads to some confusing issues like
Who documents JS_GetSTringBytes() replacements and breakage?
on to RPMJS modules, sure to be all sorts of compilation breakage there
> the "hybrid" ABI forces the application to link both -lgpsee and -lmozjs85.
What do you think off the current solution, which is to link -lmozjs185 from -lgpsee?
The one place I'm aware of where this gets its ugly is that embeddings which load like the library that links -lgpsee by dlopen can have a hard time getting at the symbols in libmozjs. This has already caused pain in APE; I solved it with dlopen("libape_spidermonkey.so", RTLD_LAZY | RTLD_GLOBAL);. libape_spidermonkey.so is -lgpsee.
Some JS_FooBarBaz() functions in -lmozjs185 are presented/used directly,
others are wrapped by GPSEE (like gpsee_getStringBytes).
The current naming convention (ugh btw) is that functions named JS_XYZ are either in JSAPI or behave exactly the ones in some version of JSAPI, where as gpsee_XYZ is *like* JS_XYZ but different in some way that matters. The example you quoted is an important one; memory allocation is different. (JS_ using magic, gpsee_ using alloca()).
All I'm tryying to say/suggest is that you might want to wrap a few
more routineswith gpsee_fooBarBaz().
I've considered this; I just haven't figured out exactly how much JSAPI I want to LTS. :)
JS_DestroyRuntime(JS_NewRuntime(1024));
Out of curiosity, why are doing this?
I'm not sure ABI matters a bit, but "hybrid" leads to some confusing issues like
Who documents JS_GetSTringBytes() replacements and breakage?
You're right, this is a problem. Right now it's 80% in my brain and 20% in the blog. That's not nearly good enough.
on to RPMJS modules, sure to be all sorts of compilation breakage there
Make sure you read spidermonkey/probe-jsapi.*, most of my 1.8.2 -> 1.8.5 knowledge is recorded there.
[jbj@wp3 wdj54]$ ./rpm -E '%{js:print("w00t!")}'
w00t!
Segmentation fault
All it took was s/JS_GetStringBytes/gpsee_getStringBytes/ in 1 place.
(aside while I'm here)
GPSEE has a tricky ABI design problem because its a piece of middleware.
Some JS_FooBarBaz() functions in -lmozjs185 are presented/used directly,
others are wrapped by GPSEE (like gpsee_getStringBytes).
This leads to a "hybrid" ABI for perfectly obvious reasons.
But from a stricter more pedantic POV (I don't care what RPM does:
once you reach linking 80+ libraries one more or less simply doesn't matter),
the "hybrid" ABI forces the application to link both -lgpsee and -lmozjs85.
The alternative and pedantically correct ABI rewraps all JS_FooBarBaz()
into gpsee_fooBarBaz() and there's an implicit inter-library linkage, not an application
linkage of all possible libraries.
All of which "works" fine but is perhaps not "correct".
All I'm tryying to say/suggest is that you might want to wrap a few
more routineswith gpsee_fooBarBaz().
Here's the handfule of JS_FooBarBaz routines in use by RPM+GPSEE that might be
candidates for re-wrapping (and might already be re-wrapped, not looked carefully)
JS_DestroyRuntime(JS_NewRuntime(1024));
gpsee_runtime_t * grt = JS_GetRuntimePrivate(JS_GetRuntime(I->cx));
JS_SetOptions(I->cx, (flags & 0xffff));
JS_SetGCZeal(I->cx, _rpmjs_zeal);
ok = JS_EvaluateScript(I->cx, I->realm->globalObject, str, strlen(str), __FILE__, __LINE__, &v);
JSString *rstr = JS_ValueToString(I->cx, v);
These are just the methods (and affect ABI): there's another whole level of pointless pedantry
rewrapping constants like JS_TRUE and JS_FALSE and typedefs etc that don't show up directly
(well size of data/bss symbols matters) in the ABI.
I'm not sure ABI matters a bit, but "hybrid" leads to some confusing issues like
Who documents JS_GetSTringBytes() replacements and breakage?
73 de Jeff on to RPMJS modules, sure to be all sorts of compilation breakage there
Is this for allowing JS scripting when configuring/compiling source code
via RPM?
What is the lifecycle of the JS context?
Will it be possible to init a JS context once in the beginning (which
can load various CommonJS packages/modules) and then calling into that
repeatedly later? That would be ideal to minimize init overhead when
using more complex JS scripting composed of many modules.
Ignore this if I am interpreting this all wrong :)
Christoph
> Jeff Johnson wrote:
>> [jbj@wp3 wdj54]$ ./rpm -E '%{js:print("w00t!")}'
>> w00t!
>
> Is this for allowing JS scripting when configuring/compiling source code via RPM?
>
The ultimate motivation is not user focussed at all, but rather converting
RPM from C to JS as a development language. That means my central
focus is all about binding existing RPM objects in C with methods
for use in JS.
Meanwhile, RPM has undertaken interpreter embeddings for just about every
language in which one might consider doing development. RPM has a unique
application niche because a software installer is expected to Just Work
on bare metal hardware and in empty chroot's. There's only a few solutions
for that constraint, one of which is embedding.
So the two user visible uses of RPM+JS are analogues of an uglix script like
#!INTERPRETER OPTIONS ARGS
BODY
or (with a "here" document
INTERPRETER OPTIONS ARGS << EOF
BODY
EOF
One usage case is with macro expansions used in templating with a programming signature like
%{INTERPRETER OPTIONS ARGS:BODY}
and the macro expansion captures stout into a memory buffer for template substitution
(and further processing).
The other usage case is a replacement for %post et al scripting performed while
installing package software with syntax in a spec file like
%post -p '<INTERPRETER OPTS ARGS>'
BODY
where one can avoid dependency on prerequisites necessary to perform a scripted operation.
Note that the BODY is also macro expanded so templating/scripting can be used together
(though the expansion operation will be during expansion, not while executing the BODY
> What is the lifecycle of the JS context?
>
Varies. There's a flag to use/share a single refcounted global interpreter, or
to be able to create/destroy multiple interpreters in their own context. Some languages
(python and ruby iirc) do not permit multiple interpreter instances, other
languages d, so there's a need outside of JS to share <-> isolate contexts
just to accommodate single instance interpreters.
A global shared interpreter is the easier paradigm to understand no matter what
else is feasible.
> Will it be possible to init a JS context once in the beginning (which can load various CommonJS packages/modules) and then calling into that repeatedly later? That would be ideal to minimize init overhead when using more complex JS scripting composed of many modules.
>
Yes: each instance has a preamble that can be expanded to load modules (I hesitate to say package,
because I have rather different associations there: I see a CommonJS "package" as a bundle of "modules"
abstraction, rather different than a *.rpm package because files != modules, files are purely content).
> Ignore this if I am interpreting this all wrong :)
>
No worries: I'm just sniffing gasoline and making up the usage case as I proceed.
I'll easily recognize the tools that I want to develop with in JS as soon as I create them.
73 de Jeff
> Will it be possible to init a JS context once in the beginning (which can load various CommonJS packages/modules) and then calling into that repeatedly later? That would be ideal to minimize init overhead when using more complex JS scripting composed of many modules. >Yes: each instance has a preamble that can be expanded to load modules (I hesitate to say package, because I have rather different associations there: I see a CommonJS "package" as a bundle of "modules" abstraction, rather different than a *.rpm package because files != modules, files are purely content).

The fuller context is thisif (F_ISSET(flags, NOUTF8) || getenv("GPSEE_NO_UTF8_C_STRINGS")) {JS_DestroyRuntime(JS_NewRuntime(1024));putenv((char *) "GPSEE_NO_UTF8_C_STRINGS=1");}
The fuller context is thisif (F_ISSET(flags, NOUTF8) || getenv("GPSEE_NO_UTF8_C_STRINGS")) {JS_DestroyRuntime(JS_NewRuntime(1024));putenv((char *) "GPSEE_NO_UTF8_C_STRINGS=1");}
Ah, I remember what this is for (more-or-less). I'm using a side-effect of JS_NewRuntime() to "lock-in" the UTF-8 settings. Funny, the exact details elude me now, I wish I had written a comment. ;) I think the idea, though, is to prevent incorrect behaviour in the event of a settings conflict, though -- preferring to throw an error instead.
>
> I rely on vermouth on the rocks with a splash of chlorox instead of docs:
> If She wishs to remind of the bug, It Will Happen.
>
GPSEE-0.4 at bitbuckey now builds and installs all modules using AutoFu.
There's two rather gross hacks that I've checked in:
1) The segfault I've been seeing with "./gsr -c1" is within GC on exit and can be avoided by
avoiding calling JS_MaybeGC() on the callback. Not at all a fix, but gud enuf to see what
other evils lurk.
2) (gffi) I don't know what the proper fix (or even what/why/how "standard" compliance is needed).
The current extraction failed on an a stray #define which I whacked out by supplying from the CLI
in modules/gffi/Makefile.am like this:
CPPFLAGS += \
-I$(builddir) \
-I$(srcdir) \
-I$(top_srcdir) \
-D__USE_POSIX_IMPLICITLY=1 \
$(STD_CPPFLAGS)
Otherwise gffi isn't anywhere near as bad as I thought it would be to wire up with AutoFu.
I had to change a few variables, and be a bit more careful for "make distcheck" bcause
srcdir != builddir there, and so some of the files needed $(srcdir) or $(builddir) prefixing.
But that does mean that srcdir SHOULD be RO now, and srcdir <-> builddir are cleanly
splits, so multiple builds in the same src tree are likely possible. I will check that when
I get around to "portability" checking on various platforms.
I've also wired up some of the existing tests/* with "make check", so there's lots of segfault
fodder there.
> I'm mostly compiling RPM modules against JS-1.85 now.
>
All I need atm is -lgpsee (which needs gpsee/system/vm linked in) so I haven't
looked too closely at run-time functionality yet. todo++.
I'll wait a day or two and tinker a bit more with generating gpsee_config.h, including more of
the existing tests, and doing "make check" more tersely, perhaps wire up the jsdoc generation
and starting to populate some of the portability checks in system.h and debug.h.
But the actual structural details (if you wish to use AutoFu) are now largely in place in
the bitbucket clone AFAIK.
Feedback on the changes is appreciated: if you can generate a short list or items you want,
it will be easier to prioritize andf finish up the work.
hth
73 de Jeff
GPSEE-0.4 at bitbuckey now builds and installs all modules using AutoFu.
There's two rather gross hacks that I've checked in:
1) The segfault I've been seeing with "./gsr -c1" is within GC on exit and can be avoided by
avoiding calling JS_MaybeGC() on the callback. Not at all a fix, but gud enuf to see what
other evils lurk.
2) (gffi) I don't know what the proper fix (or even what/why/how "standard" compliance is needed).
But that does mean that srcdir SHOULD be RO now, and srcdir <-> builddir are cleanly
splits, so multiple builds in the same src tree are likely possible. I will check that when
I get around to "portability" checking on various platforms.
Feedback on the changes is appreciated: if you can generate a short list or items you want,
it will be easier to prioritize andf finish up the work.
Do you need a simpler test case?
Christoph
On 25 September 2011 22:18, Jeff Johnson <n3...@mac.com> wrote:GPSEE-0.4 at bitbuckey now builds and installs all modules using AutoFu.
This is great!
There's two rather gross hacks that I've checked in:
1) The segfault I've been seeing with "./gsr -c1" is within GC on exit and can be avoided by
avoiding calling JS_MaybeGC() on the callback. Not at all a fix, but gud enuf to see what
other evils lurk.
Almost certainly a result of JS 1.8.5 changing shutdown GC semantics. Ugh. I had a really hard time with this on 1.8.2 as well.
2) (gffi) I don't know what the proper fix (or even what/why/how "standard" compliance is needed).
If I understand your query, these are the cflags which define the standard that GFFI compiles with. This might be different than the standard that the rest of GPSEE builds with. This is more important on UNIX-tm systems than Linux by a long shot; for example, on Solaris (and presumably other unices) you can select XPG4, XPG6, SUSv2 or SUSv3, and APIs might change slightly, or get entire interfaces added/removed. There's a bunch of other subtleties as well, and, in particular, SUSv3 implies C99.
But that does mean that srcdir SHOULD be RO now, and srcdir <-> builddir are cleanly
splits, so multiple builds in the same src tree are likely possible. I will check that when
I get around to "portability" checking on various platforms.
If you can keep an eye on solib paths when checking cross platform, that would be appreciated. Some of the current build mess is due to efforts trying to portably get full pathnames into the DSOs so that we can have careful/safe loading.
Feedback on the changes is appreciated: if you can generate a short list or items you want,
it will be easier to prioritize andf finish up the work.
I'll try and look at this tomorrow. I'm beat today, Christoph's loader bug is making me crazy. Either that, or I've found an "interation" between valgrind and libffi:
==3806== Command: /opt/local/gpsee/bin/gsr -f ./pinf-loader.js -- -v ./demos/HelloWorld/
==3806==
XXX calling umask
XXX avalues: 0x6746340 storage: 0x6746390 rtype_abi: 0x658afcc rvaluep: 0x67463e0 hnd: 0x67409d0
==3806== Invalid write of size 4
==3806== at 0x658ABE2: retint (in /Users/wes/hg/gpsee/libffi/builds/release/install/lib/libffi.5.dylib)
==3806== by 0x658A870: ffi_call (ffi.c:324)
==3806== by 0x654EAE2: cFunction_call (in /opt/local/gpsee/libexec/gffi.dylib)
==3806== by 0x4588E7: js::callJSFastNative(JSContext*, int (*)(JSContext*, unsigned int, long*), unsigned int, long*) (in /opt/local/gpsee/lib/libmozjs.dylib)
Grrr
>
> A simple example or even a pointer is likely enough to attempt …
>
Found what I need:
http://code.google.com/r/wes-js185/source/browse/docs.mk
todo++
73 de Jeff