mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
[mozjs52] It compiles, but often segfaults. No idea yet how to fix it.
This commit is contained in:
parent
a5b68a25a1
commit
d1ecd45828
@ -612,11 +612,11 @@ case "$with_spidermonkey" in
|
||||
;;
|
||||
esac
|
||||
|
||||
for package in mozjs-45; do
|
||||
for package in mozjs-52; do
|
||||
if test -n "$CONFIG_SPIDERMONKEY"; then
|
||||
break
|
||||
else
|
||||
AC_MSG_CHECKING([for SpiderMonkey (mozjs-45) in pkg-config $package])
|
||||
AC_MSG_CHECKING([for SpiderMonkey (mozjs-52) in pkg-config $package])
|
||||
if $PKG_CONFIG --cflags --libs $package > /dev/null 2>&AS_MESSAGE_LOG_FD; then
|
||||
SPIDERMONKEY_LIBS="$($PKG_CONFIG --libs $package)"
|
||||
SPIDERMONKEY_CFLAGS="$($PKG_CONFIG --cflags $package)"
|
||||
|
@ -271,7 +271,7 @@ if conf_data.get('CONFIG_BZIP2')
|
||||
endif
|
||||
|
||||
if conf_data.get('CONFIG_ECMASCRIPT')
|
||||
mozjsdeps = dependency('mozjs-45')
|
||||
mozjsdeps = dependency('mozjs-52')
|
||||
deps += mozjsdeps
|
||||
endif
|
||||
|
||||
|
@ -232,7 +232,7 @@ get_resource_info(struct terminal *term, void *data)
|
||||
val_add(n_("%ld refreshing", "%ld refreshing", val, term));
|
||||
add_to_string(&info, ".\n");
|
||||
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
add_to_string(&info, _("ECMAScript", term));
|
||||
add_to_string(&info, ": ");
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "viewer/text/vs.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
/** @todo XXX: This function is de facto obsolete, since we do not need to copy
|
||||
* snippets around anymore (we process them in one go after the document is
|
||||
* loaded; gradual processing was practically impossible because the snippets
|
||||
@ -331,7 +331,7 @@ render_document(struct view_state *vs, struct document_view *doc_view,
|
||||
vs->doc_view->used = 0; /* A bit risky, but... */
|
||||
vs->doc_view->vs = NULL;
|
||||
vs->doc_view = NULL;
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
vs->ecmascript_fragile = 1; /* And is this good? ;-) */
|
||||
#endif
|
||||
}
|
||||
@ -385,7 +385,7 @@ render_document(struct view_state *vs, struct document_view *doc_view,
|
||||
document->css_magic = get_document_css_magic(document);
|
||||
#endif
|
||||
}
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
if (!vs->ecmascript_fragile)
|
||||
assert(vs->ecmascript);
|
||||
if (!options->dump && !options->gradual_rerendering) {
|
||||
|
@ -4,7 +4,7 @@ INCLUDES += $(SPIDERMONKEY_CFLAGS)
|
||||
|
||||
SUBDIRS-$(CONFIG_ECMASCRIPT_SMJS) += spidermonkey
|
||||
|
||||
OBJS-$(CONFIG_ECMASCRIPT_SMJS) += spidermonkey.o
|
||||
OBJS-$(CONFIG_ECMASCRIPT_SMJS) += ecmascript.o spidermonkey.o
|
||||
|
||||
ifeq ($(CONFIG_ECMASCRIPT_SMJS), yes)
|
||||
CONFIG_ANY_SPIDERMONKEY = yes
|
||||
@ -16,6 +16,4 @@ endif
|
||||
|
||||
OBJS-$(CONFIG_ANY_SPIDERMONKEY) += spidermonkey-shared.o
|
||||
|
||||
OBJS = ecmascript.o
|
||||
|
||||
include $(top_srcdir)/Makefile.lib
|
||||
|
@ -5,6 +5,7 @@
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "elinks.h"
|
||||
|
||||
|
@ -53,6 +53,7 @@ struct ecmascript_interpreter {
|
||||
* is reloaded in another tab and then you just cause the current tab
|
||||
* to redraw. */
|
||||
unsigned int onload_snippets_cache_id;
|
||||
void *ac;
|
||||
};
|
||||
|
||||
/* Why is the interpreter bound to {struct view_state} instead of {struct
|
||||
|
@ -1,7 +1,7 @@
|
||||
#INCLUDES += $(SPIDERMONKEY_CFLAGS)
|
||||
if conf_data.get('CONFIG_ECMASCRIPT_SMJS')
|
||||
subdir('spidermonkey')
|
||||
srcs += files('spidermonkey.c')
|
||||
srcs += files('ecmascript.c', 'spidermonkey.c')
|
||||
endif
|
||||
|
||||
if conf_data.get('CONFIG_ECMASCRIPT_SMJS')
|
||||
@ -16,4 +16,3 @@ if CONFIG_ANY_SPIDERMONKEY
|
||||
srcs += files('spidermonkey-shared.c', 'empty.cpp')
|
||||
endif
|
||||
|
||||
srcs += files('ecmascript.c')
|
||||
|
@ -10,24 +10,12 @@
|
||||
#include "ecmascript/spidermonkey-shared.h"
|
||||
#include <js/Initialization.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 JSContext that can be used in JS_SetPrivate and JS_GetPrivate
|
||||
* when no better one is available. This context has no global
|
||||
* object, so scripts cannot be evaluated in it.
|
||||
*
|
||||
* XXX: This also works around a crash on exit. SMJS will crash on
|
||||
* JS_DestroyRuntime if the given runtime has never had any context
|
||||
* created, which will be the case if one closes ELinks without having
|
||||
* loaded any documents. */
|
||||
JSContext *spidermonkey_empty_context;
|
||||
- * when no better one is available. This context has no global
|
||||
- * object, so scripts cannot be evaluated in it.
|
||||
- */
|
||||
|
||||
JSContext *spidermonkey_empty_context;
|
||||
/** 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;
|
||||
@ -41,32 +29,18 @@ int
|
||||
spidermonkey_runtime_addref(void)
|
||||
{
|
||||
if (spidermonkey_runtime_refcount == 0) {
|
||||
assert(spidermonkey_runtime == NULL);
|
||||
assert(spidermonkey_empty_context == NULL);
|
||||
if_assert_failed return 0;
|
||||
|
||||
if (!JS_Init()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
spidermonkey_runtime = JS_NewRuntime(4L * 1024L * 1024L);
|
||||
if (!spidermonkey_runtime) return 0;
|
||||
|
||||
spidermonkey_empty_context = JS_NewContext(spidermonkey_runtime,
|
||||
0);
|
||||
spidermonkey_empty_context = JS_NewContext(0);
|
||||
if (!spidermonkey_empty_context) {
|
||||
/* Perhaps JS_DestroyRuntime will now crash
|
||||
* because no context was created, but there's
|
||||
* not much else to do. */
|
||||
JS_DestroyRuntime(spidermonkey_runtime);
|
||||
spidermonkey_runtime = NULL;
|
||||
JS_ShutDown();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
assert(spidermonkey_runtime);
|
||||
assert(spidermonkey_empty_context);
|
||||
spidermonkey_runtime_refcount++;
|
||||
assert(spidermonkey_runtime_refcount > 0);
|
||||
if_assert_failed { spidermonkey_runtime_refcount--; return 0; }
|
||||
@ -80,16 +54,10 @@ void
|
||||
spidermonkey_runtime_release(void)
|
||||
{
|
||||
assert(spidermonkey_runtime_refcount > 0);
|
||||
assert(spidermonkey_runtime);
|
||||
assert(spidermonkey_empty_context);
|
||||
if_assert_failed return;
|
||||
|
||||
--spidermonkey_runtime_refcount;
|
||||
if (spidermonkey_runtime_refcount == 0) {
|
||||
JS_DestroyContext(spidermonkey_empty_context);
|
||||
spidermonkey_empty_context = NULL;
|
||||
JS_DestroyRuntime(spidermonkey_runtime);
|
||||
spidermonkey_runtime = NULL;
|
||||
JS_ShutDown();
|
||||
}
|
||||
}
|
||||
|
@ -58,8 +58,88 @@
|
||||
|
||||
static int js_module_init_ok;
|
||||
|
||||
bool
|
||||
PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
|
||||
JSErrorReport* report, bool reportWarnings)
|
||||
{
|
||||
MOZ_ASSERT(report);
|
||||
|
||||
/* Conditionally ignore reported warnings. */
|
||||
if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
|
||||
return false;
|
||||
|
||||
char* prefix = nullptr;
|
||||
if (report->filename)
|
||||
prefix = JS_smprintf("%s:", report->filename);
|
||||
if (report->lineno) {
|
||||
char* tmp = prefix;
|
||||
prefix = JS_smprintf("%s%u:%u ", tmp ? tmp : "", report->lineno, report->column);
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
if (JSREPORT_IS_WARNING(report->flags)) {
|
||||
char* tmp = prefix;
|
||||
prefix = JS_smprintf("%s%swarning: ",
|
||||
tmp ? tmp : "",
|
||||
JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
|
||||
const char* message = toStringResult ? toStringResult.c_str() : report->message().c_str();
|
||||
|
||||
/* embedded newlines -- argh! */
|
||||
const char* ctmp;
|
||||
while ((ctmp = strchr(message, '\n')) != 0) {
|
||||
ctmp++;
|
||||
if (prefix)
|
||||
fputs(prefix, file);
|
||||
fwrite(message, 1, ctmp - message, file);
|
||||
message = ctmp;
|
||||
}
|
||||
|
||||
/* If there were no filename or lineno, the prefix might be empty */
|
||||
if (prefix)
|
||||
fputs(prefix, file);
|
||||
fputs(message, file);
|
||||
|
||||
if (const char16_t* linebuf = report->linebuf()) {
|
||||
size_t n = report->linebufLength();
|
||||
|
||||
fputs(":\n", file);
|
||||
if (prefix)
|
||||
fputs(prefix, file);
|
||||
|
||||
for (size_t i = 0; i < n; i++)
|
||||
fputc(static_cast<char>(linebuf[i]), file);
|
||||
|
||||
// linebuf usually ends with a newline. If not, add one here.
|
||||
if (n == 0 || linebuf[n-1] != '\n')
|
||||
fputc('\n', file);
|
||||
|
||||
if (prefix)
|
||||
fputs(prefix, file);
|
||||
|
||||
n = report->tokenOffset();
|
||||
for (size_t i = 0, j = 0; i < n; i++) {
|
||||
if (linebuf[i] == '\t') {
|
||||
for (size_t k = (j + 8) & ~7; j < k; j++)
|
||||
fputc('.', file);
|
||||
continue;
|
||||
}
|
||||
fputc('.', file);
|
||||
j++;
|
||||
}
|
||||
fputc('^', file);
|
||||
}
|
||||
fputc('\n', file);
|
||||
fflush(file);
|
||||
JS_free(cx, prefix);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
error_reporter(JSContext *ctx, const char *message, JSErrorReport *report)
|
||||
error_reporter(JSContext *ctx, JSErrorReport *report)
|
||||
{
|
||||
struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
|
||||
struct session *ses = interpreter->vs->doc_view->session;
|
||||
@ -75,6 +155,8 @@ error_reporter(JSContext *ctx, const char *message, JSErrorReport *report)
|
||||
|
||||
term = ses->tab->term;
|
||||
|
||||
PrintError(ctx, stderr, JS::ConstUTF8CharsZ(), report, true/*reportWarnings*/);
|
||||
|
||||
#ifdef CONFIG_LEDS
|
||||
set_led_value(ses->status.ecmascript_led, 'J');
|
||||
#endif
|
||||
@ -93,7 +175,6 @@ error_reporter(JSContext *ctx, const char *message, JSErrorReport *report)
|
||||
strict, exception, warning, error);
|
||||
|
||||
add_to_string(&msg, ":\n\n");
|
||||
add_to_string(&msg, message);
|
||||
|
||||
if (report->filename) {
|
||||
prefix = JS_smprintf("%s:", report->filename);
|
||||
@ -147,25 +228,30 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter)
|
||||
JSContext *ctx;
|
||||
JSObject *document_obj, *forms_obj, *history_obj, *location_obj,
|
||||
*statusbar_obj, *menubar_obj, *navigator_obj;
|
||||
JSAutoCompartment *ac = NULL;
|
||||
|
||||
assert(interpreter);
|
||||
if (!js_module_init_ok) return NULL;
|
||||
|
||||
ctx = JS_NewContext(spidermonkey_runtime,
|
||||
8192 /* Stack allocation chunk size */);
|
||||
// ctx = JS_NewContext(JS::DefaultHeapMaxBytes, JS::DefaultNurseryBytes);
|
||||
ctx = JS_NewContext(8L * 1024 * 1024);
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
interpreter->backend_data = ctx;
|
||||
JSAutoRequest ar(ctx);
|
||||
JS_SetContextPrivate(ctx, interpreter);
|
||||
//JS_SetOptions(ctx, JSOPTION_VAROBJFIX | JS_METHODJIT);
|
||||
JS_SetErrorReporter(spidermonkey_runtime, error_reporter);
|
||||
JS_SetInterruptCallback(spidermonkey_runtime, heartbeat_callback);
|
||||
JS::RootedObject window_obj(ctx, JS_NewGlobalObject(ctx, &window_class, NULL, JS::DontFireOnNewGlobalHook));
|
||||
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) {
|
||||
ac = new JSAutoCompartment(ctx, window_obj);
|
||||
interpreter->ac = new JSAutoCompartment(ctx, window_obj);
|
||||
} else {
|
||||
goto release_and_fail;
|
||||
}
|
||||
@ -191,6 +277,7 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter)
|
||||
if (!document_obj) {
|
||||
goto release_and_fail;
|
||||
}
|
||||
JS_SetPrivate(document_obj, interpreter->vs);
|
||||
|
||||
forms_obj = spidermonkey_InitClass(ctx, document_obj, NULL,
|
||||
&forms_class, NULL, 0,
|
||||
@ -266,8 +353,12 @@ 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);
|
||||
interpreter->backend_data = NULL;
|
||||
interpreter->ac = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,13 +50,18 @@
|
||||
|
||||
static bool document_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
|
||||
JSClassOps document_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
document_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
|
||||
/* Each @document_class object must have a @window_class parent. */
|
||||
JSClass document_class = {
|
||||
"document",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, nullptr,
|
||||
document_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr
|
||||
&document_ops
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COOKIES
|
||||
@ -249,16 +254,19 @@ document_set_property_title(JSContext *ctx, int argc, JS::Value *vp)
|
||||
{
|
||||
JS::CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JS::RootedObject hobj(ctx, &args.thisv().toObject());
|
||||
JS::RootedObject parent_win(ctx, js::GetGlobalForObjectCrossCompartment(hobj));
|
||||
// JS::RootedObject parent_win(ctx, js::GetGlobalForObjectCrossCompartment(hobj));
|
||||
struct view_state *vs;
|
||||
struct document_view *doc_view;
|
||||
struct document *document;
|
||||
|
||||
assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
assert(JS_InstanceOf(ctx, hobj, &document_class, NULL));
|
||||
if_assert_failed return false;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
&window_class, NULL);
|
||||
// assert(JS_InstanceOf(ctx, parent_win, &window_class, NULL));
|
||||
// if_assert_failed return false;
|
||||
|
||||
vs = JS_GetInstancePrivate(ctx, hobj,
|
||||
&document_class, NULL);
|
||||
if (!vs) {
|
||||
return false;
|
||||
}
|
||||
|
@ -66,13 +66,17 @@ static bool form_set_property_target(JSContext *ctx, unsigned int argc, JS::Valu
|
||||
|
||||
static void form_finalize(JSFreeOp *op, JSObject *obj);
|
||||
|
||||
static JSClassOps form_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
form_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, form_finalize
|
||||
};
|
||||
|
||||
/* Each @form_class object must have a @document_class parent. */
|
||||
static JSClass form_class = {
|
||||
"form",
|
||||
JSCLASS_HAS_PRIVATE, /* struct form_view *, or NULL if detached */
|
||||
JS_PropertyStub, nullptr,
|
||||
form_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, form_finalize
|
||||
&form_ops
|
||||
};
|
||||
|
||||
|
||||
@ -86,13 +90,17 @@ static bool input_get_property(JSContext *ctx, JS::HandleObject hobj, JS::Handle
|
||||
static bool input_set_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
static void input_finalize(JSFreeOp *op, JSObject *obj);
|
||||
|
||||
static JSClassOps input_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
input_get_property, input_set_property,
|
||||
nullptr, nullptr, nullptr, input_finalize
|
||||
};
|
||||
|
||||
/* Each @input_class object must have a @form_class parent. */
|
||||
static JSClass input_class = {
|
||||
"input", /* here, we unleash ourselves */
|
||||
JSCLASS_HAS_PRIVATE, /* struct form_state *, or NULL if detached */
|
||||
JS_PropertyStub, nullptr,
|
||||
input_get_property, input_set_property,
|
||||
nullptr, nullptr, nullptr, input_finalize
|
||||
&input_ops
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
@ -264,7 +272,7 @@ input_set_property_accessKey(JSContext *ctx, unsigned int argc, JS::Value *vp)
|
||||
}
|
||||
}
|
||||
if (accesskey == UCS_NO_CHAR) {
|
||||
JS_ReportError(ctx, "Invalid UTF-16 sequence");
|
||||
JS_ReportErrorUTF8(ctx, "Invalid UTF-16 sequence");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1890,7 +1898,7 @@ spidermonkey_detach_form_state(struct form_state *fs)
|
||||
JSObject *jsinput = fs->ecmascript_obj;
|
||||
|
||||
if (jsinput) {
|
||||
JS::RootedObject r_jsinput(spidermonkey_empty_context, jsinput);
|
||||
// JS::RootedObject r_jsinput(spidermonkey_empty_context, jsinput);
|
||||
/* This assumes JS_GetInstancePrivate and JS_SetPrivate
|
||||
* cannot GC. */
|
||||
|
||||
@ -1898,12 +1906,12 @@ spidermonkey_detach_form_state(struct form_state *fs)
|
||||
* the private pointer of jsinput should be reset;
|
||||
* crashes seem possible either way. Resetting it is
|
||||
* easiest. */
|
||||
assert(JS_GetInstancePrivate(spidermonkey_empty_context,
|
||||
r_jsinput,
|
||||
&input_class, NULL)
|
||||
== fs);
|
||||
if_assert_failed {}
|
||||
|
||||
// assert(JS_GetInstancePrivate(spidermonkey_empty_context,
|
||||
// r_jsinput,
|
||||
// &input_class, NULL)
|
||||
// == fs);
|
||||
// if_assert_failed {}
|
||||
//
|
||||
JS_SetPrivate(jsinput, NULL);
|
||||
fs->ecmascript_obj = NULL;
|
||||
}
|
||||
@ -1957,13 +1965,17 @@ get_form_control_object(JSContext *ctx,
|
||||
static struct form_view *form_get_form_view(JSContext *ctx, JSObject *jsform, JS::Value *argv);
|
||||
static bool form_elements_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
|
||||
static JSClassOps form_elements_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
form_elements_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
/* Each @form_elements_class object must have a @form_class parent. */
|
||||
static JSClass form_elements_class = {
|
||||
"elements",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, nullptr,
|
||||
form_elements_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
&form_elements_ops
|
||||
};
|
||||
|
||||
static bool form_elements_item2(JSContext *ctx, JS::HandleObject hobj, int index, JS::MutableHandleValue hvp);
|
||||
@ -3113,7 +3125,7 @@ spidermonkey_detach_form_view(struct form_view *fv)
|
||||
JSObject *jsform = fv->ecmascript_obj;
|
||||
|
||||
if (jsform) {
|
||||
JS::RootedObject r_jsform(spidermonkey_empty_context, jsform);
|
||||
// JS::RootedObject r_jsform(spidermonkey_empty_context, jsform);
|
||||
/* This assumes JS_GetInstancePrivate and JS_SetPrivate
|
||||
* cannot GC. */
|
||||
|
||||
@ -3121,11 +3133,11 @@ spidermonkey_detach_form_view(struct form_view *fv)
|
||||
* the private pointer of jsform should be reset;
|
||||
* crashes seem possible either way. Resetting it is
|
||||
* easiest. */
|
||||
assert(JS_GetInstancePrivate(spidermonkey_empty_context,
|
||||
r_jsform,
|
||||
&form_class, NULL)
|
||||
== fv);
|
||||
if_assert_failed {}
|
||||
// assert(JS_GetInstancePrivate(spidermonkey_empty_context,
|
||||
// r_jsform,
|
||||
// &form_class, NULL)
|
||||
// == fv);
|
||||
// if_assert_failed {}
|
||||
|
||||
JS_SetPrivate(jsform, NULL);
|
||||
fv->ecmascript_obj = NULL;
|
||||
@ -3136,13 +3148,17 @@ spidermonkey_detach_form_view(struct form_view *fv)
|
||||
static bool forms_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
static bool forms_get_property_length(JSContext *ctx, unsigned int argc, JS::Value *vp);
|
||||
|
||||
JSClassOps forms_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
forms_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
/* Each @forms_class object must have a @document_class parent. */
|
||||
JSClass forms_class = {
|
||||
"forms",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, nullptr,
|
||||
forms_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
&forms_ops
|
||||
};
|
||||
|
||||
static bool forms_item(JSContext *ctx, unsigned int argc, JS::Value *rval);
|
||||
@ -3415,6 +3431,6 @@ jsval_to_accesskey(JSContext *ctx, JS::MutableHandleValue hvp)
|
||||
return join_utf16_surrogates(chr[0], chr[1]);
|
||||
}
|
||||
}
|
||||
JS_ReportError(ctx, "Invalid UTF-16 sequence");
|
||||
JS_ReportErrorUTF8(ctx, "Invalid UTF-16 sequence");
|
||||
return UCS_NO_CHAR; /* which the caller will reject */
|
||||
}
|
||||
|
@ -36,6 +36,11 @@ static struct itimerval heartbeat_timer = { { 1, 0 }, { 1, 0 } };
|
||||
bool
|
||||
heartbeat_callback(JSContext *ctx)
|
||||
{
|
||||
struct ecmascript_interpreter *interpreter = JS_GetContextPrivate(ctx);
|
||||
|
||||
if (!interpreter->heartbeat || interpreter->heartbeat->ttl > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -63,7 +68,7 @@ check_heartbeats(void *data)
|
||||
|
||||
ecmascript_timeout_dialog(term, max_exec_time);
|
||||
}
|
||||
JS_RequestInterruptCallback(JS_GetRuntime(hb->interpreter->backend_data));
|
||||
JS_RequestInterruptCallback(hb->interpreter->backend_data);
|
||||
}
|
||||
}
|
||||
install_signal_handler(SIGVTALRM, check_heartbeats, NULL, 1);
|
||||
|
@ -50,14 +50,18 @@ static bool history_back(JSContext *ctx, unsigned int argc, JS::Value *rval);
|
||||
static bool history_forward(JSContext *ctx, unsigned int argc, JS::Value *rval);
|
||||
static bool history_go(JSContext *ctx, unsigned int argc, JS::Value *rval);
|
||||
|
||||
JSClass history_class = {
|
||||
"history",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JSClassOps history_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
JSClass history_class = {
|
||||
"history",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
&history_ops
|
||||
};
|
||||
|
||||
const spidermonkeyFunctionSpec history_funcs[] = {
|
||||
{ "back", history_back, 0 },
|
||||
{ "forward", history_forward, 0 },
|
||||
@ -134,13 +138,16 @@ history_go(JSContext *ctx, unsigned int argc, JS::Value *rval)
|
||||
static bool location_get_property_href(JSContext *ctx, unsigned int argc, JS::Value *vp);
|
||||
static bool location_set_property_href(JSContext *ctx, unsigned int argc, JS::Value *vp);
|
||||
|
||||
JSClassOps location_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
/* Each @location_class object must have a @window_class parent. */
|
||||
JSClass location_class = {
|
||||
"location",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
&location_ops
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
|
@ -51,14 +51,18 @@ static bool navigator_get_property_language(JSContext *ctx, unsigned int argc, J
|
||||
static bool navigator_get_property_platform(JSContext *ctx, unsigned int argc, JS::Value *vp);
|
||||
static bool navigator_get_property_userAgent(JSContext *ctx, unsigned int argc, JS::Value *vp);
|
||||
|
||||
JSClass navigator_class = {
|
||||
"navigator",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JSClassOps navigator_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
JSClass navigator_class = {
|
||||
"navigator",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
&navigator_ops
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
* from array indexes (even though this object has no array elements).
|
||||
* ECMAScript code should not use these directly as in navigator[-1];
|
||||
|
@ -48,10 +48,20 @@
|
||||
static bool unibar_get_property_visible(JSContext *ctx, unsigned int argc, JS::Value *vp);
|
||||
static bool unibar_set_property_visible(JSContext *ctx, unsigned int argc, JS::Value *vp);
|
||||
|
||||
JSClassOps menubar_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
/* Each @menubar_class object must have a @window_class parent. */
|
||||
JSClass menubar_class = {
|
||||
"menubar",
|
||||
JSCLASS_HAS_PRIVATE, /* const char * "t" */
|
||||
&menubar_ops
|
||||
};
|
||||
|
||||
JSClassOps statusbar_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
@ -60,9 +70,7 @@ JSClass menubar_class = {
|
||||
JSClass statusbar_class = {
|
||||
"statusbar",
|
||||
JSCLASS_HAS_PRIVATE, /* const char * "s" */
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
&statusbar_ops
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
|
@ -53,14 +53,18 @@ static bool window_get_property_status(JSContext *ctx, unsigned int argc, JS::Va
|
||||
static bool window_set_property_status(JSContext *ctx, unsigned int argc, JS::Value *vp);
|
||||
static bool window_get_property_top(JSContext *ctx, unsigned int argc, JS::Value *vp);
|
||||
|
||||
JSClass window_class = {
|
||||
"window",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_GLOBAL_FLAGS, /* struct view_state * */
|
||||
JSClassOps window_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
window_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
JSClass window_class = {
|
||||
"window",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_GLOBAL_FLAGS, /* struct view_state * */
|
||||
&window_ops
|
||||
};
|
||||
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
* from array indexes (even though this object has no array elements).
|
||||
@ -440,6 +444,7 @@ window_setTimeout(JSContext *ctx, unsigned int argc, JS::Value *rval)
|
||||
if (!code)
|
||||
return true;
|
||||
timeout = args[1].toInt32();
|
||||
|
||||
if (timeout <= 0) {
|
||||
mem_free(code);
|
||||
return true;
|
||||
|
@ -60,7 +60,7 @@ struct module *builtin_modules[] = {
|
||||
#ifdef CONFIG_COOKIES
|
||||
&cookies_module,
|
||||
#endif
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
&ecmascript_module,
|
||||
#endif
|
||||
#ifdef CONFIG_FORMHIST
|
||||
|
@ -219,7 +219,7 @@ generic_external_protocol_handler(struct session *ses, struct uri *uri)
|
||||
|
||||
switch (uri->protocol) {
|
||||
case PROTOCOL_JAVASCRIPT:
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
ecmascript_protocol_handler(ses, uri);
|
||||
return;
|
||||
#else
|
||||
|
@ -26,9 +26,7 @@ struct smjs_action_fn_callback_hop {
|
||||
static void smjs_action_fn_finalize(JSFreeOp *op, JSObject *obj);
|
||||
static bool smjs_action_fn_callback(JSContext *ctx, unsigned int argc, JS::Value *rval);
|
||||
|
||||
static const JSClass action_fn_class = {
|
||||
"action_fn",
|
||||
JSCLASS_HAS_PRIVATE, /* struct smjs_action_fn_callback_hop * */
|
||||
static JSClassOps action_fn_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr,
|
||||
@ -37,6 +35,12 @@ static const JSClass action_fn_class = {
|
||||
smjs_action_fn_callback,
|
||||
};
|
||||
|
||||
static const JSClass action_fn_class = {
|
||||
"action_fn",
|
||||
JSCLASS_HAS_PRIVATE, /* struct smjs_action_fn_callback_hop * */
|
||||
&action_fn_ops
|
||||
};
|
||||
|
||||
/* @action_fn_class.finalize */
|
||||
static void
|
||||
smjs_action_fn_finalize(JSFreeOp *op, JSObject *obj)
|
||||
@ -104,7 +108,7 @@ smjs_action_fn_callback(JSContext *ctx, unsigned int argc, JS::Value *rval)
|
||||
*
|
||||
* The "%s" prevents interpretation of any percent
|
||||
* signs in translations. */
|
||||
JS_ReportError(ctx, "%s",
|
||||
JS_ReportErrorUTF8(ctx, "%s",
|
||||
_("Cannot run actions in a tab that doesn't "
|
||||
"have the focus", hop->ses->tab->term));
|
||||
return false; /* make JS propagate the exception */
|
||||
@ -183,14 +187,18 @@ action_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS:
|
||||
return true;
|
||||
}
|
||||
|
||||
static const JSClass action_class = {
|
||||
"action",
|
||||
0,
|
||||
static JSClassOps action_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
action_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr,
|
||||
};
|
||||
|
||||
static const JSClass action_class = {
|
||||
"action",
|
||||
0,
|
||||
&action_ops
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
smjs_get_action_object(void)
|
||||
{
|
||||
|
@ -20,20 +20,28 @@
|
||||
static void bookmark_finalize(JSFreeOp *op, JSObject *obj);
|
||||
static bool bookmark_folder_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
|
||||
static JSClassOps bookmark_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, bookmark_finalize,
|
||||
};
|
||||
|
||||
static const JSClass bookmark_class = {
|
||||
"bookmark",
|
||||
JSCLASS_HAS_PRIVATE, /* struct bookmark * */
|
||||
&bookmark_ops
|
||||
};
|
||||
|
||||
static JSClassOps bookmark_folder_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
bookmark_folder_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, bookmark_finalize,
|
||||
};
|
||||
|
||||
static const JSClass bookmark_folder_class = {
|
||||
"bookmark_folder",
|
||||
JSCLASS_HAS_PRIVATE, /* struct bookmark * */
|
||||
JS_PropertyStub, nullptr,
|
||||
bookmark_folder_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, bookmark_finalize,
|
||||
&bookmark_folder_ops
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
|
@ -17,14 +17,18 @@
|
||||
|
||||
static void cache_entry_finalize(JSFreeOp *op, JSObject *obj);
|
||||
|
||||
static const JSClass cache_entry_class = {
|
||||
"cache_entry",
|
||||
JSCLASS_HAS_PRIVATE, /* struct cache_entry *; a weak reference */
|
||||
static JSClassOps cache_entry_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, cache_entry_finalize
|
||||
};
|
||||
|
||||
static const JSClass cache_entry_class = {
|
||||
"cache_entry",
|
||||
JSCLASS_HAS_PRIVATE, /* struct cache_entry *; a weak reference */
|
||||
&cache_entry_ops
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
* from array indexes (even though this object has no array elements).
|
||||
* ECMAScript code should not use these directly as in cache_entry[-1];
|
||||
|
@ -37,8 +37,88 @@ alert_smjs_error(unsigned char *msg)
|
||||
smjs_ses, msg);
|
||||
}
|
||||
|
||||
static bool
|
||||
PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
|
||||
JSErrorReport* report, bool reportWarnings)
|
||||
{
|
||||
MOZ_ASSERT(report);
|
||||
|
||||
/* Conditionally ignore reported warnings. */
|
||||
if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
|
||||
return false;
|
||||
|
||||
char* prefix = nullptr;
|
||||
if (report->filename)
|
||||
prefix = JS_smprintf("%s:", report->filename);
|
||||
if (report->lineno) {
|
||||
char* tmp = prefix;
|
||||
prefix = JS_smprintf("%s%u:%u ", tmp ? tmp : "", report->lineno, report->column);
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
if (JSREPORT_IS_WARNING(report->flags)) {
|
||||
char* tmp = prefix;
|
||||
prefix = JS_smprintf("%s%swarning: ",
|
||||
tmp ? tmp : "",
|
||||
JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
|
||||
const char* message = toStringResult ? toStringResult.c_str() : report->message().c_str();
|
||||
|
||||
/* embedded newlines -- argh! */
|
||||
const char* ctmp;
|
||||
while ((ctmp = strchr(message, '\n')) != 0) {
|
||||
ctmp++;
|
||||
if (prefix)
|
||||
fputs(prefix, file);
|
||||
fwrite(message, 1, ctmp - message, file);
|
||||
message = ctmp;
|
||||
}
|
||||
|
||||
/* If there were no filename or lineno, the prefix might be empty */
|
||||
if (prefix)
|
||||
fputs(prefix, file);
|
||||
fputs(message, file);
|
||||
|
||||
if (const char16_t* linebuf = report->linebuf()) {
|
||||
size_t n = report->linebufLength();
|
||||
|
||||
fputs(":\n", file);
|
||||
if (prefix)
|
||||
fputs(prefix, file);
|
||||
|
||||
for (size_t i = 0; i < n; i++)
|
||||
fputc(static_cast<char>(linebuf[i]), file);
|
||||
|
||||
// linebuf usually ends with a newline. If not, add one here.
|
||||
if (n == 0 || linebuf[n-1] != '\n')
|
||||
fputc('\n', file);
|
||||
|
||||
if (prefix)
|
||||
fputs(prefix, file);
|
||||
|
||||
n = report->tokenOffset();
|
||||
for (size_t i = 0, j = 0; i < n; i++) {
|
||||
if (linebuf[i] == '\t') {
|
||||
for (size_t k = (j + 8) & ~7; j < k; j++)
|
||||
fputc('.', file);
|
||||
continue;
|
||||
}
|
||||
fputc('.', file);
|
||||
j++;
|
||||
}
|
||||
fputc('^', file);
|
||||
}
|
||||
fputc('\n', file);
|
||||
fflush(file);
|
||||
JS_free(cx, prefix);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
error_reporter(JSContext *ctx, const char *message, JSErrorReport *report)
|
||||
error_reporter(JSContext *ctx, JSErrorReport *report)
|
||||
{
|
||||
unsigned char *strict, *exception, *warning, *error;
|
||||
struct string msg;
|
||||
@ -51,11 +131,12 @@ error_reporter(JSContext *ctx, const char *message, JSErrorReport *report)
|
||||
warning = JSREPORT_IS_WARNING(report->flags) ? " warning" : "";
|
||||
error = !report->flags ? " error" : "";
|
||||
|
||||
PrintError(ctx, stderr, JS::ConstUTF8CharsZ(), report, true/*reportWarnings*/);
|
||||
|
||||
add_format_to_string(&msg, "A client script raised the following%s%s%s%s",
|
||||
strict, exception, warning, error);
|
||||
|
||||
add_to_string(&msg, ":\n\n");
|
||||
add_to_string(&msg, message);
|
||||
|
||||
add_format_to_string(&msg, "\n\n%d:%d ", report->lineno, report->column);
|
||||
|
||||
@ -153,13 +234,13 @@ init_smjs(struct module *module)
|
||||
{
|
||||
if (!spidermonkey_runtime_addref()) return;
|
||||
|
||||
smjs_ctx = JS_NewContext(spidermonkey_runtime, 8192);
|
||||
smjs_ctx = JS_NewContext(8L * 1024 * 1024);
|
||||
if (!smjs_ctx) {
|
||||
spidermonkey_runtime_release();
|
||||
return;
|
||||
}
|
||||
|
||||
JS_SetErrorReporter(spidermonkey_runtime, error_reporter);
|
||||
JS::SetWarningReporter(smjs_ctx, error_reporter);
|
||||
|
||||
smjs_init_global_object();
|
||||
|
||||
|
@ -108,14 +108,18 @@ static const JSPropertySpec elinks_props[] = {
|
||||
static bool elinks_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
static bool elinks_set_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
|
||||
static const JSClass elinks_class = {
|
||||
"elinks",
|
||||
0,
|
||||
static const JSClassOps elinks_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
elinks_get_property, elinks_set_property,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
static const JSClass elinks_class = {
|
||||
"elinks",
|
||||
0,
|
||||
&elinks_ops
|
||||
};
|
||||
|
||||
|
||||
/* @elinks_class.getProperty */
|
||||
static bool
|
||||
@ -263,15 +267,12 @@ smjs_invoke_elinks_object_method(unsigned char *method, int argc, JS::Value *arg
|
||||
assert(argv);
|
||||
|
||||
JS::RootedObject r_smjs_elinks_object(smjs_ctx, smjs_elinks_object);
|
||||
JS::Value val;
|
||||
JS::RootedValue fun(smjs_ctx, val);
|
||||
JS::RootedValue fun(smjs_ctx);
|
||||
|
||||
if (false == JS_GetProperty(smjs_ctx, r_smjs_elinks_object,
|
||||
method, &fun))
|
||||
return false;
|
||||
|
||||
if (rval.isUndefined())
|
||||
method, &fun)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JS_CallFunctionValue(smjs_ctx, r_smjs_elinks_object, fun, args, rval);
|
||||
}
|
||||
|
@ -15,14 +15,17 @@ using namespace JS;
|
||||
|
||||
JSObject *smjs_global_object;
|
||||
|
||||
|
||||
static const JSClass global_class = {
|
||||
"global", JSCLASS_GLOBAL_FLAGS,
|
||||
static const JSClassOps global_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
static const JSClass global_class = {
|
||||
"global", JSCLASS_GLOBAL_FLAGS,
|
||||
&global_ops
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
smjs_get_global_object(void)
|
||||
{
|
||||
@ -30,9 +33,13 @@ smjs_get_global_object(void)
|
||||
JSAutoCompartment *acc = NULL;
|
||||
|
||||
JSAutoRequest ar(smjs_ctx);
|
||||
RootedObject jsobj(smjs_ctx);
|
||||
JS::CompartmentOptions opts;
|
||||
|
||||
jsobj = JS_NewGlobalObject(smjs_ctx, (JSClass *) &global_class, NULL, JS::DontFireOnNewGlobalHook);
|
||||
if (!JS::InitSelfHostedCode(smjs_ctx)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS::RootedObject jsobj(smjs_ctx, JS_NewGlobalObject(smjs_ctx, (JSClass *) &global_class, NULL, JS::DontFireOnNewGlobalHook, opts));
|
||||
|
||||
if (!jsobj) return NULL;
|
||||
|
||||
|
@ -17,15 +17,19 @@ static bool smjs_globhist_item_set_property(JSContext *ctx, JS::HandleObject hob
|
||||
|
||||
static void smjs_globhist_item_finalize(JSFreeOp *op, JSObject *obj);
|
||||
|
||||
static const JSClass smjs_globhist_item_class = {
|
||||
"global_history_item",
|
||||
JSCLASS_HAS_PRIVATE, /* struct global_history_item * */
|
||||
static const JSClassOps smjs_globhist_item_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
smjs_globhist_item_get_property, smjs_globhist_item_set_property,
|
||||
nullptr, nullptr, nullptr,
|
||||
smjs_globhist_item_finalize,
|
||||
};
|
||||
|
||||
static const JSClass smjs_globhist_item_class = {
|
||||
"global_history_item",
|
||||
JSCLASS_HAS_PRIVATE, /* struct global_history_item * */
|
||||
&smjs_globhist_item_ops
|
||||
};
|
||||
|
||||
/* @smjs_globhist_item_class.finalize */
|
||||
static void
|
||||
smjs_globhist_item_finalize(JSFreeOp *op, JSObject *obj)
|
||||
@ -243,13 +247,17 @@ ret_null:
|
||||
return true;
|
||||
}
|
||||
|
||||
static const JSClass smjs_globhist_class = {
|
||||
"global_history", 0,
|
||||
static const JSClassOps smjs_globhist_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
smjs_globhist_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
static const JSClass smjs_globhist_class = {
|
||||
"global_history", 0,
|
||||
&smjs_globhist_ops
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
smjs_get_globhist_object(void)
|
||||
{
|
||||
|
@ -27,8 +27,8 @@ script_hook_url(va_list ap, void *data)
|
||||
unsigned char **url = va_arg(ap, unsigned char **);
|
||||
struct session *ses = va_arg(ap, struct session *);
|
||||
enum evhook_status ret = EVENT_HOOK_STATUS_NEXT;
|
||||
JS::Value args[3], rval;
|
||||
JS::RootedValue r_rval(smjs_ctx, rval);
|
||||
JS::Value args[3];
|
||||
JS::RootedValue r_rval(smjs_ctx);
|
||||
|
||||
if (*url == NULL) return EVENT_HOOK_STATUS_NEXT;
|
||||
|
||||
@ -59,12 +59,14 @@ script_hook_pre_format_html(va_list ap, void *data)
|
||||
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 = NULL;
|
||||
JS::Value args[4], rval;
|
||||
JS::RootedValue r_rval(smjs_ctx, rval);
|
||||
JS::Value args[4];
|
||||
JS::RootedValue r_rval(smjs_ctx);
|
||||
|
||||
evhook_use_params(ses && cached);
|
||||
|
||||
if (!smjs_ctx || !cached->length) goto end;
|
||||
if (!smjs_ctx || !cached->length) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
smjs_ses = ses;
|
||||
|
||||
@ -81,9 +83,10 @@ script_hook_pre_format_html(va_list ap, void *data)
|
||||
args[3].setObject(*view_state_object);
|
||||
|
||||
if (true == smjs_invoke_elinks_object_method("preformat_html",
|
||||
2, args, &r_rval))
|
||||
2, args, &r_rval)) {
|
||||
if (false == r_rval.toBoolean())
|
||||
ret = EVENT_HOOK_STATUS_LAST;
|
||||
}
|
||||
|
||||
end:
|
||||
smjs_ses = NULL;
|
||||
|
@ -17,14 +17,18 @@ static bool keymap_get_property(JSContext *ctx, JS::HandleObject hobj, JS::Handl
|
||||
static bool keymap_set_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
static void keymap_finalize(JSFreeOp *op, JSObject *obj);
|
||||
|
||||
static const JSClass keymap_class = {
|
||||
"keymap",
|
||||
JSCLASS_HAS_PRIVATE, /* int * */
|
||||
static const JSClassOps keymap_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
keymap_get_property, keymap_set_property,
|
||||
nullptr, nullptr, nullptr, keymap_finalize,
|
||||
};
|
||||
|
||||
static const JSClass keymap_class = {
|
||||
"keymap",
|
||||
JSCLASS_HAS_PRIVATE, /* int * */
|
||||
&keymap_ops
|
||||
};
|
||||
|
||||
/* @keymap_class.getProperty */
|
||||
static bool
|
||||
keymap_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp)
|
||||
@ -220,14 +224,18 @@ smjs_get_keymap_object(enum keymap_id keymap_id)
|
||||
return keymap_object;
|
||||
}
|
||||
|
||||
static const JSClass keymaps_hash_class = {
|
||||
"keymaps_hash",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
static const JSClassOps keymap_hash_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr,
|
||||
};
|
||||
|
||||
static const JSClass keymaps_hash_class = {
|
||||
"keymaps_hash",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
&keymap_hash_ops
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
smjs_get_keymap_hash_object(void)
|
||||
{
|
||||
|
@ -35,24 +35,32 @@ static bool session_set_property(JSContext *ctx, JS::HandleObject hobj, JS::Hand
|
||||
static void session_finalize(JSFreeOp *op, JSObject *obj);
|
||||
static bool session_construct(JSContext *ctx, unsigned int argc, JS::Value *rval);
|
||||
|
||||
static const JSClass session_class = {
|
||||
"session",
|
||||
JSCLASS_HAS_PRIVATE, /* struct session *; a weak reference */
|
||||
static const JSClassOps session_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
session_get_property, session_set_property,
|
||||
nullptr, nullptr, nullptr, session_finalize,
|
||||
NULL, NULL, NULL, session_construct
|
||||
};
|
||||
|
||||
static const JSClass session_class = {
|
||||
"session",
|
||||
JSCLASS_HAS_PRIVATE, /* struct session *; a weak reference */
|
||||
&session_ops
|
||||
};
|
||||
|
||||
static bool smjs_location_array_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
static void smjs_location_array_finalize(JSFreeOp *op, JSObject *obj);
|
||||
|
||||
static const JSClassOps location_array_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
smjs_location_array_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, smjs_location_array_finalize,
|
||||
};
|
||||
|
||||
static const JSClass location_array_class = {
|
||||
"location_array",
|
||||
JSCLASS_HAS_PRIVATE, /* struct session *; a weak reference */
|
||||
JS_PropertyStub, nullptr,
|
||||
smjs_location_array_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, smjs_location_array_finalize,
|
||||
&location_array_ops
|
||||
};
|
||||
|
||||
/* location_array_class is the class for array object, the elements of which
|
||||
@ -1076,14 +1084,18 @@ session_array_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId h
|
||||
return true;
|
||||
}
|
||||
|
||||
static const JSClass session_array_class = {
|
||||
"session_array",
|
||||
JSCLASS_HAS_PRIVATE, /* struct terminal *term; a weak reference */
|
||||
static const JSClassOps session_array_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
session_array_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
static const JSClass session_array_class = {
|
||||
"session_array",
|
||||
JSCLASS_HAS_PRIVATE, /* struct terminal *term; a weak reference */
|
||||
&session_array_ops
|
||||
};
|
||||
|
||||
JSObject *
|
||||
smjs_get_session_array_object(struct terminal *term)
|
||||
{
|
||||
|
@ -20,14 +20,18 @@
|
||||
static bool terminal_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
static void terminal_finalize(JSFreeOp *op, JSObject *obj);
|
||||
|
||||
static const JSClass terminal_class = {
|
||||
"terminal",
|
||||
JSCLASS_HAS_PRIVATE, /* struct terminal *; a weak refernce */
|
||||
static const JSClassOps terminal_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
terminal_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, terminal_finalize
|
||||
};
|
||||
|
||||
static const JSClass terminal_class = {
|
||||
"terminal",
|
||||
JSCLASS_HAS_PRIVATE, /* struct terminal *; a weak refernce */
|
||||
&terminal_ops
|
||||
};
|
||||
|
||||
enum terminal_prop {
|
||||
TERMINAL_TAB,
|
||||
};
|
||||
@ -187,14 +191,18 @@ terminal_array_get_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId
|
||||
;
|
||||
}
|
||||
|
||||
static const JSClass terminal_array_class = {
|
||||
"terminal_array",
|
||||
0,
|
||||
static const JSClassOps terminal_array_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
terminal_array_get_property, JS_StrictPropertyStub,
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
static const JSClass terminal_array_class = {
|
||||
"terminal_array",
|
||||
0,
|
||||
&terminal_array_ops
|
||||
};
|
||||
|
||||
/** Return an SMJS object that scripts can use an array to get terminal
|
||||
* objects. */
|
||||
static JSObject *
|
||||
|
@ -24,14 +24,18 @@ static bool view_state_get_property(JSContext *ctx, JS::HandleObject hobj, JS::H
|
||||
static bool view_state_set_property(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp);
|
||||
static void view_state_finalize(JSFreeOp *op, JSObject *obj);
|
||||
|
||||
static const JSClass view_state_class = {
|
||||
"view_state",
|
||||
JSCLASS_HAS_PRIVATE, /* struct view_state * */
|
||||
static const JSClassOps view_state_ops = {
|
||||
JS_PropertyStub, nullptr,
|
||||
view_state_get_property, view_state_set_property,
|
||||
nullptr, nullptr, nullptr, view_state_finalize
|
||||
};
|
||||
|
||||
static const JSClass view_state_class = {
|
||||
"view_state",
|
||||
JSCLASS_HAS_PRIVATE, /* struct view_state * */
|
||||
&view_state_ops
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
* from array indexes (even though this object has no array elements).
|
||||
* ECMAScript code should not use these directly as in view_state[-1];
|
||||
@ -255,22 +259,22 @@ smjs_get_view_state_object(struct view_state *vs)
|
||||
}
|
||||
|
||||
static bool
|
||||
smjs_elinks_get_view_state(JSContext *ctx, JS::HandleObject hobj, JS::HandleId hid, JS::MutableHandleValue hvp)
|
||||
smjs_elinks_get_view_state(JSContext *ctx, unsigned int argc, JS::Value *vp)
|
||||
{
|
||||
JSObject *vs_obj;
|
||||
struct view_state *vs;
|
||||
JS::CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JS::RootedObject hobj(ctx, &args.thisv().toObject());
|
||||
|
||||
hvp.setNull();
|
||||
args.rval().setNull();
|
||||
|
||||
if (!smjs_ses || !have_location(smjs_ses)) return true;
|
||||
|
||||
vs = &cur_loc(smjs_ses)->vs;
|
||||
struct view_state *vs = &cur_loc(smjs_ses)->vs;
|
||||
if (!vs) return true;
|
||||
|
||||
vs_obj = smjs_get_view_state_object(vs);
|
||||
JSObject *vs_obj = smjs_get_view_state_object(vs);
|
||||
if (!vs_obj) return true;
|
||||
|
||||
hvp.setObject(*vs_obj);
|
||||
args.rval().setObject(*vs_obj);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -308,6 +312,6 @@ smjs_init_view_state_interface(void)
|
||||
JS::RootedObject r_smjs_elinks_object(smjs_ctx, smjs_elinks_object);
|
||||
|
||||
JS_DefineProperty(smjs_ctx, r_smjs_elinks_object, "vs", (int32_t)0,
|
||||
(unsigned int)(JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY), smjs_elinks_get_view_state, JS_StrictPropertyStub
|
||||
(unsigned int)(JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY), smjs_elinks_get_view_state, nullptr/*JS_StrictPropertyStub*/
|
||||
);
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ find_form_state(struct document_view *doc_view, struct el_form_control *fc)
|
||||
|
||||
if (n >= vs->form_info_len) {
|
||||
int nn = n + 1;
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
const struct form_state *const old_form_info = vs->form_info;
|
||||
#endif
|
||||
|
||||
@ -261,7 +261,7 @@ find_form_state(struct document_view *doc_view, struct el_form_control *fc)
|
||||
vs->form_info = fs;
|
||||
vs->form_info_len = nn;
|
||||
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
/* TODO: Standard C does not allow this comparison;
|
||||
* if the memory to which old_form_info pointed has
|
||||
* been freed, then the value of the pointer itself is
|
||||
@ -275,7 +275,7 @@ find_form_state(struct document_view *doc_view, struct el_form_control *fc)
|
||||
for (nn = 0; nn < vs->form_info_len; nn++)
|
||||
ecmascript_moved_form_state(&vs->form_info[nn]);
|
||||
}
|
||||
#endif /* CONFIG_ECMASCRIPT */
|
||||
#endif /* CONFIG_ECMASCRIPT_SMJS */
|
||||
}
|
||||
fs = &vs->form_info[n];
|
||||
|
||||
@ -353,7 +353,7 @@ find_form_by_form_view(struct document *document, struct form_view *fv)
|
||||
void
|
||||
done_form_state(struct form_state *fs)
|
||||
{
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
ecmascript_detach_form_state(fs);
|
||||
#endif
|
||||
mem_free_if(fs->value);
|
||||
@ -365,7 +365,7 @@ done_form_state(struct form_state *fs)
|
||||
void
|
||||
done_form_view(struct form_view *fv)
|
||||
{
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
ecmascript_detach_form_view(fv);
|
||||
#endif
|
||||
mem_free(fv);
|
||||
|
@ -52,7 +52,7 @@
|
||||
static int
|
||||
current_link_evhook(struct document_view *doc_view, enum script_event_hook_type type)
|
||||
{
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
struct link *link;
|
||||
struct script_event_hook *evhook;
|
||||
|
||||
@ -915,7 +915,7 @@ call_onsubmit_and_submit(struct session *ses, struct document_view *doc_view,
|
||||
assert(fc->form); /* regardless of whether there is a FORM element */
|
||||
if_assert_failed return 0;
|
||||
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
/* If the form has multiple submit buttons, this does not
|
||||
* explicitly tell the ECMAScript code which of them was
|
||||
* pressed. W3C DOM Level 3 doesn't seem to include such a
|
||||
@ -952,7 +952,7 @@ call_onsubmit_and_submit(struct session *ses, struct document_view *doc_view,
|
||||
if (!res) return 1;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_ECMASCRIPT */
|
||||
#endif /* CONFIG_ECMASCRIPT_SMJS */
|
||||
|
||||
uri = get_form_uri(ses, doc_view, fc);
|
||||
if (!uri) return 0;
|
||||
|
@ -38,7 +38,7 @@ init_vs(struct view_state *vs, struct uri *uri, int plain)
|
||||
vs->plain = plain;
|
||||
vs->uri = uri ? get_uri_reference(uri) : NULL;
|
||||
vs->did_fragment = !uri->fragmentlen;
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
/* If we ever get to render this vs, give it an interpreter. */
|
||||
vs->ecmascript_fragile = 1;
|
||||
#endif
|
||||
@ -67,7 +67,7 @@ destroy_vs(struct view_state *vs, int blast_ecmascript)
|
||||
}
|
||||
|
||||
if (vs->uri) done_uri(vs->uri);
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
if (blast_ecmascript && vs->ecmascript)
|
||||
ecmascript_put_interpreter(vs->ecmascript);
|
||||
#endif
|
||||
@ -87,7 +87,7 @@ copy_vs(struct view_state *dst, struct view_state *src)
|
||||
|
||||
/* We do not copy ecmascript stuff around since it's specific for
|
||||
* a single location, offsprings (followups and so) nedd their own. */
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
dst->ecmascript = NULL;
|
||||
/* If we ever get to render this vs, give it an interpreter. */
|
||||
dst->ecmascript_fragile = 1;
|
||||
@ -131,7 +131,7 @@ copy_vs(struct view_state *dst, struct view_state *src)
|
||||
struct form_state *srcfs = &src->form_info[i];
|
||||
struct form_state *dstfs = &dst->form_info[i];
|
||||
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
#ifdef CONFIG_ECMASCRIPT_SMJS
|
||||
dstfs->ecmascript_obj = NULL;
|
||||
#endif
|
||||
if (srcfs->value)
|
||||
|
@ -6,7 +6,7 @@ function scrollText() {
|
||||
tekst = tekst.substring(1, tekst.length) + znak;
|
||||
return tekst.substring(0, 80);
|
||||
}
|
||||
function scroll () {
|
||||
function scroll() {
|
||||
document.title = scrollText();
|
||||
setTimeout("scroll()", 100);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user