зеркало из https://github.com/mozilla/gecko-dev.git
Bug 630865 - Resolve interpreted function prototypes more eagerly. r=dvander.
This commit is contained in:
Родитель
d1b9b220f7
Коммит
68e21b0914
|
@ -0,0 +1,6 @@
|
|||
Object.defineProperty(Function.prototype, "prototype", {set:function(){}});
|
||||
var x;
|
||||
for (var i = 0; i < HOTLOOP + 2; i++)
|
||||
x = new Function.prototype;
|
||||
assertEq(toString.call(x), "[object Object]");
|
||||
assertEq(Object.getPrototypeOf(x), Object.prototype);
|
|
@ -0,0 +1,6 @@
|
|||
Function.prototype.prototype = function () {};
|
||||
var x;
|
||||
for (var i = 0; i < HOTLOOP + 2; i++)
|
||||
x = new Function.prototype;
|
||||
assertEq(toString.call(x), "[object Object]");
|
||||
assertEq(Object.getPrototypeOf(x), Function.prototype.prototype);
|
|
@ -0,0 +1,12 @@
|
|||
var a = [];
|
||||
function next() {
|
||||
var x = {};
|
||||
a.push(x);
|
||||
return x;
|
||||
}
|
||||
Object.defineProperty(Function.prototype, 'prototype', {get: next});
|
||||
var b = [];
|
||||
for (var i = 0; i < HOTLOOP + 2; i++)
|
||||
b[i] = new Function.prototype;
|
||||
for (var i = 0; i < HOTLOOP + 2; i++)
|
||||
assertEq(Object.getPrototypeOf(b[i]), a[i]);
|
|
@ -0,0 +1,10 @@
|
|||
Object.defineProperty(Function.prototype, 'prototype',
|
||||
{get: function () { if (i == HOTLOOP + 1) throw "X"; }});
|
||||
var x;
|
||||
try {
|
||||
for (var i = 0; i < HOTLOOP + 2; i++)
|
||||
x = new Function.prototype;
|
||||
} catch (exc) {
|
||||
assertEq(i, HOTLOOP + 1);
|
||||
assertEq(exc, "X");
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
function C(a, b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
var f = C.bind(null, 2);
|
||||
Object.defineProperty(f, "prototype", {get: function () { throw "FAIL"; }});
|
||||
var x;
|
||||
for (var i = 0; i < HOTLOOP + 2; i++)
|
||||
x = new f(i);
|
||||
assertEq(toString.call(x), "[object Object]");
|
||||
assertEq(Object.getPrototypeOf(x), C.prototype);
|
||||
assertEq(x.a, 2);
|
||||
assertEq(x.b, HOTLOOP + 1);
|
|
@ -0,0 +1,11 @@
|
|||
var a = [];
|
||||
var x, i;
|
||||
for (i = 0; i < HOTLOOP + 10; i++) {
|
||||
a[i] = function (b) { this.b = b; };
|
||||
if (i != HOTLOOP + 9)
|
||||
x = a[i].prototype;
|
||||
}
|
||||
for (i = 0; i < HOTLOOP + 10; i++)
|
||||
x = new a[i];
|
||||
assertEq(toString.call(x), "[object Object]");
|
||||
assertEq(Object.getPrototypeOf(x), a[HOTLOOP + 9].prototype);
|
|
@ -0,0 +1,11 @@
|
|||
function f(a, b) {
|
||||
this.a = a;
|
||||
assertEq(b, 'x');
|
||||
}
|
||||
|
||||
for (var x = 0; x < RUNLOOP; ++x) {
|
||||
f.prototype = {};
|
||||
var obj = new f(x, 'x');
|
||||
assertEq(obj.a, x);
|
||||
assertEq(Object.getPrototypeOf(obj), f.prototype);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
function f(a, b, c) {
|
||||
this.a = a;
|
||||
assertEq(b, 'x');
|
||||
assertEq(c, void 0);
|
||||
}
|
||||
|
||||
for (var x = 0; x < RUNLOOP; ++x) {
|
||||
f.prototype = {};
|
||||
var obj = new f(x, 'x'); // fewer than f.length arguments
|
||||
assertEq(obj.a, x);
|
||||
assertEq(Object.getPrototypeOf(obj), f.prototype);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
function f(a) {
|
||||
this.a = a;
|
||||
assertEq(arguments[1], 'x');
|
||||
}
|
||||
|
||||
for (var x = 0; x < RUNLOOP; ++x) {
|
||||
f.prototype = {};
|
||||
var obj = new f(x, 'x'); // more than f.length arguments
|
||||
assertEq(obj.a, x);
|
||||
assertEq(Object.getPrototypeOf(obj), f.prototype);
|
||||
}
|
|
@ -233,6 +233,7 @@ struct ClosureVarInfo;
|
|||
#define _JS_CTYPE_CVIPTR _JS_CTYPE(const ClosureVarInfo *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_FRAMEINFO _JS_CTYPE(FrameInfo *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_PICTABLE _JS_CTYPE(PICTable *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_UINTN _JS_CTYPE(uintN, _JS_PTR, --, --, INFALLIBLE)
|
||||
|
||||
/*
|
||||
* The "VALUE" type is used to indicate that a native takes a js::Value
|
||||
|
|
|
@ -1704,6 +1704,46 @@ fun_enumerate(JSContext *cx, JSObject *obj)
|
|||
return true;
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
ResolveInterpretedFunctionPrototype(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSFunction *fun = obj->getFunctionPrivate();
|
||||
JS_ASSERT(fun->isInterpreted());
|
||||
JS_ASSERT(!fun->isFunctionPrototype());
|
||||
|
||||
/*
|
||||
* Assert that fun is not a compiler-created function object, which
|
||||
* must never leak to script or embedding code and then be mutated.
|
||||
* Also assert that obj is not bound, per the ES5 15.3.4.5 ref above.
|
||||
*/
|
||||
JS_ASSERT(!IsInternalFunctionObject(obj));
|
||||
JS_ASSERT(!obj->isBoundFunction());
|
||||
|
||||
/*
|
||||
* Make the prototype object an instance of Object with the same parent
|
||||
* as the function object itself.
|
||||
*/
|
||||
JSObject *parent = obj->getParent();
|
||||
JSObject *proto;
|
||||
if (!js_GetClassPrototype(cx, parent, JSProto_Object, &proto))
|
||||
return NULL;
|
||||
proto = NewNativeClassInstance(cx, &js_ObjectClass, proto, parent);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* ECMA (15.3.5.2) says that a user-defined function's .prototype property
|
||||
* is non-configurable, non-enumerable, and (initially) writable. Hence
|
||||
* JSPROP_PERMANENT below. By contrast, the built-in constructors, such as
|
||||
* Object (15.2.3.1) and Function (15.3.3.1), have non-writable
|
||||
* .prototype properties. Those are eagerly defined, with attributes
|
||||
* JSPROP_PERMANENT | JSPROP_READONLY, in js_InitClass.
|
||||
*/
|
||||
if (!js_SetClassPrototype(cx, obj, proto, JSPROP_PERMANENT))
|
||||
return NULL;
|
||||
return proto;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
fun_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
JSObject **objp)
|
||||
|
@ -1730,36 +1770,8 @@ fun_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|||
if (fun->isNative() || fun->isFunctionPrototype())
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Assert that fun is not a compiler-created function object, which
|
||||
* must never leak to script or embedding code and then be mutated.
|
||||
* Also assert that obj is not bound, per the ES5 15.3.4.5 ref above.
|
||||
*/
|
||||
JS_ASSERT(!IsInternalFunctionObject(obj));
|
||||
JS_ASSERT(!obj->isBoundFunction());
|
||||
|
||||
/*
|
||||
* Make the prototype object an instance of Object with the same parent
|
||||
* as the function object itself.
|
||||
*/
|
||||
JSObject *parent = obj->getParent();
|
||||
JSObject *proto;
|
||||
if (!js_GetClassPrototype(cx, parent, JSProto_Object, &proto))
|
||||
if (!ResolveInterpretedFunctionPrototype(cx, obj))
|
||||
return false;
|
||||
proto = NewNativeClassInstance(cx, &js_ObjectClass, proto, parent);
|
||||
if (!proto)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* ECMA (15.3.5.2) says that constructor.prototype is DontDelete for
|
||||
* user-defined functions, but DontEnum | ReadOnly | DontDelete for
|
||||
* native "system" constructors such as Object or Function. So lazily
|
||||
* set the former here in fun_resolve, but eagerly define the latter
|
||||
* in js_InitClass, with the right attributes.
|
||||
*/
|
||||
if (!js_SetClassPrototype(cx, obj, proto, JSPROP_PERMANENT))
|
||||
return false;
|
||||
|
||||
*objp = obj;
|
||||
return true;
|
||||
}
|
||||
|
@ -2630,6 +2642,28 @@ IsBuiltinFunctionConstructor(JSFunction *fun)
|
|||
return fun->maybeNative() == Function;
|
||||
}
|
||||
|
||||
const Shape *
|
||||
LookupInterpretedFunctionPrototype(JSContext *cx, JSObject *funobj)
|
||||
{
|
||||
JSFunction *fun = funobj->getFunctionPrivate();
|
||||
JS_ASSERT(fun->isInterpreted());
|
||||
JS_ASSERT(!fun->isFunctionPrototype());
|
||||
JS_ASSERT(!funobj->isBoundFunction());
|
||||
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
|
||||
const Shape *shape = funobj->nativeLookup(id);
|
||||
if (!shape) {
|
||||
if (!ResolveInterpretedFunctionPrototype(cx, funobj))
|
||||
return false;
|
||||
shape = funobj->nativeLookup(id);
|
||||
}
|
||||
JS_ASSERT(!shape->configurable());
|
||||
JS_ASSERT(shape->isDataDescriptor());
|
||||
JS_ASSERT(shape->hasSlot());
|
||||
JS_ASSERT(!shape->isMethod());
|
||||
return shape;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
|
|
@ -432,6 +432,21 @@ GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes)
|
|||
extern JS_FRIEND_API(bool)
|
||||
IsBuiltinFunctionConstructor(JSFunction *fun);
|
||||
|
||||
/*
|
||||
* Preconditions: funobj->isInterpreted() && !funobj->isFunctionPrototype() &&
|
||||
* !funobj->isBoundFunction(). This is sufficient to establish that funobj has
|
||||
* a non-configurable non-method .prototype data property, thought it might not
|
||||
* have been resolved yet, and its value could be anything.
|
||||
*
|
||||
* Return the shape of the .prototype property of funobj, resolving it if
|
||||
* needed. On error, return NULL.
|
||||
*
|
||||
* This is not safe to call on trace because it defines properties, which can
|
||||
* trigger lookups that could reenter.
|
||||
*/
|
||||
const Shape *
|
||||
LookupInterpretedFunctionPrototype(JSContext *cx, JSObject *funobj);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSString *
|
||||
|
|
|
@ -2997,58 +2997,36 @@ JS_DEFINE_CALLINFO_3(extern, OBJECT, js_String_tn, CONTEXT, CALLEE_PROTOTYPE, ST
|
|||
nanojit::ACCSET_STORE_ANY)
|
||||
|
||||
JSObject * FASTCALL
|
||||
js_CreateThisFromTrace(JSContext *cx, Class *clasp, JSObject *ctor)
|
||||
js_CreateThisFromTrace(JSContext *cx, JSObject *ctor, uintN protoSlot)
|
||||
{
|
||||
JS_ASSERT(JS_ON_TRACE(cx));
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(ctor->isFunction());
|
||||
|
||||
if (!ctor->ensureClassReservedSlots(cx))
|
||||
return NULL;
|
||||
|
||||
jsid classPrototypeId = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
|
||||
const Shape *shape = ctor->nativeLookup(classPrototypeId);
|
||||
Value pval = shape ? ctor->getSlot(shape->slot) : MagicValue(JS_GENERIC_MAGIC);
|
||||
JS_ASSERT(ctor->getFunctionPrivate()->isInterpreted());
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
|
||||
const Shape *shape = ctor->nativeLookup(id);
|
||||
JS_ASSERT(shape->slot == protoSlot);
|
||||
JS_ASSERT(!shape->configurable());
|
||||
JS_ASSERT(!shape->isMethod());
|
||||
#endif
|
||||
|
||||
JSObject *parent = ctor->getParent();
|
||||
JSObject *proto;
|
||||
if (pval.isObject()) {
|
||||
/* An object in ctor.prototype, let's use it as the new instance's proto. */
|
||||
proto = &pval.toObject();
|
||||
const Value &protov = ctor->getSlotRef(protoSlot);
|
||||
if (protov.isObject()) {
|
||||
proto = &protov.toObject();
|
||||
} else {
|
||||
/* A hole or a primitive: either way, we need to get Object.prototype. */
|
||||
/*
|
||||
* GetInterpretedFunctionPrototype found that ctor.prototype is
|
||||
* primitive. Use Object.prototype for proto, per ES5 13.2.2 step 7.
|
||||
*/
|
||||
if (!js_GetClassPrototype(cx, parent, JSProto_Object, &proto))
|
||||
return NULL;
|
||||
|
||||
if (pval.isMagic(JS_GENERIC_MAGIC)) {
|
||||
/*
|
||||
* No ctor.prototype was set, so we inline-expand and optimize
|
||||
* fun_resolve's prototype creation code.
|
||||
*/
|
||||
proto = NewNativeClassInstance(cx, clasp, proto, parent);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
JSFunction *fun = ctor->getFunctionPrivate();
|
||||
if (!fun->isNative() && !fun->isFunctionPrototype()) {
|
||||
if (!js_SetClassPrototype(cx, ctor, proto, JSPROP_ENUMERATE | JSPROP_PERMANENT))
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* A primitive value in .prototype means to use Object.prototype
|
||||
* for proto. See ES5 13.2.2 step 7.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: 561785 at least. Quasi-natives including XML objects prevent us
|
||||
* from easily or unconditionally calling NewNativeClassInstance here.
|
||||
*/
|
||||
gc::FinalizeKind kind = NewObjectGCKind(cx, clasp);
|
||||
return NewNonFunction<WithProto::Given>(cx, clasp, proto, parent, kind);
|
||||
gc::FinalizeKind kind = NewObjectGCKind(cx, &js_ObjectClass);
|
||||
return NewNativeClassInstance(cx, &js_ObjectClass, proto, parent, kind);
|
||||
}
|
||||
|
||||
JS_DEFINE_CALLINFO_3(extern, CONSTRUCTOR_RETRY, js_CreateThisFromTrace, CONTEXT, CLASS, OBJECT, 0,
|
||||
JS_DEFINE_CALLINFO_3(extern, CONSTRUCTOR_RETRY, js_CreateThisFromTrace, CONTEXT, OBJECT, UINTN, 0,
|
||||
nanojit::ACCSET_STORE_ANY)
|
||||
|
||||
#else /* !JS_TRACER */
|
||||
|
|
|
@ -10483,13 +10483,6 @@ TraceRecorder::record_EnterFrame()
|
|||
RETURN_STOP_A("recursion started inlining");
|
||||
}
|
||||
|
||||
if (fp->isConstructing()) {
|
||||
LIns* args[] = { callee_ins, w.nameImmpNonGC(&js_ObjectClass), cx_ins };
|
||||
LIns* tv_ins = w.call(&js_CreateThisFromTrace_ci, args);
|
||||
guard(false, w.eqp0(tv_ins), OOM_EXIT);
|
||||
set(&fp->thisValue(), tv_ins);
|
||||
}
|
||||
|
||||
return ARECORD_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -11440,7 +11433,8 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
|
|||
|
||||
Value* vp = &stackval(0 - (2 + argc));
|
||||
JSObject* funobj = &vp[0].toObject();
|
||||
JSFunction* fun = GET_FUNCTION_PRIVATE(cx, funobj);
|
||||
JSFunction* fun = funobj->getFunctionPrivate();
|
||||
JS_ASSERT(fun->isNative());
|
||||
Native native = fun->u.n.native;
|
||||
|
||||
switch (argc) {
|
||||
|
@ -11616,39 +11610,24 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
|
|||
clasp = &js_ObjectClass;
|
||||
JS_ASSERT(((jsuword) clasp & 3) == 0);
|
||||
|
||||
// Abort on |new Function|. js_CreateThis would allocate a regular-
|
||||
// sized JSObject, not a Function-sized one. (The Function ctor would
|
||||
// deep-bail anyway but let's not go there.)
|
||||
// Abort on |new Function|. (FIXME: This restriction might not
|
||||
// unnecessary now that the constructor creates the new function object
|
||||
// itself.)
|
||||
if (clasp == &js_FunctionClass)
|
||||
RETURN_STOP("new Function");
|
||||
|
||||
if (!clasp->isNative())
|
||||
RETURN_STOP("new with non-native ops");
|
||||
|
||||
if (fun->isConstructor()) {
|
||||
// Don't trace |new Math.sin(0)|.
|
||||
if (!fun->isConstructor())
|
||||
RETURN_STOP("new with non-constructor native function");
|
||||
|
||||
vp[1].setMagicWithObjectOrNullPayload(NULL);
|
||||
newobj_ins = w.immpMagicNull();
|
||||
|
||||
/* Treat this as a regular call, the constructor will behave correctly. */
|
||||
mode = JSOP_CALL;
|
||||
} else {
|
||||
args[0] = w.immpObjGC(funobj);
|
||||
args[1] = w.immpNonGC(clasp);
|
||||
args[2] = cx_ins;
|
||||
newobj_ins = w.call(&js_CreateThisFromTrace_ci, args);
|
||||
guard(false, w.eqp0(newobj_ins), OOM_EXIT);
|
||||
|
||||
/*
|
||||
* emitNativeCall may take a snapshot below. To avoid having a type
|
||||
* mismatch (e.g., where get(&vp[1]) is an object and vp[1] is
|
||||
* null), we make sure vp[1] is some object. The actual object
|
||||
* doesn't matter; JSOP_NEW and InvokeConstructor both overwrite
|
||||
* vp[1] without observing its value.
|
||||
*
|
||||
* N.B. tracing specializes for functions, so pick a non-function.
|
||||
*/
|
||||
vp[1].setObject(*globalObj);
|
||||
}
|
||||
this_ins = newobj_ins;
|
||||
} else {
|
||||
this_ins = get(&vp[1]);
|
||||
|
@ -13741,6 +13720,42 @@ TraceRecorder::guardArguments(JSObject *obj, LIns* obj_ins, unsigned *depthp)
|
|||
return afp;
|
||||
}
|
||||
|
||||
JS_REQUIRES_STACK RecordingStatus
|
||||
TraceRecorder::createThis(JSObject& ctor, LIns* ctor_ins, LIns** thisobj_insp)
|
||||
{
|
||||
JS_ASSERT(ctor.getFunctionPrivate()->isInterpreted());
|
||||
if (ctor.getFunctionPrivate()->isFunctionPrototype())
|
||||
RETURN_STOP("new Function.prototype");
|
||||
if (ctor.isBoundFunction())
|
||||
RETURN_STOP("new applied to bound function");
|
||||
|
||||
// Given the above conditions, ctor.prototype is a non-configurable data
|
||||
// property with a slot.
|
||||
jsid id = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
|
||||
const Shape *shape = LookupInterpretedFunctionPrototype(cx, &ctor);
|
||||
if (!shape)
|
||||
RETURN_ERROR("new f: error resolving f.prototype");
|
||||
|
||||
// At run time ctor might be a different instance of the same function. Its
|
||||
// .prototype property might not be resolved yet. Guard on the function
|
||||
// object's shape to make sure .prototype is there.
|
||||
//
|
||||
// However, if ctor_ins is constant, which is usual, we don't need to
|
||||
// guard: .prototype is non-configurable, and an object's non-configurable
|
||||
// data properties always stay in the same slot for the life of the object.
|
||||
if (!ctor_ins->isImmP())
|
||||
guardShape(ctor_ins, &ctor, ctor.shape(), "ctor_shape", snapshot(MISMATCH_EXIT));
|
||||
|
||||
// Pass the slot of ctor.prototype to js_CreateThisFromTrace. We can only
|
||||
// bake the slot into the trace, not the value, since .prototype is
|
||||
// writable.
|
||||
uintN protoSlot = shape->slot;
|
||||
LIns* args[] = { w.nameImmw(protoSlot), ctor_ins, cx_ins };
|
||||
*thisobj_insp = w.call(&js_CreateThisFromTrace_ci, args);
|
||||
guard(false, w.eqp0(*thisobj_insp), OOM_EXIT);
|
||||
return RECORD_CONTINUE;
|
||||
}
|
||||
|
||||
JS_REQUIRES_STACK RecordingStatus
|
||||
TraceRecorder::interpretedFunctionCall(Value& fval, JSFunction* fun, uintN argc, bool constructing)
|
||||
{
|
||||
|
@ -13752,14 +13767,10 @@ TraceRecorder::interpretedFunctionCall(Value& fval, JSFunction* fun, uintN argc,
|
|||
*/
|
||||
if (fun->script()->isEmpty()) {
|
||||
LIns* rval_ins;
|
||||
if (constructing) {
|
||||
LIns* args[] = { get(&fval), w.nameImmpNonGC(&js_ObjectClass), cx_ins };
|
||||
LIns* tv_ins = w.call(&js_CreateThisFromTrace_ci, args);
|
||||
guard(false, w.eqp0(tv_ins), OOM_EXIT);
|
||||
rval_ins = tv_ins;
|
||||
} else {
|
||||
if (constructing)
|
||||
CHECK_STATUS(createThis(fval.toObject(), get(&fval), &rval_ins));
|
||||
else
|
||||
rval_ins = w.immiUndefined();
|
||||
}
|
||||
stack(-2 - argc, rval_ins);
|
||||
return RECORD_CONTINUE;
|
||||
}
|
||||
|
@ -13769,6 +13780,12 @@ TraceRecorder::interpretedFunctionCall(Value& fval, JSFunction* fun, uintN argc,
|
|||
|
||||
JSStackFrame* const fp = cx->fp();
|
||||
|
||||
if (constructing) {
|
||||
LIns* thisobj_ins;
|
||||
CHECK_STATUS(createThis(fval.toObject(), get(&fval), &thisobj_ins));
|
||||
stack(-argc - 1, thisobj_ins);
|
||||
}
|
||||
|
||||
// Generate a type map for the outgoing frame and stash it in the LIR
|
||||
unsigned stackSlots = NativeStackSlots(cx, 0 /* callDepth */);
|
||||
FrameInfo* fi = (FrameInfo*)
|
||||
|
|
|
@ -1483,6 +1483,8 @@ class TraceRecorder
|
|||
JS_REQUIRES_STACK RecordingStatus guardNativeConversion(Value& v);
|
||||
JS_REQUIRES_STACK void clearReturningFrameFromNativeTracker();
|
||||
JS_REQUIRES_STACK void putActivationObjects();
|
||||
JS_REQUIRES_STACK RecordingStatus createThis(JSObject& ctor, nanojit::LIns* ctor_ins,
|
||||
nanojit::LIns** thisobj_insp);
|
||||
JS_REQUIRES_STACK RecordingStatus guardCallee(Value& callee);
|
||||
JS_REQUIRES_STACK JSStackFrame *guardArguments(JSObject *obj, nanojit::LIns* obj_ins,
|
||||
unsigned *depthp);
|
||||
|
|
Загрузка…
Ссылка в новой задаче