Support symbol-named properties in API
authorwingo@igalia.com <wingo@igalia.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 20 Aug 2014 15:25:13 +0000 (15:25 +0000)
committerwingo@igalia.com <wingo@igalia.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 20 Aug 2014 15:25:13 +0000 (15:25 +0000)
Add new "Name" type to API that is a supertype of Symbol and String.

Object::SetDeclaredAccessor, Object::SetAccessorProperty, Template::Set,
Template::SetAccessorProperty, and Template::SetDeclaredAccessor now
take a Name as the property name instead of a String.

Add Object::SetAccessor, Template::SetNativeDataProperty, and
ObjectTemplate::SetAccessor overloads that can define accessors for
symbol-named properties.

R=dcarney@chromium.org, rossberg@chromium.org
BUG=v8:3394
TEST=cctest/test-api/TestSymbolProperties
LOG=Y

Review URL: https://codereview.chromium.org/459413002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23247 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

12 files changed:
include/v8.h
src/accessors.cc
src/accessors.h
src/api.cc
src/api.h
src/arguments.h
src/arm64/simulator-arm64.cc
src/assembler.h
src/objects.cc
src/stub-cache.cc
test/cctest/test-alloc.cc
test/cctest/test-api.cc

index e01da1e23f9715e6114efdf7160b9545be3b40ce..87f9f47482983e4fb80a10dec9387a1d7f4ffe2d 100644 (file)
@@ -77,6 +77,7 @@ class ImplementationUtilities;
 class Int32;
 class Integer;
 class Isolate;
+class Name;
 class Number;
 class NumberObject;
 class Object;
