From 8ad7d68b280fbfca2a65270d53c5cdc79c8c11ca Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Wed, 28 Oct 2020 22:32:20 +0100 Subject: [PATCH] [js] Small progress. It segfaults less often, but still, especially on non utf-8 pages. And sometimes it did not work. --- src/ecmascript/ecmascript.h | 1 + src/ecmascript/spidermonkey-shared.c | 16 ++++++--- src/ecmascript/spidermonkey-shared.h | 2 +- src/ecmascript/spidermonkey.c | 43 +++++++++++++++++-------- src/ecmascript/spidermonkey/document.c | 11 +++++-- src/ecmascript/spidermonkey/heartbeat.c | 9 +++++- src/ecmascript/spidermonkey/location.c | 26 +++++++++++++-- src/ecmascript/spidermonkey/window.c | 11 +++++-- 8 files changed, 93 insertions(+), 26 deletions(-) diff --git a/src/ecmascript/ecmascript.h b/src/ecmascript/ecmascript.h index 0f2a3421..7f08d1b4 100644 --- a/src/ecmascript/ecmascript.h +++ b/src/ecmascript/ecmascript.h @@ -54,6 +54,7 @@ struct ecmascript_interpreter { * to redraw. */ unsigned int onload_snippets_cache_id; void *ac; + void *ar; }; /* Why is the interpreter bound to {struct view_state} instead of {struct diff --git a/src/ecmascript/spidermonkey-shared.c b/src/ecmascript/spidermonkey-shared.c index b65f239c..84dd3e5c 100644 --- a/src/ecmascript/spidermonkey-shared.c +++ b/src/ecmascript/spidermonkey-shared.c @@ -15,7 +15,8 @@ - * object, so scripts cannot be evaluated in it. - */ -JSContext *spidermonkey_empty_context; +JSContext *main_ctx; + /** A reference count for ::spidermonkey_runtime so that modules using * it can be initialized and shut down in arbitrary order. */ static int spidermonkey_runtime_refcount; @@ -34,8 +35,15 @@ spidermonkey_runtime_addref(void) return 0; } - spidermonkey_empty_context = JS_NewContext(0); - if (!spidermonkey_empty_context) { + main_ctx = JS_NewContext(16 * 1024 * 1024); + + if (!main_ctx) { + JS_ShutDown(); + return 0; + } + + if (!JS::InitSelfHostedCode(main_ctx)) { + JS_DestroyContext(main_ctx); JS_ShutDown(); return 0; } @@ -57,7 +65,7 @@ spidermonkey_runtime_release(void) --spidermonkey_runtime_refcount; if (spidermonkey_runtime_refcount == 0) { - JS_DestroyContext(spidermonkey_empty_context); + JS_DestroyContext(main_ctx); JS_ShutDown(); } } diff --git a/src/ecmascript/spidermonkey-shared.h b/src/ecmascript/spidermonkey-shared.h index ee3fbae9..e6f9d47f 100644 --- a/src/ecmascript/spidermonkey-shared.h +++ b/src/ecmascript/spidermonkey-shared.h @@ -24,7 +24,7 @@ #include "util/string.h" extern JSRuntime *spidermonkey_runtime; -extern JSContext *spidermonkey_empty_context; +extern JSContext *main_ctx; int spidermonkey_runtime_addref(void); void spidermonkey_runtime_release(void); diff --git a/src/ecmascript/spidermonkey.c b/src/ecmascript/spidermonkey.c index 7ab712a4..960fb673 100644 --- a/src/ecmascript/spidermonkey.c +++ b/src/ecmascript/spidermonkey.c @@ -141,7 +141,14 @@ PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult, static void error_reporter(JSContext *ctx, JSErrorReport *report) { - struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); + JSCompartment *comp = js::GetContextCompartment(ctx); + + if (!comp) { + return; + } + + struct ecmascript_interpreter *interpreter = JS_GetCompartmentPrivate(comp); +// struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); struct session *ses = interpreter->vs->doc_view->session; struct terminal *term; unsigned char *strict, *exception, *warning, *error; @@ -229,25 +236,28 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter) JSObject *document_obj, *forms_obj, *history_obj, *location_obj, *statusbar_obj, *menubar_obj, *navigator_obj; + static int initialized = 0; + assert(interpreter); if (!js_module_init_ok) return NULL; -// ctx = JS_NewContext(JS::DefaultHeapMaxBytes, JS::DefaultNurseryBytes); - ctx = JS_NewContext(8L * 1024 * 1024); - if (!ctx) - return NULL; + ctx = main_ctx; + + if (!ctx) { + return nullptr; + } + interpreter->backend_data = ctx; - JSAutoRequest ar(ctx); - JS_SetContextPrivate(ctx, interpreter); - //JS_SetOptions(ctx, JSOPTION_VAROBJFIX | JS_METHODJIT); + interpreter->ar = new JSAutoRequest(ctx); + //JSAutoRequest ar(ctx); + +// JS_SetContextPrivate(ctx, interpreter); + + //JS_SetOptions(main_ctx, JSOPTION_VAROBJFIX | JS_METHODJIT); JS::SetWarningReporter(ctx, error_reporter); JS_AddInterruptCallback(ctx, heartbeat_callback); JS::CompartmentOptions options; - if (!JS::InitSelfHostedCode(ctx)) { - return NULL; - } - JS::RootedObject window_obj(ctx, JS_NewGlobalObject(ctx, &window_class, NULL, JS::FireOnNewGlobalHook, options)); if (window_obj) { @@ -338,6 +348,8 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter) } // JS_SetPrivate(navigator_obj, interpreter->vs); + JS_SetCompartmentPrivate(js::GetContextCompartment(ctx), interpreter); + return ctx; release_and_fail: @@ -352,13 +364,18 @@ spidermonkey_put_interpreter(struct ecmascript_interpreter *interpreter) assert(interpreter); if (!js_module_init_ok) return; + ctx = interpreter->backend_data; if (interpreter->ac) { delete (JSAutoCompartment *)interpreter->ac; } - JS_DestroyContext(ctx); + if (interpreter->ar) { + delete (JSAutoRequest *)interpreter->ar; + } +// JS_DestroyContext(ctx); interpreter->backend_data = NULL; interpreter->ac = nullptr; + interpreter->ar = nullptr; } diff --git a/src/ecmascript/spidermonkey/document.c b/src/ecmascript/spidermonkey/document.c index fe5bf51c..86b332bf 100644 --- a/src/ecmascript/spidermonkey/document.c +++ b/src/ecmascript/spidermonkey/document.c @@ -267,7 +267,7 @@ document_set_property_title(JSContext *ctx, int argc, JS::Value *vp) vs = JS_GetInstancePrivate(ctx, hobj, &document_class, NULL); - if (!vs) { + if (!vs || !vs->doc_view) { return false; } doc_view = vs->doc_view; @@ -401,8 +401,15 @@ const spidermonkeyFunctionSpec document_funcs[] = { static bool document_write_do(JSContext *ctx, unsigned int argc, JS::Value *rval, int newline) { + JSCompartment *comp = js::GetContextCompartment(ctx); + + if (!comp) { + return false; + } + + struct ecmascript_interpreter *interpreter = JS_GetCompartmentPrivate(comp); JS::Value val; - struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); +// struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); struct string *ret = interpreter->ret; JS::CallArgs args = JS::CallArgsFromVp(argc, rval); diff --git a/src/ecmascript/spidermonkey/heartbeat.c b/src/ecmascript/spidermonkey/heartbeat.c index 65383bf5..099881f4 100644 --- a/src/ecmascript/spidermonkey/heartbeat.c +++ b/src/ecmascript/spidermonkey/heartbeat.c @@ -36,7 +36,14 @@ static struct itimerval heartbeat_timer = { { 1, 0 }, { 1, 0 } }; bool heartbeat_callback(JSContext *ctx) { - struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); + JSCompartment *comp = js::GetContextCompartment(ctx); + + if (!comp) { + return true; + } + + struct ecmascript_interpreter *interpreter = JS_GetCompartmentPrivate(comp); +// struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); if (!interpreter->heartbeat || interpreter->heartbeat->ttl > 0) { return true; diff --git a/src/ecmascript/spidermonkey/location.c b/src/ecmascript/spidermonkey/location.c index 48827afa..10ee9e22 100644 --- a/src/ecmascript/spidermonkey/location.c +++ b/src/ecmascript/spidermonkey/location.c @@ -73,7 +73,13 @@ const spidermonkeyFunctionSpec history_funcs[] = { static bool history_back(JSContext *ctx, unsigned int argc, JS::Value *rval) { - struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); + JSCompartment *comp = js::GetContextCompartment(ctx); + + if (!comp) { + return false; + } + + struct ecmascript_interpreter *interpreter = JS_GetCompartmentPrivate(comp); struct document_view *doc_view = interpreter->vs->doc_view; struct session *ses = doc_view->session; JS::CallArgs args = JS::CallArgsFromVp(argc, rval); @@ -92,7 +98,14 @@ history_back(JSContext *ctx, unsigned int argc, JS::Value *rval) static bool history_forward(JSContext *ctx, unsigned int argc, JS::Value *rval) { - struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); + JSCompartment *comp = js::GetContextCompartment(ctx); + + if (!comp) { + return false; + } + + struct ecmascript_interpreter *interpreter = JS_GetCompartmentPrivate(comp); +// struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); struct document_view *doc_view = interpreter->vs->doc_view; struct session *ses = doc_view->session; JS::CallArgs args = JS::CallArgsFromVp(argc, rval); @@ -107,7 +120,14 @@ history_forward(JSContext *ctx, unsigned int argc, JS::Value *rval) static bool history_go(JSContext *ctx, unsigned int argc, JS::Value *rval) { - struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); + JSCompartment *comp = js::GetContextCompartment(ctx); + + if (!comp) { + return false; + } + + struct ecmascript_interpreter *interpreter = JS_GetCompartmentPrivate(comp); +// struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); struct document_view *doc_view = interpreter->vs->doc_view; struct session *ses = doc_view->session; JS::CallArgs args = JS::CallArgsFromVp(argc, rval); diff --git a/src/ecmascript/spidermonkey/window.c b/src/ecmascript/spidermonkey/window.c index 1279e231..8f4f3bda 100644 --- a/src/ecmascript/spidermonkey/window.c +++ b/src/ecmascript/spidermonkey/window.c @@ -427,9 +427,16 @@ end: static bool window_setTimeout(JSContext *ctx, unsigned int argc, JS::Value *rval) { + JSCompartment *comp = js::GetContextCompartment(ctx); + + if (!comp) { + return false; + } + + struct ecmascript_interpreter *interpreter = JS_GetCompartmentPrivate(comp); + JS::CallArgs args = JS::CallArgsFromVp(argc, rval); -// JS::Value *argv = JS_ARGV(ctx, rval); - struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); +// struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx); unsigned char *code; int timeout;