Commit 567c24d9 authored by Benedikt Meurer's avatar Benedikt Meurer

Revert of [es6] Correct Function.prototype.apply, Reflect.construct and...

Revert of [es6] Correct Function.prototype.apply, Reflect.construct and Reflect.apply. (patchset #5 id:80001 of https://codereview.chromium.org/1523753002/ )

Reason for revert:
Breaks TSAN somewhow: http://build.chromium.org/p/client.v8/builders/V8%20Linux64%20TSAN/builds/7000

Original issue's description:
> [es6] Correct Function.prototype.apply, Reflect.construct and Reflect.apply.
>
> Introduce a new Apply builtin that forms a correct and optimizable
> foundation for the Function.prototype.apply, Reflect.construct and
> Reflect.apply builtins (which properly does the PrepareForTailCall
> as required by the ES2015 spec).
>
> The new Apply builtin avoids going to the runtime if it is safe to
> just access the backing store elements of the argArray, i.e. if you
> pass a JSArray with no holes, or an unmapped, unmodified sloppy or
> strict arguments object.
>
> mips/mips64 ports by Balazs Kilvady <balazs.kilvady@imgtec.com>
>
> CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_chromium_rel_ng;tryserver.blink:linux_blink_rel
> BUG=v8:4413, v8:4430
> LOG=n
> R=yangguo@chromium.org
>
> Committed: https://chromium.googlesource.com/v8/v8/+/e4d2538911f6cb4b626830ccbb3c1f5746542697

TBR=yangguo@chromium.org,paul.lind@imgtec.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:4413, v8:4430

Review URL: https://codereview.chromium.org/1533803002 .

Cr-Commit-Position: refs/heads/master@{#32928}
parent e4d25389
This diff is collapsed.
This diff is collapsed.
......@@ -1865,8 +1865,11 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
Handle<JSFunction> apply = InstallFunction(
container, "reflect_apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
MaybeHandle<JSObject>(), Builtins::kReflectApply);
apply->shared()->DontAdaptArguments();
apply->shared()->set_internal_formal_parameter_count(3);
apply->shared()->set_length(3);
Handle<TypeFeedbackVector> feedback_vector =
TypeFeedbackVector::CreatePushAppliedArgumentsVector(isolate);
apply->shared()->set_feedback_vector(*feedback_vector);
native_context->set_reflect_apply(*apply);
}
......@@ -1874,8 +1877,11 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
Handle<JSFunction> construct = InstallFunction(
container, "reflect_construct", JS_OBJECT_TYPE, JSObject::kHeaderSize,
MaybeHandle<JSObject>(), Builtins::kReflectConstruct);
construct->shared()->DontAdaptArguments();
construct->shared()->set_internal_formal_parameter_count(3);
construct->shared()->set_length(2);
Handle<TypeFeedbackVector> feedback_vector =
TypeFeedbackVector::CreatePushAppliedArgumentsVector(isolate);
construct->shared()->set_feedback_vector(*feedback_vector);
native_context->set_reflect_construct(*construct);
}
......@@ -2529,17 +2535,22 @@ bool Genesis::InstallNatives(ContextType context_type) {
Handle<JSFunction> apply =
InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
MaybeHandle<JSObject>(), Builtins::kFunctionApply);
Handle<TypeFeedbackVector> feedback_vector =
TypeFeedbackVector::CreatePushAppliedArgumentsVector(isolate());
apply->shared()->set_feedback_vector(*feedback_vector);
// Make sure that Function.prototype.call appears to be compiled.
// The code will never be called, but inline caching for call will
// only work if it appears to be compiled.
apply->shared()->DontAdaptArguments();
call->shared()->DontAdaptArguments();
DCHECK(call->is_compiled());
// Set the expected parameters for apply to 2; required by builtin.
apply->shared()->set_internal_formal_parameter_count(2);
// Set the lengths for the functions to satisfy ECMA-262.
apply->shared()->set_length(2);
call->shared()->set_length(1);
apply->shared()->set_length(2);
}
// Set up the Promise constructor.
......
......@@ -116,8 +116,6 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
V(ConstructProxy, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(Construct, BUILTIN, UNINITIALIZED, kNoExtraICState) \
\
V(Apply, BUILTIN, UNINITIALIZED, kNoExtraICState) \
\
V(HandleFastApiCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \
\
V(InOptimizationQueue, BUILTIN, UNINITIALIZED, kNoExtraICState) \
......@@ -317,8 +315,6 @@ class Builtins {
static void Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm);
static void Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm);
static void Generate_Apply(MacroAssembler* masm);
// ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
static void Generate_CallFunction(MacroAssembler* masm,
ConvertReceiverMode mode);
......
......@@ -91,9 +91,14 @@ enum BindingFlags {
V(SPREAD_ITERABLE_INDEX, JSFunction, spread_iterable)
#define NATIVE_CONTEXT_JS_BUILTINS(V) \
V(CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, JSFunction, \
concat_iterable_to_array_builtin)
#define NATIVE_CONTEXT_JS_BUILTINS(V) \
V(APPLY_PREPARE_BUILTIN_INDEX, JSFunction, apply_prepare_builtin) \
V(CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, JSFunction, \
concat_iterable_to_array_builtin) \
V(REFLECT_APPLY_PREPARE_BUILTIN_INDEX, JSFunction, \
reflect_apply_prepare_builtin) \
V(REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, JSFunction, \
reflect_construct_prepare_builtin)
#define NATIVE_CONTEXT_IMPORTED_FIELDS(V) \
......
This diff is collapsed.
......@@ -34,6 +34,127 @@ utils.Import(function(from) {
-----------------------------
*/
function APPLY_PREPARE(args) {
var length;
// First check that the receiver is callable.
if (!IS_CALLABLE(this)) {
throw %make_type_error(kApplyNonFunction, TO_STRING(this), typeof this);
}
// First check whether length is a positive Smi and args is an
// array. This is the fast case. If this fails, we do the slow case
// that takes care of more eventualities.
if (IS_ARRAY(args)) {
length = args.length;
if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength) {
return length;
}
}
length = (args == null) ? 0 : TO_UINT32(args.length);
// We can handle any number of apply arguments if the stack is
// big enough, but sanity check the value to avoid overflow when
// multiplying with pointer size.
if (length > kSafeArgumentsLength) throw %make_range_error(kStackOverflow);
// Make sure the arguments list has the right type.
if (args != null && !IS_SPEC_OBJECT(args)) {
throw %make_type_error(kWrongArgs, "Function.prototype.apply");
}
// Return the length which is the number of arguments to copy to the
// stack. It is guaranteed to be a small integer at this point.
return length;
}
function REFLECT_APPLY_PREPARE(args) {
var length;
// First check that the receiver is callable.
if (!IS_CALLABLE(this)) {
throw %make_type_error(kApplyNonFunction, TO_STRING(this), typeof this);
}
// First check whether length is a positive Smi and args is an
// array. This is the fast case. If this fails, we do the slow case
// that takes care of more eventualities.
if (IS_ARRAY(args)) {
length = args.length;
if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength) {
return length;
}
}
if (!IS_SPEC_OBJECT(args)) {
throw %make_type_error(kWrongArgs, "Reflect.apply");
}
length = TO_LENGTH(args.length);
// We can handle any number of apply arguments if the stack is
// big enough, but sanity check the value to avoid overflow when
// multiplying with pointer size.
if (length > kSafeArgumentsLength) throw %make_range_error(kStackOverflow);
// Return the length which is the number of arguments to copy to the
// stack. It is guaranteed to be a small integer at this point.
return length;
}
function REFLECT_CONSTRUCT_PREPARE(
args, newTarget) {
var length;
var ctorOk = IS_CALLABLE(this) && %IsConstructor(this);
var newTargetOk = IS_CALLABLE(newTarget) && %IsConstructor(newTarget);
// First check whether length is a positive Smi and args is an
// array. This is the fast case. If this fails, we do the slow case
// that takes care of more eventualities.
if (IS_ARRAY(args)) {
length = args.length;
if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength &&
ctorOk && newTargetOk) {
return length;
}
}
if (!ctorOk) {
if (!IS_CALLABLE(this)) {
throw %make_type_error(kCalledNonCallable, TO_STRING(this));
} else {
throw %make_type_error(kNotConstructor, TO_STRING(this));
}
}
if (!newTargetOk) {
if (!IS_CALLABLE(newTarget)) {
throw %make_type_error(kCalledNonCallable, TO_STRING(newTarget));
} else {
throw %make_type_error(kNotConstructor, TO_STRING(newTarget));
}
}
if (!IS_SPEC_OBJECT(args)) {
throw %make_type_error(kWrongArgs, "Reflect.construct");
}
length = TO_LENGTH(args.length);
// We can handle any number of apply arguments if the stack is
// big enough, but sanity check the value to avoid overflow when
// multiplying with pointer size.
if (length > kSafeArgumentsLength) throw %make_range_error(kStackOverflow);
// Return the length which is the number of arguments to copy to the
// stack. It is guaranteed to be a small integer at this point.
return length;
}
function CONCAT_ITERABLE_TO_ARRAY(iterable) {
return %concat_iterable_to_array(this, iterable);
};
......@@ -140,7 +261,10 @@ utils.Export(function(to) {
});
%InstallToContext([
"apply_prepare_builtin", APPLY_PREPARE,
"concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY,
"reflect_apply_prepare_builtin", REFLECT_APPLY_PREPARE,
"reflect_construct_prepare_builtin", REFLECT_CONSTRUCT_PREPARE,
]);
%InstallToContext([
......
This diff is collapsed.
This diff is collapsed.
......@@ -672,72 +672,6 @@ MaybeHandle<Object> Object::GetMethod(Handle<JSReceiver> receiver,
}
// static
MaybeHandle<FixedArray> Object::CreateListFromArrayLike(
Isolate* isolate, Handle<Object> object, ElementTypes element_types) {
// 1. ReturnIfAbrupt(object).
// 2. (default elementTypes -- not applicable.)
// 3. If Type(obj) is not Object, throw a TypeError exception.
if (!object->IsJSReceiver()) {
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kCalledOnNonObject,
isolate->factory()->NewStringFromAsciiChecked(
"CreateListFromArrayLike")),
FixedArray);
}
// 4. Let len be ? ToLength(? Get(obj, "length")).
Handle<Object> raw_length_obj;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, raw_length_obj,
JSReceiver::GetProperty(object, isolate->factory()->length_string()),
FixedArray);
Handle<Object> raw_length_number;
ASSIGN_RETURN_ON_EXCEPTION(isolate, raw_length_number,
Object::ToLength(isolate, raw_length_obj),
FixedArray);
uint32_t len;
if (!raw_length_number->ToUint32(&len) ||
len > static_cast<uint32_t>(FixedArray::kMaxLength)) {
THROW_NEW_ERROR(isolate,
NewRangeError(MessageTemplate::kInvalidArrayLength),
FixedArray);
}
// 5. Let list be an empty List.
Handle<FixedArray> list = isolate->factory()->NewFixedArray(len);
// 6. Let index be 0.
// 7. Repeat while index < len:
for (uint32_t index = 0; index < len; ++index) {
// 7a. Let indexName be ToString(index).
// 7b. Let next be ? Get(obj, indexName).
Handle<Object> next;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, next, Object::GetElement(isolate, object, index), FixedArray);
switch (element_types) {
case ElementTypes::kAll:
// Nothing to do.
break;
case ElementTypes::kStringAndSymbol: {
// 7c. If Type(next) is not an element of elementTypes, throw a
// TypeError exception.
if (!next->IsName()) {
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kNotPropertyName, next),
FixedArray);
}
// 7d. Append next as the last element of list.
// Internalize on the fly so we can use pointer identity later.
next = isolate->factory()->InternalizeName(Handle<Name>::cast(next));
break;
}
}
list->set(index, *next);
// 7e. Set index to index + 1. (See loop header.)
}
// 8. Return list.
return list;
}
// static
Maybe<bool> JSReceiver::HasProperty(LookupIterator* it) {
for (; it->IsFound(); it->Next()) {
......@@ -8536,6 +8470,64 @@ Maybe<bool> JSProxy::Enumerate(Isolate* isolate, Handle<JSReceiver> receiver,
}
// ES6 7.3.17 for elementTypes = (String, Symbol)
static MaybeHandle<FixedArray> CreateListFromArrayLike_StringSymbol(
Isolate* isolate, Handle<Object> object) {
// 1. ReturnIfAbrupt(object).
// 2. (default elementTypes -- not applicable.)
// 3. If Type(obj) is not Object, throw a TypeError exception.
if (!object->IsJSReceiver()) {
isolate->Throw(*isolate->factory()->NewTypeError(
MessageTemplate::kCalledOnNonObject,
isolate->factory()->NewStringFromAsciiChecked(
"CreateListFromArrayLike")));
return MaybeHandle<FixedArray>();
}
// 4. Let len be ? ToLength(? Get(obj, "length")).
Handle<Object> raw_length_obj;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, raw_length_obj,
JSReceiver::GetProperty(object, isolate->factory()->length_string()),
FixedArray);
Handle<Object> raw_length_number;
ASSIGN_RETURN_ON_EXCEPTION(isolate, raw_length_number,
Object::ToLength(isolate, raw_length_obj),
FixedArray);
uint32_t len;
if (!raw_length_number->ToUint32(&len) ||
len > static_cast<uint32_t>(FixedArray::kMaxLength)) {
isolate->Throw(*isolate->factory()->NewRangeError(
MessageTemplate::kInvalidArrayLength));
return MaybeHandle<FixedArray>();
}
// 5. Let list be an empty List.
Handle<FixedArray> list = isolate->factory()->NewFixedArray(len);
// 6. Let index be 0.
// 7. Repeat while index < len:
for (uint32_t index = 0; index < len; ++index) {
// 7a. Let indexName be ToString(index).
// 7b. Let next be ? Get(obj, indexName).
Handle<Object> next;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, next, Object::GetElement(isolate, object, index), FixedArray);
// 7c. If Type(next) is not an element of elementTypes, throw a
// TypeError exception.
if (!next->IsName()) {
isolate->Throw(*isolate->factory()->NewTypeError(
MessageTemplate::kNotPropertyName, next));
return MaybeHandle<FixedArray>();
}
// 7d. Append next as the last element of list.
// Internalize on the fly so we can use pointer identity later.
next = isolate->factory()->InternalizeName(Handle<Name>::cast(next));
list->set(index, *next);
// 7e. Set index to index + 1. (See loop header.)
}
// 8. Return list.
return list;
}
// ES6 9.5.12
// Returns |true| on success, |nothing| in case of exception.
// static
......@@ -8580,8 +8572,7 @@ Maybe<bool> JSProxy::OwnPropertyKeys(Isolate* isolate,
Handle<FixedArray> trap_result;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, trap_result,
Object::CreateListFromArrayLike(isolate, trap_result_array,
ElementTypes::kStringAndSymbol),
CreateListFromArrayLike_StringSymbol(isolate, trap_result_array),
Nothing<bool>());
// 9. Let extensibleTarget be ? IsExtensible(target).
Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target);
......
......@@ -992,9 +992,6 @@ template <class C> inline bool Is(Object* obj);
V(WeakHashTable) \
V(OrderedHashTable)
// The element types selection for CreateListFromArrayLike.
enum class ElementTypes { kAll, kStringAndSymbol };
// Object is the abstract superclass for all classes in the
// object hierarchy.
// Object does not use any virtual functions to avoid the
......@@ -1168,10 +1165,6 @@ class Object {
MUST_USE_RESULT static MaybeHandle<Object> GetMethod(
Handle<JSReceiver> receiver, Handle<Name> name);
// ES6 section 7.3.17 CreateListFromArrayLike
MUST_USE_RESULT static MaybeHandle<FixedArray> CreateListFromArrayLike(
Isolate* isolate, Handle<Object> object, ElementTypes element_types);
// Check whether |object| is an instance of Error or NativeError.
static bool IsErrorObject(Isolate* isolate, Handle<Object> object);
......
......@@ -92,7 +92,7 @@ RUNTIME_FUNCTION(Runtime_ReThrow) {
RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) {
SealHandleScope shs(isolate);
DCHECK_LE(0, args.length());
DCHECK_EQ(0, args.length());
return isolate->StackOverflow();
}
......@@ -179,16 +179,6 @@ RUNTIME_FUNCTION(Runtime_ThrowStrongModeImplicitConversion) {
}
RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
Handle<String> type = Object::TypeOf(isolate, object);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kApplyNonFunction, object, type));
}
RUNTIME_FUNCTION(Runtime_PromiseRejectEvent) {
DCHECK(args.length() == 3);
HandleScope scope(isolate);
......@@ -447,18 +437,5 @@ RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) {
isolate, NewTypeError(MessageTemplate::kNotConstructor, callsite));
}
// ES6 section 7.3.17 CreateListFromArrayLike (obj)
RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
Handle<FixedArray> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
Object::CreateListFromArrayLike(isolate, object, ElementTypes::kAll));
return *result;
}
} // namespace internal
} // namespace v8
......@@ -319,7 +319,6 @@ namespace internal {
F(UnwindAndFindExceptionHandler, 0, 1) \
F(PromoteScheduledException, 0, 1) \
F(ThrowReferenceError, 1, 1) \
F(ThrowApplyNonFunction, 1, 1) \
F(NewTypeError, 2, 1) \
F(NewSyntaxError, 2, 1) \
F(NewReferenceError, 2, 1) \
......@@ -350,8 +349,7 @@ namespace internal {
F(IS_VAR, 1, 1) \
F(IncrementStatsCounter, 1, 1) \
F(ThrowConstructedNonConstructable, 1, 1) \
F(ThrowCalledNonCallable, 1, 1) \
F(CreateListFromArrayLike, 1, 1)
F(ThrowCalledNonCallable, 1, 1)
#define FOR_EACH_INTRINSIC_JSON(F) \
......
......@@ -159,6 +159,28 @@ int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec,
}
// static
int TypeFeedbackVector::PushAppliedArgumentsIndex() {
return kReservedIndexCount;
}
// static
Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector(
Isolate* isolate) {
StaticFeedbackVectorSpec spec;
FeedbackVectorSlot slot = spec.AddKeyedLoadICSlot();
// TODO(ishell): allocate this metadata only once.
Handle<TypeFeedbackMetadata> feedback_metadata =
TypeFeedbackMetadata::New(isolate, &spec);
Handle<TypeFeedbackVector> feedback_vector =
TypeFeedbackVector::New(isolate, feedback_metadata);
DCHECK_EQ(PushAppliedArgumentsIndex(), feedback_vector->GetIndex(slot));
USE(slot);
return feedback_vector;
}
// static
Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
Isolate* isolate, Handle<TypeFeedbackVector> vector) {
......
......@@ -254,6 +254,10 @@ class TypeFeedbackVector : public FixedArray {
return FeedbackVectorSlot(dummyIndex);
}
static int PushAppliedArgumentsIndex();
static Handle<TypeFeedbackVector> CreatePushAppliedArgumentsVector(
Isolate* isolate);
private:
void ClearSlotsImpl(SharedFunctionInfo* shared, bool force_clear);
......
This diff is collapsed.
......@@ -3678,6 +3678,39 @@ static void CheckVectorICCleared(Handle<JSFunction> f, int slot_index) {
}
TEST(ICInBuiltInIsClearedAppropriately) {
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Handle<JSFunction> apply;
{
LocalContext env;
v8::Local<v8::Value> res = CompileRun("Function.apply");
i::Handle<JSReceiver> maybe_apply =
v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res));
apply = i::Handle<JSFunction>::cast(maybe_apply);
i::Handle<TypeFeedbackVector> vector(apply->shared()->feedback_vector());
FeedbackVectorHelper feedback_helper(vector);
CHECK_EQ(1, feedback_helper.slot_count());
CheckVectorIC(apply, 0, UNINITIALIZED);
CompileRun(
"function b(a1, a2, a3) { return a1 + a2 + a3; }"
"function fun(bar) { bar.apply({}, [1, 2, 3]); };"
"fun(b); fun(b)");
CheckVectorIC(apply, 0, MONOMORPHIC);
}
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
// The IC in apply has been cleared, ready to learn again.
CheckVectorIC(apply, 0, PREMONOMORPHIC);
}
TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
......
......@@ -114,7 +114,7 @@ function al() {
return arguments.length + arguments[arguments.length - 1];
}
for (var j = 1; j < 0x4000000; j <<= 1) {
for (var j = 1; j < 0x40000000; j <<= 1) {
try {
var a = %NormalizeElements([]);
a.length = j;
......@@ -122,7 +122,7 @@ for (var j = 1; j < 0x4000000; j <<= 1) {
assertEquals(42 + j, al.apply(345, a));
} catch (e) {
assertTrue(e.toString().indexOf("Maximum call stack size exceeded") != -1);
for (; j < 0x4000000; j <<= 1) {
for (; j < 0x40000000; j <<= 1) {
var caught = false;
try {
a = %NormalizeElements([]);
......
......@@ -57,18 +57,6 @@ test(function() {
Object.defineProperty(1, "x", {});
}, "Object.defineProperty called on non-object", TypeError);
test(function() {
(function() {}).apply({}, 1);
}, "CreateListFromArrayLike called on non-object", TypeError);
test(function() {
Reflect.apply(function() {}, {}, 1);
}, "CreateListFromArrayLike called on non-object", TypeError);
test(function() {
Reflect.construct(function() {}, 1);
}, "CreateListFromArrayLike called on non-object", TypeError);
// kCalledOnNullOrUndefined
test(function() {
Array.prototype.shift.call(null);
......@@ -342,6 +330,19 @@ test(function() {
}, "Invalid property descriptor. Cannot both specify accessors " +
"and a value or writable attribute, #<Object>", TypeError);
// kWrongArgs
test(function() {
(function() {}).apply({}, 1);
}, "Function.prototype.apply: Arguments list has wrong type", TypeError);
test(function() {
Reflect.apply(function() {}, {}, 1);
}, "Reflect.apply: Arguments list has wrong type", TypeError);
test(function() {
Reflect.construct(function() {}, 1);
}, "Reflect.construct: Arguments list has wrong type", TypeError);
// === SyntaxError ===
......
......@@ -56,9 +56,9 @@ PASS arrayApplyChangeLength4() is 0
PASS var a = []; a.length = 0xFFFE; [].constructor.apply('', a).length is 0xFFFE
PASS var a = []; a.length = 0xFFFF; [].constructor.apply('', a).length is 0xFFFF
PASS var a = []; a.length = 0x10000; [].constructor.apply('', a).length is 0x10000
PASS var a = []; a.length = 0x10001; [].constructor.apply('', a).length is 0x10001
PASS var a = []; a.length = 0xFFFFFFFE; [].constructor.apply('', a).length threw exception RangeError: Invalid array length.
PASS var a = []; a.length = 0xFFFFFFFF; [].constructor.apply('', a).length threw exception RangeError: Invalid array length.
FAIL var a = []; a.length = 0x10001; [].constructor.apply('', a).length should throw an exception. Was 65537.
PASS var a = []; a.length = 0xFFFFFFFE; [].constructor.apply('', a).length threw exception RangeError: Maximum call stack size exceeded.
PASS var a = []; a.length = 0xFFFFFFFF; [].constructor.apply('', a).length threw exception RangeError: Maximum call stack size exceeded.
PASS (function(a,b,c,d){ return d ? -1 : (a+b+c); }).apply(undefined, {length:3, 0:100, 1:20, 2:3}) is 123
PASS successfullyParsed is true
......
......@@ -310,7 +310,7 @@ shouldBe("arrayApplyChangeLength4()", "0");
shouldBe("var a = []; a.length = 0xFFFE; [].constructor.apply('', a).length", "0xFFFE");
shouldBe("var a = []; a.length = 0xFFFF; [].constructor.apply('', a).length", "0xFFFF");
shouldBe("var a = []; a.length = 0x10000; [].constructor.apply('', a).length", "0x10000");
shouldBe("var a = []; a.length = 0x10001; [].constructor.apply('', a).length", "0x10001");
shouldThrow("var a = []; a.length = 0x10001; [].constructor.apply('', a).length");
shouldThrow("var a = []; a.length = 0xFFFFFFFE; [].constructor.apply('', a).length");
shouldThrow("var a = []; a.length = 0xFFFFFFFF; [].constructor.apply('', a).length");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment