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:
parent
32889bf908
commit
2024ea610b
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user