Improving error messages when adding properties to non JSObject receiver in
strict mode. LOG=N BUG=chromium:423739 Review URL: https://codereview.chromium.org/1381083004 Cr-Commit-Position: refs/heads/master@{#31192}
This commit is contained in:
parent
391ac4682a
commit
3ac2973b29
@ -214,7 +214,9 @@ class CallSite {
|
||||
T(StrictPoisonPill, \
|
||||
"'caller', 'callee', and 'arguments' properties may not be accessed on " \
|
||||
"strict mode functions or the arguments objects for calls to them") \
|
||||
T(StrictReadOnlyProperty, "Cannot assign to read only property '%' of %") \
|
||||
T(StrictReadOnlyProperty, \
|
||||
"Cannot assign to read only property '%' of % '%'") \
|
||||
T(StrictCannotCreateProperty, "Cannot create property '%' on % '%'") \
|
||||
T(StrongArity, \
|
||||
"In strong mode, calling a function with too few arguments is deprecated") \
|
||||
T(StrongDeleteProperty, \
|
||||
|
@ -383,6 +383,7 @@ Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
|
||||
if (object->IsBoolean()) return isolate->factory()->boolean_string();
|
||||
if (object->IsString()) return isolate->factory()->string_string();
|
||||
if (object->IsSymbol()) return isolate->factory()->symbol_string();
|
||||
if (object->IsString()) return isolate->factory()->string_string();
|
||||
#define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \
|
||||
if (object->Is##Type()) return isolate->factory()->type##_string();
|
||||
SIMD128_TYPES(SIMD128_TYPE)
|
||||
@ -3697,8 +3698,7 @@ MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it,
|
||||
if (found) return result;
|
||||
|
||||
if (!it->GetReceiver()->IsJSReceiver()) {
|
||||
return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
|
||||
it->GetName(), value, language_mode);
|
||||
return WriteToReadOnlyProperty(it, value, language_mode);
|
||||
}
|
||||
|
||||
LookupIterator::Configuration c = LookupIterator::OWN;
|
||||
@ -3784,6 +3784,28 @@ MaybeHandle<Object> Object::ReadAbsentProperty(Isolate* isolate,
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Object::CannotCreateProperty(LookupIterator* it,
|
||||
Handle<Object> value,
|
||||
LanguageMode language_mode) {
|
||||
return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
|
||||
value, language_mode);
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Object::CannotCreateProperty(Isolate* isolate,
|
||||
Handle<Object> receiver,
|
||||
Handle<Object> name,
|
||||
Handle<Object> value,
|
||||
LanguageMode language_mode) {
|
||||
if (is_sloppy(language_mode)) return value;
|
||||
Handle<String> typeof_string = Object::TypeOf(isolate, receiver);
|
||||
THROW_NEW_ERROR(isolate,
|
||||
NewTypeError(MessageTemplate::kStrictCannotCreateProperty,
|
||||
name, typeof_string, receiver),
|
||||
Object);
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Object::WriteToReadOnlyProperty(
|
||||
LookupIterator* it, Handle<Object> value, LanguageMode language_mode) {
|
||||
return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
|
||||
@ -3795,10 +3817,11 @@ MaybeHandle<Object> Object::WriteToReadOnlyProperty(
|
||||
Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
|
||||
Handle<Object> value, LanguageMode language_mode) {
|
||||
if (is_sloppy(language_mode)) return value;
|
||||
THROW_NEW_ERROR(
|
||||
isolate,
|
||||
NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name, receiver),
|
||||
Object);
|
||||
Handle<String> typeof_string = Object::TypeOf(isolate, receiver);
|
||||
THROW_NEW_ERROR(isolate,
|
||||
NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
|
||||
typeof_string, receiver),
|
||||
Object);
|
||||
}
|
||||
|
||||
|
||||
@ -3923,8 +3946,7 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
|
||||
StoreFromKeyed store_mode) {
|
||||
DCHECK(!it->GetReceiver()->IsJSProxy());
|
||||
if (!it->GetReceiver()->IsJSObject()) {
|
||||
// TODO(verwaest): Throw a TypeError with a more specific message.
|
||||
return WriteToReadOnlyProperty(it, value, language_mode);
|
||||
return CannotCreateProperty(it, value, language_mode);
|
||||
}
|
||||
|
||||
DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
|
||||
@ -13529,10 +13551,11 @@ bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
|
||||
MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
|
||||
Isolate* isolate = array->GetIsolate();
|
||||
Handle<Name> length = isolate->factory()->length_string();
|
||||
THROW_NEW_ERROR(
|
||||
isolate,
|
||||
NewTypeError(MessageTemplate::kStrictReadOnlyProperty, length, array),
|
||||
Object);
|
||||
Handle<String> typeof_string = Object::TypeOf(isolate, array);
|
||||
THROW_NEW_ERROR(isolate,
|
||||
NewTypeError(MessageTemplate::kStrictReadOnlyProperty, length,
|
||||
typeof_string, array),
|
||||
Object);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1234,6 +1234,11 @@ class Object {
|
||||
MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
|
||||
Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
|
||||
LanguageMode language_mode);
|
||||
MUST_USE_RESULT static MaybeHandle<Object> CannotCreateProperty(
|
||||
LookupIterator* it, Handle<Object> value, LanguageMode language_mode);
|
||||
MUST_USE_RESULT static MaybeHandle<Object> CannotCreateProperty(
|
||||
Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
|
||||
Handle<Object> value, LanguageMode language_mode);
|
||||
MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
|
||||
LookupIterator* it, Handle<Object> value, LanguageMode language_mode);
|
||||
MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
|
||||
|
@ -1076,7 +1076,7 @@
|
||||
}
|
||||
assertInstanceof(ex, TypeError);
|
||||
assertEquals(
|
||||
"Cannot assign to read only property 'ownReadOnly' of #<Base>",
|
||||
"Cannot assign to read only property 'ownReadOnly' of object '#<Base>'",
|
||||
ex.message);
|
||||
assertEquals(42, this.ownReadOnly);
|
||||
|
||||
@ -1323,7 +1323,7 @@ function TestKeyedSetterCreatingOwnPropertiesNonConfigurable(
|
||||
assertInstanceof(ex, TypeError);
|
||||
assertEquals(
|
||||
"Cannot assign to read only property '" + ownReadOnly +
|
||||
"' of #<Base>",
|
||||
"' of object '#<Base>'",
|
||||
ex.message);
|
||||
assertEquals(42, this[ownReadOnly]);
|
||||
|
||||
|
@ -301,7 +301,7 @@ test(function() {
|
||||
test(function() {
|
||||
"use strict";
|
||||
(1).a = 1;
|
||||
}, "Cannot assign to read only property 'a' of 1", TypeError);
|
||||
}, "Cannot create property 'a' on number '1'", TypeError);
|
||||
|
||||
// kStrongImplicitCast
|
||||
test(function() {
|
||||
|
@ -138,14 +138,14 @@ PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1},
|
||||
PASS 0 in Object.prototype is true
|
||||
PASS '0' in Object.prototype is true
|
||||
PASS var o = {}; o.readOnly = false; o.readOnly is true
|
||||
PASS 'use strict'; var o = {}; o.readOnly = false; o.readOnly threw exception TypeError: Cannot assign to read only property 'readOnly' of #<Object>.
|
||||
PASS 'use strict'; var o = {}; o.readOnly = false; o.readOnly threw exception TypeError: Cannot assign to read only property 'readOnly' of object '#<Object>'.
|
||||
PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false}), 'foo').writable is false
|
||||
PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false, writable: false}), 'foo').writable is false
|
||||
PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false, writable: true}), 'foo').writable is true
|
||||
PASS var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; is false
|
||||
PASS 'use strict'; var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; threw exception TypeError: Cannot assign to read only property 'length' of [object Array].
|
||||
PASS 'use strict'; var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; threw exception TypeError: Cannot assign to read only property 'length' of object '[object Array]'.
|
||||
PASS var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0]; is 42
|
||||
PASS 'use strict'; var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0]; threw exception TypeError: Cannot assign to read only property '0' of [object Array].
|
||||
PASS 'use strict'; var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0]; threw exception TypeError: Cannot assign to read only property '0' of object '[object Array]'.
|
||||
PASS var a = Object.defineProperty([], '0', {set: undefined}); a[0] = 42; a[0]; is undefined.
|
||||
PASS 'use strict'; var a = Object.defineProperty([], '0', {set: undefined}); a[0] = 42; a[0]; threw exception TypeError: Cannot set property 0 of [object Array] which has only a getter.
|
||||
PASS anObj.slot1 is "foo"
|
||||
|
@ -133,7 +133,7 @@ PASS 'use strict'; if (0) { someGlobal = 'Shouldn\'t be able to assign this.'; }
|
||||
PASS 'use strict'; someGlobal = 'Shouldn\'t be able to assign this.'; threw exception ReferenceError: someGlobal is not defined.
|
||||
PASS 'use strict'; (function f(){ f = 'shouldn\'t be able to assign to function expression name'; })() threw exception TypeError: Assignment to constant variable..
|
||||
PASS 'use strict'; eval('var introducedVariable = "FAIL: variable introduced into containing scope";'); introducedVariable threw exception ReferenceError: introducedVariable is not defined.
|
||||
PASS 'use strict'; objectWithReadonlyProperty.prop = 'fail' threw exception TypeError: Cannot assign to read only property 'prop' of #<Object>.
|
||||
PASS 'use strict'; objectWithReadonlyProperty.prop = 'fail' threw exception TypeError: Cannot assign to read only property 'prop' of object '#<Object>'.
|
||||
PASS 'use strict'; delete objectWithReadonlyProperty.prop threw exception TypeError: Cannot delete property 'prop' of #<Object>.
|
||||
PASS 'use strict'; delete objectWithReadonlyProperty[readonlyPropName] threw exception TypeError: Cannot delete property 'prop' of #<Object>.
|
||||
PASS 'use strict'; ++eval threw exception SyntaxError: Unexpected eval or arguments in strict mode.
|
||||
|
@ -47,9 +47,9 @@ PASS checkWrite(true, Boolean) is true
|
||||
PASS checkReadStrict(1, Number) is true
|
||||
PASS checkReadStrict('hello', String) is true
|
||||
PASS checkReadStrict(true, Boolean) is true
|
||||
PASS checkWriteStrict(1, Number) threw exception TypeError: Cannot assign to read only property 'foo' of 1.
|
||||
PASS checkWriteStrict('hello', String) threw exception TypeError: Cannot assign to read only property 'foo' of hello.
|
||||
PASS checkWriteStrict(true, Boolean) threw exception TypeError: Cannot assign to read only property 'foo' of true.
|
||||
PASS checkWriteStrict(1, Number) threw exception TypeError: Cannot create property 'foo' on number '1'.
|
||||
PASS checkWriteStrict('hello', String) threw exception TypeError: Cannot create property 'foo' on string 'hello'.
|
||||
PASS checkWriteStrict(true, Boolean) threw exception TypeError: Cannot create property 'foo' on boolean 'true'.
|
||||
PASS checkNumericGet(1, Number) is true
|
||||
PASS checkNumericGet('hello', String) is true
|
||||
PASS checkNumericGet(true, Boolean) is true
|
||||
@ -71,9 +71,9 @@ PASS checkNumericWrite(true, Boolean) is true
|
||||
PASS checkNumericReadStrict(1, Number) is true
|
||||
PASS checkNumericReadStrict('hello', String) is true
|
||||
PASS checkNumericReadStrict(true, Boolean) is true
|
||||
PASS checkNumericWriteStrict(1, Number) threw exception TypeError: Cannot assign to read only property '42' of 1.
|
||||
PASS checkNumericWriteStrict('hello', String) threw exception TypeError: Cannot assign to read only property '42' of hello.
|
||||
PASS checkNumericWriteStrict(true, Boolean) threw exception TypeError: Cannot assign to read only property '42' of true.
|
||||
PASS checkNumericWriteStrict(1, Number) threw exception TypeError: Cannot create property '42' on number '1'.
|
||||
PASS checkNumericWriteStrict('hello', String) threw exception TypeError: Cannot create property '42' on string 'hello'.
|
||||
PASS checkNumericWriteStrict(true, Boolean) threw exception TypeError: Cannot create property '42' on boolean 'true'.
|
||||
PASS didNotCrash is true
|
||||
PASS successfullyParsed is true
|
||||
|
||||
|
@ -42,7 +42,7 @@ PASS preDecTest(); is true
|
||||
PASS postIncTest(); is true
|
||||
PASS postDecTest(); is true
|
||||
PASS primitiveThisTest.call(1); is true
|
||||
PASS strictThisTest.call(1); threw exception TypeError: Cannot assign to read only property 'value' of 1.
|
||||
PASS strictThisTest.call(1); threw exception TypeError: Cannot create property 'value' on number '1'.
|
||||
PASS successfullyParsed is true
|
||||
|
||||
TEST COMPLETE
|
||||
|
Loading…
Reference in New Issue
Block a user