Add "own" symbols support.
"Own" symbols are symbols that can only denote own properties of objects. R=hpayer@chromium.org, verwaest@chromium.org Committed: https://code.google.com/p/v8/source/detail?r=23056 Review URL: https://codereview.chromium.org/464473002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23083 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
0f81d7698a
commit
d2fe3e68ea
@ -664,6 +664,14 @@ Handle<Symbol> Factory::NewPrivateSymbol() {
|
||||
}
|
||||
|
||||
|
||||
Handle<Symbol> Factory::NewPrivateOwnSymbol() {
|
||||
Handle<Symbol> symbol = NewSymbol();
|
||||
symbol->set_is_private(true);
|
||||
symbol->set_is_own(true);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
|
||||
Handle<Context> Factory::NewNativeContext() {
|
||||
Handle<FixedArray> array = NewFixedArray(Context::NATIVE_CONTEXT_SLOTS);
|
||||
array->set_map_no_write_barrier(*native_context_map());
|
||||
|
@ -221,6 +221,7 @@ class Factory V8_FINAL {
|
||||
// Create a symbol.
|
||||
Handle<Symbol> NewSymbol();
|
||||
Handle<Symbol> NewPrivateSymbol();
|
||||
Handle<Symbol> NewPrivateOwnSymbol();
|
||||
|
||||
// Create a global (but otherwise uninitialized) context.
|
||||
Handle<Context> NewNativeContext();
|
||||
|
@ -2834,7 +2834,7 @@ void Heap::CreateInitialObjects() {
|
||||
|
||||
// Allocate the dictionary of intrinsic function names.
|
||||
Handle<NameDictionary> intrinsic_names =
|
||||
NameDictionary::New(isolate(), Runtime::kNumFunctions);
|
||||
NameDictionary::New(isolate(), Runtime::kNumFunctions, TENURED);
|
||||
Runtime::InitializeIntrinsicFunctionNames(isolate(), intrinsic_names);
|
||||
set_intrinsic_function_names(*intrinsic_names);
|
||||
|
||||
|
13
src/lookup.h
13
src/lookup.h
@ -47,7 +47,7 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
LookupIterator(Handle<Object> receiver,
|
||||
Handle<Name> name,
|
||||
Configuration configuration = CHECK_ALL)
|
||||
: configuration_(configuration),
|
||||
: configuration_(ComputeConfiguration(configuration, name)),
|
||||
state_(NOT_FOUND),
|
||||
property_kind_(DATA),
|
||||
property_encoding_(DESCRIPTOR),
|
||||
@ -66,7 +66,7 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
Handle<Name> name,
|
||||
Handle<JSReceiver> holder,
|
||||
Configuration configuration = CHECK_ALL)
|
||||
: configuration_(configuration),
|
||||
: configuration_(ComputeConfiguration(configuration, name)),
|
||||
state_(NOT_FOUND),
|
||||
property_kind_(DATA),
|
||||
property_encoding_(DESCRIPTOR),
|
||||
@ -187,6 +187,15 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
|
||||
return number_;
|
||||
}
|
||||
|
||||
static Configuration ComputeConfiguration(
|
||||
Configuration configuration, Handle<Name> name) {
|
||||
if (name->IsOwn()) {
|
||||
return static_cast<Configuration>(configuration & CHECK_OWN);
|
||||
} else {
|
||||
return configuration;
|
||||
}
|
||||
}
|
||||
|
||||
Configuration configuration_;
|
||||
State state_;
|
||||
bool has_property_;
|
||||
|
@ -3372,6 +3372,7 @@ bool Name::Equals(Handle<Name> one, Handle<Name> two) {
|
||||
ACCESSORS(Symbol, name, Object, kNameOffset)
|
||||
ACCESSORS(Symbol, flags, Smi, kFlagsOffset)
|
||||
BOOL_ACCESSORS(Symbol, flags, is_private, kPrivateBit)
|
||||
BOOL_ACCESSORS(Symbol, flags, is_own, kOwnBit)
|
||||
|
||||
|
||||
bool String::Equals(String* other) {
|
||||
@ -6496,6 +6497,10 @@ uint32_t Name::Hash() {
|
||||
return String::cast(this)->ComputeAndSetHash();
|
||||
}
|
||||
|
||||
bool Name::IsOwn() {
|
||||
return this->IsSymbol() && Symbol::cast(this)->is_own();
|
||||
}
|
||||
|
||||
|
||||
StringHasher::StringHasher(int length, uint32_t seed)
|
||||
: length_(length),
|
||||
|
@ -430,7 +430,8 @@ void Symbol::SymbolPrint(OStream& os) { // NOLINT
|
||||
HeapObject::PrintHeader(os, "Symbol");
|
||||
os << " - hash: " << Hash();
|
||||
os << "\n - name: " << Brief(name());
|
||||
os << " - private: " << is_private();
|
||||
os << "\n - private: " << is_private();
|
||||
os << "\n - own: " << is_own();
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
|
@ -3560,6 +3560,11 @@ void JSObject::LookupRealNamedProperty(Handle<Name> name,
|
||||
|
||||
void JSObject::LookupRealNamedPropertyInPrototypes(Handle<Name> name,
|
||||
LookupResult* result) {
|
||||
if (name->IsOwn()) {
|
||||
result->NotFound();
|
||||
return;
|
||||
}
|
||||
|
||||
DisallowHeapAllocation no_gc;
|
||||
Isolate* isolate = GetIsolate();
|
||||
for (PrototypeIterator iter(isolate, this); !iter.IsAtEnd(); iter.Advance()) {
|
||||
@ -6107,7 +6112,7 @@ void JSReceiver::LookupOwn(
|
||||
}
|
||||
|
||||
js_object->LookupOwnRealNamedProperty(name, result);
|
||||
if (result->IsFound() || !search_hidden_prototypes) return;
|
||||
if (result->IsFound() || name->IsOwn() || !search_hidden_prototypes) return;
|
||||
|
||||
PrototypeIterator iter(GetIsolate(), js_object);
|
||||
if (!iter.GetCurrent()->IsJSReceiver()) return;
|
||||
@ -6126,6 +6131,10 @@ void JSReceiver::Lookup(Handle<Name> name, LookupResult* result) {
|
||||
!iter.IsAtEnd(); iter.Advance()) {
|
||||
JSReceiver::cast(iter.GetCurrent())->LookupOwn(name, result, false);
|
||||
if (result->IsFound()) return;
|
||||
if (name->IsOwn()) {
|
||||
result->NotFound();
|
||||
return;
|
||||
}
|
||||
}
|
||||
result->NotFound();
|
||||
}
|
||||
|
@ -8954,6 +8954,9 @@ class Name: public HeapObject {
|
||||
// Conversion.
|
||||
inline bool AsArrayIndex(uint32_t* index);
|
||||
|
||||
// Whether name can only name own properties.
|
||||
inline bool IsOwn();
|
||||
|
||||
DECLARE_CAST(Name)
|
||||
|
||||
DECLARE_PRINTER(Name)
|
||||
@ -9029,6 +9032,10 @@ class Symbol: public Name {
|
||||
// [is_private]: whether this is a private symbol.
|
||||
DECL_BOOLEAN_ACCESSORS(is_private)
|
||||
|
||||
// [is_own]: whether this is an own symbol, that is, only used to designate
|
||||
// own properties of objects.
|
||||
DECL_BOOLEAN_ACCESSORS(is_own)
|
||||
|
||||
DECLARE_CAST(Symbol)
|
||||
|
||||
// Dispatched behavior.
|
||||
@ -9044,6 +9051,7 @@ class Symbol: public Name {
|
||||
|
||||
private:
|
||||
static const int kPrivateBit = 0;
|
||||
static const int kOwnBit = 1;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
|
||||
};
|
||||
|
@ -608,6 +608,17 @@ RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_CreatePrivateOwnSymbol) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
|
||||
RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
|
||||
Handle<Symbol> symbol = isolate->factory()->NewPrivateOwnSymbol();
|
||||
if (name->IsString()) symbol->set_name(*name);
|
||||
return *symbol;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateSymbol) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
|
@ -260,6 +260,7 @@ namespace internal {
|
||||
F(CreateSymbol, 1, 1) \
|
||||
F(CreatePrivateSymbol, 1, 1) \
|
||||
F(CreateGlobalPrivateSymbol, 1, 1) \
|
||||
F(CreatePrivateOwnSymbol, 1, 1) \
|
||||
F(NewSymbolWrapper, 1, 1) \
|
||||
F(SymbolDescription, 1, 1) \
|
||||
F(SymbolRegistry, 0, 1) \
|
||||
|
55
test/mjsunit/own-symbols.js
Normal file
55
test/mjsunit/own-symbols.js
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright 2014 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: --allow-natives-syntax
|
||||
|
||||
var s = %CreatePrivateOwnSymbol("s");
|
||||
var s1 = %CreatePrivateOwnSymbol("s1");
|
||||
|
||||
function TestSimple() {
|
||||
var p = {}
|
||||
p[s] = "moo";
|
||||
|
||||
var o = Object.create(p);
|
||||
|
||||
assertEquals(undefined, o[s]);
|
||||
assertEquals("moo", p[s]);
|
||||
|
||||
o[s] = "bow-wow";
|
||||
assertEquals("bow-wow", o[s]);
|
||||
assertEquals("moo", p[s]);
|
||||
}
|
||||
|
||||
TestSimple();
|
||||
|
||||
|
||||
function TestICs() {
|
||||
var p = {}
|
||||
p[s] = "moo";
|
||||
|
||||
|
||||
var o = Object.create(p);
|
||||
o[s1] = "bow-wow";
|
||||
function checkNonOwn(o) {
|
||||
assertEquals(undefined, o[s]);
|
||||
assertEquals("bow-wow", o[s1]);
|
||||
}
|
||||
|
||||
checkNonOwn(o);
|
||||
|
||||
// Test monomorphic/optimized.
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
checkNonOwn(o);
|
||||
}
|
||||
|
||||
// Test non-monomorphic.
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
var oNew = Object.create(p);
|
||||
oNew["s" + i] = i;
|
||||
oNew[s1] = "bow-wow";
|
||||
checkNonOwn(oNew);
|
||||
}
|
||||
}
|
||||
|
||||
TestICs();
|
5
test/mjsunit/runtime-gen/createprivateownsymbol.js
Normal file
5
test/mjsunit/runtime-gen/createprivateownsymbol.js
Normal file
@ -0,0 +1,5 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
|
||||
// Flags: --allow-natives-syntax --harmony --harmony-proxies
|
||||
var arg0 = "foo";
|
||||
%CreatePrivateOwnSymbol(arg0);
|
@ -47,8 +47,8 @@ EXPAND_MACROS = [
|
||||
# that the parser doesn't bit-rot. Change the values as needed when you add,
|
||||
# remove or change runtime functions, but make sure we don't lose our ability
|
||||
# to parse them!
|
||||
EXPECTED_FUNCTION_COUNT = 428
|
||||
EXPECTED_FUZZABLE_COUNT = 331
|
||||
EXPECTED_FUNCTION_COUNT = 429
|
||||
EXPECTED_FUZZABLE_COUNT = 332
|
||||
EXPECTED_CCTEST_COUNT = 7
|
||||
EXPECTED_UNKNOWN_COUNT = 16
|
||||
EXPECTED_BUILTINS_COUNT = 808
|
||||
@ -226,6 +226,7 @@ CUSTOM_KNOWN_GOOD_INPUT = {
|
||||
"CreateBreakIterator": ["'en-US'", "{type: 'string'}", None, None],
|
||||
"CreateJSFunctionProxy": [None, "function() {}", None, None, None],
|
||||
"CreatePrivateSymbol": ["\"foo\"", None],
|
||||
"CreatePrivateOwnSymbol": ["\"foo\"", None],
|
||||
"CreateSymbol": ["\"foo\"", None],
|
||||
"DateParseString": [None, "new Array(8)", None],
|
||||
"DefineAccessorPropertyUnchecked": [None, None, "function() {}",
|
||||
|
Loading…
Reference in New Issue
Block a user