From 32889bf90887d5117a60e53890a5eeaa84af33a6 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Wed, 16 Jul 2008 12:32:24 +0300 Subject: [PATCH] 1031: Add spidermonkey-shared.c used for both web and user scripts Rename src/ecmascript/spidermonkey/util.c to src/ecmascript/spidermonkey-shared.c and compile it also when CONFIG_SCRIPTING_SMJS is enabled but CONFIG_ECMASCRIPT_SPIDERMONKEY is not. Then use its functions from src/scripting/smjs/ too. Move the corresponding declarations, as well as the inline functions needed by src/scripting/smjs/, from src/ecmascript/spidermonkey/util.h to src/ecmascript/spidermonkey-shared.h. ELinks is nowadays using two JSRuntimes and SpiderMonkey has bugs that make it crash in such use. To work around them, ELinks will need to be changed to use only one JSRuntime. I am planning to define and initialize that JSRuntime in src/ecmascript/spidermonkey-shared.c, now that it's compiled whenever either of the modules is enabled. --- src/ecmascript/Makefile | 10 +++ .../util.c => spidermonkey-shared.c} | 5 +- src/ecmascript/spidermonkey-shared.h | 75 +++++++++++++++++++ src/ecmascript/spidermonkey/Makefile | 2 +- src/ecmascript/spidermonkey/util.h | 61 +-------------- src/scripting/smjs/action_object.c | 2 +- src/scripting/smjs/bookmarks.c | 2 +- src/scripting/smjs/bookmarks.h | 2 +- src/scripting/smjs/cache_object.c | 2 +- src/scripting/smjs/core.c | 2 +- src/scripting/smjs/core.h | 2 +- src/scripting/smjs/elinks_object.c | 33 +++----- src/scripting/smjs/elinks_object.h | 2 +- src/scripting/smjs/global_object.c | 2 +- src/scripting/smjs/global_object.h | 2 +- src/scripting/smjs/globhist.c | 2 +- src/scripting/smjs/hooks.c | 2 +- src/scripting/smjs/keybinding.c | 2 +- src/scripting/smjs/keybinding.h | 2 +- src/scripting/smjs/load_uri.c | 2 +- src/scripting/smjs/view_state_object.c | 2 +- 21 files changed, 117 insertions(+), 99 deletions(-) rename src/ecmascript/{spidermonkey/util.c => spidermonkey-shared.c} (91%) create mode 100644 src/ecmascript/spidermonkey-shared.h diff --git a/src/ecmascript/Makefile b/src/ecmascript/Makefile index c5ca6ea0..ab936a02 100644 --- a/src/ecmascript/Makefile +++ b/src/ecmascript/Makefile @@ -8,6 +8,16 @@ SUBDIRS-$(CONFIG_ECMASCRIPT_SMJS) += spidermonkey OBJS-$(CONFIG_ECMASCRIPT_SEE) += see.o OBJS-$(CONFIG_ECMASCRIPT_SMJS) += spidermonkey.o +ifeq ($(CONFIG_ECMASCRIPT_SMJS), yes) +CONFIG_ANY_SPIDERMONKEY = yes +else ifeq ($(CONFIG_SCRIPTING_SPIDERMONKEY), yes) +CONFIG_ANY_SPIDERMONKEY = yes +else +CONFIG_ANY_SPIDERMONKEY = no +endif + +OBJS-$(CONFIG_ANY_SPIDERMONKEY) += spidermonkey-shared.o + OBJS = ecmascript.o include $(top_srcdir)/Makefile.lib diff --git a/src/ecmascript/spidermonkey/util.c b/src/ecmascript/spidermonkey-shared.c similarity index 91% rename from src/ecmascript/spidermonkey/util.c rename to src/ecmascript/spidermonkey-shared.c index ccddbcd3..769a35b3 100644 --- a/src/ecmascript/spidermonkey/util.c +++ b/src/ecmascript/spidermonkey-shared.c @@ -1,4 +1,5 @@ -/* Better compatibility across versions of SpiderMonkey. */ +/** SpiderMonkey support for both user scripts and web scripts. + * @file */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -6,7 +7,7 @@ #include "elinks.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" /** An ELinks-specific replacement for JS_DefineFunctions(). * diff --git a/src/ecmascript/spidermonkey-shared.h b/src/ecmascript/spidermonkey-shared.h new file mode 100644 index 00000000..3b2602b6 --- /dev/null +++ b/src/ecmascript/spidermonkey-shared.h @@ -0,0 +1,75 @@ +#ifndef EL__ECMASCRIPT_SPIDERMONKEY_SHARED_H +#define EL__ECMASCRIPT_SPIDERMONKEY_SHARED_H + +/* Inconsistently applied conventions for prefixes in identifiers: + * - "smjs" for user scripts (scripting/smjs/). + * - "js" for web scripts (ecmascript/spidermonkey/). + * - "spidermonkey" for common stuff, especially any that replace + * similarly named things defined in SpiderMonkey itself. */ + +/* For wild SpiderMonkey installations. */ +#ifdef CONFIG_OS_BEOS +#define XP_BEOS +#elif CONFIG_OS_OS2 +#define XP_OS2 +#elif CONFIG_OS_RISCOS +#error Out of luck, buddy! +#elif CONFIG_OS_UNIX +#define XP_UNIX +#elif CONFIG_OS_WIN32 +#define XP_WIN +#endif + +#include + +#include "util/string.h" + +/** An ELinks-specific replacement for JSFunctionSpec. + * + * Bug 1016: In SpiderMonkey 1.7 bundled with XULRunner 1.8, jsapi.h + * defines JSFunctionSpec in different ways depending on whether + * MOZILLA_1_8_BRANCH is defined, and there is no obvious way for + * ELinks to check whether MOZILLA_1_8_BRANCH was defined when the + * library was built. Avoid the unstable JSFunctionSpec definitions + * and use this ELinks-specific structure instead. */ +typedef struct spidermonkeyFunctionSpec { + const char *name; + JSNative call; + uint8 nargs; + /* ELinks does not use "flags" and "extra" so omit them here. */ +} spidermonkeyFunctionSpec; + +JSBool spidermonkey_DefineFunctions(JSContext *cx, JSObject *obj, + const spidermonkeyFunctionSpec *fs); +JSObject *spidermonkey_InitClass(JSContext *cx, JSObject *obj, + JSObject *parent_proto, JSClass *clasp, + JSNative constructor, uintN nargs, + JSPropertySpec *ps, + const spidermonkeyFunctionSpec *fs, + JSPropertySpec *static_ps, + const spidermonkeyFunctionSpec *static_fs); + +static void undef_to_jsval(JSContext *ctx, jsval *vp); +static unsigned char *jsval_to_string(JSContext *ctx, jsval *vp); + +/* Inline functions */ + +static inline void +undef_to_jsval(JSContext *ctx, jsval *vp) +{ + *vp = JSVAL_NULL; +} + +static inline unsigned char * +jsval_to_string(JSContext *ctx, jsval *vp) +{ + jsval val; + + if (JS_ConvertValue(ctx, *vp, JSTYPE_STRING, &val) == JS_FALSE) { + return ""; + } + + return empty_string_or_(JS_GetStringBytes(JS_ValueToString(ctx, val))); +} + +#endif diff --git a/src/ecmascript/spidermonkey/Makefile b/src/ecmascript/spidermonkey/Makefile index 4f07d9bf..f1c0fef3 100644 --- a/src/ecmascript/spidermonkey/Makefile +++ b/src/ecmascript/spidermonkey/Makefile @@ -2,6 +2,6 @@ top_builddir=../../.. include $(top_builddir)/Makefile.config INCLUDES += $(SPIDERMONKEY_CFLAGS) -OBJS = document.o form.o location.o navigator.o unibar.o util.o window.o +OBJS = document.o form.o location.o navigator.o unibar.o window.o include $(top_srcdir)/Makefile.lib diff --git a/src/ecmascript/spidermonkey/util.h b/src/ecmascript/spidermonkey/util.h index a9f955eb..84da9a6c 100644 --- a/src/ecmascript/spidermonkey/util.h +++ b/src/ecmascript/spidermonkey/util.h @@ -2,32 +2,16 @@ #ifndef EL__ECMASCRIPT_SPIDERMONKEY_UTIL_H #define EL__ECMASCRIPT_SPIDERMONKEY_UTIL_H -/* For wild SpiderMonkey installations. */ -#ifdef CONFIG_OS_BEOS -#define XP_BEOS -#elif CONFIG_OS_OS2 -#define XP_OS2 -#elif CONFIG_OS_RISCOS -#error Out of luck, buddy! -#elif CONFIG_OS_UNIX -#define XP_UNIX -#elif CONFIG_OS_WIN32 -#define XP_WIN -#endif - -#include +#include "ecmascript/spidermonkey-shared.h" #include "util/memory.h" -#include "util/string.h" static void string_to_jsval(JSContext *ctx, jsval *vp, unsigned char *string); static void astring_to_jsval(JSContext *ctx, jsval *vp, unsigned char *string); static void int_to_jsval(JSContext *ctx, jsval *vp, int number); static void object_to_jsval(JSContext *ctx, jsval *vp, JSObject *object); static void boolean_to_jsval(JSContext *ctx, jsval *vp, int boolean); -static void undef_to_jsval(JSContext *ctx, jsval *vp); static int jsval_to_boolean(JSContext *ctx, jsval *vp); -static unsigned char *jsval_to_string(JSContext *ctx, jsval *vp); @@ -68,12 +52,6 @@ boolean_to_jsval(JSContext *ctx, jsval *vp, int boolean) *vp = BOOLEAN_TO_JSVAL(boolean); } -static inline void -undef_to_jsval(JSContext *ctx, jsval *vp) -{ - *vp = JSVAL_NULL; -} - static inline int jsval_to_boolean(JSContext *ctx, jsval *vp) @@ -87,41 +65,4 @@ jsval_to_boolean(JSContext *ctx, jsval *vp) return JSVAL_TO_BOOLEAN(val); } -static inline unsigned char * -jsval_to_string(JSContext *ctx, jsval *vp) -{ - jsval val; - - if (JS_ConvertValue(ctx, *vp, JSTYPE_STRING, &val) == JS_FALSE) { - return ""; - } - - return empty_string_or_(JS_GetStringBytes(JS_ValueToString(ctx, val))); -} - -/** An ELinks-specific replacement for JSFunctionSpec. - * - * Bug 1016: In SpiderMonkey 1.7 bundled with XULRunner 1.8, jsapi.h - * defines JSFunctionSpec in different ways depending on whether - * MOZILLA_1_8_BRANCH is defined, and there is no obvious way for - * ELinks to check whether MOZILLA_1_8_BRANCH was defined when the - * library was built. Avoid the unstable JSFunctionSpec definitions - * and use this ELinks-specific structure instead. */ -typedef struct spidermonkeyFunctionSpec { - const char *name; - JSNative call; - uint8 nargs; - /* ELinks does not use "flags" and "extra" so omit them here. */ -} spidermonkeyFunctionSpec; - -JSBool spidermonkey_DefineFunctions(JSContext *cx, JSObject *obj, - const spidermonkeyFunctionSpec *fs); -JSObject *spidermonkey_InitClass(JSContext *cx, JSObject *obj, - JSObject *parent_proto, JSClass *clasp, - JSNative constructor, uintN nargs, - JSPropertySpec *ps, - const spidermonkeyFunctionSpec *fs, - JSPropertySpec *static_ps, - const spidermonkeyFunctionSpec *static_fs); - #endif diff --git a/src/scripting/smjs/action_object.c b/src/scripting/smjs/action_object.c index b3c38dce..d95564d2 100644 --- a/src/scripting/smjs/action_object.c +++ b/src/scripting/smjs/action_object.c @@ -7,7 +7,7 @@ #include "elinks.h" #include "config/kbdbind.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "scripting/smjs/core.h" #include "scripting/smjs/elinks_object.h" #include "session/session.h" diff --git a/src/scripting/smjs/bookmarks.c b/src/scripting/smjs/bookmarks.c index f591bd8f..fd6610d2 100644 --- a/src/scripting/smjs/bookmarks.c +++ b/src/scripting/smjs/bookmarks.c @@ -7,7 +7,7 @@ #include "elinks.h" #include "bookmarks/bookmarks.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "main/event.h" #include "scripting/smjs/core.h" #include "scripting/smjs/elinks_object.h" diff --git a/src/scripting/smjs/bookmarks.h b/src/scripting/smjs/bookmarks.h index bdf93852..16f1ec4d 100644 --- a/src/scripting/smjs/bookmarks.h +++ b/src/scripting/smjs/bookmarks.h @@ -1,7 +1,7 @@ #ifndef EL__SCRIPTING_SMJS_BOOKMARKS_H #define EL__SCRIPTING_SMJS_BOOKMARKS_H -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" void smjs_init_bookmarks_interface(void); diff --git a/src/scripting/smjs/cache_object.c b/src/scripting/smjs/cache_object.c index 59708fe8..cd23842c 100644 --- a/src/scripting/smjs/cache_object.c +++ b/src/scripting/smjs/cache_object.c @@ -7,7 +7,7 @@ #include "elinks.h" #include "cache/cache.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "protocol/uri.h" #include "scripting/smjs/cache_object.h" #include "scripting/smjs/core.h" diff --git a/src/scripting/smjs/core.c b/src/scripting/smjs/core.c index 9d51a915..60fe7ba0 100644 --- a/src/scripting/smjs/core.c +++ b/src/scripting/smjs/core.c @@ -7,7 +7,7 @@ #include "elinks.h" #include "config/home.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "main/module.h" #include "osdep/osdep.h" #include "scripting/scripting.h" diff --git a/src/scripting/smjs/core.h b/src/scripting/smjs/core.h index dcc8a74b..0542f5cb 100644 --- a/src/scripting/smjs/core.h +++ b/src/scripting/smjs/core.h @@ -1,7 +1,7 @@ #ifndef EL__SCRIPTING_SMJS_CORE_H #define EL__SCRIPTING_SMJS_CORE_H -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" struct module; struct session; diff --git a/src/scripting/smjs/elinks_object.c b/src/scripting/smjs/elinks_object.c index 09455db6..727bfda6 100644 --- a/src/scripting/smjs/elinks_object.c +++ b/src/scripting/smjs/elinks_object.c @@ -8,7 +8,7 @@ #include "bfu/msgbox.h" #include "config/home.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "intl/gettext/libintl.h" #include "protocol/uri.h" #include "scripting/scripting.h" @@ -69,7 +69,7 @@ elinks_set_location(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) return JS_TRUE; } -/* function "alert" in the object returned by smjs_get_elinks_object() */ +/* @elinks_funcs{"alert"} */ static JSBool elinks_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { @@ -90,7 +90,7 @@ elinks_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval return JS_TRUE; } -/* function "execute" in the object returned by smjs_get_elinks_object() */ +/* @elinks_funcs{"execute"} */ static JSBool elinks_execute(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { @@ -117,6 +117,12 @@ static const JSClass elinks_class = { JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub }; +static const spidermonkeyFunctionSpec elinks_funcs[] = { + { "alert", elinks_alert, 1 }, + { "execute", elinks_execute, 1 }, + { NULL } +}; + static JSObject * smjs_get_elinks_object(void) { @@ -125,24 +131,9 @@ smjs_get_elinks_object(void) assert(smjs_ctx); assert(smjs_global_object); - jsobj = JS_InitClass(smjs_ctx, smjs_global_object, NULL, - (JSClass *) &elinks_class, NULL, 0, NULL, - (JSFunctionSpec *) NULL, NULL, NULL); - - /* Bug 1016: In SpiderMonkey 1.7 bundled with XULRunner 1.8, - * jsapi.h defines JSFunctionSpec in different ways depending - * on whether MOZILLA_1_8_BRANCH is defined, and there is no - * obvious way for ELinks to check whether MOZILLA_1_8_BRANCH - * was defined when the library was built. Avoid the unstable - * JSFunctionSpec definitions and instead use JS_DefineFunction - * directly. - * - * In elinks/src/ecmascript/spidermonkey/, there is an - * ELinks-specific replacement for JSFunctionSpec; however, to - * keep the modules independent, elinks/src/scripting/smjs/ - * does not use that. */ - JS_DefineFunction(smjs_ctx, jsobj, "alert", elinks_alert, 1, 0); - JS_DefineFunction(smjs_ctx, jsobj, "execute", elinks_execute, 1, 0); + jsobj = spidermonkey_InitClass(smjs_ctx, smjs_global_object, NULL, + (JSClass *) &elinks_class, NULL, 0, NULL, + elinks_funcs, NULL, NULL); JS_DefineProperty(smjs_ctx, jsobj, "location", JSVAL_NULL, elinks_get_location, elinks_set_location, diff --git a/src/scripting/smjs/elinks_object.h b/src/scripting/smjs/elinks_object.h index aa8f57d3..0395d892 100644 --- a/src/scripting/smjs/elinks_object.h +++ b/src/scripting/smjs/elinks_object.h @@ -1,7 +1,7 @@ #ifndef EL__SCRIPTING_SMJS_ELINKS_OBJECT_H #define EL__SCRIPTING_SMJS_ELINKS_OBJECT_H -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" /* This is the all-powerful elinks object through which all client scripts * will interface with ELinks. */ diff --git a/src/scripting/smjs/global_object.c b/src/scripting/smjs/global_object.c index f2c51102..3a597823 100644 --- a/src/scripting/smjs/global_object.c +++ b/src/scripting/smjs/global_object.c @@ -6,7 +6,7 @@ #include "elinks.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "scripting/scripting.h" #include "scripting/smjs/core.h" #include "scripting/smjs/global_object.h" diff --git a/src/scripting/smjs/global_object.h b/src/scripting/smjs/global_object.h index c7ff510a..1d2b6344 100644 --- a/src/scripting/smjs/global_object.h +++ b/src/scripting/smjs/global_object.h @@ -1,7 +1,7 @@ #ifndef EL__SCRIPTING_SMJS_GLOBAL_OBJECT_H #define EL__SCRIPTING_SMJS_GLOBAL_OBJECT_H -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" /* The root of the object hierarchy. If object 'foo' has this as its parent, * you can use foo's method and properties with 'foo.'. */ diff --git a/src/scripting/smjs/globhist.c b/src/scripting/smjs/globhist.c index 094f2e9d..0ab69386 100644 --- a/src/scripting/smjs/globhist.c +++ b/src/scripting/smjs/globhist.c @@ -7,7 +7,7 @@ #include "elinks.h" #include "globhist/globhist.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "scripting/smjs/core.h" #include "scripting/smjs/elinks_object.h" #include "util/memory.h" diff --git a/src/scripting/smjs/hooks.c b/src/scripting/smjs/hooks.c index 647d2887..291039cf 100644 --- a/src/scripting/smjs/hooks.c +++ b/src/scripting/smjs/hooks.c @@ -7,7 +7,7 @@ #include "elinks.h" #include "cache/cache.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "protocol/uri.h" #include "main/event.h" #include "main/module.h" diff --git a/src/scripting/smjs/keybinding.c b/src/scripting/smjs/keybinding.c index 61bffb27..2b354776 100644 --- a/src/scripting/smjs/keybinding.c +++ b/src/scripting/smjs/keybinding.c @@ -7,7 +7,7 @@ #include "elinks.h" #include "config/kbdbind.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "main/event.h" #include "scripting/smjs/core.h" #include "scripting/smjs/elinks_object.h" diff --git a/src/scripting/smjs/keybinding.h b/src/scripting/smjs/keybinding.h index b309420f..2f2893a2 100644 --- a/src/scripting/smjs/keybinding.h +++ b/src/scripting/smjs/keybinding.h @@ -1,7 +1,7 @@ #ifndef EL__SCRIPTING_SMJS_KEYBINDING_H #define EL__SCRIPTING_SMJS_KEYBINDING_H -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" void smjs_init_keybinding_interface(void); diff --git a/src/scripting/smjs/load_uri.c b/src/scripting/smjs/load_uri.c index b8adcc2c..4f2dcf26 100644 --- a/src/scripting/smjs/load_uri.c +++ b/src/scripting/smjs/load_uri.c @@ -6,7 +6,7 @@ #include "elinks.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "network/connection.h" #include "protocol/uri.h" #include "scripting/smjs/core.h" diff --git a/src/scripting/smjs/view_state_object.c b/src/scripting/smjs/view_state_object.c index b5f1ca0c..64f43caa 100644 --- a/src/scripting/smjs/view_state_object.c +++ b/src/scripting/smjs/view_state_object.c @@ -8,7 +8,7 @@ #include "elinks.h" -#include "ecmascript/spidermonkey/util.h" +#include "ecmascript/spidermonkey-shared.h" #include "protocol/uri.h" #include "scripting/smjs/elinks_object.h" #include "scripting/smjs/view_state_object.h"