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 {
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
......
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