From e8f0ff71e304af92f771600f3d81ad74f090485a94b179bf93ce1d1a207f657c Mon Sep 17 00:00:00 2001 From: Petr Uzel Date: Mon, 11 Jun 2012 08:07:33 +0000 Subject: [PATCH] Accepting request 124374 from home:adra:branches:network Updated License to GPL-2.0, Added some patches to support js-1.8.5, lua-5.1 and to fix compilation, Added/Removed/Fixed some build dependencies, Make the package provide web_browser, Enabled some additional build options OBS-URL: https://build.opensuse.org/request/show/124374 OBS-URL: https://build.opensuse.org/package/show/network/elinks?expand=0&rev=3 --- elinks-0.12_pre5-compilation-fix.patch | 12 + elinks-0.12_pre5-js185-1-heartbeat.patch | 376 +++++ elinks-0.12_pre5-js185-2-up.patch | 1900 ++++++++++++++++++++++ elinks-0.12_pre5-js185-3-histback.patch | 57 + elinks.changes | 27 + elinks.spec | 175 +- use_lua-5.1.patch | 61 + 7 files changed, 2557 insertions(+), 51 deletions(-) create mode 100644 elinks-0.12_pre5-compilation-fix.patch create mode 100644 elinks-0.12_pre5-js185-1-heartbeat.patch create mode 100644 elinks-0.12_pre5-js185-2-up.patch create mode 100644 elinks-0.12_pre5-js185-3-histback.patch create mode 100644 use_lua-5.1.patch diff --git a/elinks-0.12_pre5-compilation-fix.patch b/elinks-0.12_pre5-compilation-fix.patch new file mode 100644 index 0000000..e46cda8 --- /dev/null +++ b/elinks-0.12_pre5-compilation-fix.patch @@ -0,0 +1,12 @@ +diff -Naurp elinks-0.12pre5-orig//src/intl/charsets.c elinks-0.12pre5/src/intl/charsets.c +--- elinks-0.12pre5-orig//src/intl/charsets.c 2010-04-04 12:19:02.000000000 +0200 ++++ elinks-0.12pre5/src/intl/charsets.c 2010-04-04 12:19:20.000000000 +0200 +@@ -821,7 +821,7 @@ free_utf_table(void) + + /* Cast away const. */ + for (i = 128; i < 256; i++) +- mem_free((unsigned char *) utf_table[i].u.str); ++ mem_free(utf_table[i].u.str); + } + + static struct conv_table * diff --git a/elinks-0.12_pre5-js185-1-heartbeat.patch b/elinks-0.12_pre5-js185-1-heartbeat.patch new file mode 100644 index 0000000..05e81df --- /dev/null +++ b/elinks-0.12_pre5-js185-1-heartbeat.patch @@ -0,0 +1,376 @@ +From a3f59264b9504e8bf3d0ac70b99a237bc964089d Mon Sep 17 00:00:00 2001 +From: Miciah Dashiel Butler Masters +Date: Sat, 18 Jul 2009 23:41:01 +0000 +Subject: [PATCH 1/3] Heartbeat code using JS_TriggerOperationCallback + +Implement new heartbeat code to catch runaway execution of document +ECMAScript code. The old code uses JS_SetBranchCallback which is +deprecated in new versions of SpiderMonkey. The new code uses setitimer(2) +and the JS_SetOperationCallback and JS_TriggerOperationCallback interfaces, +introduced in SpiderMonkey 1.8.1. Compatibility with both the old +JS_SetBranchCallback and the new interfaces is maintained. + +Signed-off-by: Kamil Dudka +--- + Makefile.config.in | 1 + + configure.in | 12 +++ + src/ecmascript/ecmascript.h | 4 + + src/ecmascript/spidermonkey.c | 38 ++++++++- + src/ecmascript/spidermonkey/Makefile | 2 + + src/ecmascript/spidermonkey/heartbeat.c | 125 +++++++++++++++++++++++++++++++ + src/ecmascript/spidermonkey/heartbeat.h | 24 ++++++ + 7 files changed, 201 insertions(+), 5 deletions(-) + create mode 100644 src/ecmascript/spidermonkey/heartbeat.c + create mode 100644 src/ecmascript/spidermonkey/heartbeat.h + +diff --git a/Makefile.config.in b/Makefile.config.in +index c463868..40a8cd7 100644 +--- a/Makefile.config.in ++++ b/Makefile.config.in +@@ -117,6 +117,7 @@ CONFIG_DOM = @CONFIG_DOM@ + CONFIG_ECMASCRIPT = @CONFIG_ECMASCRIPT@ + CONFIG_ECMASCRIPT_SEE = @CONFIG_ECMASCRIPT_SEE@ + CONFIG_ECMASCRIPT_SMJS = @CONFIG_ECMASCRIPT_SMJS@ ++CONFIG_ECMASCRIPT_SMJS_HEARTBEAT = @CONFIG_ECMASCRIPT_SMJS@ + CONFIG_EXMODE = @CONFIG_EXMODE@ + CONFIG_FASTMEM = @CONFIG_FASTMEM@ + CONFIG_FINGER = @CONFIG_FINGER@ +diff --git a/configure.in b/configure.in +index f3e3d77..f79ca78 100644 +--- a/configure.in ++++ b/configure.in +@@ -283,6 +283,7 @@ AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf) + AC_CHECK_FUNCS(getifaddrs getpwnam inet_pton inet_ntop) + AC_CHECK_FUNCS(fflush fsync fseeko ftello sigaction) + AC_CHECK_FUNCS(gettimeofday clock_gettime) ++AC_CHECK_FUNCS(setitimer, HAVE_SETITIMER=yes) + + AC_CHECK_FUNCS([cygwin_conv_to_full_win32_path]) + +@@ -651,6 +652,8 @@ AC_MSG_RESULT($cf_result) + CONFIG_SPIDERMONKEY="$cf_result" + if test "$cf_result" = "yes"; then + AC_CHECK_FUNCS([[JS_ReportAllocationOverflow]]) ++ AC_CHECK_FUNCS(JS_SetBranchCallback) ++ AC_CHECK_FUNCS(JS_TriggerOperationCallback, HAVE_JS_TRIGGEROPERATIONCALLBACK=yes) + fi + EL_RESTORE_FLAGS + +@@ -665,6 +668,15 @@ EL_CONFIG_DEPENDS(CONFIG_ECMASCRIPT, [CONFIG_ECMASCRIPT_SEE CONFIG_ECMASCRIPT_SM + AC_SUBST(CONFIG_ECMASCRIPT_SEE) + AC_SUBST(CONFIG_ECMASCRIPT_SMJS) + ++if test "x$CONFIG_ECMASCRIPT_SMJS" = xyes && ++ test "x$HAVE_JS_TRIGGEROPERATIONCALLBACK" = xyes && ++ test "x$HAVE_SETITIMER" = xyes; then ++ EL_CONFIG(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT, [ECMAScript heartbeat support]) ++else ++ CONFIG_ECMASCRIPT_SMJS_HEARTBEAT=no ++fi ++AC_SUBST(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) ++ + + # =================================================================== + # Optional Spidermonkey-based ECMAScript browser scripting +diff --git a/src/ecmascript/ecmascript.h b/src/ecmascript/ecmascript.h +index e8d84b5..8613b34 100644 +--- a/src/ecmascript/ecmascript.h ++++ b/src/ecmascript/ecmascript.h +@@ -32,7 +32,11 @@ struct ecmascript_interpreter { + /* The code evaluated by setTimeout() */ + struct string code; + ++#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) ++ struct heartbeat *heartbeat; ++#elif defined(HAVE_JS_SETBRANCHCALLBACK) + time_t exec_start; ++#endif + + /* This is a cross-rerenderings accumulator of + * @document.onload_snippets (see its description for juicy details). +diff --git a/src/ecmascript/spidermonkey.c b/src/ecmascript/spidermonkey.c +index 78c3bca..16fb0a4 100644 +--- a/src/ecmascript/spidermonkey.c ++++ b/src/ecmascript/spidermonkey.c +@@ -25,6 +25,7 @@ + #include "ecmascript/spidermonkey.h" + #include "ecmascript/spidermonkey/document.h" + #include "ecmascript/spidermonkey/form.h" ++#include "ecmascript/spidermonkey/heartbeat.h" + #include "ecmascript/spidermonkey/location.h" + #include "ecmascript/spidermonkey/navigator.h" + #include "ecmascript/spidermonkey/unibar.h" +@@ -109,6 +110,7 @@ reported: + JS_ClearPendingException(ctx); + } + ++#if !defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) && defined(HAVE_JS_SETBRANCHCALLBACK) + static JSBool + safeguard(JSContext *ctx, JSScript *script) + { +@@ -132,6 +134,7 @@ setup_safeguard(struct ecmascript_interpreter *interpreter, + interpreter->exec_start = time(NULL); + JS_SetBranchCallback(ctx, safeguard); + } ++#endif + + + static void +@@ -172,6 +175,9 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter) + * some kind of bytecode cache. (If we will ever do that.) */ + JS_SetOptions(ctx, JSOPTION_VAROBJFIX | JSOPTION_COMPILE_N_GO); + JS_SetErrorReporter(ctx, error_reporter); ++#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) ++ JS_SetOperationCallback(ctx, heartbeat_callback); ++#endif + + window_obj = JS_NewObject(ctx, (JSClass *) &window_class, NULL, NULL); + if (!window_obj) goto release_and_fail; +@@ -263,10 +269,17 @@ spidermonkey_eval(struct ecmascript_interpreter *interpreter, + assert(interpreter); + if (!js_module_init_ok) return; + ctx = interpreter->backend_data; ++#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) ++ interpreter->heartbeat = add_heartbeat(interpreter); ++#elif defined(HAVE_JS_SETBRANCHCALLBACK) + setup_safeguard(interpreter, ctx); ++#endif + interpreter->ret = ret; + JS_EvaluateScript(ctx, JS_GetGlobalObject(ctx), + code->source, code->length, "", 0, &rval); ++#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) ++ done_heartbeat(interpreter->heartbeat); ++#endif + } + + +@@ -274,17 +287,25 @@ unsigned char * + spidermonkey_eval_stringback(struct ecmascript_interpreter *interpreter, + struct string *code) + { ++ JSBool ret; + JSContext *ctx; + jsval rval; + + assert(interpreter); + if (!js_module_init_ok) return NULL; + ctx = interpreter->backend_data; +- setup_safeguard(interpreter, ctx); + interpreter->ret = NULL; +- if (JS_EvaluateScript(ctx, JS_GetGlobalObject(ctx), +- code->source, code->length, "", 0, &rval) +- == JS_FALSE) { ++#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) ++ interpreter->heartbeat = add_heartbeat(interpreter); ++#elif defined(HAVE_JS_SETBRANCHCALLBACK) ++ setup_safeguard(interpreter, ctx); ++#endif ++ ret = JS_EvaluateScript(ctx, JS_GetGlobalObject(ctx), ++ code->source, code->length, "", 0, &rval); ++#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) ++ done_heartbeat(interpreter->heartbeat); ++#endif ++ if (ret == JS_FALSE) { + return NULL; + } + if (JSVAL_IS_VOID(rval)) { +@@ -308,14 +329,21 @@ spidermonkey_eval_boolback(struct ecmascript_interpreter *interpreter, + assert(interpreter); + if (!js_module_init_ok) return 0; + ctx = interpreter->backend_data; +- setup_safeguard(interpreter, ctx); + interpreter->ret = NULL; + fun = JS_CompileFunction(ctx, NULL, "", 0, NULL, code->source, + code->length, "", 0); + if (!fun) + return -1; + ++#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) ++ interpreter->heartbeat = add_heartbeat(interpreter); ++#elif defined(HAVE_JS_SETBRANCHCALLBACK) ++ setup_safeguard(interpreter, ctx); ++#endif + ret = JS_CallFunction(ctx, NULL, fun, 0, NULL, &rval); ++#if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) ++ done_heartbeat(interpreter->heartbeat); ++#endif + if (ret == 2) { /* onClick="history.back()" */ + return 0; + } +diff --git a/src/ecmascript/spidermonkey/Makefile b/src/ecmascript/spidermonkey/Makefile +index f1c0fef..377ca80 100644 +--- a/src/ecmascript/spidermonkey/Makefile ++++ b/src/ecmascript/spidermonkey/Makefile +@@ -2,6 +2,8 @@ top_builddir=../../.. + include $(top_builddir)/Makefile.config + INCLUDES += $(SPIDERMONKEY_CFLAGS) + ++OBJS-$(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) += heartbeat.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/heartbeat.c b/src/ecmascript/spidermonkey/heartbeat.c +new file mode 100644 +index 0000000..bf95d92 +--- /dev/null ++++ b/src/ecmascript/spidermonkey/heartbeat.c +@@ -0,0 +1,125 @@ ++/* The SpiderMonkey ECMAScript backend heartbeat fuctionality. */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include /* setitimer(2) */ ++ ++#include "elinks.h" ++ ++#include "ecmascript/spidermonkey/util.h" ++ ++#include "config/options.h" ++#include "document/view.h" ++#include "ecmascript/ecmascript.h" ++#include "ecmascript/spidermonkey.h" ++#include "ecmascript/spidermonkey/heartbeat.h" ++#include "osdep/signals.h" ++#include "session/session.h" ++#include "util/lists.h" ++#include "util/math.h" /* int_upper_bound */ ++#include "util/memory.h" ++#include "viewer/text/vs.h" ++ ++ ++ ++static INIT_LIST_OF(struct heartbeat, heartbeats); ++ ++static struct itimerval heartbeat_timer = { { 1, 0 }, { 1, 0 } }; ++ ++ ++/* This callback is installed by JS_SetOperationCallback and triggered ++ * by JS_TriggerOperationCallback in the heartbeat code below. Returning ++ * JS_FALSE terminates script execution immediately. */ ++JSBool ++heartbeat_callback(JSContext *ctx) ++{ ++ return JS_FALSE; ++} ++ ++/* Callback for SIGVTALRM. Go through all heartbeats, decrease each ++ * one's TTL, and call JS_TriggerOperationCallback if a heartbeat's TTL ++ * goes to 0. */ ++static void ++check_heartbeats(void *data) ++{ ++ struct heartbeat *hb; ++ ++ foreach (hb, heartbeats) { ++ assert(hb->interpreter); ++ ++ --hb->ttl; ++ ++ if (hb->ttl <= 0) { ++ if (hb->interpreter->vs ++ && hb->interpreter->vs->doc_view ++ && hb->interpreter->vs->doc_view->session ++ && hb->interpreter->vs->doc_view->session->tab ++ && hb->interpreter->vs->doc_view->session->tab->term) { ++ struct session *ses = hb->interpreter->vs->doc_view->session; ++ struct terminal *term = ses->tab->term; ++ int max_exec_time = get_opt_int("ecmascript.max_exec_time"); ++ ++ ecmascript_timeout_dialog(term, max_exec_time); ++ } ++ ++ JS_TriggerOperationCallback(hb->interpreter->backend_data); ++ } ++ } ++ ++ install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1); ++} ++ ++/* Create a new heartbeat for the given interpreter. */ ++struct heartbeat * ++add_heartbeat(struct ecmascript_interpreter *interpreter) ++{ ++ struct session *ses; ++ struct heartbeat *hb; ++ ++ assert(interpreter); ++ ++ if (!interpreter->vs || !interpreter->vs->doc_view) ++ ses = NULL; ++ else ++ ses = interpreter->vs->doc_view->session; ++ ++ hb = mem_alloc(sizeof(struct heartbeat)); ++ if (!hb) return NULL; ++ ++ hb->ttl = get_opt_int("ecmascript.max_exec_time"); ++ hb->interpreter = interpreter; ++ ++ add_to_list(heartbeats, hb); ++ ++ /* Update the heartbeat timer. */ ++ if (list_is_singleton(*hb)) { ++ heartbeat_timer.it_value.tv_sec = 1; ++ setitimer(ITIMER_VIRTUAL, &heartbeat_timer, NULL); ++ } ++ ++ /* We install the handler every call to add_heartbeat instead of only on ++ * module initialisation because other code may set other handlers for ++ * the signal. */ ++ install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1); ++ ++ return hb; ++} ++ ++/* Destroy the given heartbeat. */ ++void ++done_heartbeat(struct heartbeat *hb) ++{ ++ assert(hb->interpreter); ++ ++ /* Stop the heartbeat timer if this heartbeat is the only one. */ ++ if (list_is_singleton(*hb)) { ++ heartbeat_timer.it_value.tv_sec = 0; ++ setitimer(ITIMER_VIRTUAL, &heartbeat_timer, NULL); ++ } ++ ++ del_from_list(hb); ++ hb->interpreter->heartbeat = NULL; ++ mem_free(hb); ++} +diff --git a/src/ecmascript/spidermonkey/heartbeat.h b/src/ecmascript/spidermonkey/heartbeat.h +new file mode 100644 +index 0000000..f7c8b12 +--- /dev/null ++++ b/src/ecmascript/spidermonkey/heartbeat.h +@@ -0,0 +1,24 @@ ++#ifndef EL__ECMASCRIPT_SPIDERMONKEY_HEARTBEAT_H ++#define EL__ECMASCRIPT_SPIDERMONKEY_HEARTBEAT_H ++ ++#include "ecmascript/spidermonkey/util.h" ++ ++#include "ecmascript/spidermonkey.h" ++ ++struct heartbeat { ++ LIST_HEAD(struct heartbeat); ++ ++ int ttl; /* Time to live. This value is assigned when the ++ * script begins execution and is decremented every ++ * second. When it reaches 0, script execution is ++ * terminated. */ ++ ++ struct ecmascript_interpreter *interpreter; ++}; ++ ++struct heartbeat *add_heartbeat(struct ecmascript_interpreter *interpreter); ++void done_heartbeat(struct heartbeat *hb); ++ ++JSBool heartbeat_callback(JSContext *ctx); ++ ++#endif +-- +1.7.4.2 + diff --git a/elinks-0.12_pre5-js185-2-up.patch b/elinks-0.12_pre5-js185-2-up.patch new file mode 100644 index 0000000..4548c4c --- /dev/null +++ b/elinks-0.12_pre5-js185-2-up.patch @@ -0,0 +1,1900 @@ +From dcaff5d937d63888c560727dda5f5348fa59a366 Mon Sep 17 00:00:00 2001 +From: witekfl +Date: Tue, 19 Apr 2011 22:41:05 +0200 +Subject: [PATCH 2/3] JS_VERSION at least 185 is required for ECMASCript + (xulrunner-2.0 or later) + +The code wasn't tested. It compiles + +Signed-off-by: Kamil Dudka +--- + configure.in | 10 ++- + src/ecmascript/spidermonkey-shared.h | 13 ++- + src/ecmascript/spidermonkey.c | 11 +-- + src/ecmascript/spidermonkey/document.c | 44 ++++---- + src/ecmascript/spidermonkey/form.c | 192 +++++++++++++++++++++---------- + src/ecmascript/spidermonkey/location.c | 42 ++++--- + src/ecmascript/spidermonkey/navigator.c | 10 +- + src/ecmascript/spidermonkey/unibar.c | 16 ++-- + src/ecmascript/spidermonkey/window.c | 57 ++++++---- + src/scripting/smjs/action_object.c | 29 +++-- + src/scripting/smjs/bookmarks.c | 24 ++-- + src/scripting/smjs/cache_object.c | 18 ++-- + src/scripting/smjs/core.c | 11 +- + src/scripting/smjs/elinks_object.c | 26 +++-- + src/scripting/smjs/global_object.c | 6 +- + src/scripting/smjs/globhist.c | 22 ++-- + src/scripting/smjs/hooks.c | 4 +- + src/scripting/smjs/keybinding.c | 12 +- + src/scripting/smjs/load_uri.c | 10 +- + src/scripting/smjs/view_state_object.c | 16 ++-- + 20 files changed, 344 insertions(+), 229 deletions(-) + +diff --git a/configure.in b/configure.in +index f79ca78..64faf85 100644 +--- a/configure.in ++++ b/configure.in +@@ -630,7 +630,7 @@ + fi + for spidermonkeydir in "$withval" "" /usr /usr/local /opt/spidermonkey /opt/js; do + for spidermonkeyinclude in "/include" "/include/js" "/include/smjs" "/include/mozjs"; do +- for spidermonkeylib in js smjs mozjs; do ++ for spidermonkeylib in js smjs mozjs185 mozjs; do + if test "$cf_result" = no && + test -f "$spidermonkeydir$spidermonkeyinclude/jsapi.h"; then + SPIDERMONKEY_LIBS="-L$spidermonkeydir/lib -l$spidermonkeylib" +@@ -641,7 +641,15 @@ if test -z "$disable_spidermonkey"; then + CPPFLAGS="$CPPFLAGS_X $SPIDERMONKEY_CFLAGS" + + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define XP_UNIX +- #include ]], [[JS_GetReservedSlot(NULL, NULL, 0, NULL)]])],[cf_result=yes],[cf_result=no]) ++ #define XP_UNIX ++ #include ]], [[ ++ #ifndef JS_VERSION ++ #error JS_VERSION ++ #endif ++ #if JS_VERSION < 185 ++ #error too old ++ #endif]])], ++ [cf_result=yes],[cf_result=no]) + fi + done + done +diff --git a/src/ecmascript/spidermonkey-shared.h b/src/ecmascript/spidermonkey-shared.h +index 4cc0eeb..98bfe31 100644 +--- a/src/ecmascript/spidermonkey-shared.h ++++ b/src/ecmascript/spidermonkey-shared.h +@@ -50,6 +50,7 @@ JSObject *spidermonkey_InitClass(JSContext *cx, JSObject *obj, + + static void undef_to_jsval(JSContext *ctx, jsval *vp); + static unsigned char *jsval_to_string(JSContext *ctx, jsval *vp); ++static unsigned char *jsid_to_string(JSContext *ctx, jsid *id); + + /* Inline functions */ + +@@ -68,7 +69,17 @@ jsval_to_string(JSContext *ctx, jsval *vp) + return ""; + } + +- return empty_string_or_(JS_GetStringBytes(JS_ValueToString(ctx, val))); ++ return empty_string_or_(JS_EncodeString(ctx, JS_ValueToString(ctx, val))); ++} ++ ++static inline unsigned char * ++jsid_to_string(JSContext *ctx, jsid *id) ++{ ++ jsval v; ++ ++ /* TODO: check returned value */ ++ JS_IdToValue(ctx, *id, &v); ++ return jsval_to_string(ctx, &v); + } + + #endif +diff --git a/src/ecmascript/spidermonkey.c b/src/ecmascript/spidermonkey.c +index 16fb0a4..021e6bd 100644 +--- a/src/ecmascript/spidermonkey.c ++++ b/src/ecmascript/spidermonkey.c +@@ -167,19 +167,14 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter) + return NULL; + interpreter->backend_data = ctx; + JS_SetContextPrivate(ctx, interpreter); +- /* TODO: Make JSOPTION_STRICT and JSOPTION_WERROR configurable. */ +-#ifndef JSOPTION_COMPILE_N_GO +-#define JSOPTION_COMPILE_N_GO 0 /* Older SM versions don't have it. */ +-#endif +- /* XXX: JSOPTION_COMPILE_N_GO will go (will it?) when we implement +- * some kind of bytecode cache. (If we will ever do that.) */ +- JS_SetOptions(ctx, JSOPTION_VAROBJFIX | JSOPTION_COMPILE_N_GO); ++ JS_SetOptions(ctx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT); ++ JS_SetVersion(ctx, JSVERSION_LATEST); + JS_SetErrorReporter(ctx, error_reporter); + #if defined(CONFIG_ECMASCRIPT_SMJS_HEARTBEAT) + JS_SetOperationCallback(ctx, heartbeat_callback); + #endif + +- window_obj = JS_NewObject(ctx, (JSClass *) &window_class, NULL, NULL); ++ window_obj = JS_NewCompartmentAndGlobalObject(ctx, (JSClass *) &window_class, NULL); + if (!window_obj) goto release_and_fail; + if (!JS_InitStandardClasses(ctx, window_obj)) goto release_and_fail; + if (!JS_DefineProperties(ctx, window_obj, (JSPropertySpec *) window_props)) +diff --git a/src/ecmascript/spidermonkey/document.c b/src/ecmascript/spidermonkey/document.c +index 8f7bb92..dd72aae 100644 +--- a/src/ecmascript/spidermonkey/document.c ++++ b/src/ecmascript/spidermonkey/document.c +@@ -47,8 +47,8 @@ + #include "viewer/text/vs.h" + + +-static JSBool document_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); +-static JSBool document_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); ++static JSBool document_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp); ++static JSBool document_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp); + + /* Each @document_class object must have a @window_class parent. */ + const JSClass document_class = { +@@ -81,7 +81,7 @@ const JSPropertySpec document_props[] = { + + /* @document_class.getProperty */ + static JSBool +-document_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++document_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + JSObject *parent_win; /* instance of @window_class */ + struct view_state *vs; +@@ -104,9 +104,9 @@ document_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + document = doc_view->document; + ses = doc_view->session; + +- if (JSVAL_IS_STRING(id)) { ++ if (JSID_IS_STRING(id)) { + struct form *form; +- unsigned char *string = jsval_to_string(ctx, &id); ++ unsigned char *string = jsid_to_string(ctx, &id); + + #ifdef CONFIG_COOKIES + if (!strcmp(string, "cookie")) { +@@ -135,12 +135,12 @@ document_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + return JS_TRUE; + } + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + + undef_to_jsval(ctx, vp); + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_DOC_LOC: + JS_GetProperty(ctx, parent_win, "location", vp); + break; +@@ -188,7 +188,7 @@ document_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @document_class.setProperty */ + static JSBool +-document_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++document_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + JSObject *parent_win; /* instance of @window_class */ + struct view_state *vs; +@@ -209,9 +209,9 @@ document_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + doc_view = vs->doc_view; + document = doc_view->document; + +- if (JSVAL_IS_STRING(id)) { ++ if (JSID_IS_STRING(id)) { + #ifdef CONFIG_COOKIES +- if (!strcmp(jsval_to_string(ctx, &id), "cookie")) { ++ if (!strcmp(jsid_to_string(ctx, &id), "cookie")) { + set_cookie(vs->uri, jsval_to_string(ctx, vp)); + /* Do NOT touch our .cookie property, evil + * SpiderMonkey!! */ +@@ -221,10 +221,10 @@ document_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + return JS_TRUE; + } + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_DOC_TITLE: + mem_free_set(&document->title, stracpy(jsval_to_string(ctx, vp))); + print_screen_status(doc_view->session); +@@ -242,8 +242,8 @@ document_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + return JS_TRUE; + } + +-static JSBool document_write(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool document_writeln(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool document_write(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool document_writeln(JSContext *ctx, uintN argc, jsval *rval); + + const spidermonkeyFunctionSpec document_funcs[] = { + { "write", document_write, 1 }, +@@ -252,11 +252,12 @@ const spidermonkeyFunctionSpec document_funcs[] = { + }; + + static JSBool +-document_write_do(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, +- jsval *rval, int newline) ++document_write_do(JSContext *ctx, uintN argc, jsval *rval, int newline) + { ++ jsval val; + struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); + struct string *ret = interpreter->ret; ++ jsval *argv = JS_ARGV(ctx, rval); + + if (argc >= 1 && ret) { + int i = 0; +@@ -281,22 +282,23 @@ document_write_do(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, + set_led_value(interpreter->vs->doc_view->session->status.ecmascript_led, 'J'); + #endif + +- boolean_to_jsval(ctx, rval, 0); ++ boolean_to_jsval(ctx, &val, 0); ++ JS_SET_RVAL(ctx, rval, val); + + return JS_TRUE; + } + + /* @document_funcs{"write"} */ + static JSBool +-document_write(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++document_write(JSContext *ctx, uintN argc, jsval *rval) + { + +- return document_write_do(ctx, obj, argc, argv, rval, 0); ++ return document_write_do(ctx, argc, rval, 0); + } + + /* @document_funcs{"writeln"} */ + static JSBool +-document_writeln(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++document_writeln(JSContext *ctx, uintN argc, jsval *rval) + { +- return document_write_do(ctx, obj, argc, argv, rval, 1); ++ return document_write_do(ctx, argc, rval, 1); + } +diff --git a/src/ecmascript/spidermonkey/form.c b/src/ecmascript/spidermonkey/form.c +index ff436a1..824b170 100644 +--- a/src/ecmascript/spidermonkey/form.c ++++ b/src/ecmascript/spidermonkey/form.c +@@ -55,8 +55,8 @@ static const JSClass form_class; /* defined below */ + * HTMLInputElement. The difference could be spotted only by some clever tricky + * JS code, but I hope it doesn't matter anywhere. --pasky */ + +-static JSBool input_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); +-static JSBool input_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); ++static JSBool input_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp); ++static JSBool input_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp); + static void input_finalize(JSContext *ctx, JSObject *obj); + + /* Each @input_class object must have a @form_class parent. */ +@@ -116,10 +116,10 @@ static const JSPropertySpec input_props[] = { + { NULL } + }; + +-static JSBool input_blur(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool input_click(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool input_focus(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool input_select(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool input_blur(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool input_click(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool input_focus(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool input_select(JSContext *ctx, uintN argc, jsval *rval); + + static const spidermonkeyFunctionSpec input_funcs[] = { + { "blur", input_blur, 0 }, +@@ -150,7 +150,7 @@ input_get_form_state(JSContext *ctx, JSObject *jsinput) + + /* @input_class.getProperty */ + static JSBool +-input_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++input_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + JSObject *parent_form; /* instance of @form_class */ + JSObject *parent_doc; /* instance of @document_class */ +@@ -189,7 +189,7 @@ input_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + assert(fc); + assert(fc->form && fs); + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + + linknum = get_form_control_link(document, fc); +@@ -198,7 +198,7 @@ input_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + undef_to_jsval(ctx, vp); + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_INPUT_ACCESSKEY: + { + JSString *keystr; +@@ -301,7 +301,7 @@ input_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @input_class.setProperty */ + static JSBool +-input_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++input_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + JSObject *parent_form; /* instance of @form_class */ + JSObject *parent_doc; /* instance of @document_class */ +@@ -341,14 +341,14 @@ input_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + assert(fc); + assert(fc->form && fs); + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + + linknum = get_form_control_link(document, fc); + /* Hiddens have no link. */ + if (linknum >= 0) link = &document->links[linknum]; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_INPUT_ACCESSKEY: + accesskey = jsval_to_accesskey(ctx, vp); + if (accesskey == UCS_NO_CHAR) +@@ -422,7 +422,7 @@ input_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @input_funcs{"blur"} */ + static JSBool +-input_blur(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++input_blur(JSContext *ctx, uintN argc, jsval *rval) + { + /* We are a text-mode browser and there *always* has to be something + * selected. So we do nothing for now. (That was easy.) */ +@@ -431,11 +431,14 @@ input_blur(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + + /* @input_funcs{"click"} */ + static JSBool +-input_click(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++input_click(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval val; + JSObject *parent_form; /* instance of @form_class */ + JSObject *parent_doc; /* instance of @document_class */ + JSObject *parent_win; /* instance of @window_class */ ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ jsval *argv = JS_ARGV(ctx, rval); + struct view_state *vs; + struct document_view *doc_view; + struct document *document; +@@ -479,17 +482,21 @@ input_click(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + else + print_screen_status(ses); + +- boolean_to_jsval(ctx, rval, 0); ++ boolean_to_jsval(ctx, &val, 0); ++ JS_SET_RVAL(ctx, rval, val); + return JS_TRUE; + } + + /* @input_funcs{"focus"} */ + static JSBool +-input_focus(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++input_focus(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval val; + JSObject *parent_form; /* instance of @form_class */ + JSObject *parent_doc; /* instance of @document_class */ + JSObject *parent_win; /* instance of @window_class */ ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ jsval *argv = JS_ARGV(ctx, rval); + struct view_state *vs; + struct document_view *doc_view; + struct document *document; +@@ -528,13 +535,14 @@ input_focus(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + + jump_to_link_number(ses, doc_view, linknum); + +- boolean_to_jsval(ctx, rval, 0); ++ boolean_to_jsval(ctx, &val, 0); ++ JS_SET_RVAL(ctx, rval, val); + return JS_TRUE; + } + + /* @input_funcs{"select"} */ + static JSBool +-input_select(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++input_select(JSContext *ctx, uintN argc, jsval *rval) + { + /* We support no text selecting yet. So we do nothing for now. + * (That was easy, too.) */ +@@ -662,19 +670,22 @@ get_form_control_object(JSContext *ctx, JSObject *jsform, + + + static struct form_view *form_get_form_view(JSContext *ctx, JSObject *jsform, jsval *argv); +-static JSBool form_elements_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); ++static JSBool form_elements_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp); + + /* Each @form_elements_class object must have a @form_class parent. */ + static const JSClass form_elements_class = { + "elements", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, +- form_elements_get_property, JS_PropertyStub, ++ form_elements_get_property, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub + }; + +-static JSBool form_elements_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool form_elements_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool form_elements_item2(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool form_elements_namedItem2(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool form_elements_item(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool form_elements_namedItem(JSContext *ctx, uintN argc, jsval *rval); ++ + + static const spidermonkeyFunctionSpec form_elements_funcs[] = { + { "item", form_elements_item, 1 }, +@@ -696,8 +707,9 @@ static const JSPropertySpec form_elements_props[] = { + + /* @form_elements_class.getProperty */ + static JSBool +-form_elements_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++form_elements_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { ++ jsval idval; + JSObject *parent_form; /* instance of @form_class */ + JSObject *parent_doc; /* instance of @document_class */ + JSObject *parent_win; /* instance of @window_class */ +@@ -730,32 +742,46 @@ form_elements_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + if (!form_view) return JS_FALSE; /* detached */ + form = find_form_by_form_view(document, form_view); + +- if (JSVAL_IS_STRING(id)) { +- form_elements_namedItem(ctx, obj, 1, &id, vp); ++ if (JSID_IS_STRING(id)) { ++ JS_IdToValue(ctx, id, &idval); ++ form_elements_namedItem2(ctx, obj, 1, &idval, vp); + return JS_TRUE; + } + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + + undef_to_jsval(ctx, vp); + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_FORM_ELEMENTS_LENGTH: + int_to_jsval(ctx, vp, list_size(&form->items)); + break; + default: + /* Array index. */ +- form_elements_item(ctx, obj, 1, &id, vp); ++ JS_IdToValue(ctx, id, &idval); ++ form_elements_item2(ctx, obj, 1, &idval, vp); + break; + } + + return JS_TRUE; + } + ++static JSBool ++form_elements_item(JSContext *ctx, uintN argc, jsval *rval) ++{ ++ jsval val; ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ jsval *argv = JS_ARGV(ctx, rval); ++ JSBool ret = form_elements_item2(ctx, obj, argc, argv, &val); ++ ++ JS_SET_RVAL(ctx, rval, val); ++ return ret; ++} ++ + /* @form_elements_funcs{"item"} */ + static JSBool +-form_elements_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++form_elements_item2(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + { + JSObject *parent_form; /* instance of @form_class */ + JSObject *parent_doc; /* instance of @document_class */ +@@ -813,9 +839,21 @@ form_elements_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval + return JS_TRUE; + } + ++static JSBool ++form_elements_namedItem(JSContext *ctx, uintN argc, jsval *rval) ++{ ++ jsval val; ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ jsval *argv = JS_ARGV(ctx, rval); ++ JSBool ret = form_elements_namedItem2(ctx, obj, argc, argv, &val); ++ ++ JS_SET_RVAL(ctx, rval, val); ++ return ret; ++} ++ + /* @form_elements_funcs{"namedItem"} */ + static JSBool +-form_elements_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++form_elements_namedItem2(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + { + JSObject *parent_form; /* instance of @form_class */ + JSObject *parent_doc; /* instance of @document_class */ +@@ -876,8 +914,8 @@ form_elements_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, + + + +-static JSBool form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); +-static JSBool form_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); ++static JSBool form_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp); ++static JSBool form_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp); + static void form_finalize(JSContext *ctx, JSObject *obj); + + /* Each @form_class object must have a @document_class parent. */ +@@ -914,8 +952,8 @@ static const JSPropertySpec form_props[] = { + { NULL } + }; + +-static JSBool form_reset(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool form_submit(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool form_reset(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool form_submit(JSContext *ctx, uintN argc, jsval *rval); + + static const spidermonkeyFunctionSpec form_funcs[] = { + { "reset", form_reset, 0 }, +@@ -940,7 +978,7 @@ form_get_form_view(JSContext *ctx, JSObject *jsform, jsval *argv) + + /* @form_class.getProperty */ + static JSBool +-form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++form_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + /* DBG("doc %p %s\n", parent_doc, JS_GetStringBytes(JS_ValueToString(ctx, OBJECT_TO_JSVAL(parent_doc)))); */ + JSObject *parent_doc; /* instance of @document_class */ +@@ -971,11 +1009,11 @@ form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + assert(form); + +- if (JSVAL_IS_STRING(id)) { ++ if (JSID_IS_STRING(id)) { + struct form_control *fc; + unsigned char *string; + +- string = jsval_to_string(ctx, &id); ++ string = jsid_to_string(ctx, &id); + foreach (fc, form->items) { + JSObject *fcobj = NULL; + struct form_state *fs; +@@ -996,12 +1034,12 @@ form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + return JS_TRUE; + } + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + + undef_to_jsval(ctx, vp); + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_FORM_ACTION: + string_to_jsval(ctx, vp, form->action); + break; +@@ -1076,7 +1114,7 @@ form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @form_class.setProperty */ + static JSBool +-form_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++form_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + JSObject *parent_doc; /* instance of @document_class */ + JSObject *parent_win; /* instance of @window_class */ +@@ -1107,10 +1145,10 @@ form_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + assert(form); + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_FORM_ACTION: + string = stracpy(jsval_to_string(ctx, vp)); + if (form->action) { +@@ -1162,10 +1200,13 @@ form_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @form_funcs{"reset"} */ + static JSBool +-form_reset(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++form_reset(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval val; + JSObject *parent_doc; /* instance of @document_class */ + JSObject *parent_win; /* instance of @window_class */ ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ jsval *argv = JS_ARGV(ctx, rval); + struct view_state *vs; + struct document_view *doc_view; + struct form_view *fv; +@@ -1191,17 +1232,21 @@ form_reset(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + do_reset_form(doc_view, form); + draw_forms(doc_view->session->tab->term, doc_view); + +- boolean_to_jsval(ctx, rval, 0); ++ boolean_to_jsval(ctx, &val, 0); ++ JS_SET_RVAL(ctx, rval, val); + + return JS_TRUE; + } + + /* @form_funcs{"submit"} */ + static JSBool +-form_submit(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++form_submit(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval val; + JSObject *parent_doc; /* instance of @document_class */ + JSObject *parent_win; /* instance of @window_class */ ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ jsval *argv = JS_ARGV(ctx, rval); + struct view_state *vs; + struct document_view *doc_view; + struct session *ses; +@@ -1227,7 +1272,8 @@ form_submit(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + assert(form); + submit_given_form(ses, doc_view, form, 0); + +- boolean_to_jsval(ctx, rval, 0); ++ boolean_to_jsval(ctx, &val, 0); ++ JS_SET_RVAL(ctx, rval, val); + + return JS_TRUE; + } +@@ -1308,19 +1354,20 @@ spidermonkey_detach_form_view(struct form_view *fv) + } + + +-static JSBool forms_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); ++static JSBool forms_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp); + + /* Each @forms_class object must have a @document_class parent. */ + const JSClass forms_class = { + "forms", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, +- forms_get_property, JS_PropertyStub, ++ forms_get_property, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub + }; + +-static JSBool forms_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool forms_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool forms_item(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool forms_item2(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool forms_namedItem(JSContext *ctx, uintN argc, jsval *rval); + + const spidermonkeyFunctionSpec forms_funcs[] = { + { "item", forms_item, 1 }, +@@ -1365,8 +1412,9 @@ find_form_by_name(JSContext *ctx, JSObject *jsdoc, + + /* @forms_class.getProperty */ + static JSBool +-forms_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++forms_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { ++ jsval idval; + JSObject *parent_doc; /* instance of @document_class */ + JSObject *parent_win; /* instance of @window_class */ + struct view_state *vs; +@@ -1390,36 +1438,50 @@ forms_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + doc_view = vs->doc_view; + document = doc_view->document; + +- if (JSVAL_IS_STRING(id)) { ++ if (JSID_IS_STRING(id)) { + /* When SMJS evaluates forms.namedItem("foo"), it first + * calls forms_get_property with id = JSString "namedItem" + * and *vp = JSObject JSFunction forms_namedItem. + * If we don't find a form whose name is id, + * we must leave *vp unchanged here, to avoid + * "TypeError: forms.namedItem is not a function". */ +- find_form_by_name(ctx, parent_doc, doc_view, id, vp); ++ JS_IdToValue(ctx, id, &idval); ++ find_form_by_name(ctx, parent_doc, doc_view, idval, vp); + return JS_TRUE; + } + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_FORMS_LENGTH: + int_to_jsval(ctx, vp, list_size(&document->forms)); + break; + default: + /* Array index. */ +- forms_item(ctx, obj, 1, &id, vp); ++ JS_IdToValue(ctx, id, &idval); ++ forms_item2(ctx, obj, 1, &idval, vp); + break; + } + + return JS_TRUE; + } + ++static JSBool ++forms_item(JSContext *ctx, uintN argc, jsval *rval) ++{ ++ jsval val; ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ jsval *argv = JS_ARGV(ctx, rval); ++ JSBool ret = forms_item2(ctx, obj, argc, argv, &val); ++ ++ JS_SET_RVAL(ctx, rval, val); ++ return ret; ++} ++ + /* @forms_funcs{"item"} */ + static JSBool +-forms_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++forms_item2(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + { + JSObject *parent_doc; /* instance of @document_class */ + JSObject *parent_win; /* instance of @window_class */ +@@ -1459,10 +1521,13 @@ forms_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + + /* @forms_funcs{"namedItem"} */ + static JSBool +-forms_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++forms_namedItem(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval val; + JSObject *parent_doc; /* instance of @document_class */ + JSObject *parent_win; /* instance of @window_class */ ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ jsval *argv = JS_ARGV(ctx, rval); + struct view_state *vs; + struct document_view *doc_view; + +@@ -1481,8 +1546,9 @@ forms_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *r + if (argc != 1) + return JS_TRUE; + +- undef_to_jsval(ctx, rval); +- find_form_by_name(ctx, parent_doc, doc_view, argv[0], rval); ++ undef_to_jsval(ctx, &val); ++ find_form_by_name(ctx, parent_doc, doc_view, argv[0], &val); ++ JS_SET_RVAL(ctx, rval, val); + return JS_TRUE; + } + +@@ -1519,13 +1585,13 @@ static unicode_val_T + jsval_to_accesskey(JSContext *ctx, jsval *vp) + { + size_t len; +- const jschar *chr; ++ const char *chr; + + /* Convert the value in place, to protect the result from GC. */ + if (JS_ConvertValue(ctx, *vp, JSTYPE_STRING, vp) == JS_FALSE) + return UCS_NO_CHAR; +- len = JS_GetStringLength(JSVAL_TO_STRING(*vp)); +- chr = JS_GetStringChars(JSVAL_TO_STRING(*vp)); ++ len = JS_GetStringEncodingLength(ctx, JSVAL_TO_STRING(*vp)); ++ chr = JS_EncodeString(ctx, JSVAL_TO_STRING(*vp)); + + /* This implementation ignores extra characters in the string. */ + if (len < 1) +diff --git a/src/ecmascript/spidermonkey/location.c b/src/ecmascript/spidermonkey/location.c +index dd5b40b..752a890 100644 +--- a/src/ecmascript/spidermonkey/location.c ++++ b/src/ecmascript/spidermonkey/location.c +@@ -45,15 +45,15 @@ + #include "viewer/text/vs.h" + + +-static JSBool history_back(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool history_forward(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool history_go(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool history_back(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool history_forward(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool history_go(JSContext *ctx, uintN argc, jsval *rval); + + const JSClass history_class = { + "history", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, +- JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub + }; + +@@ -66,7 +66,7 @@ const spidermonkeyFunctionSpec history_funcs[] = { + + /* @history_funcs{"back"} */ + static JSBool +-history_back(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++history_back(JSContext *ctx, uintN argc, jsval *rval) + { + struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); + struct document_view *doc_view = interpreter->vs->doc_view; +@@ -83,7 +83,7 @@ history_back(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval + + /* @history_funcs{"forward"} */ + static JSBool +-history_forward(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++history_forward(JSContext *ctx, uintN argc, jsval *rval) + { + struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); + struct document_view *doc_view = interpreter->vs->doc_view; +@@ -96,11 +96,12 @@ history_forward(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *r + + /* @history_funcs{"go"} */ + static JSBool +-history_go(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++history_go(JSContext *ctx, uintN argc, jsval *rval) + { + struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); + struct document_view *doc_view = interpreter->vs->doc_view; + struct session *ses = doc_view->session; ++ jsval *argv = JS_ARGV(ctx, rval); + int index; + struct location *loc; + +@@ -124,8 +125,8 @@ history_go(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + } + + +-static JSBool location_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); +-static JSBool location_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); ++static JSBool location_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp); ++static JSBool location_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp); + + /* Each @location_class object must have a @window_class parent. */ + const JSClass location_class = { +@@ -150,7 +151,7 @@ const JSPropertySpec location_props[] = { + + /* @location_class.getProperty */ + static JSBool +-location_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++location_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + JSObject *parent_win; /* instance of @window_class */ + struct view_state *vs; +@@ -167,12 +168,12 @@ location_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + vs = JS_GetInstancePrivate(ctx, parent_win, + (JSClass *) &window_class, NULL); + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + + undef_to_jsval(ctx, vp); + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_LOC_HREF: + astring_to_jsval(ctx, vp, get_uri_string(vs->uri, URI_ORIGINAL)); + break; +@@ -191,7 +192,7 @@ location_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @location_class.setProperty */ + static JSBool +-location_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++location_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + JSObject *parent_win; /* instance of @window_class */ + struct view_state *vs; +@@ -210,10 +211,10 @@ location_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + (JSClass *) &window_class, NULL); + doc_view = vs->doc_view; + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_LOC_HREF: + location_goto(doc_view, jsval_to_string(ctx, vp)); + break; +@@ -222,7 +223,7 @@ location_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + return JS_TRUE; + } + +-static JSBool location_toString(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool location_toString(JSContext *ctx, uintN argc, jsval *rval); + + const spidermonkeyFunctionSpec location_funcs[] = { + { "toString", location_toString, 0 }, +@@ -232,9 +233,14 @@ const spidermonkeyFunctionSpec location_funcs[] = { + + /* @location_funcs{"toString"}, @location_funcs{"toLocaleString"} */ + static JSBool +-location_toString(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++location_toString(JSContext *ctx, uintN argc, jsval *rval) + { +- return JS_GetProperty(ctx, obj, "href", rval); ++ jsval val; ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ JSBool ret = JS_GetProperty(ctx, obj, "href", &val); ++ ++ JS_SET_RVAL(ctx, rval, val); ++ return ret; + } + + struct delayed_goto { +diff --git a/src/ecmascript/spidermonkey/navigator.c b/src/ecmascript/spidermonkey/navigator.c +index a009d62..e08a224 100644 +--- a/src/ecmascript/spidermonkey/navigator.c ++++ b/src/ecmascript/spidermonkey/navigator.c +@@ -44,13 +44,13 @@ + #include "viewer/text/vs.h" + + +-static JSBool navigator_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); ++static JSBool navigator_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp); + + const JSClass navigator_class = { + "navigator", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, +- navigator_get_property, JS_PropertyStub, ++ navigator_get_property, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub + }; + +@@ -81,14 +81,14 @@ const JSPropertySpec navigator_props[] = { + + /* @navigator_class.getProperty */ + static JSBool +-navigator_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++navigator_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + + undef_to_jsval(ctx, vp); + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_NAVIGATOR_APP_CODENAME: + string_to_jsval(ctx, vp, "Mozilla"); /* More like a constant nowadays. */ + break; +diff --git a/src/ecmascript/spidermonkey/unibar.c b/src/ecmascript/spidermonkey/unibar.c +index 3c290a3..576c0a7 100644 +--- a/src/ecmascript/spidermonkey/unibar.c ++++ b/src/ecmascript/spidermonkey/unibar.c +@@ -45,8 +45,8 @@ + #include "viewer/text/vs.h" + + +-static JSBool unibar_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); +-static JSBool unibar_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); ++static JSBool unibar_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp); ++static JSBool unibar_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp); + + /* Each @menubar_class object must have a @window_class parent. */ + const JSClass menubar_class = { +@@ -80,7 +80,7 @@ const JSPropertySpec unibar_props[] = { + + /* @menubar_class.getProperty, @statusbar_class.getProperty */ + static JSBool +-unibar_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++unibar_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + JSObject *parent_win; /* instance of @window_class */ + struct view_state *vs; +@@ -104,10 +104,10 @@ unibar_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + status = &doc_view->session->status; + bar = JS_GetPrivate(ctx, obj); /* from @menubar_class or @statusbar_class */ + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_UNIBAR_VISIBLE: + #define unibar_fetch(bar) \ + boolean_to_jsval(ctx, vp, status->force_show_##bar##_bar >= 0 \ +@@ -139,7 +139,7 @@ unibar_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @menubar_class.setProperty, @statusbar_class.setProperty */ + static JSBool +-unibar_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++unibar_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + JSObject *parent_win; /* instance of @window_class */ + struct view_state *vs; +@@ -163,10 +163,10 @@ unibar_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + status = &doc_view->session->status; + bar = JS_GetPrivate(ctx, obj); /* from @menubar_class or @statusbar_class */ + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_UNIBAR_VISIBLE: + switch (*bar) { + case 's': +diff --git a/src/ecmascript/spidermonkey/window.c b/src/ecmascript/spidermonkey/window.c +index 5e93a6f..9bc8dd9 100644 +--- a/src/ecmascript/spidermonkey/window.c ++++ b/src/ecmascript/spidermonkey/window.c +@@ -44,12 +44,12 @@ + #include "viewer/text/vs.h" + + +-static JSBool window_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); +-static JSBool window_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp); ++static JSBool window_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp); ++static JSBool window_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp); + + const JSClass window_class = { + "window", +- JSCLASS_HAS_PRIVATE, /* struct view_state * */ ++ JSCLASS_HAS_PRIVATE | JSCLASS_GLOBAL_FLAGS, /* struct view_state * */ + JS_PropertyStub, JS_PropertyStub, + window_get_property, window_set_property, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub +@@ -122,7 +122,7 @@ find_child_frame(struct document_view *doc_view, struct frame_desc *tframe) + + /* @window_class.getProperty */ + static JSBool +-window_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++window_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + struct view_state *vs; + +@@ -138,11 +138,11 @@ window_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + * location is then evaluated in string context, toString() + * is called which we overrode for that class below, so + * everything's fine. */ +- if (JSVAL_IS_STRING(id)) { ++ if (JSID_IS_STRING(id)) { + struct document_view *doc_view = vs->doc_view; + JSObject *obj; + +- obj = try_resolve_frame(doc_view, jsval_to_string(ctx, &id)); ++ obj = try_resolve_frame(doc_view, jsid_to_string(ctx, &id)); + /* TODO: Try other lookups (mainly element lookup) until + * something yields data. */ + if (obj) { +@@ -151,12 +151,12 @@ window_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + return JS_TRUE; + } + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + + undef_to_jsval(ctx, vp); + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_WIN_CLOSED: + /* TODO: It will be a major PITA to implement this properly. + * Well, perhaps not so much if we introduce reference tracking +@@ -254,7 +254,7 @@ void location_goto(struct document_view *doc_view, unsigned char *url); + + /* @window_class.setProperty */ + static JSBool +-window_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++window_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + struct view_state *vs; + +@@ -266,8 +266,8 @@ window_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + vs = JS_GetInstancePrivate(ctx, obj, (JSClass *) &window_class, NULL); + +- if (JSVAL_IS_STRING(id)) { +- if (!strcmp(jsval_to_string(ctx, &id), "location")) { ++ if (JSID_IS_STRING(id)) { ++ if (!strcmp(jsid_to_string(ctx, &id), "location")) { + struct document_view *doc_view = vs->doc_view; + + location_goto(doc_view, jsval_to_string(ctx, vp)); +@@ -278,10 +278,10 @@ window_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + return JS_TRUE; + } + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_TRUE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case JSP_WIN_STATUS: + mem_free_set(&vs->doc_view->session->status.window_status, stracpy(jsval_to_string(ctx, vp))); + print_screen_status(vs->doc_view->session); +@@ -298,9 +298,9 @@ window_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + } + + +-static JSBool window_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-static JSBool window_setTimeout(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++static JSBool window_alert(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool window_open(JSContext *ctx, uintN argc, jsval *rval); ++static JSBool window_setTimeout(JSContext *ctx, uintN argc, jsval *rval); + + const spidermonkeyFunctionSpec window_funcs[] = { + { "alert", window_alert, 1 }, +@@ -311,8 +311,11 @@ const spidermonkeyFunctionSpec window_funcs[] = { + + /* @window_funcs{"alert"} */ + static JSBool +-window_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++window_alert(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval val; ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ jsval *argv = JS_ARGV(ctx, rval); + struct view_state *vs; + unsigned char *string; + +@@ -330,14 +333,18 @@ window_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval + info_box(vs->doc_view->session->tab->term, MSGBOX_FREE_TEXT, + N_("JavaScript Alert"), ALIGN_CENTER, stracpy(string)); + +- undef_to_jsval(ctx, rval); ++ undef_to_jsval(ctx, &val); ++ JS_SET_RVAL(ctx, rval, val); + return JS_TRUE; + } + + /* @window_funcs{"open"} */ + static JSBool +-window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++window_open(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval val; ++ JSObject *obj = JS_THIS_OBJECT(ctx, rval); ++ jsval *argv = JS_ARGV(ctx, rval); + struct view_state *vs; + struct document_view *doc_view; + struct session *ses; +@@ -407,7 +414,7 @@ window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + deo->uri = get_uri_reference(uri); + deo->target = stracpy(frame); + register_bottom_half(delayed_goto_uri_frame, deo); +- boolean_to_jsval(ctx, rval, 1); ++ boolean_to_jsval(ctx, &val, 1); + goto end; + } + } +@@ -418,7 +425,7 @@ window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + && can_open_in_new(ses->tab->term)) { + open_uri_in_new_window(ses, uri, NULL, ENV_ANY, + CACHE_MODE_NORMAL, TASK_NONE); +- boolean_to_jsval(ctx, rval, 1); ++ boolean_to_jsval(ctx, &val, 1); + } else { + /* When opening a new tab, we might get rerendered, losing our + * context and triggerring a disaster, so postpone that. */ +@@ -428,9 +435,9 @@ window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) + deo->ses = ses; + deo->uri = get_uri_reference(uri); + register_bottom_half(delayed_open, deo); +- boolean_to_jsval(ctx, rval, 1); ++ boolean_to_jsval(ctx, &val, 1); + } else { +- undef_to_jsval(ctx, rval); ++ undef_to_jsval(ctx, &val); + } + } + +@@ -438,13 +445,15 @@ end: + done_uri(uri); + mem_free_if(frame); + ++ JS_SET_RVAL(ctx, rval, val); + return JS_TRUE; + } + + /* @window_funcs{"setTimeout"} */ + static JSBool +-window_setTimeout(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++window_setTimeout(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval *argv = JS_ARGV(ctx, rval); + struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); + unsigned char *code; + int timeout; +diff --git a/src/scripting/smjs/action_object.c b/src/scripting/smjs/action_object.c +index d95564d..d0379e0 100644 +--- a/src/scripting/smjs/action_object.c ++++ b/src/scripting/smjs/action_object.c +@@ -40,25 +40,31 @@ smjs_action_fn_finalize(JSContext *ctx, JSObject *obj) + + /* @action_fn_class.call */ + static JSBool +-smjs_action_fn_callback(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, +- jsval *rval) ++smjs_action_fn_callback(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval value; ++ jsval *argv = JS_ARGV(ctx, rval); + struct smjs_action_fn_callback_hop *hop; + JSObject *fn_obj; + + assert(smjs_ctx); + if_assert_failed return JS_FALSE; + +- *rval = JS_FALSE; ++ value = JS_FALSE; + +- if (JS_TRUE != JS_ValueToObject(ctx, argv[-2], &fn_obj)) ++ if (JS_TRUE != JS_ValueToObject(ctx, argv[-2], &fn_obj)) { ++ JS_SET_RVAL(ctx, rval, value); + return JS_TRUE; ++ } + assert(JS_InstanceOf(ctx, fn_obj, (JSClass *) &action_fn_class, NULL)); + if_assert_failed return JS_FALSE; + + hop = JS_GetInstancePrivate(ctx, fn_obj, + (JSClass *) &action_fn_class, NULL); +- if (!hop) return JS_TRUE; ++ if (!hop) { ++ JS_SET_RVAL(ctx, rval, value); ++ return JS_TRUE; ++ } + + if (argc >= 1) { + int32 val; +@@ -70,7 +76,8 @@ smjs_action_fn_callback(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, + + do_action(hop->ses, hop->action_id, 1); + +- *rval = JS_TRUE; ++ value = JS_TRUE; ++ JS_SET_RVAL(ctx, rval, value); + + return JS_TRUE; + } +@@ -79,7 +86,7 @@ static const JSClass action_fn_class = { + "action_fn", + JSCLASS_HAS_PRIVATE, /* struct smjs_action_fn_callback_hop * */ + JS_PropertyStub, JS_PropertyStub, +- JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, + smjs_action_fn_finalize, + NULL, NULL, +@@ -124,14 +131,16 @@ smjs_get_action_fn_object(unsigned char *action_str) + + /* @action_class.getProperty */ + static JSBool +-action_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++action_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { ++ jsval val; + JSObject *action_fn; + unsigned char *action_str; + + *vp = JSVAL_NULL; + +- action_str = JS_GetStringBytes(JS_ValueToString(ctx, id)); ++ JS_IdToValue(ctx, id, &val); ++ action_str = JS_EncodeString(ctx, JS_ValueToString(ctx, val)); + if (!action_str) return JS_TRUE; + + action_fn = smjs_get_action_fn_object(action_str); +@@ -146,7 +155,7 @@ static const JSClass action_class = { + "action", + 0, + JS_PropertyStub, JS_PropertyStub, +- action_get_property, JS_PropertyStub, ++ action_get_property, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + }; + +diff --git a/src/scripting/smjs/bookmarks.c b/src/scripting/smjs/bookmarks.c +index f12f84b..6c8b7fa 100644 +--- a/src/scripting/smjs/bookmarks.c ++++ b/src/scripting/smjs/bookmarks.c +@@ -113,29 +113,29 @@ jsval_to_bookmark_string(JSContext *ctx, jsval val, unsigned char **result) + unsigned char *str; + + /* jsstring_to_utf8() might GC; protect the string to come. */ +- if (!JS_AddNamedRoot(ctx, &jsstr, "jsval_to_bookmark_string")) ++ if (!JS_AddNamedStringRoot(ctx, &jsstr, "jsval_to_bookmark_string")) + return JS_FALSE; + + jsstr = JS_ValueToString(ctx, val); + if (jsstr == NULL) { +- JS_RemoveRoot(ctx, &jsstr); ++ JS_RemoveStringRoot(ctx, &jsstr); + return JS_FALSE; + } + + str = jsstring_to_utf8(ctx, jsstr, NULL); + if (str == NULL) { +- JS_RemoveRoot(ctx, &jsstr); ++ JS_RemoveStringRoot(ctx, &jsstr); + return JS_FALSE; + } + +- JS_RemoveRoot(ctx, &jsstr); ++ JS_RemoveStringRoot(ctx, &jsstr); + mem_free_set(result, str); + return JS_TRUE; + } + + /* @bookmark_class.getProperty */ + static JSBool +-bookmark_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++bookmark_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + struct bookmark *bookmark; + +@@ -152,10 +152,10 @@ bookmark_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + undef_to_jsval(ctx, vp); + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_FALSE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case BOOKMARK_TITLE: + return bookmark_string_to_jsval(ctx, bookmark->title, vp); + case BOOKMARK_URL: +@@ -177,7 +177,7 @@ bookmark_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @bookmark_class.setProperty */ + static JSBool +-bookmark_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++bookmark_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + struct bookmark *bookmark; + unsigned char *title = NULL; +@@ -195,10 +195,10 @@ bookmark_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + if (!bookmark) return JS_FALSE; + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_FALSE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case BOOKMARK_TITLE: + if (!jsval_to_bookmark_string(ctx, *vp, &title)) + return JS_FALSE; +@@ -250,7 +250,7 @@ smjs_get_bookmark_object(struct bookmark *bookmark) + + /* @bookmark_folder_class.getProperty */ + static JSBool +-bookmark_folder_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++bookmark_folder_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + struct bookmark *bookmark; + struct bookmark *folder; +@@ -283,7 +283,7 @@ static const JSClass bookmark_folder_class = { + "bookmark_folder", + JSCLASS_HAS_PRIVATE, /* struct bookmark * */ + JS_PropertyStub, JS_PropertyStub, +- bookmark_folder_get_property, JS_PropertyStub, ++ bookmark_folder_get_property, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, bookmark_finalize, + }; + +diff --git a/src/scripting/smjs/cache_object.c b/src/scripting/smjs/cache_object.c +index cd23842..0bdb563 100644 +--- a/src/scripting/smjs/cache_object.c ++++ b/src/scripting/smjs/cache_object.c +@@ -40,7 +40,7 @@ static const JSPropertySpec cache_entry_props[] = { + + /* @cache_entry_class.getProperty */ + static JSBool +-cache_entry_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++cache_entry_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + struct cache_entry *cached; + JSBool ret; +@@ -66,9 +66,9 @@ cache_entry_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + undef_to_jsval(ctx, vp); + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + ret = JS_FALSE; +- else switch (JSVAL_TO_INT(id)) { ++ else switch (JSID_TO_INT(id)) { + case CACHE_ENTRY_CONTENT: { + struct fragment *fragment = get_cache_fragment(cached); + +@@ -121,7 +121,7 @@ cache_entry_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @cache_entry_class.setProperty */ + static JSBool +-cache_entry_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++cache_entry_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + struct cache_entry *cached; + JSBool ret; +@@ -145,12 +145,12 @@ cache_entry_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + * eventually unlock the object. */ + object_lock(cached); + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + ret = JS_FALSE; +- else switch (JSVAL_TO_INT(id)) { ++ else switch (JSID_TO_INT(id)) { + case CACHE_ENTRY_CONTENT: { + JSString *jsstr = JS_ValueToString(smjs_ctx, *vp); +- unsigned char *str = JS_GetStringBytes(jsstr); ++ unsigned char *str = JS_EncodeString(smjs_ctx, jsstr); + size_t len = JS_GetStringLength(jsstr); + + add_fragment(cached, 0, str, len); +@@ -161,7 +161,7 @@ cache_entry_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + } + case CACHE_ENTRY_TYPE: { + JSString *jsstr = JS_ValueToString(smjs_ctx, *vp); +- unsigned char *str = JS_GetStringBytes(jsstr); ++ unsigned char *str = JS_EncodeString(smjs_ctx, jsstr); + + mem_free_set(&cached->content_type, stracpy(str)); + +@@ -170,7 +170,7 @@ cache_entry_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + } + case CACHE_ENTRY_HEAD: { + JSString *jsstr = JS_ValueToString(smjs_ctx, *vp); +- unsigned char *str = JS_GetStringBytes(jsstr); ++ unsigned char *str = JS_EncodeString(smjs_ctx, jsstr); + + mem_free_set(&cached->head, stracpy(str)); + +diff --git a/src/scripting/smjs/core.c b/src/scripting/smjs/core.c +index 2493904..ced28b0 100644 +--- a/src/scripting/smjs/core.c ++++ b/src/scripting/smjs/core.c +@@ -94,11 +94,11 @@ smjs_do_file(unsigned char *path) + } + + static JSBool +-smjs_do_file_wrapper(JSContext *ctx, JSObject *obj, uintN argc, +- jsval *argv, jsval *rval) ++smjs_do_file_wrapper(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval *argv = JS_ARGV(ctx, rval); + JSString *jsstr = JS_ValueToString(smjs_ctx, *argv); +- unsigned char *path = JS_GetStringBytes(jsstr); ++ unsigned char *path = JS_EncodeString(smjs_ctx, jsstr); + + if (smjs_do_file(path)) + return JS_TRUE; +@@ -136,6 +136,9 @@ init_smjs(struct module *module) + return; + } + ++ JS_SetOptions(smjs_ctx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT); ++ JS_SetVersion(smjs_ctx, JSVERSION_LATEST); ++ + JS_SetErrorReporter(smjs_ctx, error_reporter); + + smjs_init_global_object(); +@@ -308,7 +311,7 @@ jsstring_to_utf8(JSContext *ctx, JSString *jsstr, int *length) + struct string utf8; + + utf16_len = JS_GetStringLength(jsstr); +- utf16 = JS_GetStringChars(jsstr); /* stays owned by jsstr */ ++ utf16 = JS_GetStringCharsZ(ctx, jsstr); /* stays owned by jsstr */ + if (utf16 == NULL) { + /* JS_GetStringChars doesn't have a JSContext * + * parameter so it can't report the error +diff --git a/src/scripting/smjs/elinks_object.c b/src/scripting/smjs/elinks_object.c +index 5a9b394..3c51ec9 100644 +--- a/src/scripting/smjs/elinks_object.c ++++ b/src/scripting/smjs/elinks_object.c +@@ -27,7 +27,7 @@ + + + static JSBool +-elinks_get_home(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++elinks_get_home(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, elinks_home)); + +@@ -35,7 +35,7 @@ elinks_get_home(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + } + + static JSBool +-elinks_get_location(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++elinks_get_location(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + struct uri *uri; + +@@ -51,7 +51,7 @@ elinks_get_location(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + } + + static JSBool +-elinks_set_location(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++elinks_set_location(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + JSString *jsstr; + unsigned char *url; +@@ -61,7 +61,7 @@ elinks_set_location(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + jsstr = JS_ValueToString(smjs_ctx, *vp); + if (!jsstr) return JS_FALSE; + +- url = JS_GetStringBytes(jsstr); ++ url = JS_EncodeString(smjs_ctx, jsstr); + if (!url) return JS_FALSE; + + goto_url(smjs_ses, url); +@@ -71,8 +71,10 @@ elinks_set_location(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @elinks_funcs{"alert"} */ + static JSBool +-elinks_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++elinks_alert(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval val; ++ jsval *argv = JS_ARGV(ctx, rval); + unsigned char *string; + + if (argc != 1) +@@ -85,15 +87,18 @@ elinks_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval + info_box(smjs_ses->tab->term, MSGBOX_NO_TEXT_INTL, + N_("User script alert"), ALIGN_LEFT, string); + +- undef_to_jsval(ctx, rval); ++ undef_to_jsval(ctx, &val); ++ JS_SET_RVAL(ctx, rval, val); + + return JS_TRUE; + } + + /* @elinks_funcs{"execute"} */ + static JSBool +-elinks_execute(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++elinks_execute(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval val; ++ jsval *argv = JS_ARGV(ctx, rval); + unsigned char *string; + + if (argc != 1) +@@ -104,8 +109,9 @@ elinks_execute(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rv + return JS_TRUE; + + exec_on_terminal(smjs_ses->tab->term, string, "", TERM_EXEC_BG); +- undef_to_jsval(ctx, rval); + ++ undef_to_jsval(ctx, &val); ++ JS_SET_RVAL(ctx, rval, val); + return JS_TRUE; + } + +@@ -113,7 +119,7 @@ static const JSClass elinks_class = { + "elinks", + 0, + JS_PropertyStub, JS_PropertyStub, +- JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub + }; + +@@ -142,7 +148,7 @@ smjs_get_elinks_object(void) + return NULL; + + if (!JS_DefineProperty(smjs_ctx, jsobj, "home", JSVAL_NULL, +- elinks_get_home, JS_PropertyStub, ++ elinks_get_home, JS_StrictPropertyStub, + JSPROP_ENUMERATE + | JSPROP_PERMANENT + | JSPROP_READONLY)) +diff --git a/src/scripting/smjs/global_object.c b/src/scripting/smjs/global_object.c +index 3a59782..0976f8a 100644 +--- a/src/scripting/smjs/global_object.c ++++ b/src/scripting/smjs/global_object.c +@@ -16,9 +16,9 @@ JSObject *smjs_global_object; + + + static const JSClass global_class = { +- "global", 0, +- JS_PropertyStub, JS_PropertyStub, ++ "global", JSCLASS_GLOBAL_FLAGS, + JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub + }; + +@@ -29,7 +29,7 @@ smjs_get_global_object(void) + + assert(smjs_ctx); + +- jsobj = JS_NewObject(smjs_ctx, (JSClass *) &global_class, NULL, NULL); ++ jsobj = JS_NewCompartmentAndGlobalObject(smjs_ctx, (JSClass *) &global_class, NULL); + + if (!jsobj) return NULL; + +diff --git a/src/scripting/smjs/globhist.c b/src/scripting/smjs/globhist.c +index 0ab6938..376c44e 100644 +--- a/src/scripting/smjs/globhist.c ++++ b/src/scripting/smjs/globhist.c +@@ -51,7 +51,7 @@ static const JSPropertySpec smjs_globhist_item_props[] = { + + /* @smjs_globhist_item_class.getProperty */ + static JSBool +-smjs_globhist_item_get_property(JSContext *ctx, JSObject *obj, jsval id, ++smjs_globhist_item_get_property(JSContext *ctx, JSObject *obj, jsid id, + jsval *vp) + { + struct global_history_item *history_item; +@@ -70,10 +70,10 @@ smjs_globhist_item_get_property(JSContext *ctx, JSObject *obj, jsval id, + + undef_to_jsval(ctx, vp); + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_FALSE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case GLOBHIST_TITLE: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, + history_item->title)); +@@ -117,7 +117,7 @@ smjs_globhist_item_get_property(JSContext *ctx, JSObject *obj, jsval id, + + /* @smjs_globhist_item_class.setProperty */ + static JSBool +-smjs_globhist_item_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++smjs_globhist_item_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + struct global_history_item *history_item; + +@@ -133,13 +133,13 @@ smjs_globhist_item_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval * + + if (!history_item) return JS_FALSE; + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_FALSE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case GLOBHIST_TITLE: { + JSString *jsstr = JS_ValueToString(smjs_ctx, *vp); +- unsigned char *str = JS_GetStringBytes(jsstr); ++ unsigned char *str = JS_EncodeString(smjs_ctx, jsstr); + + mem_free_set(&history_item->title, stracpy(str)); + +@@ -147,7 +147,7 @@ smjs_globhist_item_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval * + } + case GLOBHIST_URL: { + JSString *jsstr = JS_ValueToString(smjs_ctx, *vp); +- unsigned char *str = JS_GetStringBytes(jsstr); ++ unsigned char *str = JS_EncodeString(smjs_ctx, jsstr); + + mem_free_set(&history_item->url, stracpy(str)); + +@@ -201,13 +201,13 @@ smjs_get_globhist_item_object(struct global_history_item *history_item) + + /* @smjs_globhist_class.getProperty */ + static JSBool +-smjs_globhist_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++smjs_globhist_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + JSObject *jsobj; + unsigned char *uri_string; + struct global_history_item *history_item; + +- uri_string = JS_GetStringBytes(JS_ValueToString(ctx, id)); ++ uri_string = JS_EncodeString(ctx, JS_ValueToString(ctx, id)); + if (!uri_string) goto ret_null; + + history_item = get_global_history_item(uri_string); +@@ -229,7 +229,7 @@ ret_null: + static const JSClass smjs_globhist_class = { + "global_history", 0, + JS_PropertyStub, JS_PropertyStub, +- smjs_globhist_get_property, JS_PropertyStub, ++ smjs_globhist_get_property, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + }; + +diff --git a/src/scripting/smjs/hooks.c b/src/scripting/smjs/hooks.c +index 291039c..d69daf6 100644 +--- a/src/scripting/smjs/hooks.c ++++ b/src/scripting/smjs/hooks.c +@@ -41,7 +41,7 @@ script_hook_url(va_list ap, void *data) + ret = EVENT_HOOK_STATUS_LAST; + } else { + JSString *jsstr = JS_ValueToString(smjs_ctx, rval); +- unsigned char *str = JS_GetStringBytes(jsstr); ++ unsigned char *str = JS_EncodeString(smjs_ctx, jsstr); + + mem_free_set(url, stracpy(str)); + } +@@ -58,7 +58,7 @@ script_hook_pre_format_html(va_list ap, void *data) + struct session *ses = va_arg(ap, struct session *); + struct cache_entry *cached = va_arg(ap, struct cache_entry *); + enum evhook_status ret = EVENT_HOOK_STATUS_NEXT; +- JSObject *cache_entry_object, *view_state_object = JSVAL_NULL; ++ JSObject *cache_entry_object, *view_state_object = NULL; + jsval args[2], rval; + + evhook_use_params(ses && cached); +diff --git a/src/scripting/smjs/keybinding.c b/src/scripting/smjs/keybinding.c +index 2b35477..b452298 100644 +--- a/src/scripting/smjs/keybinding.c ++++ b/src/scripting/smjs/keybinding.c +@@ -17,7 +17,7 @@ static const JSClass keymap_class; /* defined below */ + + /* @keymap_class.getProperty */ + static JSBool +-keymap_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++keymap_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + unsigned char *action_str; + const unsigned char *keystroke_str; +@@ -32,7 +32,7 @@ keymap_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + data = JS_GetInstancePrivate(ctx, obj, + (JSClass *) &keymap_class, NULL); + +- keystroke_str = JS_GetStringBytes(JS_ValueToString(ctx, id)); ++ keystroke_str = JS_EncodeString(ctx, JS_ValueToString(ctx, id)); + if (!keystroke_str) goto ret_null; + + action_str = get_action_name_from_keystroke((enum keymap_id) *data, +@@ -70,7 +70,7 @@ smjs_keybinding_action_callback(va_list ap, void *data) + + /* @keymap_class.setProperty */ + static JSBool +-keymap_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++keymap_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + int *data; + unsigned char *keymap_str; +@@ -90,13 +90,13 @@ keymap_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + keymap_str = get_keymap_name((enum keymap_id) *data); + if (!keymap_str) return JS_FALSE; + +- keystroke_str = JS_GetStringBytes(JS_ValueToString(ctx, id)); ++ keystroke_str = JS_EncodeString(ctx, JS_ValueToString(ctx, id)); + if (!keystroke_str) return JS_FALSE; + + if (JSVAL_IS_STRING(*vp)) { + unsigned char *action_str; + +- action_str = JS_GetStringBytes(JS_ValueToString(ctx, *vp)); ++ action_str = JS_EncodeString(ctx, JS_ValueToString(ctx, *vp)); + if (!action_str) return JS_FALSE; + + if (bind_do(keymap_str, keystroke_str, action_str, 0)) +@@ -203,7 +203,7 @@ static const JSClass keymaps_hash_class = { + "keymaps_hash", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, +- JS_PropertyStub, JS_PropertyStub, ++ JS_PropertyStub, JS_StrictPropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + }; + +diff --git a/src/scripting/smjs/load_uri.c b/src/scripting/smjs/load_uri.c +index 4f2dcf2..7e3881c 100644 +--- a/src/scripting/smjs/load_uri.c ++++ b/src/scripting/smjs/load_uri.c +@@ -56,7 +56,7 @@ smjs_loading_callback(struct download *download, void *data) + end: + if (download->cached) + object_unlock(download->cached); +- JS_RemoveRoot(smjs_ctx, &hop->callback); ++ JS_RemoveValueRoot(smjs_ctx, &hop->callback); + mem_free(download->data); + mem_free(download); + +@@ -64,9 +64,9 @@ end: + } + + static JSBool +-smjs_load_uri(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, +- jsval *rval) ++smjs_load_uri(JSContext *ctx, uintN argc, jsval *rval) + { ++ jsval *argv = JS_ARGV(ctx, rval); + struct smjs_load_uri_hop *hop; + struct download *download; + JSString *jsstr; +@@ -76,7 +76,7 @@ smjs_load_uri(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, + if (argc < 2) return JS_FALSE; + + jsstr = JS_ValueToString(smjs_ctx, argv[0]); +- uri_string = JS_GetStringBytes(jsstr); ++ uri_string = JS_EncodeString(smjs_ctx, jsstr); + + uri = get_uri(uri_string, 0); + if (!uri) return JS_FALSE; +@@ -96,7 +96,7 @@ smjs_load_uri(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, + + hop->callback = argv[1]; + hop->ses = smjs_ses; +- if (!JS_AddNamedRoot(smjs_ctx, &hop->callback, ++ if (!JS_AddNamedValueRoot(smjs_ctx, &hop->callback, + "smjs_load_uri_hop.callback")) { + mem_free(hop); + mem_free(download); +diff --git a/src/scripting/smjs/view_state_object.c b/src/scripting/smjs/view_state_object.c +index 64f43ca..636b37b 100644 +--- a/src/scripting/smjs/view_state_object.c ++++ b/src/scripting/smjs/view_state_object.c +@@ -39,7 +39,7 @@ static const JSPropertySpec view_state_props[] = { + + /* @view_state_class.getProperty */ + static JSBool +-view_state_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++view_state_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + struct view_state *vs; + +@@ -54,10 +54,10 @@ view_state_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + undef_to_jsval(ctx, vp); + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_FALSE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case VIEW_STATE_PLAIN: + *vp = INT_TO_JSVAL(vs->plain); + +@@ -80,7 +80,7 @@ view_state_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + + /* @view_state_class.setProperty */ + static JSBool +-view_state_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++view_state_set_property(JSContext *ctx, JSObject *obj, jsid id, JSBool strict, jsval *vp) + { + struct view_state *vs; + +@@ -93,10 +93,10 @@ view_state_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) + vs = JS_GetInstancePrivate(ctx, obj, + (JSClass *) &view_state_class, NULL); + +- if (!JSVAL_IS_INT(id)) ++ if (!JSID_IS_INT(id)) + return JS_FALSE; + +- switch (JSVAL_TO_INT(id)) { ++ switch (JSID_TO_INT(id)) { + case VIEW_STATE_PLAIN: { + vs->plain = atol(jsval_to_string(ctx, vp)); + +@@ -143,7 +143,7 @@ smjs_get_view_state_object(struct view_state *vs) + } + + static JSBool +-smjs_elinks_get_view_state(JSContext *ctx, JSObject *obj, jsval id, jsval *vp) ++smjs_elinks_get_view_state(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) + { + JSObject *vs_obj; + struct view_state *vs; +@@ -170,6 +170,6 @@ smjs_init_view_state_interface(void) + return; + + JS_DefineProperty(smjs_ctx, smjs_elinks_object, "vs", JSVAL_NULL, +- smjs_elinks_get_view_state, JS_PropertyStub, ++ smjs_elinks_get_view_state, JS_StrictPropertyStub, + JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY); + } +-- +1.7.4.2 + diff --git a/elinks-0.12_pre5-js185-3-histback.patch b/elinks-0.12_pre5-js185-3-histback.patch new file mode 100644 index 0000000..902aa85 --- /dev/null +++ b/elinks-0.12_pre5-js185-3-histback.patch @@ -0,0 +1,57 @@ +From 32109054ce40067b8c55837fb69f1bc1249e38fd Mon Sep 17 00:00:00 2001 +From: witekfl +Date: Mon, 25 Apr 2011 21:04:03 +0200 +Subject: [PATCH 3/3] SpiderMonkey: fix issue with javascript:history.back() + +In history.back() and others set rval to NULL. +Do not convert NULL to string in spidermoney_eval_stringback. + +Signed-off-by: Kamil Dudka +--- + src/ecmascript/spidermonkey.c | 2 +- + src/ecmascript/spidermonkey/location.c | 3 +++ + 2 files changed, 4 insertions(+), 1 deletions(-) + +diff --git a/src/ecmascript/spidermonkey.c b/src/ecmascript/spidermonkey.c +index 021e6bd..5360455 100644 +--- a/src/ecmascript/spidermonkey.c ++++ b/src/ecmascript/spidermonkey.c +@@ -303,7 +303,7 @@ spidermonkey_eval_stringback(struct ecmascript_interpreter *interpreter, + if (ret == JS_FALSE) { + return NULL; + } +- if (JSVAL_IS_VOID(rval)) { ++ if (JSVAL_IS_VOID(rval) || JSVAL_IS_NULL(rval)) { + /* Undefined value. */ + return NULL; + } +diff --git a/src/ecmascript/spidermonkey/location.c b/src/ecmascript/spidermonkey/location.c +index 752a890..d1fbdfb 100644 +--- a/src/ecmascript/spidermonkey/location.c ++++ b/src/ecmascript/spidermonkey/location.c +@@ -78,6 +78,7 @@ history_back(JSContext *ctx, uintN argc, jsval *rval) + * and return non zero for to prevent + * "calculating" new link. Returned value 2 is changed to 0 in function + * spidermonkey_eval_boolback */ ++ JS_SET_RVAL(ctx, rval, JSVAL_NULL); + return 2; + } + +@@ -91,6 +92,7 @@ history_forward(JSContext *ctx, uintN argc, jsval *rval) + + go_unback(ses); + ++ JS_SET_RVAL(ctx, rval, JSVAL_NULL); + return 2; + } + +@@ -121,6 +123,7 @@ history_go(JSContext *ctx, uintN argc, jsval *rval) + index += index > 0 ? -1 : 1; + } + ++ JS_SET_RVAL(ctx, rval, JSVAL_NULL); + return 2; + } + +-- +1.7.4.4 diff --git a/elinks.changes b/elinks.changes index 65d5692..f37302f 100644 --- a/elinks.changes +++ b/elinks.changes @@ -1,3 +1,30 @@ +------------------------------------------------------------------- +Sun Jun 10 17:19:18 UTC 2012 - asterios.dramis@gmail.com + +- Updated License to GPL-2.0. +- Added the following patches: + * elinks-0.12_pre5-js185-1-heartbeat.patch, + elinks-0.12_pre5-js185-2-up.patch, + elinks-0.12_pre5-js185-3-histback.patch: Support for new js-1.8.5 + * elinks-0.12_pre5-compilation-fix.patch: Fix compilation with gc + * use_lua-5.1.patch: Support for lua-5.1 +- Added automake in BuildRequires in order to regenerate the build system + because of patches modifying configure.in. +- Corrected gmp-devel build dependency to gpm-devel. +- Removed guile-devel build dependency (wasn't used anyway and the support is + expiremental). +- Removed python-devel build dependency since the support is expiremental. +- Use ruby-devel only in openSUSE <= 12.1 since it fails with ruby 1.9 from + Factory. +- Added the following build dependencies that can be used by the package: + gc-devel (for openSUSE > 11.4), js-devel (for openSUSE > 11.4), krb5-devel, + lua*-devel, pkg-config and tre-devel. +- Make the package provide "web_browser", similar to other web browser + packages. +- Removed build time references so build-compare can do its work. +- Enabled the following build options: true-color and fastmem. +- Install documentation only for the scripting languages that are compiled. + ------------------------------------------------------------------- Fri Jun 10 12:54:28 UTC 2011 - lijewski.stefan@gmail.com diff --git a/elinks.spec b/elinks.spec index 4262219..5e4832a 100644 --- a/elinks.spec +++ b/elinks.spec @@ -1,27 +1,67 @@ # +# spec file for package elinks +# +# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + +%define pkg_version 0.12pre5 + Name: elinks Version: 0.11.995 Release: 0 -%define pkg_version 0.12pre5 -# -License: GPL -# +License: GPL-2.0 Summary: An advanced and well-established feature-rich text mode web browser -# Url: http://elinks.or.cz/ Group: Productivity/Networking/Web/Browsers -Source: http://elinks.or.cz/download/elinks-%{pkg_version}.tar.bz2 -BuildRequires: gmp-devel -BuildRequires: guile-devel +Source0: http://elinks.or.cz/download/%{name}-%{pkg_version}.tar.bz2 +# PATCH-FIX-UPSTREAM elinks-0.12_pre5-js185-1-heartbeat.patch asterios.dramis@gmail.com -- Support for new js-1.8.5 (patch taken from Gentoo) +Patch0: elinks-0.12_pre5-js185-1-heartbeat.patch +# PATCH-FIX-UPSTREAM elinks-0.12_pre5-js185-2-up.patch asterios.dramis@gmail.com -- Support for new js-1.8.5 (patch taken from Gentoo) +Patch1: elinks-0.12_pre5-js185-2-up.patch +# PATCH-FIX-UPSTREAM elinks-0.12_pre5-js185-3-histback.patch asterios.dramis@gmail.com -- Support for new js-1.8.5 (patch taken from Gentoo) +Patch2: elinks-0.12_pre5-js185-3-histback.patch +# PATCH-FIX-UPSTREAM elinks-0.12_pre5-compilation-fix.patch asterios.dramis@gmail.com -- Fix compilation with gc (patch taken from Gentoo) +Patch3: elinks-0.12_pre5-compilation-fix.patch +# PATCH-FIX-UPSTREAM use_lua-5.1.patch asterios.dramis@gmail.com -- Support for lua-5.1 (based on patch from Debian) +Patch4: use_lua-5.1.patch +BuildRequires: automake +%if 0%{?suse_version} > 1140 +BuildRequires: gc-devel +%endif +BuildRequires: gpm-devel +%if 0%{?suse_version} > 1140 +BuildRequires: js-devel +%endif +BuildRequires: krb5-devel BuildRequires: libbz2-devel BuildRequires: libexpat-devel BuildRequires: libidn-devel +%if 0%{?suse_version} > 1210 +BuildRequires: lua51-devel +%else +BuildRequires: lua-devel +%endif BuildRequires: openssl-devel -BuildRequires: python-devel +BuildRequires: pkg-config +%if 0%{?suse_version} && 0%{?suse_version} <= 1210 BuildRequires: ruby-devel +%endif +BuildRequires: tre-devel BuildRequires: zlib-devel -# +Provides: web_browser BuildRoot: %{_tmppath}/%{name}-%{version}-build + %description ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks can render both frames and tables, is highly @@ -30,61 +70,94 @@ and runs on a variety of platforms. Check the about page for a more complete description. %prep -%setup -n elinks-%{pkg_version} +%setup -q -n %{name}-%{pkg_version} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 + +# Remove build time references so build-compare can do its work +FAKE_BUILDTIME=$(LC_ALL=C date -u -r %{_sourcedir}/%{name}.changes '+%%H:%%M') +FAKE_BUILDDATE=$(LC_ALL=C date -u -r %{_sourcedir}/%{name}.changes '+%%b %%e %%Y') +sed -i "s/__TIME__/\"$FAKE_BUILDTIME\"/" src/vernum.c +sed -i "s/__DATE__/\"$FAKE_BUILDDATE\"/" src/vernum.c %build -#./autogen.sh -export CFLAGS="%{optflags} -fstack-protector -I/usr/include/js/" -export LIBS="-lm" # for spidermonkey +# Regenerate build system because of patches modifying configure.in +autoreconf -vif +export CFLAGS="%{optflags} -fstack-protector" %configure \ - --sysconfdir=/etc/elinks \ - --enable-nntp \ + --sysconfdir=%{_sysconfdir}/elinks \ + --enable-bittorrent \ --enable-cgi \ - --enable-gopher \ --enable-finger \ - --enable-exmode \ - --enable-html-highlight \ + --disable-fsp \ + --enable-gopher \ + --enable-nntp \ + --disable-smb \ --enable-88-colors \ --enable-256-colors \ - --enable-leds \ - --with-idn \ - --without-lua \ - --with-perl \ - --with-ruby \ - --without-guile \ - --with-python \ - --without-see \ + --enable-true-color \ + --enable-exmode \ + --enable-html-highlight \ + --enable-fastmem \ --with-xterm \ - --enable-bittorrent -make +%if 0%{?suse_version} > 1140 + --with-gc \ +%else + --without-gc \ +%endif + --without-lzma \ + --with-gssapi \ + --without-see \ + --without-guile \ + --with-perl \ + --without-python \ + --with-lua \ +%if 0%{?suse_version} && 0%{?suse_version} <= 1210 + --with-ruby \ +%else + --without-ruby \ +%endif + --without-gnutls \ + --without-x +make %{?_smp_mflags} %install %make_install -rm -f %{buildroot}%{_datadir}/locale/locale.alias -%find_lang %{name} -# -%define _pkgdocdir %{buildroot}%{_docdir}/%{name} -install -Dd -m 0755 %{_pkgdocdir}/scripts -cp -r \ - ABOUT-NLS AUTHORS BUGS ChangeLog COPYING INSTALL NEWS README \ - features.* SITES THANKS TODO doc/*.txt doc/html \ - contrib/*.conf contrib/*.vim contrib/*.css contrib/TIPS-AND-TRICKS \ - %{_pkgdocdir} -install -m 0644 contrib/wipe-out-ssl* contrib/conv/* \ - %{_pkgdocdir}/scripts/ -for lang in perl python guile ruby lua ; do - install -Dd -m 0755 %{_pkgdocdir}/${lang} - install -m 0644 contrib/${lang}/* \ - %{_pkgdocdir}/${lang}/ -done -%clean -rm -rf %{buildroot}; +# Remove unneeded file +rm -f %{buildroot}%{_datadir}/locale/locale.alias + +%find_lang %{name} + +# Install documentation +%define _pkgdocdir %{buildroot}%{_docdir}/%{name} +install -Dd -m 0755 %{_pkgdocdir} +install -pm 0644 AUTHORS BUGS COPYING ChangeLog NEWS README SITES THANKS TODO features.conf %{_pkgdocdir} +cp -a doc/ %{_pkgdocdir} +rm -rf %{_pkgdocdir}/doc/{.deps/,.gitignore,Doxyfile.in,Makefile,man/,tools/} +install -Dd -m 0755 %{_pkgdocdir}/contrib/ +install -pm 0644 contrib/*.conf contrib/*.vim contrib/*.css contrib/TIPS-AND-TRICKS %{_pkgdocdir}/contrib/ +install -Dd -m 0755 %{_pkgdocdir}/scripts/ +install -pm 0644 contrib/wipe-out-ssl* contrib/conv/* %{_pkgdocdir}/scripts/ +rm -f %{_pkgdocdir}/scripts/conv/.gitignore +# Install only the languages that are compiled +for lang in lua perl smjs; do + install -Dd -m 0755 %{_pkgdocdir}/${lang} + install -pm 0644 contrib/${lang}/* %{_pkgdocdir}/${lang} +done +rm -f %{_pkgdocdir}/lua/.gitignore +%if 0%{?suse_version} && 0%{?suse_version} <= 1210 +cp -a contrib/ruby %{_pkgdocdir}/ +%endif %files -f %{name}.lang -%defattr(-,root,root) +%defattr(-,root,root,-) %{_bindir}/%{name} -%{_mandir}/man?/%{name}* -%doc %{_docdir}/%{name} +%doc %{_docdir}/%{name}/ +%{_mandir}/man1/%{name}.1%{ext_man} +%{_mandir}/man5/%{name}*.5%{ext_man} %changelog diff --git a/use_lua-5.1.patch b/use_lua-5.1.patch new file mode 100644 index 0000000..3942ce0 --- /dev/null +++ b/use_lua-5.1.patch @@ -0,0 +1,61 @@ +--- configure.in.orig 2009-07-07 15:23:17.000000000 +0300 ++++ configure.in 2012-06-10 15:47:58.962180590 +0300 +@@ -884,11 +884,11 @@ + withval=""; + fi + for luadir in "$withval" "" /usr /usr/local; do +- for suffix in "" 50; do ++ for suffix in "" 50 51; do + if test "$cf_result" = no && ( test -f "$luadir/include/lua.h" || \ + test -f "$luadir/include/lua$suffix/lua.h" ) ; then +- LUA_LIBS="-L$luadir/lib -llua$suffix -llualib$suffix -lm" +- LUA_CFLAGS="-I$luadir/include -I$luadir/include/lua$suffix" ++ LUA_LIBS=`pkg-config --libs lua` ++ LUA_CFLAGS=`pkg-config --cflags lua` + + LIBS="$LUA_LIBS $LIBS_X" + CFLAGS="$CFLAGS_X $LUA_CFLAGS" +--- src/scripting/lua/core.c.orig 2009-07-07 15:23:17.000000000 +0300 ++++ src/scripting/lua/core.c 2012-06-10 14:20:57.215111234 +0300 +@@ -658,7 +658,7 @@ + if (file_can_read(file)) { + int oldtop = lua_gettop(S); + +- if (lua_dofile(S, file) != 0) ++ if (luaL_dofile(S, file) != 0) + sleep(3); /* Let some time to see error messages. */ + lua_settop(S, oldtop); + } +@@ -671,11 +671,7 @@ + { + L = lua_open(); + +- luaopen_base(L); +- luaopen_table(L); +- luaopen_io(L); +- luaopen_string(L); +- luaopen_math(L); ++ luaL_openlibs(L); + + lua_register(L, LUA_ALERT, l_alert); + lua_register(L, "current_url", l_current_url); +@@ -780,7 +776,7 @@ + int oldtop = lua_gettop(L); + + if (prepare_lua(ses) == 0) { +- lua_dostring(L, expr); ++ (void) luaL_dostring(L, expr); + lua_settop(L, oldtop); + finish_lua(); + } +--- src/scripting/lua/hooks.c.orig 2009-07-07 15:23:17.000000000 +0300 ++++ src/scripting/lua/hooks.c 2012-06-10 14:21:26.216351680 +0300 +@@ -200,7 +200,7 @@ + script_hook_quit(va_list ap, void *data) + { + if (!prepare_lua(NULL)) { +- lua_dostring(lua_state, "if quit_hook then quit_hook() end"); ++ (void) luaL_dostring(lua_state, "if quit_hook then quit_hook() end"); + finish_lua(); + } +