1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-25 01:05:37 +00:00

[mozjs52] It compiles, but often segfaults. No idea yet how to fix it.

This commit is contained in:
Witold Filipczyk 2020-10-27 14:53:24 +01:00
parent a5b68a25a1
commit d1ecd45828
35 changed files with 461 additions and 198 deletions

View File

@ -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)"

View File

@ -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

View File

@ -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, ": ");

View File

@ -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) {

View File

@ -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

View File

@ -5,6 +5,7 @@
#endif
#include <stdlib.h>
#include <stdio.h>
#include "elinks.h"

View File

@ -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

View File

@ -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')

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */
}

View File

@ -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);

View File

@ -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

View File

@ -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];

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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 *

View File

@ -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];

View File

@ -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();

View File

@ -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);
}

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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 *

View File

@ -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*/
);
}

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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);
}