1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-11-04 08:17:17 -05:00

952, 954: Finalize form_view.ecmascript_obj for SpiderMonkey

This commit is contained in:
Kalle Olavi Niemitalo 2008-07-18 20:16:17 +03:00 committed by Kalle Olavi Niemitalo
parent 2d49f6e9cd
commit f4213ac350
2 changed files with 100 additions and 22 deletions

View File

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

View File

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