mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
952, 954: Finalize form_view.ecmascript_obj for SpiderMonkey
This commit is contained in:
parent
2d49f6e9cd
commit
f4213ac350
@ -7,7 +7,7 @@ struct string;
|
||||
void *spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter);
|
||||
void spidermonkey_put_interpreter(struct ecmascript_interpreter *interpreter);
|
||||
|
||||
#define spidermonkey_detach_form_view(fv) ((fv)->ecmascript_obj = NULL)
|
||||
void spidermonkey_detach_form_view(struct form_view *fv);
|
||||
void spidermonkey_detach_form_state(struct form_state *fs);
|
||||
void spidermonkey_moved_form_state(struct form_state *fs);
|
||||
|
||||
|
@ -661,7 +661,7 @@ get_form_control_object(JSContext *ctx, JSObject *jsform,
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct form_view *form_get_form_view(JSContext *ctx, JSObject *jsform, jsval *argv);
|
||||
static JSBool form_elements_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);
|
||||
|
||||
/* Each @form_elements_class object must have a @form_class parent. */
|
||||
@ -726,8 +726,8 @@ form_elements_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
(JSClass *) &window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
document = doc_view->document;
|
||||
form_view = JS_GetInstancePrivate(ctx, parent_form,
|
||||
(JSClass *) &form_class, NULL);
|
||||
form_view = form_get_form_view(ctx, parent_form, NULL);
|
||||
if (!form_view) return JS_FALSE; /* detached */
|
||||
form = find_form_by_form_view(document, form_view);
|
||||
|
||||
if (JSVAL_IS_STRING(id)) {
|
||||
@ -784,8 +784,8 @@ form_elements_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval
|
||||
(JSClass *) &window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
document = doc_view->document;
|
||||
form_view = JS_GetInstancePrivate(ctx, parent_form,
|
||||
(JSClass *) &form_class, NULL);
|
||||
form_view = form_get_form_view(ctx, parent_form, NULL);
|
||||
if (!form_view) return JS_FALSE; /* detached */
|
||||
form = find_form_by_form_view(document, form_view);
|
||||
|
||||
if (argc != 1)
|
||||
@ -843,8 +843,8 @@ form_elements_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv,
|
||||
(JSClass *) &window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
document = doc_view->document;
|
||||
form_view = JS_GetInstancePrivate(ctx, parent_form,
|
||||
(JSClass *) &form_class, NULL);
|
||||
form_view = form_get_form_view(ctx, parent_form, NULL);
|
||||
if (!form_view) return JS_FALSE; /* detached */
|
||||
form = find_form_by_form_view(document, form_view);
|
||||
|
||||
if (argc != 1)
|
||||
@ -877,14 +877,15 @@ form_elements_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv,
|
||||
|
||||
static JSBool form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);
|
||||
static JSBool form_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);
|
||||
static void form_finalize(JSContext *ctx, JSObject *obj);
|
||||
|
||||
/* Each @form_class object must have a @document_class parent. */
|
||||
static const JSClass form_class = {
|
||||
"form",
|
||||
JSCLASS_HAS_PRIVATE, /* struct form_view * */
|
||||
JSCLASS_HAS_PRIVATE, /* struct form_view *, or NULL if detached */
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
form_get_property, form_set_property,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, form_finalize
|
||||
};
|
||||
|
||||
/* Tinyids of properties. Use negative values to distinguish these
|
||||
@ -921,6 +922,21 @@ static const spidermonkeyFunctionSpec form_funcs[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static struct form_view *
|
||||
form_get_form_view(JSContext *ctx, JSObject *jsform, jsval *argv)
|
||||
{
|
||||
struct form_view *fv = JS_GetInstancePrivate(ctx, jsform,
|
||||
(JSClass *) &form_class,
|
||||
argv);
|
||||
|
||||
if (!fv) return NULL; /* detached */
|
||||
|
||||
assert(fv->ecmascript_obj == jsform);
|
||||
if_assert_failed return NULL;
|
||||
|
||||
return fv;
|
||||
}
|
||||
|
||||
/* @form_class.getProperty */
|
||||
static JSBool
|
||||
form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
@ -948,7 +964,8 @@ form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
(JSClass *) &window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
fv = JS_GetInstancePrivate(ctx, obj, (JSClass *) &form_class, NULL);
|
||||
fv = form_get_form_view(ctx, obj, NULL);
|
||||
if (!fv) return JS_FALSE; /* detached */
|
||||
form = find_form_by_form_view(doc_view->document, fv);
|
||||
|
||||
assert(form);
|
||||
@ -1082,7 +1099,8 @@ form_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
(JSClass *) &window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
fv = JS_GetInstancePrivate(ctx, obj, (JSClass *) &form_class, NULL);
|
||||
fv = form_get_form_view(ctx, obj, NULL);
|
||||
if (!fv) return JS_FALSE; /* detached */
|
||||
form = find_form_by_form_view(doc_view->document, fv);
|
||||
|
||||
assert(form);
|
||||
@ -1162,7 +1180,8 @@ form_reset(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
vs = JS_GetInstancePrivate(ctx, parent_win,
|
||||
(JSClass *) &window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
fv = JS_GetInstancePrivate(ctx, obj, (JSClass *) &form_class, argv);
|
||||
fv = form_get_form_view(ctx, obj, argv);
|
||||
if (!fv) return JS_FALSE; /* detached */
|
||||
form = find_form_by_form_view(doc_view->document, fv);
|
||||
|
||||
assert(form);
|
||||
@ -1199,7 +1218,8 @@ form_submit(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
(JSClass *) &window_class, NULL);
|
||||
doc_view = vs->doc_view;
|
||||
ses = doc_view->session;
|
||||
fv = JS_GetInstancePrivate(ctx, obj, (JSClass *) &form_class, argv);
|
||||
fv = form_get_form_view(ctx, obj, argv);
|
||||
if (!fv) return JS_FALSE; /* detached */
|
||||
form = find_form_by_form_view(doc_view->document, fv);
|
||||
|
||||
assert(form);
|
||||
@ -1213,21 +1233,79 @@ form_submit(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
JSObject *
|
||||
get_form_object(JSContext *ctx, JSObject *jsdoc, struct form_view *fv)
|
||||
{
|
||||
#if 0
|
||||
if (fv->ecmascript_obj)
|
||||
return fv->ecmascript_obj;
|
||||
#endif
|
||||
JSObject *jsform = fv->ecmascript_obj;
|
||||
|
||||
if (jsform) {
|
||||
/* This assumes JS_GetInstancePrivate cannot GC. */
|
||||
assert(JS_GetInstancePrivate(ctx, jsform,
|
||||
(JSClass *) &form_class, NULL)
|
||||
== fv);
|
||||
if_assert_failed return NULL;
|
||||
|
||||
return jsform;
|
||||
}
|
||||
|
||||
/* jsdoc ('document') is fv's parent */
|
||||
/* FIXME: That is NOT correct since the real containing element
|
||||
* should be its parent, but gimme DOM first. --pasky */
|
||||
JSObject *jsform = JS_NewObject(ctx, (JSClass *) &form_class, NULL, jsdoc);
|
||||
|
||||
jsform = JS_NewObject(ctx, (JSClass *) &form_class, NULL, jsdoc);
|
||||
if (jsform == NULL)
|
||||
return NULL;
|
||||
JS_DefineProperties(ctx, jsform, (JSPropertySpec *) form_props);
|
||||
spidermonkey_DefineFunctions(ctx, jsform, form_funcs);
|
||||
JS_SetPrivate(ctx, jsform, fv); /* to @form_class */
|
||||
|
||||
if (!JS_SetPrivate(ctx, jsform, fv)) /* to @form_class */
|
||||
return NULL;
|
||||
fv->ecmascript_obj = jsform;
|
||||
return fv->ecmascript_obj;
|
||||
return jsform;
|
||||
}
|
||||
|
||||
static void
|
||||
form_finalize(JSContext *ctx, JSObject *jsform)
|
||||
{
|
||||
struct form_view *fv = JS_GetInstancePrivate(ctx, jsform,
|
||||
(JSClass *) &form_class,
|
||||
NULL);
|
||||
|
||||
if (fv) {
|
||||
/* If this assertion fails, leave fv->ecmascript_obj
|
||||
* unchanged, because it may point to a different
|
||||
* JSObject whose private pointer will later have to
|
||||
* be updated to avoid crashes. */
|
||||
assert(fv->ecmascript_obj == jsform);
|
||||
if_assert_failed return;
|
||||
|
||||
fv->ecmascript_obj = NULL;
|
||||
/* No need to JS_SetPrivate, because the object is
|
||||
* being destroyed. */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
spidermonkey_detach_form_view(struct form_view *fv)
|
||||
{
|
||||
JSObject *jsform = fv->ecmascript_obj;
|
||||
|
||||
if (jsform) {
|
||||
/* This assumes JS_GetInstancePrivate and JS_SetPrivate
|
||||
* cannot GC. */
|
||||
|
||||
/* If this assertion fails, it is not clear whether
|
||||
* the private pointer of jsform should be reset;
|
||||
* crashes seem possible either way. Resetting it is
|
||||
* easiest. */
|
||||
assert(JS_GetInstancePrivate(spidermonkey_empty_context,
|
||||
jsform,
|
||||
(JSClass *) &form_class, NULL)
|
||||
== fv);
|
||||
if_assert_failed {}
|
||||
|
||||
JS_SetPrivate(spidermonkey_empty_context, jsform, NULL);
|
||||
fv->ecmascript_obj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static JSBool forms_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp);
|
||||
|
||||
/* Each @forms_class object must have a @document_class parent. */
|
||||
|
Loading…
Reference in New Issue
Block a user