1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

1031: Replace smjs_rt with spidermonkey_runtime

src/scripting/smjs/ now uses a JSRuntime managed by spidermonkey-shared.c.
This commit is contained in:
Kalle Olavi Niemitalo 2008-07-16 14:23:19 +03:00 committed by Kalle Olavi Niemitalo
parent 32889bf908
commit 2024ea610b
3 changed files with 65 additions and 11 deletions

View File

@ -9,6 +9,54 @@
#include "ecmascript/spidermonkey-shared.h"
/** A shared runtime used for both user scripts (scripting/smjs/) and
* scripts on web pages (ecmascript/spidermonkey/).
*
* SpiderMonkey has bugs that corrupt memory when multiple JSRuntimes
* are used: https://bugzilla.mozilla.org/show_bug.cgi?id=378918 and
* perhaps others. */
JSRuntime *spidermonkey_runtime;
/** 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;
/** Add a reference to ::spidermonkey_runtime, and initialize it if
* that is the first reference.
* @return 1 if successful or 0 on error. If this succeeds, the
* caller must eventually call spidermonkey_runtime_release(). */
int
spidermonkey_runtime_addref(void)
{
if (!spidermonkey_runtime) {
assert(spidermonkey_runtime_refcount == 0);
if_assert_failed return 0;
spidermonkey_runtime = JS_NewRuntime(1L * 1024L * 1024L);
if (!spidermonkey_runtime) return 0;
}
spidermonkey_runtime_refcount++;
assert(spidermonkey_runtime_refcount > 0);
if_assert_failed { spidermonkey_runtime_refcount--; return 0; }
return 1;
}
/** Release a reference to ::spidermonkey_runtime, and destroy it if
* that was the last reference. If spidermonkey_runtime_addref()
* failed, then this must not be called. */
void
spidermonkey_runtime_release(void)
{
assert(spidermonkey_runtime_refcount > 0);
assert(spidermonkey_runtime);
if_assert_failed return;
--spidermonkey_runtime_refcount;
if (spidermonkey_runtime_refcount == 0) {
JS_DestroyRuntime(spidermonkey_runtime);
spidermonkey_runtime = NULL;
}
}
/** An ELinks-specific replacement for JS_DefineFunctions().
*
* @relates spidermonkeyFunctionSpec */

View File

@ -24,6 +24,10 @@
#include "util/string.h"
extern JSRuntime *spidermonkey_runtime;
int spidermonkey_runtime_addref(void);
void spidermonkey_runtime_release(void);
/** An ELinks-specific replacement for JSFunctionSpec.
*
* Bug 1016: In SpiderMonkey 1.7 bundled with XULRunner 1.8, jsapi.h

View File

@ -68,8 +68,6 @@ reported:
JS_ClearPendingException(ctx);
}
static JSRuntime *smjs_rt;
static int
smjs_do_file(unsigned char *path)
{
@ -127,13 +125,11 @@ smjs_load_hooks(void)
void
init_smjs(struct module *module)
{
smjs_rt = JS_NewRuntime(1L * 1024L * 1024L);
if (!smjs_rt) return;
if (!spidermonkey_runtime_addref()) return;
smjs_ctx = JS_NewContext(smjs_rt, 8192);
smjs_ctx = JS_NewContext(spidermonkey_runtime, 8192);
if (!smjs_ctx) {
JS_DestroyRuntime(smjs_rt);
smjs_rt = NULL;
spidermonkey_runtime_release();
return;
}
@ -154,9 +150,15 @@ cleanup_smjs(struct module *module)
{
if (!smjs_ctx) return;
/* These calls also finalize all JSObjects that have been
* allocated in the JSRuntime, so cache_entry_finalize gets
* called and resets each cache_entry.jsobject = NULL. */
/* JS_DestroyContext also collects garbage in the JSRuntime.
* Because the JSObjects created in smjs_ctx have not been
* made visible to any other JSContext, and the garbage
* collector of SpiderMonkey is precise, SpiderMonkey
* finalizes all of those objects, so cache_entry_finalize
* gets called and resets each cache_entry.jsobject = NULL.
* If the garbage collector were conservative, ELinks would
* have to call smjs_detach_cache_entry_object on each cache
* entry before it releases the runtime here. */
JS_DestroyContext(smjs_ctx);
JS_DestroyRuntime(smjs_rt);
spidermonkey_runtime_release();
}