@@ -1366,6 +1367,12 @@ class V8_EXPORT Value : public Data {
    */
   bool IsFalse() const;
 
+  /**
+   * Returns true if this value is a symbol or a string.
+   * This is an experimental feature.
+   */
+  bool IsName() const;
+
   /**
    * Returns true if this value is an instance of the String type.
    * See ECMA-262 8.4.
@@ -1598,10 +1605,21 @@ class V8_EXPORT Boolean : public Primitive {
 };
 
 
+/**
+ * A superclass for symbols and strings.
+ */
+class V8_EXPORT Name : public Primitive {
+ public:
+  V8_INLINE static Name* Cast(v8::Value* obj);
+ private:
+  static void CheckCast(v8::Value* obj);
+};
+
+
 /**
  * A JavaScript string value (ECMA-262, 4.3.17).
  */
-class V8_EXPORT String : public Primitive {
+class V8_EXPORT String : public Name {
  public:
   enum Encoding {
     UNKNOWN_ENCODING = 0x1,
@@ -1940,7 +1958,7 @@ class V8_EXPORT String : public Primitive {
  *
  * This is an experimental feature. Use at your own risk.
  */
-class V8_EXPORT Symbol : public Primitive {
+class V8_EXPORT Symbol : public Name {
  public:
   // Returns the print name string of the symbol, or undefined if none.
   Local<Value> Name() const;
@@ -2089,12 +2107,19 @@ enum ExternalArrayType {
 typedef void (*AccessorGetterCallback)(
     Local<String> property,
     const PropertyCallbackInfo<Value>& info);
+typedef void (*AccessorNameGetterCallback)(
+    Local<Name> property,
+    const PropertyCallbackInfo<Value>& info);
 
 
 typedef void (*AccessorSetterCallback)(
     Local<String> property,
     Local<Value> value,
     const PropertyCallbackInfo<void>& info);
+typedef void (*AccessorNameSetterCallback)(
+    Local<Name> property,
+    Local<Value> value,
+    const PropertyCallbackInfo<void>& info);
 
 
 /**
@@ -2169,14 +2194,20 @@ class V8_EXPORT Object : public Value {
                    Handle<Value> data = Handle<Value>(),
                    AccessControl settings = DEFAULT,
                    PropertyAttribute attribute = None);
+  bool SetAccessor(Handle<Name> name,
+                   AccessorNameGetterCallback getter,
+                   AccessorNameSetterCallback setter = 0,
+                   Handle<Value> data = Handle<Value>(),
+                   AccessControl settings = DEFAULT,
+                   PropertyAttribute attribute = None);
 
   // This function is not yet stable and should not be used at this time.
-  bool SetDeclaredAccessor(Local<String> name,
+  bool SetDeclaredAccessor(Local<Name> name,
                            Local<DeclaredAccessorDescriptor> descriptor,
                            PropertyAttribute attribute = None,
                            AccessControl settings = DEFAULT);
 
-  void SetAccessorProperty(Local<String> name,
+  void SetAccessorProperty(Local<Name> name,
                            Local<Function> getter,
                            Handle<Function> setter = Handle<Function>(),
                            PropertyAttribute attribute = None,
@@ -3178,12 +3209,12 @@ class V8_EXPORT External : public Value {
 class V8_EXPORT Template : public Data {
  public:
   /** Adds a property to each instance created by this template.*/
-  void Set(Handle<String> name, Handle<Data> value,
+  void Set(Handle<Name> name, Handle<Data> value,
            PropertyAttribute attributes = None);
   V8_INLINE void Set(Isolate* isolate, const char* name, Handle<Data> value);
 
   void SetAccessorProperty(
-     Local<String> name,
+     Local<Name> name,
      Local<FunctionTemplate> getter = Local<FunctionTemplate>(),
      Local<FunctionTemplate> setter = Local<FunctionTemplate>(),
      PropertyAttribute attribute = None,
@@ -3225,9 +3256,18 @@ class V8_EXPORT Template : public Data {
                              Local<AccessorSignature> signature =
                                  Local<AccessorSignature>(),
                              AccessControl settings = DEFAULT);
+  void SetNativeDataProperty(Local<Name> name,
+                             AccessorNameGetterCallback getter,
+                             AccessorNameSetterCallback setter = 0,
+                             // TODO(dcarney): gcc can't handle Local below
+                             Handle<Value> data = Handle<Value>(),
+                             PropertyAttribute attribute = None,
+                             Local<AccessorSignature> signature =
+                                 Local<AccessorSignature>(),
+                             AccessControl settings = DEFAULT);
 
   // This function is not yet stable and should not be used at this time.
-  bool SetDeclaredAccessor(Local<String> name,
+  bool SetDeclaredAccessor(Local<Name> name,
                            Local<DeclaredAccessorDescriptor> descriptor,
                            PropertyAttribute attribute = None,
                            Local<AccessorSignature> signature =
@@ -3594,12 +3634,20 @@ class V8_EXPORT ObjectTemplate : public Template {
                    PropertyAttribute attribute = None,
                    Handle<AccessorSignature> signature =
                        Handle<AccessorSignature>());
+  void SetAccessor(Handle<Name> name,
+                   AccessorNameGetterCallback getter,
+                   AccessorNameSetterCallback setter = 0,
+                   Handle<Value> data = Handle<Value>(),
+                   AccessControl settings = DEFAULT,
+                   PropertyAttribute attribute = None,
+                   Handle<AccessorSignature> signature =
+                       Handle<AccessorSignature>());
 
   /**
    * Sets a named property handler on the object template.
    *
-   * Whenever a named property is accessed on objects created from
-   * this object template, the provided callback is invoked instead of
+   * Whenever a property whose name is a string is accessed on objects created
+   * from this object template, the provided callback is invoked instead of
    * accessing the property directly on the JavaScript object.
    *
    * \param getter The callback to invoke when getting a property.
@@ -6348,6 +6396,14 @@ template <class T> Value* Value::Cast(T* value) {
 }
 
 
+Name* Name::Cast(v8::Value* value) {
+#ifdef V8_ENABLE_CHECKS
+  CheckCast(value);
+#endif
+  return static_cast<Name*>(value);
+}
+
+
 Symbol* Symbol::Cast(v8::Value* value) {
 #ifdef V8_ENABLE_CHECKS
   CheckCast(value);
index 3875c4fdf482418cfc5b88b9ae21d9ceb4eedde8..c2361b3e9cda753c69ae5e12bb57ded05385cde8 100644 (file)
@@ -23,9 +23,9 @@ namespace internal {
 
 Handle<AccessorInfo> Accessors::MakeAccessor(
     Isolate* isolate,
-    Handle<String> name,
-    AccessorGetterCallback getter,
-    AccessorSetterCallback setter,
+    Handle<Name> name,
+    AccessorNameGetterCallback getter,
+    AccessorNameSetterCallback setter,
     PropertyAttributes attributes) {
   Factory* factory = isolate->factory();
   Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
@@ -138,7 +138,7 @@ bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type,
 
 bool SetPropertyOnInstanceIfInherited(
     Isolate* isolate, const v8::PropertyCallbackInfo<void>& info,
-    v8::Local<v8::String> name, Handle<Object> value) {
+    v8::Local<v8::Name> name, Handle<Object> value) {
   Handle<Object> holder = Utils::OpenHandle(*info.Holder());
   Handle<Object> receiver = Utils::OpenHandle(*info.This());
   if (*holder == *receiver) return false;
@@ -176,7 +176,7 @@ Handle<Object> Accessors::FlattenNumber(Isolate* isolate,
 
 
 void Accessors::ArrayLengthGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -188,7 +188,7 @@ void Accessors::ArrayLengthGetter(
 
 
 void Accessors::ArrayLengthSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> val,
     const v8::PropertyCallbackInfo<void>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
@@ -244,7 +244,7 @@ Handle<AccessorInfo> Accessors::ArrayLengthInfo(
 //
 
 void Accessors::StringLengthGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -267,7 +267,7 @@ void Accessors::StringLengthGetter(
 
 
 void Accessors::StringLengthSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -290,7 +290,7 @@ Handle<AccessorInfo> Accessors::StringLengthInfo(
 
 
 void Accessors::ScriptColumnOffsetGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -302,7 +302,7 @@ void Accessors::ScriptColumnOffsetGetter(
 
 
 void Accessors::ScriptColumnOffsetSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -327,7 +327,7 @@ Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
 
 
 void Accessors::ScriptIdGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -339,7 +339,7 @@ void Accessors::ScriptIdGetter(
 
 
 void Accessors::ScriptIdSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -364,7 +364,7 @@ Handle<AccessorInfo> Accessors::ScriptIdInfo(
 
 
 void Accessors::ScriptNameGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -376,7 +376,7 @@ void Accessors::ScriptNameGetter(
 
 
 void Accessors::ScriptNameSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -399,7 +399,7 @@ Handle<AccessorInfo> Accessors::ScriptNameInfo(
 
 
 void Accessors::ScriptSourceGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -411,7 +411,7 @@ void Accessors::ScriptSourceGetter(
 
 
 void Accessors::ScriptSourceSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -434,7 +434,7 @@ Handle<AccessorInfo> Accessors::ScriptSourceInfo(
 
 
 void Accessors::ScriptLineOffsetGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -446,7 +446,7 @@ void Accessors::ScriptLineOffsetGetter(
 
 
 void Accessors::ScriptLineOffsetSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -471,7 +471,7 @@ Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
 
 
 void Accessors::ScriptTypeGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -483,7 +483,7 @@ void Accessors::ScriptTypeGetter(
 
 
 void Accessors::ScriptTypeSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -508,7 +508,7 @@ Handle<AccessorInfo> Accessors::ScriptTypeInfo(
 
 
 void Accessors::ScriptCompilationTypeGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -521,7 +521,7 @@ void Accessors::ScriptCompilationTypeGetter(
 
 
 void Accessors::ScriptCompilationTypeSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -546,7 +546,7 @@ Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
 
 
 void Accessors::ScriptLineEndsGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
@@ -566,7 +566,7 @@ void Accessors::ScriptLineEndsGetter(
 
 
 void Accessors::ScriptLineEndsSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -591,7 +591,7 @@ Handle<AccessorInfo> Accessors::ScriptLineEndsInfo(
 
 
 void Accessors::ScriptSourceUrlGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -603,7 +603,7 @@ void Accessors::ScriptSourceUrlGetter(
 
 
 void Accessors::ScriptSourceUrlSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -626,7 +626,7 @@ Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
 
 
 void Accessors::ScriptSourceMappingUrlGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -639,7 +639,7 @@ void Accessors::ScriptSourceMappingUrlGetter(
 
 
 void Accessors::ScriptSourceMappingUrlSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -662,7 +662,7 @@ Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
 
 
 void Accessors::ScriptContextDataGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
@@ -674,7 +674,7 @@ void Accessors::ScriptContextDataGetter(
 
 
 void Accessors::ScriptContextDataSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -699,7 +699,7 @@ Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
 
 
 void Accessors::ScriptEvalFromScriptGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
@@ -721,7 +721,7 @@ void Accessors::ScriptEvalFromScriptGetter(
 
 
 void Accessors::ScriptEvalFromScriptSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -746,7 +746,7 @@ Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
 
 
 void Accessors::ScriptEvalFromScriptPositionGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
@@ -767,7 +767,7 @@ void Accessors::ScriptEvalFromScriptPositionGetter(
 
 
 void Accessors::ScriptEvalFromScriptPositionSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -792,7 +792,7 @@ Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
 
 
 void Accessors::ScriptEvalFromFunctionNameGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
@@ -813,7 +813,7 @@ void Accessors::ScriptEvalFromFunctionNameGetter(
 
 
 void Accessors::ScriptEvalFromFunctionNameSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
@@ -884,7 +884,7 @@ Handle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
 
 
 void Accessors::FunctionPrototypeGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
@@ -896,7 +896,7 @@ void Accessors::FunctionPrototypeGetter(
 
 
 void Accessors::FunctionPrototypeSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> val,
     const v8::PropertyCallbackInfo<void>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
@@ -927,7 +927,7 @@ Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
 
 
 void Accessors::FunctionLengthGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
@@ -953,7 +953,7 @@ void Accessors::FunctionLengthGetter(
 
 
 void Accessors::FunctionLengthSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> val,
     const v8::PropertyCallbackInfo<void>& info) {
   // Function length is non writable, non configurable.
@@ -977,7 +977,7 @@ Handle<AccessorInfo> Accessors::FunctionLengthInfo(
 
 
 void Accessors::FunctionNameGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
@@ -989,7 +989,7 @@ void Accessors::FunctionNameGetter(
 
 
 void Accessors::FunctionNameSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> val,
     const v8::PropertyCallbackInfo<void>& info) {
   // Function name is non writable, non configurable.
@@ -1114,7 +1114,7 @@ Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
 
 
 void Accessors::FunctionArgumentsGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
@@ -1126,7 +1126,7 @@ void Accessors::FunctionArgumentsGetter(
 
 
 void Accessors::FunctionArgumentsSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> val,
     const v8::PropertyCallbackInfo<void>& info) {
   // Function arguments is non writable, non configurable.
@@ -1257,7 +1257,7 @@ MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
 
 
 void Accessors::FunctionCallerGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
@@ -1277,7 +1277,7 @@ void Accessors::FunctionCallerGetter(
 
 
 void Accessors::FunctionCallerSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> val,
     const v8::PropertyCallbackInfo<void>& info) {
   // Function caller is non writable, non configurable.
index 17b7510adef66bed8af00378af08ec6c52385f79..75099a0c728fdcf40f6dcce239b6a0e6c189682a 100644 (file)
@@ -43,10 +43,10 @@ class Accessors : public AllStatic {
   // Accessor descriptors.
 #define ACCESSOR_INFO_DECLARATION(name)                   \
   static void name##Getter(                               \
-      v8::Local<v8::String> name,                         \
+      v8::Local<v8::Name> name,                           \
       const v8::PropertyCallbackInfo<v8::Value>& info);   \
   static void name##Setter(                               \
-      v8::Local<v8::String> name,                         \
+      v8::Local<v8::Name> name,                           \
       v8::Local<v8::Value> value,                         \
       const v8::PropertyCallbackInfo<void>& info);   \
   static Handle<AccessorInfo> name##Info(                 \
@@ -83,9 +83,9 @@ class Accessors : public AllStatic {
 
   static Handle<AccessorInfo> MakeAccessor(
       Isolate* isolate,
-      Handle<String> name,
-      AccessorGetterCallback getter,
-      AccessorSetterCallback setter,
+      Handle<Name> name,
+      AccessorNameGetterCallback getter,
+      AccessorNameSetterCallback setter,
       PropertyAttributes attributes);
 
   static Handle<ExecutableAccessorInfo> CloneAccessor(
index 5e91d5890dacff9e692726de0385673e344bdc51..b23ec0e38e0db5359cc4a01d69c199ab240769e9 100644 (file)
@@ -828,7 +828,7 @@ static void TemplateSet(i::Isolate* isolate,
 }
 
 
-void Template::Set(v8::Handle<String> name,
+void Template::Set(v8::Handle<Name> name,
                    v8::Handle<Data> value,
                    v8::PropertyAttribute attribute) {
   i::Isolate* isolate = i::Isolate::Current();
@@ -845,7 +845,7 @@ void Template::Set(v8::Handle<String> name,
 
 
 void Template::SetAccessorProperty(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<FunctionTemplate> getter,
     v8::Local<FunctionTemplate> setter,
     v8::PropertyAttribute attribute,
@@ -1156,7 +1156,7 @@ void FunctionTemplate::SetCallHandler(FunctionCallback callback,
 
 static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
     i::Handle<i::AccessorInfo> obj,
-    v8::Handle<String> name,
+    v8::Handle<Name> name,
     v8::AccessControl settings,
     v8::PropertyAttribute attributes,
     v8::Handle<AccessorSignature> signature) {
@@ -1173,7 +1173,7 @@ static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
 
 template<typename Getter, typename Setter>
 static i::Handle<i::AccessorInfo> MakeAccessorInfo(
-    v8::Handle<String> name,
+    v8::Handle<Name> name,
     Getter getter,
     Setter setter,
     v8::Handle<Value> data,
@@ -1194,7 +1194,7 @@ static i::Handle<i::AccessorInfo> MakeAccessorInfo(
 
 
 static i::Handle<i::AccessorInfo> MakeAccessorInfo(
-    v8::Handle<String> name,
+    v8::Handle<Name> name,
     v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
     void* setter_ignored,
     void* data_ignored,
@@ -1345,10 +1345,10 @@ static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
 }
 
 
-template<typename Setter, typename Getter, typename Data, typename Template>
+template<typename Getter, typename Setter, typename Data, typename Template>
 static bool TemplateSetAccessor(
     Template* template_obj,
-    v8::Local<String> name,
+    v8::Local<Name> name,
     Getter getter,
     Setter setter,
     Data data,
@@ -1368,7 +1368,7 @@ static bool TemplateSetAccessor(
 
 
 bool Template::SetDeclaredAccessor(
-    Local<String> name,
+    Local<Name> name,
     Local<DeclaredAccessorDescriptor> descriptor,
     PropertyAttribute attribute,
     Local<AccessorSignature> signature,
@@ -1391,6 +1391,18 @@ void Template::SetNativeDataProperty(v8::Local<String> name,
 }
 
 
+void Template::SetNativeDataProperty(v8::Local<Name> name,
+                                     AccessorNameGetterCallback getter,
+                                     AccessorNameSetterCallback setter,
+                                     v8::Handle<Value> data,
+                                     PropertyAttribute attribute,
+                                     v8::Local<AccessorSignature> signature,
+                                     AccessControl settings) {
+  TemplateSetAccessor(
+      this, name, getter, setter, data, settings, attribute, signature);
+}
+
+
 void ObjectTemplate::SetAccessor(v8::Handle<String> name,
                                  AccessorGetterCallback getter,
                                  AccessorSetterCallback setter,
@@ -1403,6 +1415,18 @@ void ObjectTemplate::SetAccessor(v8::Handle<String> name,
 }
 
 
+void ObjectTemplate::SetAccessor(v8::Handle<Name> name,
+                                 AccessorNameGetterCallback getter,
+                                 AccessorNameSetterCallback setter,
+                                 v8::Handle<Value> data,
+                                 AccessControl settings,
+                                 PropertyAttribute attribute,
+                                 v8::Handle<AccessorSignature> signature) {
+  TemplateSetAccessor(
+      this, name, getter, setter, data, settings, attribute, signature);
+}
+
+
 void ObjectTemplate::SetNamedPropertyHandler(
     NamedPropertyGetterCallback getter,
     NamedPropertySetterCallback setter,
@@ -2324,6 +2348,11 @@ bool Value::IsFunction() const {
 }
 
 
+bool Value::IsName() const {
+  return Utils::OpenHandle(this)->IsName();
+}
+
+
 bool Value::FullIsString() const {
   bool result = Utils::OpenHandle(this)->IsString();
   DCHECK_EQ(result, QuickIsString());
@@ -2640,6 +2669,14 @@ void v8::Function::CheckCast(Value* that) {
 }
 
 
+void v8::Name::CheckCast(v8::Value* that) {
+  i::Handle<i::Object> obj = Utils::OpenHandle(that);
+  Utils::ApiCheck(obj->IsName(),
+                  "v8::Name::Cast()",
+                  "Could not convert to name");
+}
+
+
 void v8::String::CheckCast(v8::Value* that) {
   i::Handle<i::Object> obj = Utils::OpenHandle(that);
   Utils::ApiCheck(obj->IsString(),
@@ -3423,11 +3460,11 @@ bool v8::Object::Has(uint32_t index) {
 }
 
 
-template<typename Setter, typename Getter, typename Data>
+template<typename Getter, typename Setter, typename Data>
 static inline bool ObjectSetAccessor(Object* obj,
-                                     Handle<String> name,
-                                     Setter getter,
-                                     Getter setter,
+                                     Handle<Name> name,
+                                     Getter getter,
+                                     Setter setter,
                                      Data data,
                                      AccessControl settings,
                                      PropertyAttribute attributes) {
@@ -3462,7 +3499,18 @@ bool Object::SetAccessor(Handle<String> name,
 }
 
 
-bool Object::SetDeclaredAccessor(Local<String> name,
+bool Object::SetAccessor(Handle<Name> name,
+                         AccessorNameGetterCallback getter,
+                         AccessorNameSetterCallback setter,
+                         v8::Handle<Value> data,
+                         AccessControl settings,
+                         PropertyAttribute attributes) {
+  return ObjectSetAccessor(
+      this, name, getter, setter, data, settings, attributes);
+}
+
+
+bool Object::SetDeclaredAccessor(Local<Name> name,
                                  Local<DeclaredAccessorDescriptor> descriptor,
                                  PropertyAttribute attributes,
                                  AccessControl settings) {
@@ -3472,7 +3520,7 @@ bool Object::SetDeclaredAccessor(Local<String> name,
 }
 
 
-void Object::SetAccessorProperty(Local<String> name,
+void Object::SetAccessorProperty(Local<Name> name,
                                  Local<Function> getter,
                                  Handle<Function> setter,
                                  PropertyAttribute attribute,
@@ -7637,9 +7685,9 @@ void DeferredHandles::Iterate(ObjectVisitor* v) {
 
 
 void InvokeAccessorGetterCallback(
-    v8::Local<v8::String> property,
+    v8::Local<v8::Name> property,
     const v8::PropertyCallbackInfo<v8::Value>& info,
-    v8::AccessorGetterCallback getter) {
+    v8::AccessorNameGetterCallback getter) {
   // Leaving JavaScript.
   Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
   Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
index c87bd712efe2cf8ebd6847c21c42507f6242d99f..9aed5dd4e971e859790fcb02e9d1117baa5bda17 100644 (file)
--- a/src/api.h
+++ b/src/api.h
@@ -158,6 +158,7 @@ class RegisteredExtension {
   V(Float32Array, JSTypedArray)                \
   V(Float64Array, JSTypedArray)                \
   V(DataView, JSDataView)                      \
+  V(Name, Name)                                \
   V(String, String)                            \
   V(Symbol, Symbol)                            \
   V(Script, JSFunction)                        \
@@ -189,6 +190,8 @@ class Utils {
       v8::internal::Handle<v8::internal::Object> obj);
   static inline Local<Function> ToLocal(
       v8::internal::Handle<v8::internal::JSFunction> obj);
+  static inline Local<Name> ToLocal(
+      v8::internal::Handle<v8::internal::Name> obj);
   static inline Local<String> ToLocal(
       v8::internal::Handle<v8::internal::String> obj);
   static inline Local<Symbol> ToLocal(
@@ -333,6 +336,7 @@ inline v8::Local<T> ToApiHandle(
 MAKE_TO_LOCAL(ToLocal, Context, Context)
 MAKE_TO_LOCAL(ToLocal, Object, Value)
 MAKE_TO_LOCAL(ToLocal, JSFunction, Function)
+MAKE_TO_LOCAL(ToLocal, Name, Name)
 MAKE_TO_LOCAL(ToLocal, String, String)
 MAKE_TO_LOCAL(ToLocal, Symbol, Symbol)
 MAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp)
@@ -671,9 +675,9 @@ void HandleScopeImplementer::DeleteExtensions(internal::Object** prev_limit) {
 // Interceptor functions called from generated inline caches to notify
 // CPU profiler that external callbacks are invoked.
 void InvokeAccessorGetterCallback(
-    v8::Local<v8::String> property,
+    v8::Local<v8::Name> property,
     const v8::PropertyCallbackInfo<v8::Value>& info,
-    v8::AccessorGetterCallback getter);
+    v8::AccessorNameGetterCallback getter);
 
 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
                             v8::FunctionCallback callback);
index bbd2262fd7854fee0dd1e0fac07606c029026317..9fb2da3bc5ccaa950427295aca54c6e6515e949f 100644 (file)
@@ -68,13 +68,13 @@ class Arguments BASE_EMBEDDED {
 // They are used to generate the Call() functions below
 // These aren't included in the list as they have duplicate signatures
 // F(NamedPropertyEnumeratorCallback, ...)
-// F(NamedPropertyGetterCallback, ...)
 
 #define FOR_EACH_CALLBACK_TABLE_MAPPING_0(F) \
   F(IndexedPropertyEnumeratorCallback, v8::Array) \
 
 #define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F) \
-  F(AccessorGetterCallback, v8::Value, v8::Local<v8::String>) \
+  F(NamedPropertyGetterCallback, v8::Value, v8::Local<v8::String>) \
+  F(AccessorNameGetterCallback, v8::Value, v8::Local<v8::Name>) \
   F(NamedPropertyQueryCallback, \
     v8::Integer, \
     v8::Local<v8::String>) \
@@ -102,9 +102,9 @@ class Arguments BASE_EMBEDDED {
     v8::Local<v8::Value>) \
 
 #define FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(F) \
-  F(AccessorSetterCallback, \
+  F(AccessorNameSetterCallback, \
     void, \
-    v8::Local<v8::String>, \
+    v8::Local<v8::Name>, \
     v8::Local<v8::Value>) \
 
 
index cde93db98e0f4ff66cd3cd90020533180857a5e5..9d4f7812552f6bf7e2bb7d274a60ca53f98423af 100644 (file)
@@ -704,7 +704,7 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
 
     case ExternalReference::PROFILING_GETTER_CALL: {
       // void f(Local<String> property, PropertyCallbackInfo& info,
-      //        AccessorGetterCallback callback)
+      //        AccessorNameGetterCallback callback)
       TraceSim("Type: PROFILING_GETTER_CALL\n");
       SimulatorRuntimeProfilingGetterCall target =
         reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(
index a128c09d095f5446652fc42379372620ee9052c1..a293c398a3bcd5a5012ad2775ae65a8a7f1ab944 100644 (file)
@@ -774,12 +774,12 @@ class ExternalReference BASE_EMBEDDED {
     PROFILING_API_CALL,
 
     // Direct call to accessor getter callback.
-    // void f(Local<String> property, PropertyCallbackInfo& info)
+    // void f(Local<Name> property, PropertyCallbackInfo& info)
     DIRECT_GETTER_CALL,
 
     // Call to accessor getter callback via InvokeAccessorGetterCallback.
-    // void f(Local<String> property, PropertyCallbackInfo& info,
-    //     AccessorGetterCallback callback)
+    // void f(Local<Name> property, PropertyCallbackInfo& info,
+    //     AccessorNameGetterCallback callback)
     PROFILING_GETTER_CALL
   };
 
index e4961632051cd0a7a70b10272a4dd429a3500126..a784b1d2364bec557341d3cf49df4a51a6ff2623 100644 (file)
@@ -428,9 +428,6 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver,
                                                         ARRAY_SIZE(args)));
       return isolate->Throw<Object>(error);
     }
-    // TODO(rossberg): Handling symbols in the API requires changing the API,
-    // so we do not support it for now.
-    if (name->IsSymbol()) return isolate->factory()->undefined_value();
     if (structure->IsDeclaredAccessorInfo()) {
       return GetDeclaredAccessorProperty(
           receiver,
@@ -440,15 +437,14 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver,
 
     Handle<ExecutableAccessorInfo> data =
         Handle<ExecutableAccessorInfo>::cast(structure);
-    v8::AccessorGetterCallback call_fun =
-        v8::ToCData<v8::AccessorGetterCallback>(data->getter());
+    v8::AccessorNameGetterCallback call_fun =
+        v8::ToCData<v8::AccessorNameGetterCallback>(data->getter());
     if (call_fun == NULL) return isolate->factory()->undefined_value();
 
-    Handle<String> key = Handle<String>::cast(name);
     LOG(isolate, ApiNamedPropertyAccess("load", *holder, *name));
     PropertyCallbackArguments args(isolate, data->data(), *receiver, *holder);
     v8::Handle<v8::Value> result =
-        args.Call(call_fun, v8::Utils::ToLocal(key));
+        args.Call(call_fun, v8::Utils::ToLocal(name));
     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
     if (result.IsEmpty()) {
       return isolate->factory()->undefined_value();
@@ -504,17 +500,14 @@ MaybeHandle<Object> Object::SetPropertyWithAccessor(
                                                         ARRAY_SIZE(args)));
       return isolate->Throw<Object>(error);
     }
-    // TODO(rossberg): Support symbols in the API.
-    if (name->IsSymbol()) return value;
     Object* call_obj = info->setter();
-    v8::AccessorSetterCallback call_fun =
-        v8::ToCData<v8::AccessorSetterCallback>(call_obj);
+    v8::AccessorNameSetterCallback call_fun =
+        v8::ToCData<v8::AccessorNameSetterCallback>(call_obj);
     if (call_fun == NULL) return value;
-    Handle<String> key = Handle<String>::cast(name);
     LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name));
     PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder);
     args.Call(call_fun,
-              v8::Utils::ToLocal(key),
+              v8::Utils::ToLocal(name),
               v8::Utils::ToLocal(value));
     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
     return value;
@@ -11959,8 +11952,8 @@ MaybeHandle<Object> JSObject::GetElementWithCallback(
     Handle<ExecutableAccessorInfo> data =
         Handle<ExecutableAccessorInfo>::cast(structure);
     Object* fun_obj = data->getter();
-    v8::AccessorGetterCallback call_fun =
-        v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
+    v8::AccessorNameGetterCallback call_fun =
+        v8::ToCData<v8::AccessorNameGetterCallback>(fun_obj);
     if (call_fun == NULL) return isolate->factory()->undefined_value();
     Handle<JSObject> holder_handle = Handle<JSObject>::cast(holder);
     Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
@@ -12017,8 +12010,8 @@ MaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
     Handle<ExecutableAccessorInfo> data =
         Handle<ExecutableAccessorInfo>::cast(structure);
     Object* call_obj = data->setter();
-    v8::AccessorSetterCallback call_fun =
-        v8::ToCData<v8::AccessorSetterCallback>(call_obj);
+    v8::AccessorNameSetterCallback call_fun =
+        v8::ToCData<v8::AccessorNameSetterCallback>(call_obj);
     if (call_fun == NULL) return value;
     Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
     Handle<String> key(isolate->factory()->NumberToString(number));
index e89a6b60451aff0305fea1a2e236ba8848dc0cdf..4a7a7a69a0802f1c105818029846144fec3d1e11 100644 (file)
@@ -503,18 +503,14 @@ RUNTIME_FUNCTION(StoreCallbackProperty) {
   DCHECK(callback->IsCompatibleReceiver(*receiver));
 
   Address setter_address = v8::ToCData<Address>(callback->setter());
-  v8::AccessorSetterCallback fun =
-      FUNCTION_CAST<v8::AccessorSetterCallback>(setter_address);
+  v8::AccessorNameSetterCallback fun =
+      FUNCTION_CAST<v8::AccessorNameSetterCallback>(setter_address);
   DCHECK(fun != NULL);
 
-  // TODO(rossberg): Support symbols in the API.
-  if (name->IsSymbol()) return *value;
-  Handle<String> str = Handle<String>::cast(name);
-
   LOG(isolate, ApiNamedPropertyAccess("store", *receiver, *name));
   PropertyCallbackArguments custom_args(isolate, callback->data(), *receiver,
                                         *holder);
-  custom_args.Call(fun, v8::Utils::ToLocal(str), v8::Utils::ToLocal(value));
+  custom_args.Call(fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   return *value;
 }
index 314c3c14790f6d3e532bc8c7a22bebf044678f09..da273802947a892e727e372a8b5e9ec43d439fe4 100644 (file)
@@ -106,7 +106,7 @@ TEST(StressHandles) {
 
 
 void TestGetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
@@ -115,7 +115,7 @@ void TestGetter(
 
 
 void TestSetter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<void>& info) {
   UNREACHABLE();
index 50ce753db869947089012d42c9710ace2ac70818..a89c996f29379f02893e07f668f3d094b8fb861a 100644 (file)
@@ -63,6 +63,7 @@ using ::v8::FunctionTemplate;
 using ::v8::Handle;
 using ::v8::HandleScope;
 using ::v8::Local;
+using ::v8::Name;
 using ::v8::Message;
 using ::v8::MessageCallback;
 using ::v8::Object;
@@ -71,6 +72,7 @@ using ::v8::Persistent;
 using ::v8::Script;
 using ::v8::StackTrace;
 using ::v8::String;
+using ::v8::Symbol;
 using ::v8::TryCatch;
 using ::v8::Undefined;
 using ::v8::UniqueId;
@@ -1891,6 +1893,24 @@ void SimpleAccessorSetter(Local<String> name, Local<Value> value,
   self->Set(String::Concat(v8_str("accessor_"), name), value);
 }
 
+void SymbolAccessorGetter(Local<Name> name,
+                          const v8::PropertyCallbackInfo<v8::Value>& info) {
+  CHECK(name->IsSymbol());
+  Local<Symbol> sym = Local<Symbol>::Cast(name);
+  if (sym->Name()->IsUndefined())
+    return;
+  SimpleAccessorGetter(Local<String>::Cast(sym->Name()), info);
+}
+
+void SymbolAccessorSetter(Local<Name> name, Local<Value> value,
+                          const v8::PropertyCallbackInfo<void>& info) {
+  CHECK(name->IsSymbol());
+  Local<Symbol> sym = Local<Symbol>::Cast(name);
+  if (sym->Name()->IsUndefined())
+    return;
+  SimpleAccessorSetter(Local<String>::Cast(sym->Name()), value, info);
+}
+
 void EmptyInterceptorGetter(Local<String> name,
                             const v8::PropertyCallbackInfo<v8::Value>& info) {
 }
@@ -1949,6 +1969,14 @@ void AddInterceptor(Handle<FunctionTemplate> templ,
 }
 
 
+void AddAccessor(Handle<FunctionTemplate> templ,
+                 Handle<Name> name,
+                 v8::AccessorNameGetterCallback getter,
+                 v8::AccessorNameSetterCallback setter) {
+  templ->PrototypeTemplate()->SetAccessor(name, getter, setter);
+}
+
+
 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) {
   v8::HandleScope scope(CcTest::isolate());
   Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate());
@@ -2759,6 +2787,8 @@ THREADED_TEST(SymbolProperties) {
   v8::Local<v8::Symbol> sym1 = v8::Symbol::New(isolate);
   v8::Local<v8::Symbol> sym2 =
       v8::Symbol::New(isolate, v8_str("my-symbol"));
+  v8::Local<v8::Symbol> sym3 =
+      v8::Symbol::New(isolate, v8_str("sym3"));
 
   CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
 
@@ -2814,27 +2844,44 @@ THREADED_TEST(SymbolProperties) {
 
   CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
 
+  CHECK(obj->SetAccessor(sym3, SymbolAccessorGetter, SymbolAccessorSetter));
+  CHECK(obj->Get(sym3)->IsUndefined());
+  CHECK(obj->Set(sym3, v8::Integer::New(isolate, 42)));
+  CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42)));
+  CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals(
+      v8::Integer::New(isolate, 42)));
+
   // Add another property and delete it afterwards to force the object in
   // slow case.
   CHECK(obj->Set(sym2, v8::Integer::New(isolate, 2008)));
   CHECK_EQ(2002, obj->Get(sym1)->Int32Value());
   CHECK_EQ(2008, obj->Get(sym2)->Int32Value());
   CHECK_EQ(2002, obj->Get(sym1)->Int32Value());
-  CHECK_EQ(1, obj->GetOwnPropertyNames()->Length());
+  CHECK_EQ(2, obj->GetOwnPropertyNames()->Length());
 
   CHECK(obj->Has(sym1));
   CHECK(obj->Has(sym2));
+  CHECK(obj->Has(sym3));
+  CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3")));
   CHECK(obj->Delete(sym2));
   CHECK(obj->Has(sym1));
   CHECK(!obj->Has(sym2));
+  CHECK(obj->Has(sym3));
+  CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3")));
   CHECK_EQ(2002, obj->Get(sym1)->Int32Value());
-  CHECK_EQ(1, obj->GetOwnPropertyNames()->Length());
+  CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42)));
+  CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals(
+      v8::Integer::New(isolate, 42)));
+  CHECK_EQ(2, obj->GetOwnPropertyNames()->Length());
 
   // Symbol properties are inherited.
   v8::Local<v8::Object> child = v8::Object::New(isolate);
   child->SetPrototype(obj);
   CHECK(child->Has(sym1));
   CHECK_EQ(2002, child->Get(sym1)->Int32Value());
+  CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42)));
+  CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals(
+      v8::Integer::New(isolate, 42)));
   CHECK_EQ(0, child->GetOwnPropertyNames()->Length());
 }