Commit 3ac2973b authored by cbruni's avatar cbruni Committed by Commit bot

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}
parent 391ac468
...@@ -214,7 +214,9 @@ class CallSite { ...@@ -214,7 +214,9 @@ class CallSite {
T(StrictPoisonPill, \ T(StrictPoisonPill, \
"'caller', 'callee', and 'arguments' properties may not be accessed on " \ "'caller', 'callee', and 'arguments' properties may not be accessed on " \
"strict mode functions or the arguments objects for calls to them") \ "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, \ T(StrongArity, \
"In strong mode, calling a function with too few arguments is deprecated") \ "In strong mode, calling a function with too few arguments is deprecated") \
T(StrongDeleteProperty, \ T(StrongDeleteProperty, \
......
...@@ -383,6 +383,7 @@ Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) { ...@@ -383,6 +383,7 @@ Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) {
if (object->IsBoolean()) return isolate->factory()->boolean_string(); if (object->IsBoolean()) return isolate->factory()->boolean_string();
if (object->IsString()) return isolate->factory()->string_string(); if (object->IsString()) return isolate->factory()->string_string();
if (object->IsSymbol()) return isolate->factory()->symbol_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) \ #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \
if (object->Is##Type()) return isolate->factory()->type##_string(); if (object->Is##Type()) return isolate->factory()->type##_string();
SIMD128_TYPES(SIMD128_TYPE) SIMD128_TYPES(SIMD128_TYPE)
...@@ -3697,8 +3698,7 @@ MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it, ...@@ -3697,8 +3698,7 @@ MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it,
if (found) return result; if (found) return result;
if (!it->GetReceiver()->IsJSReceiver()) { if (!it->GetReceiver()->IsJSReceiver()) {
return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(), return WriteToReadOnlyProperty(it, value, language_mode);
it->GetName(), value, language_mode);
} }
LookupIterator::Configuration c = LookupIterator::OWN; LookupIterator::Configuration c = LookupIterator::OWN;
...@@ -3784,6 +3784,28 @@ MaybeHandle<Object> Object::ReadAbsentProperty(Isolate* isolate, ...@@ -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( MaybeHandle<Object> Object::WriteToReadOnlyProperty(
LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { LookupIterator* it, Handle<Object> value, LanguageMode language_mode) {
return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(), return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
...@@ -3795,10 +3817,11 @@ MaybeHandle<Object> Object::WriteToReadOnlyProperty( ...@@ -3795,10 +3817,11 @@ MaybeHandle<Object> Object::WriteToReadOnlyProperty(
Isolate* isolate, Handle<Object> receiver, Handle<Object> name, Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
Handle<Object> value, LanguageMode language_mode) { Handle<Object> value, LanguageMode language_mode) {
if (is_sloppy(language_mode)) return value; if (is_sloppy(language_mode)) return value;
THROW_NEW_ERROR( Handle<String> typeof_string = Object::TypeOf(isolate, receiver);
isolate, THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name, receiver), NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
Object); typeof_string, receiver),
Object);
} }
...@@ -3923,8 +3946,7 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, ...@@ -3923,8 +3946,7 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
StoreFromKeyed store_mode) { StoreFromKeyed store_mode) {
DCHECK(!it->GetReceiver()->IsJSProxy()); DCHECK(!it->GetReceiver()->IsJSProxy());
if (!it->GetReceiver()->IsJSObject()) { if (!it->GetReceiver()->IsJSObject()) {
// TODO(verwaest): Throw a TypeError with a more specific message. return CannotCreateProperty(it, value, language_mode);
return WriteToReadOnlyProperty(it, value, language_mode);
} }
DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state()); DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
...@@ -13529,10 +13551,11 @@ bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array, ...@@ -13529,10 +13551,11 @@ bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) { MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
Isolate* isolate = array->GetIsolate(); Isolate* isolate = array->GetIsolate();
Handle<Name> length = isolate->factory()->length_string(); Handle<Name> length = isolate->factory()->length_string();
THROW_NEW_ERROR( Handle<String> typeof_string = Object::TypeOf(isolate, array);
isolate, THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kStrictReadOnlyProperty, length, array), NewTypeError(MessageTemplate::kStrictReadOnlyProperty, length,
Object); typeof_string, array),
Object);
} }
......
...@@ -1234,6 +1234,11 @@ class Object { ...@@ -1234,6 +1234,11 @@ class Object {
MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty( MUST_USE_RESULT static MaybeHandle<Object> ReadAbsentProperty(
Isolate* isolate, Handle<Object> receiver, Handle<Object> name, Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
LanguageMode language_mode); 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( MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
LookupIterator* it, Handle<Object> value, LanguageMode language_mode); LookupIterator* it, Handle<Object> value, LanguageMode language_mode);
MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty( MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
......
...@@ -1076,7 +1076,7 @@ ...@@ -1076,7 +1076,7 @@
} }
assertInstanceof(ex, TypeError); assertInstanceof(ex, TypeError);
assertEquals( assertEquals(
"Cannot assign to read only property 'ownReadOnly' of #<Base>", "Cannot assign to read only property 'ownReadOnly' of object '#<Base>'",
ex.message); ex.message);
assertEquals(42, this.ownReadOnly); assertEquals(42, this.ownReadOnly);
...@@ -1323,7 +1323,7 @@ function TestKeyedSetterCreatingOwnPropertiesNonConfigurable( ...@@ -1323,7 +1323,7 @@ function TestKeyedSetterCreatingOwnPropertiesNonConfigurable(
assertInstanceof(ex, TypeError); assertInstanceof(ex, TypeError);
assertEquals( assertEquals(
"Cannot assign to read only property '" + ownReadOnly + "Cannot assign to read only property '" + ownReadOnly +
"' of #<Base>", "' of object '#<Base>'",
ex.message); ex.message);
assertEquals(42, this[ownReadOnly]); assertEquals(42, this[ownReadOnly]);
......
...@@ -301,7 +301,7 @@ test(function() { ...@@ -301,7 +301,7 @@ test(function() {
test(function() { test(function() {
"use strict"; "use strict";
(1).a = 1; (1).a = 1;
}, "Cannot assign to read only property 'a' of 1", TypeError); }, "Cannot create property 'a' on number '1'", TypeError);
// kStrongImplicitCast // kStrongImplicitCast
test(function() { test(function() {
......
...@@ -138,14 +138,14 @@ PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1}, ...@@ -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 '0' in Object.prototype is true PASS '0' in Object.prototype is true
PASS var o = {}; o.readOnly = false; o.readOnly 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}), '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: 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 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 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 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 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 '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" PASS anObj.slot1 is "foo"
......
...@@ -133,7 +133,7 @@ PASS 'use strict'; if (0) { someGlobal = 'Shouldn\'t be able to assign this.'; } ...@@ -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'; 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'; (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'; 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.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'; 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. PASS 'use strict'; ++eval threw exception SyntaxError: Unexpected eval or arguments in strict mode.
......
...@@ -47,9 +47,9 @@ PASS checkWrite(true, Boolean) is true ...@@ -47,9 +47,9 @@ PASS checkWrite(true, Boolean) is true
PASS checkReadStrict(1, Number) is true PASS checkReadStrict(1, Number) is true
PASS checkReadStrict('hello', String) is true PASS checkReadStrict('hello', String) is true
PASS checkReadStrict(true, Boolean) 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(1, Number) threw exception TypeError: Cannot create property 'foo' on number '1'.
PASS checkWriteStrict('hello', String) threw exception TypeError: Cannot assign to read only property 'foo' of hello. PASS checkWriteStrict('hello', String) threw exception TypeError: Cannot create property 'foo' on string 'hello'.
PASS checkWriteStrict(true, Boolean) threw exception TypeError: Cannot assign to read only property 'foo' of true. PASS checkWriteStrict(true, Boolean) threw exception TypeError: Cannot create property 'foo' on boolean 'true'.
PASS checkNumericGet(1, Number) is true PASS checkNumericGet(1, Number) is true
PASS checkNumericGet('hello', String) is true PASS checkNumericGet('hello', String) is true
PASS checkNumericGet(true, Boolean) is true PASS checkNumericGet(true, Boolean) is true
...@@ -71,9 +71,9 @@ PASS checkNumericWrite(true, Boolean) is true ...@@ -71,9 +71,9 @@ PASS checkNumericWrite(true, Boolean) is true
PASS checkNumericReadStrict(1, Number) is true PASS checkNumericReadStrict(1, Number) is true
PASS checkNumericReadStrict('hello', String) is true PASS checkNumericReadStrict('hello', String) is true
PASS checkNumericReadStrict(true, Boolean) 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(1, Number) threw exception TypeError: Cannot create property '42' on number '1'.
PASS checkNumericWriteStrict('hello', String) threw exception TypeError: Cannot assign to read only property '42' of hello. PASS checkNumericWriteStrict('hello', String) threw exception TypeError: Cannot create property '42' on string 'hello'.
PASS checkNumericWriteStrict(true, Boolean) threw exception TypeError: Cannot assign to read only property '42' of true. PASS checkNumericWriteStrict(true, Boolean) threw exception TypeError: Cannot create property '42' on boolean 'true'.
PASS didNotCrash is true PASS didNotCrash is true
PASS successfullyParsed is true PASS successfullyParsed is true
......
...@@ -42,7 +42,7 @@ PASS preDecTest(); is true ...@@ -42,7 +42,7 @@ PASS preDecTest(); is true
PASS postIncTest(); is true PASS postIncTest(); is true
PASS postDecTest(); is true PASS postDecTest(); is true
PASS primitiveThisTest.call(1); 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 PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
......
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