зеркало из https://github.com/mozilla/gecko-dev.git
Back out 3da143341145 (bug 784294) and 862f9cd7eb0b (bug 791850) for breaking Jetpack
This commit is contained in:
Родитель
c5a421dab6
Коммит
e9d8463b63
|
@ -1,338 +1 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* ES5 15.4.4.14. */
|
||||
function ArrayIndexOf(searchElement/*, fromIndex*/) {
|
||||
/* Step 1. */
|
||||
var O = %ToObject(this);
|
||||
|
||||
/* Steps 2-3. */
|
||||
var len = TO_UINT32(O.length);
|
||||
|
||||
/* Step 4. */
|
||||
if (len === 0)
|
||||
return -1;
|
||||
|
||||
/* Step 5. */
|
||||
var n = arguments.length > 1 ? %ToInteger(arguments[1]) : 0;
|
||||
|
||||
/* Step 6. */
|
||||
if (n >= len)
|
||||
return -1;
|
||||
|
||||
var k;
|
||||
/* Step 7. */
|
||||
if (n >= 0)
|
||||
k = n;
|
||||
/* Step 8. */
|
||||
else {
|
||||
/* Step a. */
|
||||
k = len + n;
|
||||
/* Step b. */
|
||||
if (k < 0)
|
||||
k = 0;
|
||||
}
|
||||
|
||||
/* Step 9. */
|
||||
for (; k < len; k++) {
|
||||
if (k in O && O[k] === searchElement)
|
||||
return k;
|
||||
}
|
||||
|
||||
/* Step 10. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
function ArrayStaticIndexOf(list, searchElement/*, fromIndex*/) {
|
||||
if (arguments.length < 1)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.indexOf');
|
||||
var fromIndex = arguments.length > 2 ? arguments[2] : 0;
|
||||
return %_CallFunction(list, searchElement, fromIndex, ArrayIndexOf);
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.15. */
|
||||
function ArrayLastIndexOf(searchElement/*, fromIndex*/) {
|
||||
/* Step 1. */
|
||||
var O = %ToObject(this);
|
||||
|
||||
/* Steps 2-3. */
|
||||
var len = TO_UINT32(O.length);
|
||||
|
||||
/* Step 4. */
|
||||
if (len === 0)
|
||||
return -1;
|
||||
|
||||
/* Step 5. */
|
||||
var n = arguments.length > 1 ? %ToInteger(arguments[1]) : len - 1;
|
||||
|
||||
/* Steps 6-7. */
|
||||
var k;
|
||||
if (n > len - 1)
|
||||
k = len - 1;
|
||||
else if (n < 0)
|
||||
k = len + n;
|
||||
else
|
||||
k = n;
|
||||
|
||||
/* Step 8. */
|
||||
for (; k >= 0; k--) {
|
||||
if (k in O && O[k] === searchElement)
|
||||
return k;
|
||||
}
|
||||
|
||||
/* Step 9. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
function ArrayStaticLastIndexOf(list, searchElement/*, fromIndex*/) {
|
||||
if (arguments.length < 1)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.lastIndexOf');
|
||||
var fromIndex;
|
||||
if (arguments.length > 2) {
|
||||
fromIndex = arguments[2];
|
||||
} else {
|
||||
var O = %ToObject(list);
|
||||
var len = TO_UINT32(O.length);
|
||||
fromIndex = len - 1;
|
||||
}
|
||||
return %_CallFunction(list, searchElement, fromIndex, ArrayLastIndexOf);
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.16. */
|
||||
function ArrayEvery(callbackfn/*, thisArg*/) {
|
||||
/* Step 1. */
|
||||
var O = %ToObject(this);
|
||||
|
||||
/* Steps 2-3. */
|
||||
var len = TO_UINT32(O.length);
|
||||
|
||||
/* Step 4. */
|
||||
if (arguments.length === 0)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.every');
|
||||
if (!IsCallable(callbackfn))
|
||||
%ThrowError(JSMSG_NOT_FUNCTION, callbackfn);
|
||||
|
||||
/* Step 5. */
|
||||
var T = arguments.length > 1 ? arguments[1] : void 0;
|
||||
|
||||
/* Steps 6-7. */
|
||||
/* Steps a (implicit), and d. */
|
||||
for (var k = 0; k < len; k++) {
|
||||
/* Step b */
|
||||
if (k in O) {
|
||||
/* Step c. */
|
||||
if (!%_CallFunction(T, O[k], k, O, callbackfn))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 8. */
|
||||
return true;
|
||||
}
|
||||
|
||||
function ArrayStaticEvery(list, callbackfn/*, thisArg*/) {
|
||||
if (arguments.length < 2)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.every');
|
||||
var T = arguments.length > 2 ? arguments[2] : void 0;
|
||||
return %_CallFunction(list, callbackfn, T, ArrayEvery);
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.17. */
|
||||
function ArraySome(callbackfn/*, thisArg*/) {
|
||||
/* Step 1. */
|
||||
var O = %ToObject(this);
|
||||
|
||||
/* Steps 2-3. */
|
||||
var len = TO_UINT32(O.length);
|
||||
|
||||
/* Step 4. */
|
||||
if (arguments.length === 0)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.some');
|
||||
if (!IsCallable(callbackfn))
|
||||
%ThrowError(JSMSG_NOT_FUNCTION, callbackfn);
|
||||
|
||||
/* Step 5. */
|
||||
var T = arguments.length > 1 ? arguments[1] : void 0;
|
||||
|
||||
/* Steps 6-7. */
|
||||
/* Steps a (implicit), and d. */
|
||||
for (var k = 0; k < len; k++) {
|
||||
/* Step b */
|
||||
if (k in O) {
|
||||
/* Step c. */
|
||||
if (%_CallFunction(T, O[k], k, O, callbackfn))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 8. */
|
||||
return false;
|
||||
}
|
||||
|
||||
function ArrayStaticSome(list, callbackfn/*, thisArg*/) {
|
||||
if (arguments.length < 2)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.some');
|
||||
var T = arguments.length > 2 ? arguments[2] : void 0;
|
||||
return %_CallFunction(list, callbackfn, T, ArraySome);
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.18. */
|
||||
function ArrayForEach(callbackfn/*, thisArg*/) {
|
||||
/* Step 1. */
|
||||
var O = %ToObject(this);
|
||||
|
||||
/* Steps 2-3. */
|
||||
var len = TO_UINT32(O.length);
|
||||
|
||||
/* Step 4. */
|
||||
if (arguments.length === 0)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.forEach');
|
||||
if (!IsCallable(callbackfn))
|
||||
%ThrowError(JSMSG_NOT_FUNCTION, callbackfn);
|
||||
|
||||
/* Step 5. */
|
||||
var T = arguments.length > 1 ? arguments[1] : void 0;
|
||||
|
||||
/* Steps 6-7. */
|
||||
/* Steps a (implicit), and d. */
|
||||
for (var k = 0; k < len; k++) {
|
||||
/* Step b */
|
||||
if (k in O) {
|
||||
/* Step c. */
|
||||
%_CallFunction(T, O[k], k, O, callbackfn);
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 8. */
|
||||
return void 0;
|
||||
}
|
||||
|
||||
function ArrayStaticForEach(list, callbackfn/*, thisArg*/) {
|
||||
if (arguments.length < 2)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.forEach');
|
||||
var T = arguments.length > 2 ? arguments[2] : void 0;
|
||||
%_CallFunction(list, callbackfn, T, ArrayForEach);
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.21. */
|
||||
function ArrayReduce(callbackfn/*, initialValue*/) {
|
||||
/* Step 1. */
|
||||
var O = %ToObject(this);
|
||||
|
||||
/* Steps 2-3. */
|
||||
var len = TO_UINT32(O.length);
|
||||
|
||||
/* Step 4. */
|
||||
if (arguments.length === 0)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.reduce');
|
||||
if (!IsCallable(callbackfn))
|
||||
%ThrowError(JSMSG_NOT_FUNCTION, callbackfn);
|
||||
|
||||
/* Step 6. */
|
||||
var k = 0;
|
||||
|
||||
/* Steps 5, 7-8. */
|
||||
var accumulator;
|
||||
if (arguments.length > 1) {
|
||||
accumulator = arguments[1];
|
||||
} else {
|
||||
/* Step 5. */
|
||||
if (len === 0)
|
||||
%ThrowError(JSMSG_EMPTY_ARRAY_REDUCE);
|
||||
var kPresent = false;
|
||||
for (; k < len; k++) {
|
||||
if (k in O) {
|
||||
accumulator = O[k];
|
||||
kPresent = true;
|
||||
k++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!kPresent)
|
||||
%ThrowError(JSMSG_EMPTY_ARRAY_REDUCE);
|
||||
}
|
||||
|
||||
/* Step 9. */
|
||||
/* Steps a (implicit), and d. */
|
||||
for (; k < len; k++) {
|
||||
/* Step b */
|
||||
if (k in O) {
|
||||
/* Step c. */
|
||||
accumulator = callbackfn(accumulator, O[k], k, O);
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 10. */
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
function ArrayStaticReduce(list, callbackfn) {
|
||||
if (arguments.length < 2)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.reduce');
|
||||
if (arguments.length > 2)
|
||||
%_CallFunction(list, callbackfn, arguments[2], ArrayReduce);
|
||||
else
|
||||
%_CallFunction(list, callbackfn, ArrayReduce);
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.22. */
|
||||
function ArrayReduceRight(callbackfn/*, initialValue*/) {
|
||||
/* Step 1. */
|
||||
var O = %ToObject(this);
|
||||
|
||||
/* Steps 2-3. */
|
||||
var len = TO_UINT32(O.length);
|
||||
|
||||
/* Step 4. */
|
||||
if (arguments.length === 0)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.reduce');
|
||||
if (!IsCallable(callbackfn))
|
||||
%ThrowError(JSMSG_NOT_FUNCTION, callbackfn);
|
||||
|
||||
/* Step 6. */
|
||||
var k = len - 1;
|
||||
|
||||
/* Steps 5, 7-8. */
|
||||
var accumulator;
|
||||
if (arguments.length > 1) {
|
||||
accumulator = arguments[1];
|
||||
} else {
|
||||
/* Step 5. */
|
||||
if (len === 0)
|
||||
%ThrowError(JSMSG_EMPTY_ARRAY_REDUCE);
|
||||
var kPresent = false;
|
||||
for (; k >= 0; k--) {
|
||||
if (k in O) {
|
||||
accumulator = O[k];
|
||||
kPresent = true;
|
||||
k--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!kPresent)
|
||||
%ThrowError(JSMSG_EMPTY_ARRAY_REDUCE);
|
||||
}
|
||||
|
||||
/* Step 9. */
|
||||
/* Steps a (implicit), and d. */
|
||||
for (; k >= 0; k--) {
|
||||
/* Step b */
|
||||
if (k in O) {
|
||||
/* Step c. */
|
||||
accumulator = callbackfn(accumulator, O[k], k, O);
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 10. */
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
function ArrayStaticReduceRight(list, callbackfn) {
|
||||
if (arguments.length < 2)
|
||||
%ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'Array.reduceRight');
|
||||
if (arguments.length > 2)
|
||||
%_CallFunction(list, callbackfn, arguments[2], ArrayReduceRight);
|
||||
else
|
||||
%_CallFunction(list, callbackfn, ArrayReduceRight);
|
||||
}
|
||||
//this space intentionally left blank
|
|
@ -2665,7 +2665,7 @@ frontend::EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *bod
|
|||
/* Initialize fun->script() so that the debugger has a valid fun->script(). */
|
||||
RootedFunction fun(cx, bce->script->function());
|
||||
JS_ASSERT(fun->isInterpreted());
|
||||
JS_ASSERT(!fun->hasScript());
|
||||
JS_ASSERT(!fun->script().unsafeGet());
|
||||
fun->setScript(bce->script);
|
||||
if (!JSFunction::setTypeForScriptedFunction(cx, fun, singleton))
|
||||
return false;
|
||||
|
@ -4835,7 +4835,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
AssertCanGC();
|
||||
RootedFunction fun(cx, pn->pn_funbox->function());
|
||||
JS_ASSERT(fun->isInterpreted());
|
||||
if (fun->hasScript()) {
|
||||
if (fun->script().unsafeGet()) {
|
||||
/*
|
||||
* This second pass is needed to emit JSOP_NOP with a source note
|
||||
* for the already-emitted function definition prolog opcode. See
|
||||
|
|
|
@ -4995,8 +4995,8 @@ JS_DefineFunctions(JSContext *cx, JSObject *objArg, JSFunctionSpec *fs)
|
|||
|
||||
flags &= ~JSFUN_GENERIC_NATIVE;
|
||||
JSFunction *fun = js_DefineFunction(cx, ctor, id, js_generic_native_method_dispatcher,
|
||||
fs->nargs + 1, flags,
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
fs->nargs + 1, flags, NullPtr(),
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -5017,26 +5017,19 @@ JS_DefineFunctions(JSContext *cx, JSObject *objArg, JSFunctionSpec *fs)
|
|||
if (fs->selfHostedName && cx->runtime->isSelfHostedGlobal(cx->global()))
|
||||
return JS_TRUE;
|
||||
|
||||
/*
|
||||
* Delay cloning self-hosted functions until they are called. This is
|
||||
* achieved by passing js_DefineFunction a NULL JSNative which
|
||||
* produces an interpreted JSFunction where !hasScript. Interpreted
|
||||
* call paths then call InitializeLazyFunctionScript if !hasScript.
|
||||
*/
|
||||
Rooted<PropertyName*> selfHostedPropertyName(cx);
|
||||
if (fs->selfHostedName) {
|
||||
JSFunction *fun = js_DefineFunction(cx, obj, id, /* native = */ NULL, fs->nargs, 0,
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
if (!fun)
|
||||
JSAtom *selfHostedAtom = Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName));
|
||||
if (!selfHostedAtom)
|
||||
return JS_FALSE;
|
||||
fun->setIsSelfHostedBuiltin();
|
||||
fun->setExtendedSlot(0, PrivateValue(fs));
|
||||
} else {
|
||||
JSFunction *fun = js_DefineFunction(cx, obj, id, fs->call.op, fs->nargs, flags);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
if (fs->call.info)
|
||||
fun->setJitInfo(fs->call.info);
|
||||
selfHostedPropertyName = selfHostedAtom->asPropertyName();
|
||||
}
|
||||
JSFunction *fun = js_DefineFunction(cx, obj, id, fs->call.op, fs->nargs, flags,
|
||||
selfHostedPropertyName);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
if (fs->call.info)
|
||||
fun->setJitInfo(fs->call.info);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
|
@ -2939,6 +2939,228 @@ array_slice(JSContext *cx, unsigned argc, Value *vp)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
enum IndexOfKind {
|
||||
IndexOf,
|
||||
LastIndexOf
|
||||
};
|
||||
|
||||
static JSBool
|
||||
array_indexOfHelper(JSContext *cx, IndexOfKind mode, CallArgs &args)
|
||||
{
|
||||
uint32_t length, i, stop;
|
||||
int direction;
|
||||
JSBool hole;
|
||||
|
||||
RootedValue tosearch(cx), elt(cx);
|
||||
|
||||
RootedObject obj(cx, ToObject(cx, args.thisv()));
|
||||
if (!obj)
|
||||
return false;
|
||||
if (!GetLengthProperty(cx, obj, &length))
|
||||
return JS_FALSE;
|
||||
if (length == 0)
|
||||
goto not_found;
|
||||
|
||||
if (args.length() <= 1) {
|
||||
i = (mode == LastIndexOf) ? length - 1 : 0;
|
||||
tosearch = (args.length() != 0) ? args[0] : UndefinedValue();
|
||||
} else {
|
||||
double start;
|
||||
|
||||
tosearch = args[0];
|
||||
if (!ToInteger(cx, args[1], &start))
|
||||
return false;
|
||||
if (start < 0) {
|
||||
start += length;
|
||||
if (start < 0) {
|
||||
if (mode == LastIndexOf)
|
||||
goto not_found;
|
||||
i = 0;
|
||||
} else {
|
||||
i = (uint32_t)start;
|
||||
}
|
||||
} else if (start >= length) {
|
||||
if (mode == IndexOf)
|
||||
goto not_found;
|
||||
i = length - 1;
|
||||
} else {
|
||||
i = (uint32_t)start;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == LastIndexOf) {
|
||||
stop = 0;
|
||||
direction = -1;
|
||||
} else {
|
||||
stop = length - 1;
|
||||
direction = 1;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
|
||||
!GetElement(cx, obj, (uint32_t)i, &hole, &elt)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (!hole) {
|
||||
bool equal;
|
||||
if (!StrictlyEqual(cx, elt, tosearch, &equal))
|
||||
return false;
|
||||
if (equal) {
|
||||
args.rval().setNumber(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (i == stop)
|
||||
goto not_found;
|
||||
i += direction;
|
||||
}
|
||||
|
||||
not_found:
|
||||
args.rval().setInt32(-1);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
array_indexOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return array_indexOfHelper(cx, IndexOf, args);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
array_lastIndexOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return array_indexOfHelper(cx, LastIndexOf, args);
|
||||
}
|
||||
|
||||
/* ECMA 15.4.4.16-15.4.4.18. */
|
||||
class ArrayForEachBehavior
|
||||
{
|
||||
public:
|
||||
static bool shouldExit(MutableHandleValue callbackRval, MutableHandleValue rval) { return false; }
|
||||
static Value lateExitValue() { return UndefinedValue(); }
|
||||
};
|
||||
|
||||
class ArrayEveryBehavior
|
||||
{
|
||||
public:
|
||||
static bool shouldExit(MutableHandleValue callbackRval, MutableHandleValue rval)
|
||||
{
|
||||
if (!ToBoolean(callbackRval)) {
|
||||
rval.setBoolean(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static Value lateExitValue() { return BooleanValue(true); }
|
||||
};
|
||||
|
||||
class ArraySomeBehavior
|
||||
{
|
||||
public:
|
||||
static bool shouldExit(MutableHandleValue callbackRval, MutableHandleValue rval)
|
||||
{
|
||||
if (ToBoolean(callbackRval)) {
|
||||
rval.setBoolean(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static Value lateExitValue() { return BooleanValue(false); }
|
||||
};
|
||||
|
||||
template <class Behavior>
|
||||
static inline bool
|
||||
array_readonlyCommon(JSContext *cx, CallArgs &args)
|
||||
{
|
||||
/* Step 1. */
|
||||
RootedObject obj(cx, ToObject(cx, args.thisv()));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
/* Step 2-3. */
|
||||
uint32_t len;
|
||||
if (!GetLengthProperty(cx, obj, &len))
|
||||
return false;
|
||||
|
||||
/* Step 4. */
|
||||
if (args.length() == 0) {
|
||||
js_ReportMissingArg(cx, args.calleev(), 0);
|
||||
return false;
|
||||
}
|
||||
RootedObject callable(cx, ValueToCallable(cx, &args[0]));
|
||||
if (!callable)
|
||||
return false;
|
||||
|
||||
/* Step 5. */
|
||||
RootedValue thisv(cx, args.length() >= 2 ? args[1] : UndefinedValue());
|
||||
|
||||
/* Step 6. */
|
||||
uint32_t k = 0;
|
||||
|
||||
/* Step 7. */
|
||||
RootedValue kValue(cx);
|
||||
FastInvokeGuard fig(cx, ObjectValue(*callable));
|
||||
InvokeArgsGuard &ag = fig.args();
|
||||
while (k < len) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx))
|
||||
return false;
|
||||
|
||||
/* Step a, b, and c.i. */
|
||||
JSBool kNotPresent;
|
||||
if (!GetElement(cx, obj, k, &kNotPresent, &kValue))
|
||||
return false;
|
||||
|
||||
/* Step c.ii-iii. */
|
||||
if (!kNotPresent) {
|
||||
if (!ag.pushed() && !cx->stack.pushInvokeArgs(cx, 3, &ag))
|
||||
return false;
|
||||
ag.setCallee(ObjectValue(*callable));
|
||||
ag.setThis(thisv);
|
||||
ag[0] = kValue;
|
||||
ag[1] = NumberValue(k);
|
||||
ag[2] = ObjectValue(*obj);
|
||||
if (!fig.invoke(cx))
|
||||
return false;
|
||||
|
||||
if (Behavior::shouldExit(ag.rval(), args.rval()))
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Step d. */
|
||||
k++;
|
||||
}
|
||||
|
||||
/* Step 8. */
|
||||
args.rval().set(Behavior::lateExitValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.16. */
|
||||
static JSBool
|
||||
array_every(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return array_readonlyCommon<ArrayEveryBehavior>(cx, args);
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.17. */
|
||||
static JSBool
|
||||
array_some(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return array_readonlyCommon<ArraySomeBehavior>(cx, args);
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.18. */
|
||||
static JSBool
|
||||
array_forEach(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return array_readonlyCommon<ArrayForEachBehavior>(cx, args);
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.19. */
|
||||
static JSBool
|
||||
array_map(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
@ -3101,6 +3323,137 @@ array_filter(JSContext *cx, unsigned argc, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.21-15.4.4.22. */
|
||||
class ArrayReduceBehavior
|
||||
{
|
||||
public:
|
||||
static void initialize(uint32_t len, uint32_t *start, uint32_t *end, int32_t *step)
|
||||
{
|
||||
*start = 0;
|
||||
*step = 1;
|
||||
*end = len;
|
||||
}
|
||||
};
|
||||
|
||||
class ArrayReduceRightBehavior
|
||||
{
|
||||
public:
|
||||
static void initialize(uint32_t len, uint32_t *start, uint32_t *end, int32_t *step)
|
||||
{
|
||||
*start = len - 1;
|
||||
*step = -1;
|
||||
/*
|
||||
* We rely on (well defined) unsigned integer underflow to check our
|
||||
* end condition after visiting the full range (including 0).
|
||||
*/
|
||||
*end = UINT32_MAX;
|
||||
}
|
||||
};
|
||||
|
||||
template<class Behavior>
|
||||
static inline bool
|
||||
array_reduceCommon(JSContext *cx, CallArgs &args)
|
||||
{
|
||||
/* Step 1. */
|
||||
RootedObject obj(cx, ToObject(cx, args.thisv()));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
/* Step 2-3. */
|
||||
uint32_t len;
|
||||
if (!GetLengthProperty(cx, obj, &len))
|
||||
return false;
|
||||
|
||||
/* Step 4. */
|
||||
if (args.length() == 0) {
|
||||
js_ReportMissingArg(cx, args.calleev(), 0);
|
||||
return false;
|
||||
}
|
||||
RootedObject callable(cx, ValueToCallable(cx, &args[0]));
|
||||
if (!callable)
|
||||
return false;
|
||||
|
||||
/* Step 5. */
|
||||
if (len == 0 && args.length() < 2) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_EMPTY_ARRAY_REDUCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Step 6. */
|
||||
uint32_t k, end;
|
||||
int32_t step;
|
||||
Behavior::initialize(len, &k, &end, &step);
|
||||
|
||||
/* Step 7-8. */
|
||||
RootedValue accumulator(cx);
|
||||
if (args.length() >= 2) {
|
||||
accumulator = args[1];
|
||||
} else {
|
||||
JSBool kNotPresent = true;
|
||||
while (kNotPresent && k != end) {
|
||||
if (!GetElement(cx, obj, k, &kNotPresent, &accumulator))
|
||||
return false;
|
||||
k += step;
|
||||
}
|
||||
if (kNotPresent) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_EMPTY_ARRAY_REDUCE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 9. */
|
||||
RootedValue kValue(cx);
|
||||
FastInvokeGuard fig(cx, ObjectValue(*callable));
|
||||
InvokeArgsGuard &ag = fig.args();
|
||||
while (k != end) {
|
||||
if (!JS_CHECK_OPERATION_LIMIT(cx))
|
||||
return false;
|
||||
|
||||
/* Step a, b, and c.i. */
|
||||
JSBool kNotPresent;
|
||||
if (!GetElement(cx, obj, k, &kNotPresent, &kValue))
|
||||
return false;
|
||||
|
||||
/* Step c.ii. */
|
||||
if (!kNotPresent) {
|
||||
if (!ag.pushed() && !cx->stack.pushInvokeArgs(cx, 4, &ag))
|
||||
return false;
|
||||
ag.setCallee(ObjectValue(*callable));
|
||||
ag.setThis(UndefinedValue());
|
||||
ag[0] = accumulator;
|
||||
ag[1] = kValue;
|
||||
ag[2] = NumberValue(k);
|
||||
ag[3] = ObjectValue(*obj);
|
||||
if (!fig.invoke(cx))
|
||||
return false;
|
||||
accumulator = ag.rval();
|
||||
}
|
||||
|
||||
/* Step d. */
|
||||
k += step;
|
||||
}
|
||||
|
||||
/* Step 10. */
|
||||
args.rval().set(accumulator);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.21. */
|
||||
static JSBool
|
||||
array_reduce(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return array_reduceCommon<ArrayReduceBehavior>(cx, args);
|
||||
}
|
||||
|
||||
/* ES5 15.4.4.22. */
|
||||
static JSBool
|
||||
array_reduceRight(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return array_reduceCommon<ArrayReduceRightBehavior>(cx, args);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
array_isArray(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
|
@ -3133,15 +3486,15 @@ static JSFunctionSpec array_methods[] = {
|
|||
JS_FN("concat", array_concat, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("slice", array_slice, 2,JSFUN_GENERIC_NATIVE),
|
||||
|
||||
{"lastIndexOf", {NULL, NULL}, 1,0, "ArrayLastIndexOf"},
|
||||
{"indexOf", {NULL, NULL}, 1,0, "ArrayIndexOf"},
|
||||
{"forEach", {NULL, NULL}, 1,0, "ArrayForEach"},
|
||||
JS_FN("indexOf", array_indexOf, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("lastIndexOf", array_lastIndexOf, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("forEach", array_forEach, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("map", array_map, 1,JSFUN_GENERIC_NATIVE),
|
||||
{"reduce", {NULL, NULL}, 1,0, "ArrayReduce"},
|
||||
{"reduceRight", {NULL, NULL}, 1,0, "ArrayReduceRight"},
|
||||
JS_FN("reduce", array_reduce, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("reduceRight", array_reduceRight, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("filter", array_filter, 1,JSFUN_GENERIC_NATIVE),
|
||||
{"some", {NULL, NULL}, 1,0, "ArraySome"},
|
||||
{"every", {NULL, NULL}, 1,0, "ArrayEvery"},
|
||||
JS_FN("some", array_some, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("every", array_every, 1,JSFUN_GENERIC_NATIVE),
|
||||
|
||||
JS_FN("iterator", JS_ArrayIterator, 0,0),
|
||||
JS_FS_END
|
||||
|
@ -3149,13 +3502,6 @@ static JSFunctionSpec array_methods[] = {
|
|||
|
||||
static JSFunctionSpec array_static_methods[] = {
|
||||
JS_FN("isArray", array_isArray, 1,0),
|
||||
{"lastIndexOf", {NULL, NULL}, 2,0, "ArrayStaticLastIndexOf"},
|
||||
{"indexOf", {NULL, NULL}, 2,0, "ArrayStaticIndexOf"},
|
||||
{"forEach", {NULL, NULL}, 2,0, "ArrayStaticForEach"},
|
||||
{"every", {NULL, NULL}, 2,0, "ArrayStaticEvery"},
|
||||
{"some", {NULL, NULL}, 2,0, "ArrayStaticSome"},
|
||||
{"reduce", {NULL, NULL}, 2,0, "ArrayStaticReduce"},
|
||||
{"reduceRight", {NULL, NULL}, 2,0, "ArrayStaticReduceRight"},
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
|
|
@ -381,47 +381,27 @@ JSRuntime::markSelfHostedGlobal(JSTracer *trc)
|
|||
MarkObjectRoot(trc, &selfHostedGlobal_, "self-hosting global");
|
||||
}
|
||||
|
||||
bool
|
||||
JSRuntime::getUnclonedSelfHostedValue(JSContext *cx, Handle<PropertyName*> name,
|
||||
MutableHandleValue vp)
|
||||
JSFunction *
|
||||
JSRuntime::getSelfHostedFunction(JSContext *cx, Handle<PropertyName*> name)
|
||||
{
|
||||
RootedObject shg(cx, selfHostedGlobal_);
|
||||
AutoCompartment ac(cx, shg);
|
||||
return JS_GetPropertyById(cx, shg, NameToId(name), vp.address());
|
||||
RootedObject holder(cx, cx->global()->getIntrinsicsHolder());
|
||||
RootedId id(cx, NameToId(name));
|
||||
RootedValue funVal(cx, NullValue());
|
||||
if (!cloneSelfHostedValueById(cx, id, holder, &funVal))
|
||||
return NULL;
|
||||
return funVal.toObject().toFunction();
|
||||
}
|
||||
|
||||
bool
|
||||
JSRuntime::cloneSelfHostedFunctionScript(JSContext *cx, Handle<PropertyName*> name,
|
||||
Handle<JSFunction*> targetFun)
|
||||
JSRuntime::cloneSelfHostedValueById(JSContext *cx, HandleId id, HandleObject holder, MutableHandleValue vp)
|
||||
{
|
||||
RootedValue funVal(cx);
|
||||
if (!getUnclonedSelfHostedValue(cx, name, &funVal))
|
||||
return false;
|
||||
|
||||
Rooted<JSScript*> sourceScript(cx, funVal.toObject().toFunction()->script());
|
||||
JS_ASSERT(!sourceScript->enclosingStaticScope());
|
||||
RawScript cscript = CloneScript(cx, NullPtr(), targetFun, sourceScript);
|
||||
if (!cscript)
|
||||
return false;
|
||||
targetFun->setScript(cscript);
|
||||
cscript->setFunction(targetFun);
|
||||
if (!JSFunction::setTypeForScriptedFunction(cx, targetFun))
|
||||
return false;
|
||||
|
||||
RootedValue targetFunVal(cx, OBJECT_TO_JSVAL(targetFun));
|
||||
DebugOnly<bool> ok = JS_DefinePropertyById(cx, cx->global()->getIntrinsicsHolder(),
|
||||
NameToId(name), targetFunVal, NULL, NULL, 0);
|
||||
JS_ASSERT(ok);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JSRuntime::cloneSelfHostedValue(JSContext *cx, Handle<PropertyName*> name, HandleObject holder,
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
RootedValue funVal(cx);
|
||||
if (!getUnclonedSelfHostedValue(cx, name, &funVal))
|
||||
return false;
|
||||
Value funVal;
|
||||
{
|
||||
RootedObject shg(cx, selfHostedGlobal_);
|
||||
AutoCompartment ac(cx, shg);
|
||||
if (!JS_GetPropertyById(cx, shg, id, &funVal) || !funVal.isObject())
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't clone if we're operating in the self-hosting global, as that
|
||||
|
@ -429,14 +409,14 @@ JSRuntime::cloneSelfHostedValue(JSContext *cx, Handle<PropertyName*> name, Handl
|
|||
* initializing the runtime (see JSRuntime::initSelfHosting).
|
||||
*/
|
||||
if (cx->global() == selfHostedGlobal_) {
|
||||
vp.set(funVal);
|
||||
vp.set(ObjectValue(funVal.toObject()));
|
||||
} else {
|
||||
RootedObject clone(cx, JS_CloneFunctionObject(cx, &funVal.toObject(), cx->global()));
|
||||
if (!clone)
|
||||
return false;
|
||||
vp.set(ObjectValue(*clone));
|
||||
}
|
||||
DebugOnly<bool> ok = JS_DefinePropertyById(cx, holder, NameToId(name), vp, NULL, NULL, 0);
|
||||
DebugOnly<bool> ok = JS_DefinePropertyById(cx, holder, id, vp, NULL, NULL, 0);
|
||||
JS_ASSERT(ok);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -535,12 +535,9 @@ struct JSRuntime : js::RuntimeFriendFields
|
|||
bool isSelfHostedGlobal(js::HandleObject global) {
|
||||
return global == selfHostedGlobal_;
|
||||
}
|
||||
bool getUnclonedSelfHostedValue(JSContext *cx, js::Handle<js::PropertyName*> name,
|
||||
js::MutableHandleValue vp);
|
||||
bool cloneSelfHostedFunctionScript(JSContext *cx, js::Handle<js::PropertyName*> name,
|
||||
js::Handle<JSFunction*> targetFun);
|
||||
bool cloneSelfHostedValue(JSContext *cx, js::Handle<js::PropertyName*> name,
|
||||
js::HandleObject holder, js::MutableHandleValue vp);
|
||||
JSFunction *getSelfHostedFunction(JSContext *cx, js::Handle<js::PropertyName*> name);
|
||||
bool cloneSelfHostedValueById(JSContext *cx, js::HandleId id, js::HandleObject holder,
|
||||
js::MutableHandleValue vp);
|
||||
|
||||
/* Base address of the native stack for the current thread. */
|
||||
uintptr_t nativeStackBase;
|
||||
|
|
|
@ -402,7 +402,7 @@ js::DefineFunctionWithReserved(JSContext *cx, JSObject *objArg, const char *name
|
|||
if (!atom)
|
||||
return NULL;
|
||||
Rooted<jsid> id(cx, AtomToId(atom));
|
||||
return js_DefineFunction(cx, obj, id, call, nargs, attrs, JSFunction::ExtendedFinalizeKind);
|
||||
return js_DefineFunction(cx, obj, id, call, nargs, attrs, NullPtr(), JSFunction::ExtendedFinalizeKind);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSFunction *)
|
||||
|
|
|
@ -326,8 +326,7 @@ fun_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
|
|||
|
||||
RootedValue v(cx);
|
||||
if (JSID_IS_ATOM(id, cx->names().length)) {
|
||||
//FIXME: bug 810715 - deal with lazy interpreted functions with default args
|
||||
uint16_t defaults = fun->hasScript() ? fun->script()->ndefaults : 0;
|
||||
uint16_t defaults = fun->isInterpreted() ? fun->script()->ndefaults : 0;
|
||||
v.setInt32(fun->nargs - defaults - fun->hasRest());
|
||||
} else {
|
||||
v.setString(fun->atom() == NULL ? cx->runtime->emptyString : fun->atom());
|
||||
|
@ -484,18 +483,6 @@ js::CloneInterpretedFunction(JSContext *cx, HandleObject enclosingScope, HandleF
|
|||
return clone;
|
||||
}
|
||||
|
||||
bool
|
||||
js::InitializeLazyFunctionScript(JSContext *cx, HandleFunction fun)
|
||||
{
|
||||
JS_ASSERT(fun->isLazy());
|
||||
JSFunctionSpec *fs = static_cast<JSFunctionSpec *>(fun->getExtendedSlot(0).toPrivate());
|
||||
RootedAtom funAtom(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName)));
|
||||
if (!funAtom)
|
||||
return false;
|
||||
Rooted<PropertyName *> funName(cx, funAtom->asPropertyName());
|
||||
return cx->runtime->cloneSelfHostedFunctionScript(cx, funName, fun);
|
||||
}
|
||||
|
||||
/*
|
||||
* [[HasInstance]] internal method for Function objects: fetch the .prototype
|
||||
* property of its 'this' parameter, and walks the prototype chain of v (only
|
||||
|
@ -546,7 +533,7 @@ JSFunction::trace(JSTracer *trc)
|
|||
MarkString(trc, &atom_, "atom");
|
||||
|
||||
if (isInterpreted()) {
|
||||
if (hasScript())
|
||||
if (u.i.script_)
|
||||
MarkScriptUnbarriered(trc, &u.i.script_, "script");
|
||||
if (u.i.env_)
|
||||
MarkObjectUnbarriered(trc, &u.i.env_, "fun_callscope");
|
||||
|
@ -637,17 +624,16 @@ js::FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lamb
|
|||
StringBuffer out(cx);
|
||||
RootedScript script(cx);
|
||||
|
||||
if (fun->hasScript()) {
|
||||
if (fun->isInterpreted())
|
||||
script = fun->script();
|
||||
if (script->isGeneratorExp) {
|
||||
if ((!bodyOnly && !out.append("function genexp() {")) ||
|
||||
!out.append("\n [generator expression]\n") ||
|
||||
(!bodyOnly && !out.append("}")))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return out.finishString();
|
||||
|
||||
if (fun->isInterpreted() && script->isGeneratorExp) {
|
||||
if ((!bodyOnly && !out.append("function genexp() {")) ||
|
||||
!out.append("\n [generator expression]\n") ||
|
||||
(!bodyOnly && !out.append("}"))) {
|
||||
return NULL;
|
||||
}
|
||||
return out.finishString();
|
||||
}
|
||||
if (!bodyOnly) {
|
||||
// If we're not in pretty mode, put parentheses around lambda functions.
|
||||
|
@ -1138,7 +1124,7 @@ fun_isGenerator(JSContext *cx, unsigned argc, Value *vp)
|
|||
}
|
||||
|
||||
bool result = false;
|
||||
if (fun->hasScript()) {
|
||||
if (fun->isInterpreted()) {
|
||||
RawScript script = fun->script().get(nogc);
|
||||
JS_ASSERT(script->length != 0);
|
||||
result = script->isGenerator;
|
||||
|
@ -1544,6 +1530,7 @@ js_CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
|
|||
*/
|
||||
if (clone->isInterpreted()) {
|
||||
RootedScript script(cx, clone->script());
|
||||
JS_ASSERT(script);
|
||||
JS_ASSERT(script->compartment() == fun->compartment());
|
||||
JS_ASSERT_IF(script->compartment() != cx->compartment,
|
||||
!script->enclosingStaticScope());
|
||||
|
@ -1571,7 +1558,7 @@ js_CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
|
|||
|
||||
JSFunction *
|
||||
js_DefineFunction(JSContext *cx, HandleObject obj, HandleId id, Native native,
|
||||
unsigned nargs, unsigned flags, AllocKind kind)
|
||||
unsigned nargs, unsigned flags, Handle<PropertyName*> selfHostedName, AllocKind kind)
|
||||
{
|
||||
PropertyOp gop;
|
||||
StrictPropertyOp sop;
|
||||
|
@ -1593,13 +1580,23 @@ js_DefineFunction(JSContext *cx, HandleObject obj, HandleId id, Native native,
|
|||
sop = NULL;
|
||||
}
|
||||
|
||||
JSFunction::Flags funFlags;
|
||||
if (!native)
|
||||
funFlags = JSFunction::INTERPRETED;
|
||||
else
|
||||
funFlags = JSAPIToJSFunctionFlags(flags);
|
||||
RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : NULL);
|
||||
fun = js_NewFunction(cx, NullPtr(), native, nargs, funFlags, obj, atom, kind);
|
||||
/*
|
||||
* To support specifying both native and self-hosted functions using
|
||||
* JSFunctionSpec, js_DefineFunction can be invoked with either native
|
||||
* or selfHostedName set. It is assumed that selfHostedName is set if
|
||||
* native isn't.
|
||||
*/
|
||||
if (native) {
|
||||
JS_ASSERT(!selfHostedName);
|
||||
RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : NULL);
|
||||
JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags);
|
||||
fun = js_NewFunction(cx, NullPtr(), native, nargs,
|
||||
funFlags, obj, atom, kind);
|
||||
} else {
|
||||
JS_ASSERT(!cx->runtime->isSelfHostedGlobal(cx->global()));
|
||||
fun = cx->runtime->getSelfHostedFunction(cx, selfHostedName);
|
||||
fun->initAtom(JSID_TO_ATOM(id));
|
||||
}
|
||||
if (!fun)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -84,8 +84,6 @@ struct JSFunction : public JSObject
|
|||
/* Possible attributes of an interpreted function: */
|
||||
bool isHeavyweight() const { return flags & HEAVYWEIGHT; }
|
||||
bool isFunctionPrototype() const { return flags & IS_FUN_PROTO; }
|
||||
bool isLazy() const { return isInterpreted() && !hasScript(); }
|
||||
bool hasScript() const { return isInterpreted() && u.i.script_; }
|
||||
bool isExprClosure() const { return flags & EXPR_CLOSURE; }
|
||||
bool hasGuessedAtom() const { return flags & HAS_GUESSED_ATOM; }
|
||||
bool isLambda() const { return flags & LAMBDA; }
|
||||
|
@ -169,7 +167,7 @@ struct JSFunction : public JSObject
|
|||
static inline size_t offsetOfAtom() { return offsetof(JSFunction, atom_); }
|
||||
|
||||
js::Return<JSScript*> script() const {
|
||||
JS_ASSERT(hasScript());
|
||||
JS_ASSERT(isInterpreted());
|
||||
return JS::HandleScript::fromMarkedLocation(&u.i.script_);
|
||||
}
|
||||
|
||||
|
@ -290,7 +288,7 @@ js_CloneFunctionObject(JSContext *cx, js::HandleFunction fun,
|
|||
|
||||
extern JSFunction *
|
||||
js_DefineFunction(JSContext *cx, js::HandleObject obj, js::HandleId id, JSNative native,
|
||||
unsigned nargs, unsigned flags,
|
||||
unsigned nargs, unsigned flags, js::Handle<js::PropertyName*> selfHostedName = JS::NullPtr(),
|
||||
js::gc::AllocKind kind = JSFunction::FinalizeKind);
|
||||
|
||||
namespace js {
|
||||
|
@ -336,9 +334,6 @@ XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope,
|
|||
extern JSObject *
|
||||
CloneInterpretedFunction(JSContext *cx, HandleObject enclosingScope, HandleFunction fun);
|
||||
|
||||
bool
|
||||
InitializeLazyFunctionScript(JSContext *cx, HandleFunction fun);
|
||||
|
||||
/*
|
||||
* Report an error that call.thisv is not compatible with the specified class,
|
||||
* assuming that the method (clasp->name).prototype.<name of callee function>
|
||||
|
|
|
@ -368,9 +368,6 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct)
|
|||
if (fun->isNative())
|
||||
return CallJSNative(cx, fun->native(), args);
|
||||
|
||||
if (fun->isLazy() && !InitializeLazyFunctionScript(cx, fun))
|
||||
return false;
|
||||
|
||||
if (!TypeMonitorCall(cx, args, construct))
|
||||
return false;
|
||||
|
||||
|
@ -2342,8 +2339,6 @@ BEGIN_CASE(JSOP_FUNCALL)
|
|||
|
||||
InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE;
|
||||
bool newType = cx->typeInferenceEnabled() && UseNewType(cx, script, regs.pc);
|
||||
if (fun->isLazy() && !InitializeLazyFunctionScript(cx, fun))
|
||||
goto error;
|
||||
RawScript funScript = fun->script().unsafeGet();
|
||||
if (!cx->stack.pushInlineFrame(cx, regs, args, *fun, funScript, initial))
|
||||
goto error;
|
||||
|
|
|
@ -1020,7 +1020,7 @@ class FastInvokeGuard
|
|||
void initFunction(const Value &fval) {
|
||||
if (fval.isObject() && fval.toObject().isFunction()) {
|
||||
JSFunction *fun = fval.toObject().toFunction();
|
||||
if (fun->hasScript()) {
|
||||
if (fun->isInterpreted()) {
|
||||
fun_ = fun;
|
||||
script_ = fun->script();
|
||||
}
|
||||
|
|
|
@ -5283,7 +5283,7 @@ dumpValue(const Value &v)
|
|||
} else {
|
||||
fputs("<unnamed function", stderr);
|
||||
}
|
||||
if (fun->hasScript()) {
|
||||
if (fun->isInterpreted()) {
|
||||
JSScript *script = fun->script().get(nogc);
|
||||
fprintf(stderr, " (%s:%u)",
|
||||
script->filename ? script->filename : "", script->lineno);
|
||||
|
|
|
@ -1113,7 +1113,7 @@ js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun,
|
|||
jp->fun = fun;
|
||||
jp->localNames = NULL;
|
||||
jp->decompiledOpcodes = NULL;
|
||||
if (fun && fun->hasScript()) {
|
||||
if (fun && fun->isInterpreted()) {
|
||||
if (!SetPrinterLocalNames(cx, fun->script().unsafeGet(), jp)) {
|
||||
js_DestroyPrinter(jp);
|
||||
return NULL;
|
||||
|
|
|
@ -1841,6 +1841,8 @@ JSScript::isShortRunning()
|
|||
bool
|
||||
JSScript::enclosingScriptsCompiledSuccessfully() const
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
|
||||
/*
|
||||
* When a nested script is succesfully compiled, it is eagerly given the
|
||||
* static JSFunction of its enclosing script. The enclosing function's
|
||||
|
@ -1852,7 +1854,7 @@ JSScript::enclosingScriptsCompiledSuccessfully() const
|
|||
while (enclosing) {
|
||||
if (enclosing->isFunction()) {
|
||||
RawFunction fun = enclosing->toFunction();
|
||||
if (!fun->hasScript())
|
||||
if (!fun->script().get(nogc))
|
||||
return false;
|
||||
enclosing = fun->script()->enclosingScope_;
|
||||
} else {
|
||||
|
|
|
@ -2366,7 +2366,7 @@ LambdaIsGetElem(JSObject &lambda)
|
|||
return NULL;
|
||||
|
||||
JSFunction *fun = lambda.toFunction();
|
||||
if (!fun->hasScript())
|
||||
if (!fun->isInterpreted())
|
||||
return NULL;
|
||||
|
||||
RawScript script = fun->script().get(nogc);
|
||||
|
|
|
@ -284,10 +284,6 @@ UncachedInlineCall(VMFrame &f, InitialFrameFlags initial,
|
|||
JSContext *cx = f.cx;
|
||||
CallArgs args = CallArgsFromSp(argc, f.regs.sp);
|
||||
RootedFunction newfun(cx, args.callee().toFunction());
|
||||
|
||||
if (newfun->isLazy() && !InitializeLazyFunctionScript(cx, newfun))
|
||||
return false;
|
||||
|
||||
RootedScript newscript(cx, newfun->script());
|
||||
|
||||
bool construct = InitialFrameFlagsAreConstructing(initial);
|
||||
|
|
|
@ -2212,7 +2212,7 @@ Clone(JSContext *cx, unsigned argc, jsval *vp)
|
|||
}
|
||||
if (funobj->compartment() != cx->compartment) {
|
||||
JSFunction *fun = funobj->toFunction();
|
||||
if (fun->hasScript() && fun->script()->compileAndGo) {
|
||||
if (fun->isInterpreted() && fun->script()->compileAndGo) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE,
|
||||
"function", "compile-and-go");
|
||||
return false;
|
||||
|
|
|
@ -392,8 +392,13 @@ class GlobalObject : public JSObject
|
|||
RootedId id(cx, NameToId(name));
|
||||
if (HasDataProperty(cx, holder, id, value.address()))
|
||||
return true;
|
||||
Rooted<PropertyName*> rootedName(cx, name);
|
||||
return cx->runtime->cloneSelfHostedValue(cx, rootedName, holder, value);
|
||||
bool ok = cx->runtime->cloneSelfHostedValueById(cx, id, holder, value);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
ok = JS_DefinePropertyById(cx, holder, id, value, NULL, NULL, 0);
|
||||
JS_ASSERT(ok);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline RegExpStatics *getRegExpStatics() const;
|
||||
|
|
Загрузка…
Ссылка в новой задаче