Commit 5d40e9de authored by Joyee Cheung's avatar Joyee Cheung Committed by Commit Bot

[class] show private name in invalid private field access

This patch sets the name slot of the private name symbols for
private fields and display the names in error messages of invalid
private field accesses.

TBR: adamk@chromium.org
Bug: v8:8144
Change-Id: Id34c468e2bddd1c3001517b4d447c7497402df76
Reviewed-on: https://chromium-review.googlesource.com/c/1374332Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarMathias Bynens <mathias@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarMythri Alle <mythria@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/master@{#58601}
parent 9fc55a9d
......@@ -1962,7 +1962,7 @@ bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
DCHECK(proxy->is_private_name());
info->pending_error_handler()->ReportMessageAt(
proxy->position(), proxy->position() + 1,
MessageTemplate::kInvalidPrivateFieldAccess, proxy->raw_name(),
MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
kSyntaxError);
return false;
}
......@@ -2075,7 +2075,7 @@ bool Scope::ResolveVariablesRecursively(ParseInfo* info) {
if (var == nullptr) {
info->pending_error_handler()->ReportMessageAt(
proxy->position(), proxy->position() + 1,
MessageTemplate::kInvalidPrivateFieldAccess, proxy->raw_name(),
MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
kSyntaxError);
DCHECK(proxy->is_private_name());
return false;
......
......@@ -1403,9 +1403,10 @@ Handle<Symbol> Factory::NewPrivateSymbol(PretenureFlag flag) {
return symbol;
}
Handle<Symbol> Factory::NewPrivateNameSymbol() {
Handle<Symbol> Factory::NewPrivateNameSymbol(Handle<String> name) {
Handle<Symbol> symbol = NewSymbol();
symbol->set_is_private_name();
symbol->set_name(*name);
return symbol;
}
......
......@@ -372,7 +372,7 @@ class V8_EXPORT_PRIVATE Factory {
// Create a symbol in old or read-only space.
Handle<Symbol> NewSymbol(PretenureFlag pretenure = TENURED);
Handle<Symbol> NewPrivateSymbol(PretenureFlag pretenure = TENURED);
Handle<Symbol> NewPrivateNameSymbol();
Handle<Symbol> NewPrivateNameSymbol(Handle<String> name);
// Create a global (but otherwise uninitialized) context.
Handle<NativeContext> NewNativeContext();
......
......@@ -456,8 +456,10 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
if (name->IsPrivate()) {
if (name->IsPrivateName() && !it.IsFound()) {
return TypeError(MessageTemplate::kInvalidPrivateFieldAccess, object,
name);
Handle<String> name_string(String::cast(Symbol::cast(*name)->name()),
isolate());
return TypeError(MessageTemplate::kInvalidPrivateFieldRead, object,
name_string);
}
// IC handling of private symbols/fields lookup on JSProxy is not
......@@ -1427,8 +1429,10 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
if (name->IsPrivate()) {
if (name->IsPrivateName() && !it.IsFound()) {
return TypeError(MessageTemplate::kInvalidPrivateFieldAccess, object,
name);
Handle<String> name_string(String::cast(Symbol::cast(*name)->name()),
isolate());
return TypeError(MessageTemplate::kInvalidPrivateFieldWrite, object,
name_string);
}
// IC handling of private fields/symbols stores on JSProxy is not
......
......@@ -1904,7 +1904,13 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) {
if (property->kind() == ClassLiteral::Property::FIELD) {
if (property->is_private()) {
builder()->CallRuntime(Runtime::kCreatePrivateNameSymbol);
RegisterAllocationScope private_name_register_scope(this);
Register private_name = register_allocator()->NewRegister();
VisitForRegisterValue(property->key(), private_name);
builder()
->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
.StoreAccumulatorInRegister(private_name)
.CallRuntime(Runtime::kCreatePrivateNameSymbol, private_name);
DCHECK_NOT_NULL(property->private_name_var());
BuildVariableAssignment(property->private_name_var(), Token::INIT,
HoleCheckMode::kElided);
......
......@@ -396,7 +396,12 @@ namespace internal {
"Invalid left-hand side expression in prefix operation") \
T(InvalidRegExpFlags, "Invalid flags supplied to RegExp constructor '%'") \
T(InvalidOrUnexpectedToken, "Invalid or unexpected token") \
T(InvalidPrivateFieldAccess, "Invalid private field '%'") \
T(InvalidPrivateFieldResolution, \
"Undefined private field %: must be declared in an enclosing class") \
T(InvalidPrivateFieldRead, \
"Read of private field % from an object which did not contain the field") \
T(InvalidPrivateFieldWrite, \
"Write of private field % to an object which did not contain the field") \
T(JsonParseUnexpectedEOS, "Unexpected end of JSON input") \
T(JsonParseUnexpectedToken, "Unexpected token % in JSON at position %") \
T(JsonParseUnexpectedTokenNumber, "Unexpected number in JSON at position %") \
......
......@@ -42,10 +42,12 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
if (!it.IsFound() && key->IsSymbol() &&
Symbol::cast(*key)->is_private_name()) {
THROW_NEW_ERROR(
isolate,
NewTypeError(MessageTemplate::kInvalidPrivateFieldAccess, key, object),
Object);
Handle<Object> name_string(Symbol::cast(*key)->name(), isolate);
DCHECK(name_string->IsString());
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kInvalidPrivateFieldRead,
name_string, object),
Object);
}
return result;
}
......@@ -360,10 +362,12 @@ MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
if (!it.IsFound() && key->IsSymbol() &&
Symbol::cast(*key)->is_private_name()) {
THROW_NEW_ERROR(
isolate,
NewTypeError(MessageTemplate::kInvalidPrivateFieldAccess, key, object),
Object);
Handle<Object> name_string(Symbol::cast(*key)->name(), isolate);
DCHECK(name_string->IsString());
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kInvalidPrivateFieldWrite,
name_string, object),
Object);
}
MAYBE_RETURN_NULL(
......
......@@ -26,8 +26,9 @@ RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
RUNTIME_FUNCTION(Runtime_CreatePrivateNameSymbol) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
Handle<Symbol> symbol = isolate->factory()->NewPrivateNameSymbol();
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
Handle<Symbol> symbol = isolate->factory()->NewPrivateNameSymbol(name);
return *symbol;
}
......
......@@ -424,7 +424,7 @@ namespace internal {
F(StringTrim, 2, 1)
#define FOR_EACH_INTRINSIC_SYMBOL(F, I) \
F(CreatePrivateNameSymbol, 0, 1) \
F(CreatePrivateNameSymbol, 1, 1) \
F(CreatePrivateSymbol, -1 /* <= 1 */, 1) \
F(SymbolDescriptiveString, 1, 1) \
F(SymbolIsPrivate, 1, 1)
......
......@@ -23,9 +23,9 @@ snippet: "
new B;
}
"
frame size: 9
frame size: 10
parameter count: 1
bytecode array length: 127
bytecode array length: 143
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
......@@ -38,36 +38,44 @@ bytecodes: [
B(Star), R(5),
B(LdaConstant), U8(1),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(0), U8(0),
B(LdaConstant), U8(3),
B(Star), R(9),
B(LdaConstant), U8(3),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(9), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(1),
B(CreateClosure), U8(3), U8(1), U8(2),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(7),
B(StaNamedProperty), R(5), U8(4), U8(2),
B(StaNamedProperty), R(5), U8(5), U8(2),
B(PopContext), R(4),
B(Mov), R(1), R(2),
/* 38 E> */ B(CreateBlockContext), U8(5),
/* 38 E> */ B(CreateBlockContext), U8(6),
B(PushContext), R(4),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(Star), R(8),
B(CreateClosure), U8(7), U8(4), U8(2),
B(CreateClosure), U8(8), U8(4), U8(2),
B(Star), R(5),
B(LdaConstant), U8(6),
B(LdaConstant), U8(7),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(0), U8(0),
B(LdaConstant), U8(3),
B(Star), R(9),
B(LdaConstant), U8(3),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(9), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(0),
B(CreateClosure), U8(8), U8(5), U8(2),
B(CreateClosure), U8(9), U8(5), U8(2),
B(Star), R(7),
B(StaNamedProperty), R(5), U8(4), U8(6),
B(StaNamedProperty), R(5), U8(5), U8(6),
B(PopContext), R(4),
B(Mov), R(0), R(3),
/* 136 S> */ B(Ldar), R(1),
......@@ -81,6 +89,7 @@ constant pool: [
SCOPE_INFO_TYPE,
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"],
SHARED_FUNCTION_INFO_TYPE,
SYMBOL_TYPE,
SCOPE_INFO_TYPE,
......@@ -128,7 +137,7 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 257
bytecode array length: 289
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
......@@ -148,19 +157,23 @@ bytecodes: [
B(Star), R(7),
B(LdaConstant), U8(1),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(0), U8(0),
B(LdaConstant), U8(5),
B(Star), R(11),
B(LdaConstant), U8(5),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(7), R(9),
B(Mov), R(13), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(3),
B(Star), R(8),
B(Mov), R(9), R(2),
B(CreateClosure), U8(5), U8(2), U8(2),
B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(6), U8(3),
B(StaNamedProperty), R(7), U8(7), U8(3),
B(PopContext), R(6),
B(Mov), R(2), R(3),
/* 38 E> */ B(CreateBlockContext), U8(7),
/* 38 E> */ B(CreateBlockContext), U8(8),
B(PushContext), R(6),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
......@@ -168,53 +181,65 @@ bytecodes: [
B(StaCurrentContextSlot), U8(5),
B(LdaTheHole),
B(Star), R(14),
B(CreateClosure), U8(10), U8(5), U8(2),
B(CreateClosure), U8(11), U8(5), U8(2),
B(Star), R(11),
B(LdaConstant), U8(9),
B(LdaConstant), U8(10),
B(Star), R(12),
B(Mov), R(11), R(13),
B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3),
B(Star), R(12),
B(CreateClosure), U8(11), U8(6), U8(2),
B(CreateClosure), U8(12), U8(6), U8(2),
B(Star), R(7),
B(LdaConstant), U8(8),
B(LdaConstant), U8(9),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(0), U8(0),
B(LdaConstant), U8(5),
B(Star), R(11),
B(LdaConstant), U8(5),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1),
B(StaCurrentContextSlot), U8(4),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(0), U8(0),
B(LdaConstant), U8(13),
B(Star), R(11),
B(LdaConstant), U8(13),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(12), U8(7), U8(2),
B(CreateClosure), U8(14), U8(7), U8(2),
B(Star), R(11),
B(CreateClosure), U8(13), U8(8), U8(2),
B(CreateClosure), U8(15), U8(8), U8(2),
B(Star), R(12),
B(Mov), R(7), R(9),
B(Mov), R(13), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5),
B(Star), R(8),
B(Mov), R(9), R(1),
B(CreateClosure), U8(14), U8(9), U8(2),
B(CreateClosure), U8(16), U8(9), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(6), U8(10),
B(StaNamedProperty), R(7), U8(7), U8(10),
B(PopContext), R(6),
B(Mov), R(1), R(4),
/* 140 E> */ B(CreateBlockContext), U8(15),
/* 140 E> */ B(CreateBlockContext), U8(17),
B(PushContext), R(6),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
/* 356 E> */ B(CreateClosure), U8(17), U8(12), U8(2),
/* 356 E> */ B(CreateClosure), U8(19), U8(12), U8(2),
B(Star), R(7),
B(LdaConstant), U8(16),
B(LdaConstant), U8(18),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(0), U8(0),
B(LdaConstant), U8(5),
B(Star), R(11),
B(LdaConstant), U8(5),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(7), R(9),
B(Mov), R(1), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(3),
B(Star), R(8),
B(Mov), R(9), R(0),
B(CreateClosure), U8(18), U8(13), U8(2),
B(CreateClosure), U8(20), U8(13), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(6), U8(14),
B(StaNamedProperty), R(7), U8(7), U8(14),
B(PopContext), R(6),
B(Mov), R(0), R(5),
/* 430 S> */ B(Ldar), R(2),
......@@ -232,6 +257,7 @@ constant pool: [
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"],
SHARED_FUNCTION_INFO_TYPE,
SYMBOL_TYPE,
SCOPE_INFO_TYPE,
......@@ -239,6 +265,7 @@ constant pool: [
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#b"],
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
......
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-private-fields
class X {
#x;
constructor() {
({}).#x = 1;
}
}
new X;
*%(basename)s:10: TypeError: Write of private field #x to an object which did not contain the field
({}).#x = 1;
^
TypeError: Write of private field #x to an object which did not contain the field
at new X (*%(basename)s:10:13)
at *%(basename)s:14:1
\ No newline at end of file
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-private-fields
class X {
constructor() {
this.#x = 1;
}
}
*%(basename)s:9: SyntaxError: Undefined private field #x: must be declared in an enclosing class
this.#x = 1;
^
SyntaxError: Undefined private field #x: must be declared in an enclosing class
\ No newline at end of file
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-private-fields
class X {
#x;
eq(o) { return this.#x === o.#x; }
}
new X().eq({});
*%(basename)s:9: TypeError: Read of private field #x from an object which did not contain the field
eq(o) { return this.#x === o.#x; }
^
TypeError: Read of private field #x from an object which did not contain the field
at X.eq (*%(basename)s:9:32)
at *%(basename)s:12:9
\ No newline at end of file
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-private-fields
class X {
#x;
setX(o, val) { o.#x = val; }
}
new X().setX({}, 1);
*%(basename)s:9: TypeError: Write of private field #x to an object which did not contain the field
setX(o, val) { o.#x = val; }
^
TypeError: Write of private field #x to an object which did not contain the field
at X.setX (*%(basename)s:9:23)
at *%(basename)s:12:9
\ No newline at end of file
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