зеркало из https://github.com/mozilla/gecko-dev.git
Bug 579471 - fast constructors (r=dmandelin,lw)
This commit is contained in:
Родитель
04dc9788a5
Коммит
3a7d7158e0
|
@ -1007,7 +1007,8 @@ Class js_ArrayClass = {
|
|||
"Array",
|
||||
Class::NON_NATIVE |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::DENSE_ARRAY_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Array) |
|
||||
JSCLASS_FAST_CONSTRUCTOR,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
|
@ -1042,7 +1043,9 @@ Class js_ArrayClass = {
|
|||
|
||||
Class js_SlowArrayClass = {
|
||||
"Array",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Array) |
|
||||
JSCLASS_FAST_CONSTRUCTOR,
|
||||
slowarray_addProperty,
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
|
@ -2953,31 +2956,29 @@ NewDenseArrayObject(JSContext *cx)
|
|||
}
|
||||
|
||||
JSBool
|
||||
js_Array(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
|
||||
js_Array(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
jsuint length;
|
||||
const Value *vector;
|
||||
|
||||
/* If called without new, replace obj with a new Array object. */
|
||||
if (!JS_IsConstructing(cx)) {
|
||||
obj = NewDenseArrayObject(cx);
|
||||
/* Whether called with 'new' or not, use a new Array object. */
|
||||
JSObject *obj = NewDenseArrayObject(cx);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
rval->setObject(*obj);
|
||||
}
|
||||
vp->setObject(*obj);
|
||||
|
||||
if (argc == 0) {
|
||||
length = 0;
|
||||
vector = NULL;
|
||||
} else if (argc > 1) {
|
||||
length = (jsuint) argc;
|
||||
vector = argv;
|
||||
} else if (!argv[0].isNumber()) {
|
||||
vector = vp + 2;
|
||||
} else if (!vp[2].isNumber()) {
|
||||
length = 1;
|
||||
vector = argv;
|
||||
vector = vp + 2;
|
||||
} else {
|
||||
length = ValueIsLength(cx, &argv[0]);
|
||||
if (argv[0].isNull())
|
||||
length = ValueIsLength(cx, vp + 2);
|
||||
if (vp[2].isNull())
|
||||
return JS_FALSE;
|
||||
vector = NULL;
|
||||
}
|
||||
|
@ -3027,7 +3028,7 @@ JS_DEFINE_CALLINFO_3(extern, OBJECT, js_NewPreallocatedArray, CONTEXT, OBJECT, I
|
|||
JSObject *
|
||||
js_InitArrayClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObject *proto = js_InitClass(cx, obj, NULL, &js_ArrayClass, js_Array, 1,
|
||||
JSObject *proto = js_InitClass(cx, obj, NULL, &js_ArrayClass, (Native) js_Array, 1,
|
||||
NULL, array_methods, NULL, array_static_methods);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
|
|
@ -239,7 +239,7 @@ js_GetDenseArrayElementValue(JSContext *cx, JSObject *obj, jsid id,
|
|||
|
||||
/* Array constructor native. Exposed only so the JIT can know its address. */
|
||||
JSBool
|
||||
js_Array(JSContext* cx, JSObject* obj, uintN argc, js::Value* argv, js::Value* rval);
|
||||
js_Array(JSContext *cx, uintN argc, js::Value *vp);
|
||||
|
||||
/*
|
||||
* Friend api function that allows direct creation of an array object with a
|
||||
|
|
|
@ -484,7 +484,8 @@ msFromTime(jsdouble t)
|
|||
Class js_DateClass = {
|
||||
js_Date_str,
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JSObject::DATE_FIXED_RESERVED_SLOTS) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Date) |
|
||||
JSCLASS_FAST_CONSTRUCTOR,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
|
@ -2302,28 +2303,28 @@ static JSFunctionSpec date_methods[] = {
|
|||
};
|
||||
|
||||
JSBool
|
||||
js_Date(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
|
||||
js_Date(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
/* Date called as function. */
|
||||
if (!JS_IsConstructing(cx))
|
||||
return date_format(cx, NowAsMillis(), FORMATSPEC_FULL, rval);
|
||||
if (!vp[1].isMagic(JS_FAST_CONSTRUCTOR))
|
||||
return date_format(cx, NowAsMillis(), FORMATSPEC_FULL, vp);
|
||||
|
||||
/* Date called as constructor. */
|
||||
jsdouble d;
|
||||
if (argc == 0) {
|
||||
d = NowAsMillis();
|
||||
} else if (argc == 1) {
|
||||
if (!argv[0].isString()) {
|
||||
if (!vp[2].isString()) {
|
||||
/* the argument is a millisecond number */
|
||||
if (!ValueToNumber(cx, argv[0], &d))
|
||||
if (!ValueToNumber(cx, vp[2], &d))
|
||||
return JS_FALSE;
|
||||
d = TIMECLIP(d);
|
||||
} else {
|
||||
/* the argument is a string; parse it. */
|
||||
JSString *str = js_ValueToString(cx, argv[0]);
|
||||
JSString *str = js_ValueToString(cx, vp[2]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
argv[0].setString(str);
|
||||
vp[2].setString(str);
|
||||
|
||||
if (!date_parseString(str, &d, cx))
|
||||
d = js_NaN;
|
||||
|
@ -2332,7 +2333,7 @@ js_Date(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
|
|||
}
|
||||
} else {
|
||||
jsdouble msec_time;
|
||||
if (!date_msecFromArgs(cx, argc, argv, &msec_time))
|
||||
if (!date_msecFromArgs(cx, argc, vp + 2, &msec_time))
|
||||
return JS_FALSE;
|
||||
|
||||
if (JSDOUBLE_IS_FINITE(msec_time)) {
|
||||
|
@ -2341,7 +2342,13 @@ js_Date(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
|
|||
}
|
||||
d = msec_time;
|
||||
}
|
||||
return SetUTCTime(cx, obj, d);
|
||||
|
||||
JSObject *obj = js_NewDateObjectMsec(cx, d);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
vp->setObject(*obj);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
@ -2349,7 +2356,7 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
|
|||
{
|
||||
/* set static LocalTZA */
|
||||
LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
|
||||
JSObject *proto = js_InitClass(cx, obj, NULL, &js_DateClass, js_Date, MAXARGS,
|
||||
JSObject *proto = js_InitClass(cx, obj, NULL, &js_DateClass, (Native) js_Date, MAXARGS,
|
||||
NULL, date_methods, NULL, date_static_methods);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
|
|
@ -132,6 +132,6 @@ js_IntervalNow();
|
|||
|
||||
/* Date constructor native. Exposed only so the JIT can know its address. */
|
||||
JSBool
|
||||
js_Date(JSContext *cx, JSObject *obj, uintN argc, js::Value *argv, js::Value *rval);
|
||||
js_Date(JSContext *cx, uintN argc, js::Value *vp);
|
||||
|
||||
#endif /* jsdate_h___ */
|
||||
|
|
|
@ -2435,7 +2435,8 @@ js_NewFunction(JSContext *cx, JSObject *funobj, Native native, uintN nargs,
|
|||
|
||||
/* Initialize all function members. */
|
||||
fun->nargs = uint16(nargs);
|
||||
fun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_KINDMASK | JSFUN_TRCINFO);
|
||||
fun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_KINDMASK |
|
||||
JSFUN_TRCINFO | JSFUN_FAST_NATIVE_CTOR);
|
||||
if ((flags & JSFUN_KINDMASK) >= JSFUN_INTERPRETED) {
|
||||
JS_ASSERT(!native);
|
||||
JS_ASSERT(nargs == 0);
|
||||
|
@ -2579,7 +2580,8 @@ js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, Native native,
|
|||
} else {
|
||||
gsop = NULL;
|
||||
}
|
||||
fun = js_NewFunction(cx, NULL, native, nargs, attrs, obj, atom);
|
||||
fun = js_NewFunction(cx, NULL, native, nargs,
|
||||
attrs & (JSFUN_FLAGS_MASK | JSFUN_TRCINFO), obj, atom);
|
||||
if (!fun)
|
||||
return NULL;
|
||||
if (!obj->defineProperty(cx, ATOM_TO_JSID(atom), ObjectValue(*fun),
|
||||
|
|
|
@ -101,6 +101,17 @@ typedef union JSLocalNames {
|
|||
appear to call itself via its own name
|
||||
or arguments.callee */
|
||||
|
||||
#define JSFUN_FAST_NATIVE_CTOR 0x0002 /* JSFastNative directly invokable
|
||||
* during construction. */
|
||||
|
||||
/*
|
||||
* Extra JSCLASS flag indicating the native passed to JS_InitClass is
|
||||
* a fast native constructor. This is internal for now as the 'this' value passed
|
||||
* to such a constructor is a magic value, and there is no way to query this
|
||||
* in the API. See bug 581263.
|
||||
*/
|
||||
#define JSCLASS_FAST_CONSTRUCTOR (1<<4)
|
||||
|
||||
#define JSFUN_EXPR_CLOSURE 0x1000 /* expression closure: function(x) x*x */
|
||||
#define JSFUN_TRCINFO 0x2000 /* when set, u.n.trcinfo is non-null,
|
||||
JSFunctionSpec::call points to a
|
||||
|
@ -169,6 +180,7 @@ struct JSFunction : public JSObject
|
|||
bool needsWrapper() const { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
|
||||
bool isInterpreted() const { return FUN_INTERPRETED(this); }
|
||||
bool isFastNative() const { return !!(flags & JSFUN_FAST_NATIVE); }
|
||||
bool isFastConstructor() const { return !!(flags & JSFUN_FAST_NATIVE_CTOR); }
|
||||
bool isHeavyweight() const { return JSFUN_HEAVYWEIGHT_TEST(flags); }
|
||||
unsigned minArgs() const { return FUN_MINARGS(this); }
|
||||
|
||||
|
|
|
@ -286,7 +286,12 @@ namespace js {
|
|||
JSObject *
|
||||
ComputeThisFromArgv(JSContext *cx, Value *argv)
|
||||
{
|
||||
JS_ASSERT(!argv[-1].isMagic(JS_THIS_POISON));
|
||||
/*
|
||||
* Check for SynthesizeFrame poisoning and fast constructors which
|
||||
* didn't check their vp properly.
|
||||
*/
|
||||
JS_ASSERT(!argv[-1].isMagic());
|
||||
|
||||
if (argv[-1].isNull())
|
||||
return ComputeGlobalThis(cx, argv);
|
||||
|
||||
|
@ -1126,19 +1131,35 @@ InvokeConstructor(JSContext *cx, const CallArgs &argsRef)
|
|||
return false;
|
||||
}
|
||||
|
||||
Class *clasp = &js_ObjectClass;
|
||||
|
||||
/*
|
||||
* Call fast constructors without making the object first.
|
||||
* The native will be able to make the right new object faster.
|
||||
*/
|
||||
if (obj2->isFunction()) {
|
||||
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj2);
|
||||
if (fun->isFastConstructor()) {
|
||||
args.thisv().setMagic(JS_FAST_CONSTRUCTOR);
|
||||
|
||||
FastNative fn = (FastNative)fun->u.n.native;
|
||||
if (!fn(cx, args.argc(), args.base()))
|
||||
return JS_FALSE;
|
||||
JS_ASSERT(!args.rval().isPrimitive());
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Get the class, for natives that aren't fast constructors. */
|
||||
if (!fun->isInterpreted() && fun->u.n.clasp)
|
||||
clasp = fun->u.n.clasp;
|
||||
}
|
||||
|
||||
Value protov;
|
||||
if (!obj2->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom), &protov))
|
||||
return false;
|
||||
|
||||
JSObject *proto = protov.isObjectOrNull() ? protov.toObjectOrNull() : NULL;
|
||||
JSObject *parent = obj2->getParent();
|
||||
Class *clasp = &js_ObjectClass;
|
||||
|
||||
if (obj2->getClass() == &js_FunctionClass) {
|
||||
JSFunction *f = GET_FUNCTION_PRIVATE(cx, obj2);
|
||||
if (!f->isInterpreted() && f->u.n.clasp)
|
||||
clasp = f->u.n.clasp;
|
||||
}
|
||||
|
||||
JSObject* obj = NewObject<WithProto::Class>(cx, clasp, proto, parent);
|
||||
if (!obj)
|
||||
|
|
|
@ -106,7 +106,8 @@ JS_FRIEND_DATA(const JSObjectMap) JSObjectMap::sharedNonNative(JSObjectMap::SHAP
|
|||
|
||||
Class js_ObjectClass = {
|
||||
js_Object_str,
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
|
||||
JSCLASS_FAST_CONSTRUCTOR,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
|
@ -2554,25 +2555,25 @@ static JSFunctionSpec object_static_methods[] = {
|
|||
};
|
||||
|
||||
JSBool
|
||||
js_Object(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
|
||||
js_Object(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
JSObject *obj;
|
||||
if (argc == 0) {
|
||||
/* Trigger logic below to construct a blank object. */
|
||||
obj = NULL;
|
||||
} else {
|
||||
/* If argv[0] is null or undefined, obj comes back null. */
|
||||
if (!js_ValueToObjectOrNull(cx, argv[0], &obj))
|
||||
if (!js_ValueToObjectOrNull(cx, vp[2], &obj))
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (!obj) {
|
||||
JS_ASSERT(!argc || argv[0].isNull() || argv[0].isUndefined());
|
||||
if (JS_IsConstructing(cx))
|
||||
return JS_TRUE;
|
||||
/* Make an object whether this was called with 'new' or not. */
|
||||
JS_ASSERT(!argc || vp[2].isNull() || vp[2].isUndefined());
|
||||
obj = NewBuiltinClassInstance(cx, &js_ObjectClass);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
rval->setObject(*obj);
|
||||
vp->setObject(*obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -3253,7 +3254,7 @@ Class js_BlockClass = {
|
|||
JSObject *
|
||||
js_InitObjectClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObject *proto = js_InitClass(cx, obj, NULL, &js_ObjectClass, js_Object, 1,
|
||||
JSObject *proto = js_InitClass(cx, obj, NULL, &js_ObjectClass, (Native) js_Object, 1,
|
||||
object_props, object_methods, NULL, object_static_methods);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
@ -3402,7 +3403,11 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
|||
|
||||
ctor = proto;
|
||||
} else {
|
||||
fun = js_NewFunction(cx, NULL, constructor, nargs, 0, obj, atom);
|
||||
uint16 flags = 0;
|
||||
if (clasp->flags & JSCLASS_FAST_CONSTRUCTOR)
|
||||
flags |= JSFUN_FAST_NATIVE | JSFUN_FAST_NATIVE_CTOR;
|
||||
|
||||
fun = js_NewFunction(cx, NULL, constructor, nargs, flags, obj, atom);
|
||||
if (!fun)
|
||||
goto bad;
|
||||
|
||||
|
|
|
@ -1332,7 +1332,7 @@ js_InferFlags(JSContext *cx, uintN defaultFlags);
|
|||
|
||||
/* Object constructor native. Exposed only so the JIT can know its address. */
|
||||
JSBool
|
||||
js_Object(JSContext *cx, JSObject *obj, uintN argc, js::Value *argv, js::Value *rval);
|
||||
js_Object(JSContext *cx, uintN argc, js::Value *vp);
|
||||
|
||||
|
||||
namespace js {
|
||||
|
|
|
@ -817,7 +817,8 @@ str_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|||
Class js_StringClass = {
|
||||
js_String_str,
|
||||
JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_NEW_RESOLVE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_String),
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_String) |
|
||||
JSCLASS_FAST_CONSTRUCTOR,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
str_getProperty,
|
||||
|
@ -3057,23 +3058,28 @@ const char JSString::deflatedUnitStringTable[] = {
|
|||
#undef U8
|
||||
|
||||
JSBool
|
||||
js_String(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
|
||||
js_String(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
JSString *str;
|
||||
|
||||
if (argc > 0) {
|
||||
str = js_ValueToString(cx, argv[0]);
|
||||
str = js_ValueToString(cx, vp[2]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
argv[0].setString(str);
|
||||
vp[2].setString(str);
|
||||
} else {
|
||||
str = cx->runtime->emptyString;
|
||||
}
|
||||
if (!JS_IsConstructing(cx)) {
|
||||
rval->setString(str);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (vp[1].isMagic(JS_FAST_CONSTRUCTOR)) {
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &js_StringClass);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
obj->setPrimitiveThis(StringValue(str));
|
||||
vp->setObject(*obj);
|
||||
} else {
|
||||
vp->setString(str);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -3163,7 +3169,7 @@ js_InitStringClass(JSContext *cx, JSObject *obj)
|
|||
if (!JS_DefineFunctions(cx, obj, string_functions))
|
||||
return NULL;
|
||||
|
||||
proto = js_InitClass(cx, obj, NULL, &js_StringClass, js_String, 1,
|
||||
proto = js_InitClass(cx, obj, NULL, &js_StringClass, (Native) js_String, 1,
|
||||
NULL, string_methods,
|
||||
NULL, string_static_methods);
|
||||
if (!proto)
|
||||
|
|
|
@ -1151,7 +1151,7 @@ js_PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp,
|
|||
JSString *str, uint32 quote);
|
||||
|
||||
extern JSBool
|
||||
js_String(JSContext *cx, JSObject *obj, uintN argc, js::Value *argv, js::Value *rval);
|
||||
js_String(JSContext *cx, uintN argc, js::Value *vp);
|
||||
|
||||
namespace js {
|
||||
|
||||
|
|
|
@ -11458,11 +11458,19 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
|
|||
if (!clasp->isNative())
|
||||
RETURN_STOP("new with non-native ops");
|
||||
|
||||
if (fun->isFastConstructor()) {
|
||||
vp[1].setMagic(JS_FAST_CONSTRUCTOR);
|
||||
newobj_ins = INS_CONST(JS_FAST_CONSTRUCTOR);
|
||||
|
||||
/* Treat this as a regular call, the constructor will behave correctly. */
|
||||
mode = JSOP_CALL;
|
||||
} else {
|
||||
args[0] = INS_CONSTOBJ(funobj);
|
||||
args[1] = INS_CONSTPTR(clasp);
|
||||
args[2] = cx_ins;
|
||||
newobj_ins = lir->insCall(&js_NewInstance_ci, args);
|
||||
guard(false, lir->insEqP_0(newobj_ins), OOM_EXIT);
|
||||
}
|
||||
this_ins = newobj_ins;
|
||||
} else if (JSFUN_BOUND_METHOD_TEST(fun->flags)) {
|
||||
this_ins = INS_CONSTOBJ(funobj->getParent());
|
||||
|
@ -11624,8 +11632,7 @@ TraceRecorder::functionCall(uintN argc, JSOp mode)
|
|||
return interpretedFunctionCall(fval, fun, argc, mode == JSOP_NEW);
|
||||
}
|
||||
|
||||
if (FUN_SLOW_NATIVE(fun)) {
|
||||
Native native = fun->u.n.native;
|
||||
FastNative native = FUN_FAST_NATIVE(fun);
|
||||
Value* argv = &tval + 1;
|
||||
if (native == js_Array)
|
||||
return newArray(&fval.toObject(), argc, argv, &fval);
|
||||
|
@ -11640,7 +11647,6 @@ TraceRecorder::functionCall(uintN argc, JSOp mode)
|
|||
pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK;
|
||||
return RECORD_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
RecordingStatus rs = callNative(argc, mode);
|
||||
#ifdef MOZ_TRACE_JSCALLS
|
||||
|
@ -13513,10 +13519,11 @@ TraceRecorder::record_NativeCallComplete()
|
|||
if (pendingSpecializedNative == IGNORE_NATIVE_CALL_COMPLETE_CALLBACK)
|
||||
return ARECORD_CONTINUE;
|
||||
|
||||
jsbytecode* pc = cx->regs->pc;
|
||||
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(pendingSpecializedNative);
|
||||
jsbytecode* pc = cx->regs->pc;
|
||||
JS_ASSERT(*pc == JSOP_CALL || *pc == JSOP_APPLY || *pc == JSOP_NEW || *pc == JSOP_SETPROP);
|
||||
#endif
|
||||
|
||||
Value& v = stackval(-1);
|
||||
LIns* v_ins = get(&v);
|
||||
|
@ -13550,7 +13557,7 @@ TraceRecorder::record_NativeCallComplete()
|
|||
* indicating the error status.
|
||||
*/
|
||||
|
||||
if (*pc == JSOP_NEW) {
|
||||
if (pendingSpecializedNative->flags & JSTN_CONSTRUCTOR) {
|
||||
LIns *cond_ins;
|
||||
LIns *x;
|
||||
|
||||
|
|
|
@ -258,6 +258,7 @@ typedef enum JSWhyMagic
|
|||
* enumerated like a native object. */
|
||||
JS_NO_ITER_VALUE, /* there is not a pending iterator value */
|
||||
JS_GENERATOR_CLOSING, /* exception value thrown when closing a generator */
|
||||
JS_FAST_CONSTRUCTOR, /* 'this' value for fast natives invoked with 'new' */
|
||||
JS_NO_CONSTANT, /* compiler sentinel value */
|
||||
JS_THIS_POISON, /* used in debug builds to catch tracing errors */
|
||||
JS_GENERIC_MAGIC /* for local use */
|
||||
|
|
Загрузка…
Ссылка в новой задаче