зеркало из https://github.com/mozilla/pjs.git
Bug 411025: temp rooting implemenation cleanup, r,a=brendan
This commit is contained in:
Родитель
a16f13c621
Коммит
34e194fd9f
|
@ -4653,6 +4653,7 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
|||
const char *filename, uintN lineno)
|
||||
{
|
||||
JSFunction *fun;
|
||||
JSTempValueRooter tvr;
|
||||
JSAtom *funAtom, *argAtom;
|
||||
uintN i;
|
||||
|
||||
|
@ -4663,12 +4664,15 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
|||
funAtom = js_Atomize(cx, name, strlen(name), 0);
|
||||
if (!funAtom) {
|
||||
fun = NULL;
|
||||
goto out;
|
||||
goto out2;
|
||||
}
|
||||
}
|
||||
fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, obj, funAtom);
|
||||
if (!fun)
|
||||
goto out;
|
||||
goto out2;
|
||||
|
||||
/* From this point the control must flow through the label out. */
|
||||
JS_PUSH_TEMP_ROOT_FUNCTION(cx, fun, &tvr);
|
||||
for (i = 0; i < nargs; i++) {
|
||||
argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
|
||||
if (!argAtom) {
|
||||
|
@ -4707,6 +4711,10 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
|||
#endif
|
||||
|
||||
out:
|
||||
cx->weakRoots.newborn[JSTRACE_FUNCTION] = fun;
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
|
||||
out2:
|
||||
LAST_FRAME_CHECKS(cx, fun);
|
||||
return fun;
|
||||
}
|
||||
|
|
159
js/src/jscntxt.h
159
js/src/jscntxt.h
|
@ -514,141 +514,92 @@ typedef struct JSLocalRootStack {
|
|||
* a C function across several layers of other functions, use the
|
||||
* js_LeaveLocalRootScopeWithResult internal API (see further below) instead.
|
||||
*
|
||||
* JSTempValueRooter.count defines the type of the rooted value referenced by
|
||||
* JSTempValueRooter.u union of type JSTempValueUnion according to the
|
||||
* following table:
|
||||
* The macros also provide a simple way to get a single rooted pointer via
|
||||
* JS_PUSH_TEMP_ROOT_<KIND>(cx, NULL, &tvr). Then &tvr.u.<kind> gives the
|
||||
* necessary pointer.
|
||||
*
|
||||
* count description
|
||||
* JSTVU_SINGLE u.value contains the single value or GC-thing to root.
|
||||
* JSTVU_TRACE u.trace holds a trace hook called to trace the values.
|
||||
* JSTVU_SPROP u.sprop points to the property tree node to mark.
|
||||
* JSTVU_WEAK_ROOTS u.weakRoots points to saved weak roots.
|
||||
* JSTVU_PARSE_CONTEXT u.parseContext roots things generated during parsing.
|
||||
* JSTVU_SCRIPT u.script roots a pointer to JSScript.
|
||||
* >= 0 u.array points to a stack-allocated vector of jsvals.
|
||||
* JSTempValueRooter.count defines the type of the rooted value referenced by
|
||||
* JSTempValueRooter.u union of type JSTempValueUnion. When count is positive
|
||||
* or zero, u.array points to a vector of jsvals. Otherwise it must be one of
|
||||
* the following constants:
|
||||
*/
|
||||
#define JSTVU_SINGLE (-1)
|
||||
#define JSTVU_TRACE (-2)
|
||||
#define JSTVU_SPROP (-3)
|
||||
#define JSTVU_WEAK_ROOTS (-4)
|
||||
#define JSTVU_PARSE_CONTEXT (-5)
|
||||
#define JSTVU_SCRIPT (-6)
|
||||
#define JSTVU_SINGLE (-1) /* u.value or u.<gcthing> is single jsval
|
||||
or GC-thing */
|
||||
#define JSTVU_TRACE (-2) /* u.trace is a hook to trace a custom
|
||||
* structure */
|
||||
#define JSTVU_SPROP (-3) /* u.sprop roots property tree node */
|
||||
#define JSTVU_WEAK_ROOTS (-4) /* u.weakRoots points to saved weak roots */
|
||||
#define JSTVU_PARSE_CONTEXT (-5) /* u.parseContext roots JSParseContext* */
|
||||
#define JSTVU_SCRIPT (-6) /* u.script roots JSScript* */
|
||||
|
||||
/*
|
||||
* To root a single GC-thing pointer, which need not be tagged and stored as a
|
||||
* jsval, use JS_PUSH_TEMP_ROOT_GCTHING. The macro reinterprets an arbitrary
|
||||
* GC-thing as jsval. It works because a GC-thing is aligned on a 0 mod 8
|
||||
* boundary, and object has the 0 jsval tag. So any GC-thing may be tagged as
|
||||
* if it were an object and untagged, if it's then used only as an opaque
|
||||
* pointer until discriminated by other means than tag bits (this is how the
|
||||
* GC mark function uses its |thing| parameter -- it consults GC-thing flags
|
||||
* stored separately from the thing to decide the type of thing).
|
||||
*
|
||||
* JS_PUSH_TEMP_ROOT_OBJECT and JS_PUSH_TEMP_ROOT_STRING are type-safe
|
||||
* alternatives to JS_PUSH_TEMP_ROOT_GCTHING for JSObject and JSString. They
|
||||
* also provide a simple way to get a single pointer to rooted JSObject or
|
||||
* JSString via JS_PUSH_TEMP_ROOT_(OBJECT|STRTING)(cx, NULL, &tvr). Then
|
||||
* &tvr.u.object or tvr.u.string gives the necessary pointer, which puns
|
||||
* tvr.u.value safely because JSObject * and JSString * are GC-things and, as
|
||||
* such, their tag bits are all zeroes.
|
||||
* Here single JSTVU_SINGLE covers both jsval and pointers to any GC-thing via
|
||||
* reinterpreting the thing as JSVAL_OBJECT. It works because the GC-thing is
|
||||
* aligned on a 0 mod 8 boundary, and object has the 0 jsval tag. So any
|
||||
* GC-thing may be tagged as if it were an object and untagged, if it's then
|
||||
* used only as an opaque pointer until discriminated by other means than tag
|
||||
* bits. This is how, for example, js_GetGCThingTraceKind uses its |thing|
|
||||
* parameter -- it consults GC-thing flags stored separately from the thing to
|
||||
* decide the kind of thing.
|
||||
*
|
||||
* The following checks that this type-punning is possible.
|
||||
*/
|
||||
JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(jsval));
|
||||
JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(JSObject *));
|
||||
JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(void *));
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_COMMON(cx,tvr) \
|
||||
#define JS_PUSH_TEMP_ROOT_COMMON(cx,x,tvr,cnt,kind) \
|
||||
JS_BEGIN_MACRO \
|
||||
JS_ASSERT((cx)->tempValueRooters != (tvr)); \
|
||||
(tvr)->count = (cnt); \
|
||||
(tvr)->u.kind = (x); \
|
||||
(tvr)->down = (cx)->tempValueRooters; \
|
||||
(cx)->tempValueRooters = (tvr); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_PUSH_SINGLE_TEMP_ROOT(cx,val,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
(tvr)->count = JSTVU_SINGLE; \
|
||||
(tvr)->u.value = val; \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT(cx,cnt,arr,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
JS_ASSERT((int)(cnt) >= 0); \
|
||||
(tvr)->count = (ptrdiff_t)(cnt); \
|
||||
(tvr)->u.array = (arr); \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_TRACE(cx,trace_,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
(tvr)->count = JSTVU_TRACE; \
|
||||
(tvr)->u.trace = (trace_); \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_OBJECT(cx,obj,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
(tvr)->count = JSTVU_SINGLE; \
|
||||
(tvr)->u.object = (obj); \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_STRING(cx,str,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
(tvr)->count = JSTVU_SINGLE; \
|
||||
(tvr)->u.string = (str); \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_GCTHING(cx,thing,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
JS_ASSERT(JSVAL_IS_OBJECT((jsval)thing)); \
|
||||
(tvr)->count = JSTVU_SINGLE; \
|
||||
(tvr)->u.gcthing = (thing); \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_POP_TEMP_ROOT(cx,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
JS_ASSERT((cx)->tempValueRooters == (tvr)); \
|
||||
(cx)->tempValueRooters = (tvr)->down; \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_TEMP_ROOT_EVAL(cx,cnt,val,expr) \
|
||||
#define JS_PUSH_TEMP_ROOT(cx,cnt,arr,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
JSTempValueRooter tvr; \
|
||||
JS_PUSH_TEMP_ROOT(cx, cnt, val, &tvr); \
|
||||
(expr); \
|
||||
JS_POP_TEMP_ROOT(cx, &tvr); \
|
||||
JS_ASSERT((int)(cnt) >= 0); \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, arr, tvr, (ptrdiff_t) (cnt), array); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_PUSH_SINGLE_TEMP_ROOT(cx,val,tvr) \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, val, tvr, JSTVU_SINGLE, value)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_OBJECT(cx,obj,tvr) \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, obj, tvr, JSTVU_SINGLE, object)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_STRING(cx,str,tvr) \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, str, tvr, JSTVU_SINGLE, string)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_FUNCTION(cx,fun,tvr) \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, fun, tvr, JSTVU_SINGLE, function)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_QNAME(cx,qn,tvr) \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, qn, tvr, JSTVU_SINGLE, qname)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_XML(cx,xml_,tvr) \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, xml_, tvr, JSTVU_SINGLE, xml)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_TRACE(cx,trace_,tvr) \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, trace_, tvr, JSTVU_TRACE, trace)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_SPROP(cx,sprop_,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
(tvr)->count = JSTVU_SPROP; \
|
||||
(tvr)->u.sprop = (sprop_); \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
JS_END_MACRO
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, sprop_, tvr, JSTVU_SPROP, sprop)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_WEAK_COPY(cx,weakRoots_,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
(tvr)->count = JSTVU_WEAK_ROOTS; \
|
||||
(tvr)->u.weakRoots = (weakRoots_); \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
JS_END_MACRO
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, weakRoots_, tvr, JSTVU_WEAK_ROOTS, weakRoots)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_PARSE_CONTEXT(cx,pc,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
(tvr)->count = JSTVU_PARSE_CONTEXT; \
|
||||
(tvr)->u.parseContext = (pc); \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
JS_END_MACRO
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, pc, tvr, JSTVU_PARSE_CONTEXT, parseContext)
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_SCRIPT(cx,script_,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
(tvr)->count = JSTVU_SCRIPT; \
|
||||
(tvr)->u.script = (script_); \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
JS_END_MACRO
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, script_, tvr, JSTVU_SCRIPT, script)
|
||||
|
||||
struct JSContext {
|
||||
/* JSRuntime contextList linkage. */
|
||||
|
|
|
@ -234,7 +234,9 @@ typedef union JSTempValueUnion {
|
|||
jsval value;
|
||||
JSObject *object;
|
||||
JSString *string;
|
||||
void *gcthing;
|
||||
JSFunction *function;
|
||||
JSXML *xml;
|
||||
JSXMLQName *qname;
|
||||
JSTempValueTrace trace;
|
||||
JSScopeProperty *sprop;
|
||||
JSWeakRoots *weakRoots;
|
||||
|
|
|
@ -3121,7 +3121,7 @@ ToAttributeName(JSContext *cx, jsval v)
|
|||
if (!qn)
|
||||
return NULL;
|
||||
|
||||
JS_PUSH_TEMP_ROOT_GCTHING(cx, qn, &tvr);
|
||||
JS_PUSH_TEMP_ROOT_QNAME(cx, qn, &tvr);
|
||||
obj = js_GetAttributeNameObject(cx, qn);
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
if (!obj)
|
||||
|
@ -7559,7 +7559,7 @@ js_NewXMLObject(JSContext *cx, JSXMLClass xml_class)
|
|||
xml = js_NewXML(cx, xml_class);
|
||||
if (!xml)
|
||||
return NULL;
|
||||
JS_PUSH_TEMP_ROOT_GCTHING(cx, xml, &tvr);
|
||||
JS_PUSH_TEMP_ROOT_XML(cx, xml, &tvr);
|
||||
obj = js_GetXMLObject(cx, xml);
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
return obj;
|
||||
|
|
Загрузка…
Ссылка в новой задаче