Add support for private names
authorbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 May 2012 00:37:09 +0000 (00:37 +0000)
committerbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 May 2012 00:37:09 +0000 (00:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=86509

Reviewed by Oliver Hunt.

The spec isn't final, but we can start adding support to allow property maps
to contain keys that aren't identifiers.

Source/JavaScriptCore:

* API/JSCallbackObjectFunctions.h:
(JSC::::getOwnPropertySlot):
(JSC::::put):
(JSC::::deleteProperty):
(JSC::::getStaticValue):
(JSC::::staticFunctionGetter):
(JSC::::callbackGetter):
    - Only expose public named properties over the JSC API.
* CMakeLists.txt:
* DerivedSources.make:
* DerivedSources.pri:
* GNUmakefile.list.am:
* JavaScriptCore.gypi:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
    - Added new files to build system.
* dfg/DFGOperations.cpp:
(JSC::DFG::operationPutByValInternal):
    - Added support for property access with name objects.
* interpreter/CallFrame.h:
(JSC::ExecState::privateNamePrototypeTable):
    - Added hash table for NamePrototype
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
    - Added support for property access with name objects.
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
    - Added support for property access with name objects.
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::getByVal):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
(JSC::CommonSlowPaths::opIn):
* runtime/JSActivation.cpp:
(JSC::JSActivation::symbolTableGet):
(JSC::JSActivation::symbolTablePut):
(JSC::JSActivation::symbolTablePutWithAttributes):
    - Added support for property access with name objects.
* runtime/JSGlobalData.cpp:
(JSC):
(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::~JSGlobalData):
* runtime/JSGlobalData.h:
(JSGlobalData):
    - Added hash table for NamePrototype
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::reset):
* runtime/JSGlobalObject.h:
(JSGlobalObject):
(JSC::JSGlobalObject::privateNameStructure):
(JSC::JSGlobalObject::symbolTableHasProperty):
    - Added new global properties.
* runtime/JSType.h:
* runtime/JSTypeInfo.h:
(JSC::TypeInfo::isName):
    - Added type for NameInstances, for fast isName check.
* runtime/JSVariableObject.cpp:
(JSC::JSVariableObject::deleteProperty):
(JSC::JSVariableObject::symbolTableGet):
* runtime/JSVariableObject.h:
(JSC::JSVariableObject::symbolTableGet):
(JSC::JSVariableObject::symbolTablePut):
(JSC::JSVariableObject::symbolTablePutWithAttributes):
    - symbol table lookup should take a PropertyName.
* runtime/Lookup.cpp:
(JSC::setUpStaticFunctionSlot):
* runtime/Lookup.h:
(JSC::HashTable::entry):
    - entry lookup should take a PropertyName.
* runtime/NameConstructor.cpp: Added.
(JSC):
(JSC::NameConstructor::NameConstructor):
(JSC::NameConstructor::finishCreation):
(JSC::constructPrivateName):
(JSC::NameConstructor::getConstructData):
(JSC::NameConstructor::getCallData):
* runtime/NameConstructor.h: Added.
(JSC):
(NameConstructor):
(JSC::NameConstructor::create):
(JSC::NameConstructor::createStructure):
    - Added constructor.
* runtime/NameInstance.cpp: Added.
(JSC):
(JSC::NameInstance::NameInstance):
(JSC::NameInstance::destroy):
* runtime/NameInstance.h: Added.
(JSC):
(NameInstance):
(JSC::NameInstance::createStructure):
(JSC::NameInstance::create):
(JSC::NameInstance::privateName):
(JSC::NameInstance::nameString):
(JSC::NameInstance::finishCreation):
(JSC::isName):
    - Added instance.
* runtime/NamePrototype.cpp: Added.
(JSC):
(JSC::NamePrototype::NamePrototype):
(JSC::NamePrototype::finishCreation):
(JSC::NamePrototype::getOwnPropertySlot):
(JSC::NamePrototype::getOwnPropertyDescriptor):
(JSC::privateNameProtoFuncToString):
* runtime/NamePrototype.h: Added.
(JSC):
(NamePrototype):
(JSC::NamePrototype::create):
(JSC::NamePrototype::createStructure):
    - Added prototype.
* runtime/PrivateName.h: Added.
(JSC):
(PrivateName):
(JSC::PrivateName::PrivateName):
(JSC::PrivateName::uid):
    - A private name object holds a StringImpl that can be used as a unique key in a property map.
* runtime/PropertyMapHashTable.h:
(JSC::PropertyTable::find):
(JSC::PropertyTable::findWithString):
    - Strings should only match keys in the table that are identifiers.
* runtime/PropertyName.h:
(JSC::PropertyName::PropertyName):
(PropertyName):
(JSC::PropertyName::uid):
(JSC::PropertyName::publicName):
(JSC::PropertyName::asIndex):
(JSC::operator==):
(JSC::operator!=):
    - replaced impl() & ustring() with uid() [to get the raw impl] and publicName() [impl or null, if not an identifier].
* runtime/Structure.cpp:
(JSC::Structure::despecifyDictionaryFunction):
(JSC::Structure::addPropertyTransitionToExistingStructure):
(JSC::Structure::addPropertyTransition):
(JSC::Structure::attributeChangeTransition):
(JSC::Structure::get):
(JSC::Structure::despecifyFunction):
(JSC::Structure::putSpecificValue):
(JSC::Structure::remove):
(JSC::Structure::getPropertyNamesFromStructure):
* runtime/Structure.h:
(JSC::Structure::get):
    - call uid() to get a PropertyName raw impl, for use as a key.

Source/WebCore:

Test: fast/js/names.html

* bindings/js/JSCSSStyleDeclarationCustom.cpp:
(WebCore::cssPropertyIDForJSCSSPropertyName):
* bindings/js/JSDOMBinding.cpp:
(WebCore::findAtomicString):
(WebCore::objectToStringFunctionGetter):
* bindings/js/JSDOMBinding.h:
(WebCore::propertyNameToString):
(WebCore::propertyNameToAtomicString):
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::nonCachingStaticFunctionGetter):
* bindings/js/JSHistoryCustom.cpp:
(WebCore::nonCachingStaticBackFunctionGetter):
(WebCore::nonCachingStaticForwardFunctionGetter):
(WebCore::nonCachingStaticGoFunctionGetter):
* bindings/js/JSLocationCustom.cpp:
(WebCore::nonCachingStaticReplaceFunctionGetter):
(WebCore::nonCachingStaticReloadFunctionGetter):
(WebCore::nonCachingStaticAssignFunctionGetter):
* bridge/c/c_class.cpp:
(JSC::Bindings::CClass::methodsNamed):
(JSC::Bindings::CClass::fieldNamed):
* bridge/c/c_instance.cpp:
(JSC::Bindings::CInstance::getMethod):
* bridge/jni/jsc/JavaClassJSC.cpp:
(JavaClass::methodsNamed):
(JavaClass::fieldNamed):
* bridge/jni/jsc/JavaInstanceJSC.cpp:
* bridge/objc/objc_class.mm:
(JSC::Bindings::ObjcClass::methodsNamed):
(JSC::Bindings::ObjcClass::fieldNamed):
(JSC::Bindings::ObjcClass::fallbackObject):
* bridge/objc/objc_instance.mm:
(ObjcInstance::setValueOfUndefinedField):
(ObjcInstance::getValueOfUndefinedField):
    - Removed PropertyName::impl(), call publicName() to get the string associated with a name.

Source/WebKit/mac:

* Plugins/Hosted/ProxyInstance.mm:
(WebKit::ProxyClass::methodsNamed):
(WebKit::ProxyClass::fieldNamed):
(WebKit::ProxyInstance::getMethod):
(WebKit::ProxyInstance::methodsNamed):
(WebKit::ProxyInstance::fieldNamed):
    - Removed PropertyName::impl(), call publicName() to get the string associated with a name.

Source/WebKit2:

* WebProcess/Plugins/Netscape/JSNPObject.cpp:
(WebKit::npIdentifierFromIdentifier):
(WebKit::JSNPObject::methodGetter):
    - Removed PropertyName::impl(), call publicName() to get the string associated with a name.

Source/WTF:

* wtf/text/StringImpl.h:
(WTF::StringImpl::StringImpl):
(StringImpl):
(WTF::StringImpl::createEmptyUnique):
(WTF::StringImpl::isEmptyUnique):
    - Allow empty string impls to be allocated, which can be used as unique keys.

LayoutTests:

* fast/js/names-expected.txt: Added.
* fast/js/names.html: Added.
* fast/js/script-tests/names.js: Added.
    - Added test cases.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@117859 268f45cc-cd09-0410-ab3c-d52691b4dbfc

67 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/js/names-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/names.html [new file with mode: 0644]
LayoutTests/fast/js/script-tests/names.js [new file with mode: 0644]
LayoutTests/platform/chromium/test_expectations.txt
Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/DerivedSources.make
Source/JavaScriptCore/DerivedSources.pri
Source/JavaScriptCore/GNUmakefile.list.am
Source/JavaScriptCore/JavaScriptCore.gypi
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Target.pri
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/interpreter/CallFrame.h
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JITStubs.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.h
Source/JavaScriptCore/runtime/JSActivation.cpp
Source/JavaScriptCore/runtime/JSGlobalData.cpp
Source/JavaScriptCore/runtime/JSGlobalData.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSType.h
Source/JavaScriptCore/runtime/JSTypeInfo.h
Source/JavaScriptCore/runtime/JSVariableObject.cpp
Source/JavaScriptCore/runtime/JSVariableObject.h
Source/JavaScriptCore/runtime/Lookup.cpp
Source/JavaScriptCore/runtime/Lookup.h
Source/JavaScriptCore/runtime/NameConstructor.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/NameConstructor.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/NameInstance.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/NameInstance.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/NamePrototype.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/NamePrototype.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/PrivateName.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/PropertyMapHashTable.h
Source/JavaScriptCore/runtime/PropertyName.h
Source/JavaScriptCore/runtime/Structure.cpp
Source/JavaScriptCore/runtime/Structure.h
Source/WTF/ChangeLog
Source/WTF/wtf/text/StringImpl.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/bindings/js/JSDOMBinding.h
Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
Source/WebCore/bindings/js/JSHistoryCustom.cpp
Source/WebCore/bindings/js/JSLocationCustom.cpp
Source/WebCore/bridge/c/c_class.cpp
Source/WebCore/bridge/c/c_instance.cpp
Source/WebCore/bridge/jni/jsc/JavaClassJSC.cpp
Source/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp
Source/WebCore/bridge/objc/objc_class.mm
Source/WebCore/bridge/objc/objc_instance.mm
Source/WebCore/bridge/qt/qt_class.cpp
Source/WebCore/bridge/qt/qt_instance.cpp
Source/WebCore/bridge/qt/qt_pixmapruntime.cpp
Source/WebCore/bridge/qt/qt_runtime.cpp
Source/WebCore/bridge/qt/qt_runtime_qt4.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp

index f8195fc..dfd7432 100644 (file)
@@ -1,3 +1,18 @@
+2012-05-15  Gavin Barraclough  <barraclough@apple.com>
+
+        Add support for private names
+        https://bugs.webkit.org/show_bug.cgi?id=86509
+
+        Reviewed by Oliver Hunt.
+
+        The spec isn't final, but we can start adding support to allow property maps
+        to contain keys that aren't identifiers.
+
+        * fast/js/names-expected.txt: Added.
+        * fast/js/names.html: Added.
+        * fast/js/script-tests/names.js: Added.
+            - Added test cases.
+
 2012-05-21  Emil A Eklund  <eae@chromium.org>
 
         Fix bug in paintNinePieceImage exposed by subpixel change
diff --git a/LayoutTests/fast/js/names-expected.txt b/LayoutTests/fast/js/names-expected.txt
new file mode 100644 (file)
index 0000000..f12be86
--- /dev/null
@@ -0,0 +1,25 @@
+This tests an early experimental implementation of ES6-esque private names.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS prop in o is false
+PASS 'prop' in o is false
+PASS Object.getOwnPropertyNames(o).length is 0
+PASS forIn(o) is []
+PASS prop in o is true
+PASS 'prop' in o is false
+PASS Object.getOwnPropertyNames(o).length is 0
+PASS forIn(o) is []
+PASS o[prop] is 42
+PASS o['prop'] is 101
+PASS Object.getOwnPropertyNames(o).length is 1
+PASS forIn(o) is ["prop"]
+PASS prop in o is false
+PASS 'prop' in o is true
+PASS Object.getOwnPropertyNames(o).length is 1
+PASS forIn(o) is ["prop"]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/names.html b/LayoutTests/fast/js/names.html
new file mode 100644 (file)
index 0000000..5cc79e7
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="script-tests/names.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/js/script-tests/names.js b/LayoutTests/fast/js/script-tests/names.js
new file mode 100644 (file)
index 0000000..14dc141
--- /dev/null
@@ -0,0 +1,42 @@
+description(
+"This tests an early experimental implementation of ES6-esque private names."
+);
+
+function forIn(o)
+{
+    var a = [];
+    for (x in o)
+        a.push(x);
+    return a;
+}
+
+var prop = Name("prop");
+var o = {};
+
+shouldBeFalse("prop in o");
+shouldBeFalse("'prop' in o");
+shouldBe("Object.getOwnPropertyNames(o).length", '0');
+shouldBe("forIn(o)", '[]');
+
+o[prop] = 42;
+
+shouldBeTrue("prop in o");
+shouldBeFalse("'prop' in o");
+shouldBe("Object.getOwnPropertyNames(o).length", '0');
+shouldBe("forIn(o)", '[]');
+
+o['prop'] = 101;
+
+shouldBe("o[prop]", '42');
+shouldBe("o['prop']", '101');
+shouldBe("Object.getOwnPropertyNames(o).length", '1');
+shouldBe("forIn(o)", '["prop"]');
+
+delete o[prop];
+
+shouldBeFalse("prop in o");
+shouldBeTrue("'prop' in o");
+shouldBe("Object.getOwnPropertyNames(o).length", '1');
+shouldBe("forIn(o)", '["prop"]');
+
+successfullyParsed = true;
index 46f9053..e1d2e1c 100644 (file)
@@ -1436,6 +1436,9 @@ BUGWK80335 : fast/js/mozilla/strict/15.4.4.13.html = TEXT
 // V8 should implement the length property of constructors
 BUGWK78657 : fast/js/constructor-length.html = FAIL
 
+// This is JSC-only, preliminary implementation of a ES6 feature - doesn't exist in V8 (yet)
+BUGWK86509 SKIP WONTFIX : fast/js/names.html = FAIL
+
 // Linux pixeltest failure: The text suggests that the radios should not
 // overlap, but it's very close and quite different from the Windows version
 BUGCR10350 LINUX : fast/replaced/width100percent-radio.html = FAIL
index fdc58fc..160f488 100644 (file)
@@ -129,54 +129,56 @@ bool JSCallbackObject<Parent>::getOwnPropertySlot(JSCell* cell, ExecState* exec,
     JSObjectRef thisRef = toRef(thisObject);
     RefPtr<OpaqueJSString> propertyNameRef;
     
-    for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
-        // optional optimization to bypass getProperty in cases when we only need to know if the property exists
-        if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
-            if (!propertyNameRef)
-                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-            APICallbackShim callbackShim(exec);
-            if (hasProperty(ctx, thisRef, propertyNameRef.get())) {
-                slot.setCustom(thisObject, callbackGetter);
-                return true;
-            }
-        } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
-            if (!propertyNameRef)
-                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-            JSValueRef exception = 0;
-            JSValueRef value;
-            {
+    if (StringImpl* name = propertyName.publicName()) {
+        for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
+            // optional optimization to bypass getProperty in cases when we only need to know if the property exists
+            if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
+                if (!propertyNameRef)
+                    propertyNameRef = OpaqueJSString::create(name);
                 APICallbackShim callbackShim(exec);
-                value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
-            }
-            if (exception) {
-                throwError(exec, toJS(exec, exception));
-                slot.setValue(jsUndefined());
-                return true;
-            }
-            if (value) {
-                slot.setValue(toJS(exec, value));
-                return true;
-            }
-        }
-        
-        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
-            if (staticValues->contains(propertyName.impl())) {
-                JSValue value = thisObject->getStaticValue(exec, propertyName);
+                if (hasProperty(ctx, thisRef, propertyNameRef.get())) {
+                    slot.setCustom(thisObject, callbackGetter);
+                    return true;
+                }
+            } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
+                if (!propertyNameRef)
+                    propertyNameRef = OpaqueJSString::create(name);
+                JSValueRef exception = 0;
+                JSValueRef value;
+                {
+                    APICallbackShim callbackShim(exec);
+                    value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
+                }
+                if (exception) {
+                    throwError(exec, toJS(exec, exception));
+                    slot.setValue(jsUndefined());
+                    return true;
+                }
                 if (value) {
-                    slot.setValue(value);
+                    slot.setValue(toJS(exec, value));
                     return true;
                 }
             }
-        }
-        
-        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
-            if (staticFunctions->contains(propertyName.impl())) {
-                slot.setCustom(thisObject, staticFunctionGetter);
-                return true;
+            
+            if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
+                if (staticValues->contains(name)) {
+                    JSValue value = thisObject->getStaticValue(exec, propertyName);
+                    if (value) {
+                        slot.setValue(value);
+                        return true;
+                    }
+                }
+            }
+            
+            if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
+                if (staticFunctions->contains(name)) {
+                    slot.setCustom(thisObject, staticFunctionGetter);
+                    return true;
+                }
             }
         }
     }
-    
+
     return Parent::getOwnPropertySlot(thisObject, exec, propertyName, slot);
 }
 
@@ -233,53 +235,55 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
     RefPtr<OpaqueJSString> propertyNameRef;
     JSValueRef valueRef = toRef(exec, value);
     
-    for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
-        if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
-            if (!propertyNameRef)
-                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-            JSValueRef exception = 0;
-            bool result;
-            {
-                APICallbackShim callbackShim(exec);
-                result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
-            }
-            if (exception)
-                throwError(exec, toJS(exec, exception));
-            if (result || exception)
-                return;
-        }
-        
-        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
-            if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) {
-                if (entry->attributes & kJSPropertyAttributeReadOnly)
+    if (StringImpl* name = propertyName.publicName()) {
+        for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
+            if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
+                if (!propertyNameRef)
+                    propertyNameRef = OpaqueJSString::create(name);
+                JSValueRef exception = 0;
+                bool result;
+                {
+                    APICallbackShim callbackShim(exec);
+                    result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+                }
+                if (exception)
+                    throwError(exec, toJS(exec, exception));
+                if (result || exception)
                     return;
-                if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
-                    if (!propertyNameRef)
-                        propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-                    JSValueRef exception = 0;
-                    bool result;
-                    {
-                        APICallbackShim callbackShim(exec);
-                        result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
-                    }
-                    if (exception)
-                        throwError(exec, toJS(exec, exception));
-                    if (result || exception)
+            }
+            
+            if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
+                if (StaticValueEntry* entry = staticValues->get(name)) {
+                    if (entry->attributes & kJSPropertyAttributeReadOnly)
                         return;
+                    if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
+                        if (!propertyNameRef)
+                            propertyNameRef = OpaqueJSString::create(name);
+                        JSValueRef exception = 0;
+                        bool result;
+                        {
+                            APICallbackShim callbackShim(exec);
+                            result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+                        }
+                        if (exception)
+                            throwError(exec, toJS(exec, exception));
+                        if (result || exception)
+                            return;
+                    }
                 }
             }
-        }
-        
-        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
-            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
-                if (entry->attributes & kJSPropertyAttributeReadOnly)
+            
+            if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
+                if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
+                    if (entry->attributes & kJSPropertyAttributeReadOnly)
+                        return;
+                    thisObject->JSCallbackObject<Parent>::putDirect(exec->globalData(), propertyName, value); // put as override property
                     return;
-                thisObject->JSCallbackObject<Parent>::putDirect(exec->globalData(), propertyName, value); // put as override property
-                return;
+                }
             }
         }
     }
-    
+
     return Parent::put(thisObject, exec, propertyName, value, slot);
 }
 
@@ -291,39 +295,41 @@ bool JSCallbackObject<Parent>::deleteProperty(JSCell* cell, ExecState* exec, Pro
     JSObjectRef thisRef = toRef(thisObject);
     RefPtr<OpaqueJSString> propertyNameRef;
     
-    for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
-        if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
-            if (!propertyNameRef)
-                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-            JSValueRef exception = 0;
-            bool result;
-            {
-                APICallbackShim callbackShim(exec);
-                result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
+    if (StringImpl* name = propertyName.publicName()) {
+        for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
+            if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
+                if (!propertyNameRef)
+                    propertyNameRef = OpaqueJSString::create(name);
+                JSValueRef exception = 0;
+                bool result;
+                {
+                    APICallbackShim callbackShim(exec);
+                    result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
+                }
+                if (exception)
+                    throwError(exec, toJS(exec, exception));
+                if (result || exception)
+                    return true;
             }
-            if (exception)
-                throwError(exec, toJS(exec, exception));
-            if (result || exception)
-                return true;
-        }
-        
-        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
-            if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) {
-                if (entry->attributes & kJSPropertyAttributeDontDelete)
-                    return false;
-                return true;
+            
+            if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
+                if (StaticValueEntry* entry = staticValues->get(name)) {
+                    if (entry->attributes & kJSPropertyAttributeDontDelete)
+                        return false;
+                    return true;
+                }
             }
-        }
-        
-        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
-            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
-                if (entry->attributes & kJSPropertyAttributeDontDelete)
-                    return false;
-                return true;
+            
+            if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
+                if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
+                    if (entry->attributes & kJSPropertyAttributeDontDelete)
+                        return false;
+                    return true;
+                }
             }
         }
     }
-    
+
     return Parent::deleteProperty(thisObject, exec, propertyName);
 }
 
@@ -509,25 +515,30 @@ JSValue JSCallbackObject<Parent>::getStaticValue(ExecState* exec, PropertyName p
     JSObjectRef thisRef = toRef(this);
     RefPtr<OpaqueJSString> propertyNameRef;
     
-    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
-        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec))
-            if (StaticValueEntry* entry = staticValues->get(propertyName.impl()))
-                if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
-                    if (!propertyNameRef)
-                        propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-                    JSValueRef exception = 0;
-                    JSValueRef value;
-                    {
-                        APICallbackShim callbackShim(exec);
-                        value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
-                    }
-                    if (exception) {
-                        throwError(exec, toJS(exec, exception));
-                        return jsUndefined();
+    if (StringImpl* name = propertyName.publicName()) {
+        for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
+            if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
+                if (StaticValueEntry* entry = staticValues->get(name)) {
+                    if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
+                        if (!propertyNameRef)
+                            propertyNameRef = OpaqueJSString::create(name);
+                        JSValueRef exception = 0;
+                        JSValueRef value;
+                        {
+                            APICallbackShim callbackShim(exec);
+                            value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
+                        }
+                        if (exception) {
+                            throwError(exec, toJS(exec, exception));
+                            return jsUndefined();
+                        }
+                        if (value)
+                            return toJS(exec, value);
                     }
-                    if (value)
-                        return toJS(exec, value);
                 }
+            }
+        }
+    }
 
     return JSValue();
 }
@@ -542,19 +553,21 @@ JSValue JSCallbackObject<Parent>::staticFunctionGetter(ExecState* exec, JSValue
     if (Parent::getOwnPropertySlot(thisObj, exec, propertyName, slot2))
         return slot2.getValue(exec, propertyName);
     
-    for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
-        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
-            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
-                if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
-                    
-                    JSObject* o = JSCallbackFunction::create(exec, thisObj->globalObject(), callAsFunction, propertyName.ustring());
-                    thisObj->putDirect(exec->globalData(), propertyName, o, entry->attributes);
-                    return o;
+    if (StringImpl* name = propertyName.publicName()) {
+        for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
+            if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
+                if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
+                    if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
+                        
+                        JSObject* o = JSCallbackFunction::create(exec, thisObj->globalObject(), callAsFunction, name);
+                        thisObj->putDirect(exec->globalData(), propertyName, o, entry->attributes);
+                        return o;
+                    }
                 }
             }
         }
     }
-    
+
     return throwError(exec, createReferenceError(exec, "Static function property defined with NULL callAsFunction callback."));
 }
 
@@ -566,24 +579,27 @@ JSValue JSCallbackObject<Parent>::callbackGetter(ExecState* exec, JSValue slotPa
     JSObjectRef thisRef = toRef(thisObj);
     RefPtr<OpaqueJSString> propertyNameRef;
     
-    for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass)
-        if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
-            if (!propertyNameRef)
-                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-            JSValueRef exception = 0;
-            JSValueRef value;
-            {
-                APICallbackShim callbackShim(exec);
-                value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
-            }
-            if (exception) {
-                throwError(exec, toJS(exec, exception));
-                return jsUndefined();
+    if (StringImpl* name = propertyName.publicName()) {
+        for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
+            if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
+                if (!propertyNameRef)
+                    propertyNameRef = OpaqueJSString::create(name);
+                JSValueRef exception = 0;
+                JSValueRef value;
+                {
+                    APICallbackShim callbackShim(exec);
+                    value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
+                }
+                if (exception) {
+                    throwError(exec, toJS(exec, exception));
+                    return jsUndefined();
+                }
+                if (value)
+                    return toJS(exec, value);
             }
-            if (value)
-                return toJS(exec, value);
         }
-            
+    }
+
     return throwError(exec, createReferenceError(exec, "hasProperty callback returned true for a property that doesn't exist."));
 }
 
index 69edcca..b9e19a8 100644 (file)
@@ -192,6 +192,12 @@ SET(JavaScriptCore_SOURCES
     runtime/LiteralParser.cpp
     runtime/Lookup.cpp
     runtime/MathObject.cpp
+    runtime/NameConstructor.cpp
+    runtime/NameConstructor.h
+    runtime/NameInstance.cpp
+    runtime/NameInstance.h
+    runtime/NamePrototype.cpp
+    runtime/NamePrototype.h
     runtime/NativeErrorConstructor.cpp
     runtime/NativeErrorPrototype.cpp
     runtime/NumberConstructor.cpp
@@ -243,6 +249,7 @@ SET(JavaScriptCore_LUT_FILES
     runtime/JSGlobalObject.cpp
     runtime/JSONObject.cpp
     runtime/MathObject.cpp
+    runtime/NamePrototype.cpp
     runtime/NumberConstructor.cpp
     runtime/NumberPrototype.cpp
     runtime/ObjectConstructor.cpp
index 23e6be9..08aa5a5 100644 (file)
@@ -1,3 +1,156 @@
+2012-05-15  Gavin Barraclough  <barraclough@apple.com>
+
+        Add support for private names
+        https://bugs.webkit.org/show_bug.cgi?id=86509
+
+        Reviewed by Oliver Hunt.
+
+        The spec isn't final, but we can start adding support to allow property maps
+        to contain keys that aren't identifiers.
+
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::::getOwnPropertySlot):
+        (JSC::::put):
+        (JSC::::deleteProperty):
+        (JSC::::getStaticValue):
+        (JSC::::staticFunctionGetter):
+        (JSC::::callbackGetter):
+            - Only expose public named properties over the JSC API.
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * DerivedSources.pri:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Target.pri:
+            - Added new files to build system.
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::operationPutByValInternal):
+            - Added support for property access with name objects.
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::privateNamePrototypeTable):
+            - Added hash table for NamePrototype
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::privateExecute):
+            - Added support for property access with name objects.
+        * jit/JITStubs.cpp:
+        (JSC::DEFINE_STUB_FUNCTION):
+            - Added support for property access with name objects.
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::getByVal):
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        (JSC::CommonSlowPaths::opIn):
+        * runtime/JSActivation.cpp:
+        (JSC::JSActivation::symbolTableGet):
+        (JSC::JSActivation::symbolTablePut):
+        (JSC::JSActivation::symbolTablePutWithAttributes):
+            - Added support for property access with name objects.
+        * runtime/JSGlobalData.cpp:
+        (JSC):
+        (JSC::JSGlobalData::JSGlobalData):
+        (JSC::JSGlobalData::~JSGlobalData):
+        * runtime/JSGlobalData.h:
+        (JSGlobalData):
+            - Added hash table for NamePrototype
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        * runtime/JSGlobalObject.h:
+        (JSGlobalObject):
+        (JSC::JSGlobalObject::privateNameStructure):
+        (JSC::JSGlobalObject::symbolTableHasProperty):
+            - Added new global properties.
+        * runtime/JSType.h:
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::isName):
+            - Added type for NameInstances, for fast isName check.
+        * runtime/JSVariableObject.cpp:
+        (JSC::JSVariableObject::deleteProperty):
+        (JSC::JSVariableObject::symbolTableGet):
+        * runtime/JSVariableObject.h:
+        (JSC::JSVariableObject::symbolTableGet):
+        (JSC::JSVariableObject::symbolTablePut):
+        (JSC::JSVariableObject::symbolTablePutWithAttributes):
+            - symbol table lookup should take a PropertyName.
+        * runtime/Lookup.cpp:
+        (JSC::setUpStaticFunctionSlot):
+        * runtime/Lookup.h:
+        (JSC::HashTable::entry):
+            - entry lookup should take a PropertyName.
+        * runtime/NameConstructor.cpp: Added.
+        (JSC):
+        (JSC::NameConstructor::NameConstructor):
+        (JSC::NameConstructor::finishCreation):
+        (JSC::constructPrivateName):
+        (JSC::NameConstructor::getConstructData):
+        (JSC::NameConstructor::getCallData):
+        * runtime/NameConstructor.h: Added.
+        (JSC):
+        (NameConstructor):
+        (JSC::NameConstructor::create):
+        (JSC::NameConstructor::createStructure):
+            - Added constructor.
+        * runtime/NameInstance.cpp: Added.
+        (JSC):
+        (JSC::NameInstance::NameInstance):
+        (JSC::NameInstance::destroy):
+        * runtime/NameInstance.h: Added.
+        (JSC):
+        (NameInstance):
+        (JSC::NameInstance::createStructure):
+        (JSC::NameInstance::create):
+        (JSC::NameInstance::privateName):
+        (JSC::NameInstance::nameString):
+        (JSC::NameInstance::finishCreation):
+        (JSC::isName):
+            - Added instance.
+        * runtime/NamePrototype.cpp: Added.
+        (JSC):
+        (JSC::NamePrototype::NamePrototype):
+        (JSC::NamePrototype::finishCreation):
+        (JSC::NamePrototype::getOwnPropertySlot):
+        (JSC::NamePrototype::getOwnPropertyDescriptor):
+        (JSC::privateNameProtoFuncToString):
+        * runtime/NamePrototype.h: Added.
+        (JSC):
+        (NamePrototype):
+        (JSC::NamePrototype::create):
+        (JSC::NamePrototype::createStructure):
+            - Added prototype.
+        * runtime/PrivateName.h: Added.
+        (JSC):
+        (PrivateName):
+        (JSC::PrivateName::PrivateName):
+        (JSC::PrivateName::uid):
+            - A private name object holds a StringImpl that can be used as a unique key in a property map.
+        * runtime/PropertyMapHashTable.h:
+        (JSC::PropertyTable::find):
+        (JSC::PropertyTable::findWithString):
+            - Strings should only match keys in the table that are identifiers.
+        * runtime/PropertyName.h:
+        (JSC::PropertyName::PropertyName):
+        (PropertyName):
+        (JSC::PropertyName::uid):
+        (JSC::PropertyName::publicName):
+        (JSC::PropertyName::asIndex):
+        (JSC::operator==):
+        (JSC::operator!=):
+            - replaced impl() & ustring() with uid() [to get the raw impl] and publicName() [impl or null, if not an identifier].
+        * runtime/Structure.cpp:
+        (JSC::Structure::despecifyDictionaryFunction):
+        (JSC::Structure::addPropertyTransitionToExistingStructure):
+        (JSC::Structure::addPropertyTransition):
+        (JSC::Structure::attributeChangeTransition):
+        (JSC::Structure::get):
+        (JSC::Structure::despecifyFunction):
+        (JSC::Structure::putSpecificValue):
+        (JSC::Structure::remove):
+        (JSC::Structure::getPropertyNamesFromStructure):
+        * runtime/Structure.h:
+        (JSC::Structure::get):
+            - call uid() to get a PropertyName raw impl, for use as a key.
+
 2012-04-30  Filip Pizlo  <fpizlo@apple.com>
 
         Bytecode dumps should contain data about the state of get_by_id caches
index 90e099d..fb60d30 100644 (file)
@@ -47,6 +47,7 @@ all : \
     KeywordLookup.h \
     Lexer.lut.h \
     MathObject.lut.h \
+    NamePrototype.lut.h \
     NumberConstructor.lut.h \
     NumberPrototype.lut.h \
     ObjectConstructor.lut.h \
index 755a5b0..8d0f053 100644 (file)
@@ -16,6 +16,7 @@ LUT_FILES += \
     runtime/JSGlobalObject.cpp \
     runtime/JSONObject.cpp \
     runtime/MathObject.cpp \
+    runtime/NamePrototype.cpp \
     runtime/NumberConstructor.cpp \
     runtime/NumberPrototype.cpp \
     runtime/ObjectConstructor.cpp \
index 44080de..6cd3a65 100644 (file)
@@ -20,6 +20,7 @@ javascriptcore_built_nosources += \
        DerivedSources/JavaScriptCore/JSGlobalObject.lut.h \
        DerivedSources/JavaScriptCore/JSONObject.lut.h \
        DerivedSources/JavaScriptCore/MathObject.lut.h \
+    DerivedSources/JavaScriptCore/NamePrototype.lut.h \
        DerivedSources/JavaScriptCore/NumberConstructor.lut.h \
        DerivedSources/JavaScriptCore/NumberPrototype.lut.h \
        DerivedSources/JavaScriptCore/ObjectConstructor.lut.h \
@@ -507,6 +508,12 @@ javascriptcore_sources += \
        Source/JavaScriptCore/runtime/MathObject.cpp \
        Source/JavaScriptCore/runtime/MathObject.h \
        Source/JavaScriptCore/runtime/MemoryStatistics.h \
+       Source/JavaScriptCore/runtime/NameConstructor.cpp \
+       Source/JavaScriptCore/runtime/NameConstructor.h \
+       Source/JavaScriptCore/runtime/NameInstance.cpp \
+       Source/JavaScriptCore/runtime/NameInstance.h \
+       Source/JavaScriptCore/runtime/NamePrototype.cpp \
+       Source/JavaScriptCore/runtime/NamePrototype.h \
        Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp \
        Source/JavaScriptCore/runtime/NativeErrorConstructor.h \
        Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp \
index 4a03be8..1c3bb0a 100644 (file)
             'runtime/MatchResult.h',
             'runtime/MathObject.h',
             'runtime/MemoryStatistics.h',
+            'runtime/NameConstructor.h',
+            'runtime/NameInstance.h',
+            'runtime/NamePrototype.h',
             'runtime/NativeErrorConstructor.h',
             'runtime/NativeErrorPrototype.h',
             'runtime/NumberConstructor.h',
             'runtime/Lookup.cpp',
             'runtime/MathObject.cpp',
             'runtime/MemoryStatistics.cpp',
+            'runtime/NameConstructor.cpp',
+            'runtime/NameInstance.cpp',
+            'runtime/NamePrototype.cpp',
             'runtime/NativeErrorConstructor.cpp',
             'runtime/NativeErrorPrototype.cpp',
             'runtime/NumberConstructor.cpp',
             '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/JSGlobalObject.lut.h',
             '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/JSONObject.lut.h',
             '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/MathObject.lut.h',
+            '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/NamePrototype.lut.h',
             '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/NumberConstructor.lut.h',
             '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/NumberPrototype.lut.h',
             '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/ObjectConstructor.lut.h',
index e71b433..254e2d0 100644 (file)
                                >
                        </File>
                        <File
+                               RelativePath="..\..\runtime\NameConstructor.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\runtime\NameConstructor.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\runtime\NameInstance.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\runtime\NameInstance.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\runtime\NamePrototype.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\runtime\NamePrototype.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\runtime\NativeErrorConstructor.cpp"
                                >
                        </File>
                                >
                        </File>
                        <File
+                               RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\NamePrototype.lut.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\NumberConstructor.lut.h"
                                >
                        </File>
index c265464..a5ed0c3 100644 (file)
                86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8312DBA33700A9FE7B /* YarrPattern.h */; settings = {ATTRIBUTES = (Private, ); }; };
                86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */; };
                86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */; };
+               868916B0155F286300CB2B9A /* PrivateName.h in Headers */ = {isa = PBXBuildFile; fileRef = 868916A9155F285400CB2B9A /* PrivateName.h */; settings = {ATTRIBUTES = (Private, ); }; };
                869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
                869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; };
                86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */; };
                86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E116B00FE75AC800B512BC /* CodeLocation.h */; };
                86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E85538111B9968001AF51E /* JSStringBuilder.h */; };
+               86EBF2FF1560F06A008E9222 /* NameConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EBF2F91560F036008E9222 /* NameConstructor.cpp */; };
+               86EBF3001560F06A008E9222 /* NameConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FA1560F036008E9222 /* NameConstructor.h */; };
+               86EBF3011560F06A008E9222 /* NameInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EBF2FB1560F036008E9222 /* NameInstance.cpp */; };
+               86EBF3021560F06A008E9222 /* NameInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FC1560F036008E9222 /* NameInstance.h */; };
+               86EBF3031560F06A008E9222 /* NamePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EBF2FD1560F036008E9222 /* NamePrototype.cpp */; };
+               86EBF3041560F06A008E9222 /* NamePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FE1560F036008E9222 /* NamePrototype.h */; };
                86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */; };
                86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */; };
                86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */; };
                86704B8312DBA33700A9FE7B /* YarrPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrPattern.h; path = yarr/YarrPattern.h; sourceTree = "<group>"; };
                86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSpeculativeJIT32_64.cpp; path = dfg/DFGSpeculativeJIT32_64.cpp; sourceTree = "<group>"; };
                86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSpeculativeJIT64.cpp; path = dfg/DFGSpeculativeJIT64.cpp; sourceTree = "<group>"; };
+               868916A9155F285400CB2B9A /* PrivateName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateName.h; sourceTree = "<group>"; };
                869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedTranscendentalFunction.h; sourceTree = "<group>"; };
                869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; };
                86A054461556451B00445157 /* LowLevelInterpreter.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter.asm; path = llint/LowLevelInterpreter.asm; sourceTree = "<group>"; };
                86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorFixedVMPool.cpp; sourceTree = "<group>"; };
                86E116B00FE75AC800B512BC /* CodeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeLocation.h; sourceTree = "<group>"; };
                86E85538111B9968001AF51E /* JSStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringBuilder.h; sourceTree = "<group>"; };
+               86EBF2F91560F036008E9222 /* NameConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NameConstructor.cpp; sourceTree = "<group>"; };
+               86EBF2FA1560F036008E9222 /* NameConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameConstructor.h; sourceTree = "<group>"; };
+               86EBF2FB1560F036008E9222 /* NameInstance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NameInstance.cpp; sourceTree = "<group>"; };
+               86EBF2FC1560F036008E9222 /* NameInstance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameInstance.h; sourceTree = "<group>"; };
+               86EBF2FD1560F036008E9222 /* NamePrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NamePrototype.cpp; sourceTree = "<group>"; };
+               86EBF2FE1560F036008E9222 /* NamePrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NamePrototype.h; sourceTree = "<group>"; };
                86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGByteCodeParser.cpp; path = dfg/DFGByteCodeParser.cpp; sourceTree = "<group>"; };
                86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeParser.h; path = dfg/DFGByteCodeParser.h; sourceTree = "<group>"; };
                86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGGenerationInfo.h; path = dfg/DFGGenerationInfo.h; sourceTree = "<group>"; };
                7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
                        isa = PBXGroup;
                        children = (
-                               0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */,
-                               0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
-                               0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */,
                                BCF605110E203EF800B9A64D /* ArgList.cpp */,
                                BCF605120E203EF800B9A64D /* ArgList.h */,
                                BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
                                BCA62DFE0E2826230004F30D /* CallData.cpp */,
                                145C507F0D9DF63B0088F6B9 /* CallData.h */,
                                BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */,
+                               0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */,
                                65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */,
                                65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */,
+                               0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */,
                                969A09220ED1E09C00F1F681 /* Completion.cpp */,
                                F5BB2BC5030F772101FCFE1D /* Completion.h */,
                                BCA62DFF0E2826310004F30D /* ConstructData.cpp */,
                                A72701B30DADE94900E548D7 /* ExceptionHelpers.h */,
                                86CA032D1038E8440028A609 /* Executable.cpp */,
                                86CAFEE21035DDE60028A609 /* Executable.h */,
+                               0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
                                BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */,
                                BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */,
                                F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
                                F692A86B0255597D01FF60F7 /* MathObject.h */,
                                90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */,
                                90213E3C123A40C200D422F3 /* MemoryStatistics.h */,
+                               86EBF2F91560F036008E9222 /* NameConstructor.cpp */,
+                               86EBF2FA1560F036008E9222 /* NameConstructor.h */,
+                               86EBF2FB1560F036008E9222 /* NameInstance.cpp */,
+                               86EBF2FC1560F036008E9222 /* NameInstance.h */,
+                               86EBF2FD1560F036008E9222 /* NamePrototype.cpp */,
+                               86EBF2FE1560F036008E9222 /* NamePrototype.h */,
                                BC02E9080E1839DB000F9297 /* NativeErrorConstructor.cpp */,
                                BC02E9090E1839DB000F9297 /* NativeErrorConstructor.h */,
                                BC02E90A0E1839DB000F9297 /* NativeErrorPrototype.cpp */,
                                F692A8780255597D01FF60F7 /* Operations.h */,
                                0FE228EA1436AB2300196C48 /* Options.cpp */,
                                0FE228EB1436AB2300196C48 /* Options.h */,
+                               868916A9155F285400CB2B9A /* PrivateName.h */,
                                A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */,
                                A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */,
                                BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */,
                                14150133154BB13F005D8C98 /* WeakSetInlines.h in Headers */,
                                14816E1C154CC56C00B8054C /* BlockAllocator.h in Headers */,
                                86158AB3155C8B4000B45C9C /* PropertyName.h in Headers */,
+                               868916B0155F286300CB2B9A /* PrivateName.h in Headers */,
+                               86EBF3001560F06A008E9222 /* NameConstructor.h in Headers */,
+                               86EBF3021560F06A008E9222 /* NameInstance.h in Headers */,
+                               86EBF3041560F06A008E9222 /* NamePrototype.h in Headers */,
                                0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */,
                                0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */,
                                0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */,
                                8642C512151C083D0046D4EF /* RegExpMatchesArray.cpp in Sources */,
                                863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */,
                                14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */,
+                               86EBF2FF1560F06A008E9222 /* NameConstructor.cpp in Sources */,
+                               86EBF3011560F06A008E9222 /* NameInstance.cpp in Sources */,
+                               86EBF3031560F06A008E9222 /* NamePrototype.cpp in Sources */,
                                0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */,
                                0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */,
                                0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */,
index 6313258..b43cdf0 100644 (file)
@@ -200,6 +200,9 @@ SOURCES += \
     runtime/LiteralParser.cpp \
     runtime/Lookup.cpp \
     runtime/MathObject.cpp \
+    runtime/NameConstructor.cpp \
+    runtime/NameInstance.cpp \
+    runtime/NamePrototype.cpp \
     runtime/NativeErrorConstructor.cpp \
     runtime/NativeErrorPrototype.cpp \
     runtime/NumberConstructor.cpp \
index 1dc3f1f..05e5ae6 100644 (file)
@@ -36,6 +36,7 @@
 #include "JSActivation.h"
 #include "JSGlobalData.h"
 #include "JSStaticScopeObject.h"
+#include "NameInstance.h"
 #include "Operations.h"
 
 #if ENABLE(DFG_JIT)
@@ -200,6 +201,11 @@ ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exe
         }
     }
 
+    if (isName(property)) {
+        PutPropertySlot slot(strict);
+        baseValue.put(exec, jsCast<NameInstance*>(property.asCell())->privateName(), value, slot);
+        return;
+    }
 
     // Don't put to an object if toString throws an exception.
     Identifier ident(exec, property.toString(exec)->value(exec));
@@ -307,6 +313,9 @@ EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue e
         }
     }
 
+    if (isName(property))
+        return JSValue::encode(baseValue.get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
+
     Identifier ident(exec, property.toString(exec)->value(exec));
     return JSValue::encode(baseValue.get(exec, ident));
 }
@@ -330,6 +339,9 @@ EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base
             return JSValue::encode(result);
     }
 
+    if (isName(property))
+        return JSValue::encode(JSValue(base).get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
+
     Identifier ident(exec, property.toString(exec)->value(exec));
     return JSValue::encode(JSValue(base).get(exec, ident));
 }
index 4ec3de7..f4e2087 100644 (file)
@@ -90,6 +90,7 @@ namespace JSC  {
         static const HashTable* numberPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().numberPrototypeTable; }
         static const HashTable* objectConstructorTable(CallFrame* callFrame) { return callFrame->globalData().objectConstructorTable; }
         static const HashTable* objectPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().objectPrototypeTable; }
+        static const HashTable* privateNamePrototypeTable(CallFrame* callFrame) { return callFrame->globalData().privateNamePrototypeTable; }
         static const HashTable* regExpTable(CallFrame* callFrame) { return callFrame->globalData().regExpTable; }
         static const HashTable* regExpConstructorTable(CallFrame* callFrame) { return callFrame->globalData().regExpConstructorTable; }
         static const HashTable* regExpPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().regExpPrototypeTable; }
index d31ae42..b486dc6 100644 (file)
@@ -50,6 +50,7 @@
 #include "LiteralParser.h"
 #include "JSStaticScopeObject.h"
 #include "JSString.h"
+#include "NameInstance.h"
 #include "ObjectPrototype.h"
 #include "Operations.h"
 #include "Parser.h"
@@ -2795,6 +2796,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         uint32_t i;
         if (propName.getUInt32(i))
             callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, i));
+        else if (isName(propName))
+            callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, jsCast<NameInstance*>(propName.asCell())->privateName()));
         else {
             Identifier property(callFrame, propName.toString(callFrame)->value(callFrame));
             CHECK_FOR_EXCEPTION();
@@ -3775,7 +3778,9 @@ skip_id_custom_self:
                 result = asString(baseValue)->getIndex(callFrame, i);
             else
                 result = baseValue.get(callFrame, i);
-        } else {
+        } else if (isName(subscript))
+            result = baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
+        else {
             Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
             result = baseValue.get(callFrame, property);
         }
@@ -3813,6 +3818,9 @@ skip_id_custom_self:
                     jsArray->JSArray::putByIndex(jsArray, callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
             } else
                 baseValue.putByIndex(callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
+        } else if (isName(subscript)) {
+            PutPropertySlot slot(codeBlock->isStrictMode());
+            baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), callFrame->r(value).jsValue(), slot);
         } else {
             Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
             if (!globalData->exception) { // Don't put to an object if toString threw an exception.
@@ -3844,6 +3852,8 @@ skip_id_custom_self:
         uint32_t i;
         if (subscript.getUInt32(i))
             result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i);
+        else if (isName(subscript))
+            result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
         else {
             CHECK_FOR_EXCEPTION();
             Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
index bab7a03..0136082 100644 (file)
@@ -54,6 +54,7 @@
 #include "JSPropertyNameIterator.h"
 #include "JSStaticScopeObject.h"
 #include "JSString.h"
+#include "NameInstance.h"
 #include "ObjectPrototype.h"
 #include "Operations.h"
 #include "Parser.h"
@@ -2447,7 +2448,13 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
         CHECK_FOR_EXCEPTION();
         return JSValue::encode(result);
     }
-    
+
+    if (isName(subscript)) {
+        JSValue result = baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
+        CHECK_FOR_EXCEPTION();
+        return JSValue::encode(result);
+    }
+
     Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
     JSValue result = baseValue.get(callFrame, property);
     CHECK_FOR_EXCEPTION_AT_END();
@@ -2474,7 +2481,9 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
             if (!isJSString(baseValue))
                 ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
         }
-    } else {
+    } else if (isName(subscript))
+        result = baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
+    else {
         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
         result = baseValue.get(callFrame, property);
     }
@@ -2520,6 +2529,9 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
                 JSArray::putByIndex(jsArray, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
         } else
             baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
+    } else if (isName(subscript)) {
+        PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
+        baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
     } else {
         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
         if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
@@ -3241,6 +3253,9 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_in)
     if (propName.getUInt32(i))
         return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, i)));
 
+    if (isName(propName))
+        return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, jsCast<NameInstance*>(propName.asCell())->privateName())));
+
     Identifier property(callFrame, propName.toString(callFrame)->value(callFrame));
     CHECK_FOR_EXCEPTION();
     return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, property)));
@@ -3353,6 +3368,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val)
     uint32_t i;
     if (subscript.getUInt32(i))
         result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i);
+    else if (isName(subscript))
+        result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
     else {
         CHECK_FOR_EXCEPTION();
         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
index 5c6a099..066530c 100644 (file)
@@ -952,6 +952,9 @@ inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
         
         return baseValue.get(exec, i);
     }
+
+    if (isName(subscript))
+        return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
     
     Identifier property(exec, subscript.toString(exec)->value(exec));
     return baseValue.get(exec, property);
@@ -1004,7 +1007,13 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
         baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
         LLINT_END();
     }
-    
+
+    if (isName(subscript)) {
+        PutPropertySlot slot(exec->codeBlock()->isStrictMode());
+        baseValue.put(exec, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
+        LLINT_END();
+    }
+
     Identifier property(exec, subscript.toString(exec)->value(exec));
     LLINT_CHECK_EXCEPTION();
     PutPropertySlot slot(exec->codeBlock()->isStrictMode());
@@ -1025,6 +1034,8 @@ LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
     uint32_t i;
     if (subscript.getUInt32(i))
         couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
+    else if (isName(subscript))
+        couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
     else {
         LLINT_CHECK_EXCEPTION();
         Identifier property(exec, subscript.toString(exec)->value(exec));
index c41ced7..0d34801 100644 (file)
@@ -30,6 +30,7 @@
 #include "CodeSpecializationKind.h"
 #include "ExceptionHelpers.h"
 #include "JSArray.h"
+#include "NameInstance.h"
 
 namespace JSC {
 
@@ -109,6 +110,9 @@ inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
     if (propName.getUInt32(i))
         return baseObj->hasProperty(exec, i);
 
+    if (isName(propName))
+        return baseObj->hasProperty(exec, jsCast<NameInstance*>(propName.asCell())->privateName());
+
     Identifier property(exec, propName.toString(exec)->value(exec));
     if (exec->globalData().exception)
         return false;
index f888318..5417b00 100644 (file)
@@ -92,7 +92,7 @@ void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
 
 inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
 {
-    SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+    SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName());
     if (entry.isNull())
         return false;
     if (m_isTornOff && entry.getIndex() >= m_numCapturedVars)
@@ -107,7 +107,7 @@ inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyN
     JSGlobalData& globalData = exec->globalData();
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
     
-    SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+    SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName());
     if (entry.isNull())
         return false;
     if (entry.isReadOnly()) {
@@ -141,7 +141,7 @@ inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData,
 {
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
     
-    SymbolTable::iterator iter = symbolTable().find(propertyName.impl());
+    SymbolTable::iterator iter = symbolTable().find(propertyName.publicName());
     if (iter == symbolTable().end())
         return false;
     SymbolTableEntry& entry = iter->second;
index 9e9469d..dd03ab4 100644 (file)
@@ -86,6 +86,7 @@ extern const HashTable numberConstructorTable;
 extern const HashTable numberPrototypeTable;
 JS_EXPORTDATA extern const HashTable objectConstructorTable;
 extern const HashTable objectPrototypeTable;
+extern const HashTable privateNamePrototypeTable;
 extern const HashTable regExpTable;
 extern const HashTable regExpConstructorTable;
 extern const HashTable regExpPrototypeTable;
@@ -135,6 +136,7 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
     , numberPrototypeTable(fastNew<HashTable>(JSC::numberPrototypeTable))
     , objectConstructorTable(fastNew<HashTable>(JSC::objectConstructorTable))
     , objectPrototypeTable(fastNew<HashTable>(JSC::objectPrototypeTable))
+    , privateNamePrototypeTable(fastNew<HashTable>(JSC::privateNamePrototypeTable))
     , regExpTable(fastNew<HashTable>(JSC::regExpTable))
     , regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
     , regExpPrototypeTable(fastNew<HashTable>(JSC::regExpPrototypeTable))
@@ -241,6 +243,7 @@ JSGlobalData::~JSGlobalData()
     numberPrototypeTable->deleteTable();
     objectConstructorTable->deleteTable();
     objectPrototypeTable->deleteTable();
+    privateNamePrototypeTable->deleteTable();
     regExpTable->deleteTable();
     regExpConstructorTable->deleteTable();
     regExpPrototypeTable->deleteTable();
@@ -260,6 +263,7 @@ JSGlobalData::~JSGlobalData()
     fastDelete(const_cast<HashTable*>(numberPrototypeTable));
     fastDelete(const_cast<HashTable*>(objectConstructorTable));
     fastDelete(const_cast<HashTable*>(objectPrototypeTable));
+    fastDelete(const_cast<HashTable*>(privateNamePrototypeTable));
     fastDelete(const_cast<HashTable*>(regExpTable));
     fastDelete(const_cast<HashTable*>(regExpConstructorTable));
     fastDelete(const_cast<HashTable*>(regExpPrototypeTable));
index 3bf8a29..d45a5ba 100644 (file)
@@ -192,6 +192,7 @@ namespace JSC {
         const HashTable* numberPrototypeTable;
         const HashTable* objectConstructorTable;
         const HashTable* objectPrototypeTable;
+        const HashTable* privateNamePrototypeTable;
         const HashTable* regExpTable;
         const HashTable* regExpConstructorTable;
         const HashTable* regExpPrototypeTable;
index da55c01..4f8cf35 100644 (file)
@@ -56,6 +56,9 @@
 #include "Interpreter.h"
 #include "Lookup.h"
 #include "MathObject.h"
+#include "NameConstructor.h"
+#include "NameInstance.h"
+#include "NamePrototype.h"
 #include "NativeErrorConstructor.h"
 #include "NativeErrorPrototype.h"
 #include "NumberConstructor.h"
@@ -244,6 +247,9 @@ void JSGlobalObject::reset(JSValue prototype)
     ErrorPrototype* errorPrototype = ErrorPrototype::create(exec, this, ErrorPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get()));
     m_errorStructure.set(exec->globalData(), this, ErrorInstance::createStructure(exec->globalData(), this, errorPrototype));
 
+    NamePrototype* privateNamePrototype = NamePrototype::create(exec, NamePrototype::createStructure(exec->globalData(), this, m_objectPrototype.get()));
+    m_privateNameStructure.set(exec->globalData(), this, NameInstance::createStructure(exec->globalData(), this, privateNamePrototype));
+
     // Constructors
 
     JSCell* objectConstructor = ObjectConstructor::create(exec, this, ObjectConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_objectPrototype.get());
@@ -257,6 +263,7 @@ void JSGlobalObject::reset(JSValue prototype)
     m_regExpConstructor.set(exec->globalData(), this, RegExpConstructor::create(exec, this, RegExpConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_regExpPrototype.get()));
 
     m_errorConstructor.set(exec->globalData(), this, ErrorConstructor::create(exec, this, ErrorConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), errorPrototype));
+    JSCell* privateNameConstructor = NameConstructor::create(exec, this, NameConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), privateNamePrototype);
 
     Structure* nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(exec->globalData(), this, errorPrototype);
     Structure* nativeErrorStructure = NativeErrorConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get());
@@ -276,6 +283,7 @@ void JSGlobalObject::reset(JSValue prototype)
     m_datePrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, dateConstructor, DontEnum);
     m_regExpPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, m_regExpConstructor.get(), DontEnum);
     errorPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, m_errorConstructor.get(), DontEnum);
+    privateNamePrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, privateNameConstructor, DontEnum);
 
     putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Object"), objectConstructor, DontEnum);
     putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Function"), functionConstructor, DontEnum);
@@ -292,6 +300,7 @@ void JSGlobalObject::reset(JSValue prototype)
     putDirectWithoutTransition(exec->globalData(), Identifier(exec, "SyntaxError"), m_syntaxErrorConstructor.get(), DontEnum);
     putDirectWithoutTransition(exec->globalData(), Identifier(exec, "TypeError"), m_typeErrorConstructor.get(), DontEnum);
     putDirectWithoutTransition(exec->globalData(), Identifier(exec, "URIError"), m_URIErrorConstructor.get(), DontEnum);
+    putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Name"), privateNameConstructor, DontEnum);
 
     m_evalFunction.set(exec->globalData(), this, JSFunction::create(exec, this, 1, exec->propertyNames().eval.ustring(), globalFuncEval));
     putDirectWithoutTransition(exec->globalData(), exec->propertyNames().eval, m_evalFunction.get(), DontEnum);
index a330f5f..cb39b61 100644 (file)
@@ -130,6 +130,7 @@ namespace JSC {
         WriteBarrier<Structure> m_namedFunctionStructure;
         size_t m_functionNameOffset;
         WriteBarrier<Structure> m_numberObjectStructure;
+        WriteBarrier<Structure> m_privateNameStructure;
         WriteBarrier<Structure> m_regExpMatchesArrayStructure;
         WriteBarrier<Structure> m_regExpStructure;
         WriteBarrier<Structure> m_stringObjectStructure;
@@ -263,6 +264,7 @@ namespace JSC {
         Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); }
         size_t functionNameOffset() const { return m_functionNameOffset; }
         Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); }
+        Structure* privateNameStructure() const { return m_privateNameStructure.get(); }
         Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
         Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
         Structure* regExpStructure() const { return m_regExpStructure.get(); }
@@ -376,7 +378,7 @@ namespace JSC {
 
     inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName)
     {
-        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName());
         return !entry.isNull();
     }
 
index 880240e..c960343 100644 (file)
@@ -45,6 +45,7 @@ enum JSType {
     ObjectType,
     FinalObjectType,
     JSFunctionType,
+    NameInstanceType,
     NumberObjectType,
     ErrorInstanceType,
     GlobalThisType,
index 83a3594..8c62fa1 100644 (file)
@@ -67,6 +67,7 @@ namespace JSC {
         bool isObject() const { return type() >= ObjectType; }
         bool isFinalObject() const { return type() == FinalObjectType; }
         bool isNumberObject() const { return type() == NumberObjectType; }
+        bool isName() const { return type() == NameInstanceType; }
 
         bool masqueradesAsUndefined() const { return isSetOnFlags1(MasqueradesAsUndefined); }
         bool implementsHasInstance() const { return isSetOnFlags1(ImplementsHasInstance); }
index 3a4df74..eb9dfd4 100644 (file)
@@ -45,7 +45,7 @@ void JSVariableObject::destroy(JSCell* cell)
 bool JSVariableObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
 {
     JSVariableObject* thisObject = jsCast<JSVariableObject*>(cell);
-    if (thisObject->symbolTable().contains(propertyName.impl()))
+    if (thisObject->symbolTable().contains(propertyName.publicName()))
         return false;
 
     return JSObject::deleteProperty(thisObject, exec, propertyName);
@@ -65,7 +65,7 @@ void JSVariableObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Pr
 
 bool JSVariableObject::symbolTableGet(PropertyName propertyName, PropertyDescriptor& descriptor)
 {
-    SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+    SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName());
     if (!entry.isNull()) {
         descriptor.setDescriptor(registerAt(entry.getIndex()).get(), entry.getAttributes() | DontDelete);
         return true;
index 8b7587b..ea27984 100644 (file)
@@ -102,7 +102,7 @@ namespace JSC {
 
     inline bool JSVariableObject::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
     {
-        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName());
         if (!entry.isNull()) {
             slot.setValue(registerAt(entry.getIndex()).get());
             return true;
@@ -112,7 +112,7 @@ namespace JSC {
 
     inline bool JSVariableObject::symbolTableGet(PropertyName propertyName, PropertySlot& slot, bool& slotIsWriteable)
     {
-        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName());
         if (!entry.isNull()) {
             slot.setValue(registerAt(entry.getIndex()).get());
             slotIsWriteable = !entry.isReadOnly();
@@ -126,7 +126,7 @@ namespace JSC {
         JSGlobalData& globalData = exec->globalData();
         ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
 
-        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName());
         if (entry.isNull())
             return false;
         if (entry.isReadOnly()) {
@@ -142,7 +142,7 @@ namespace JSC {
     {
         ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
 
-        SymbolTable::iterator iter = symbolTable().find(propertyName.impl());
+        SymbolTable::iterator iter = symbolTable().find(propertyName.publicName());
         if (iter == symbolTable().end())
             return false;
         SymbolTableEntry& entry = iter->second;
index 30d982d..a6a3499 100644 (file)
@@ -76,7 +76,10 @@ bool setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject*
         if (thisObj->staticFunctionsReified())
             return false;
     
-        JSFunction* function = JSFunction::create(exec, thisObj->globalObject(), entry->functionLength(), propertyName.ustring(), entry->function(), entry->intrinsic());
+        StringImpl* name = propertyName.publicName();
+        ASSERT(name);
+        
+        JSFunction* function = JSFunction::create(exec, thisObj->globalObject(), entry->functionLength(), name, entry->function(), entry->intrinsic());
         thisObj->putDirect(exec->globalData(), propertyName, function, entry->attributes());
         location = thisObj->getDirectLocation(exec->globalData(), propertyName);
     }
index d6806ae..a75b521 100644 (file)
@@ -199,17 +199,21 @@ namespace JSC {
         }
 
     private:
-        ALWAYS_INLINE const HashEntry* entry(PropertyName identifier) const
+        ALWAYS_INLINE const HashEntry* entry(PropertyName propertyName) const
         {
+            StringImpl* impl = propertyName.publicName();
+            if (!impl)
+                return 0;
+        
             ASSERT(table);
 
-            const HashEntry* entry = &table[identifier.impl()->existingHash() & compactHashSizeMask];
+            const HashEntry* entry = &table[impl->existingHash() & compactHashSizeMask];
 
             if (!entry->key())
                 return 0;
 
             do {
-                if (entry->key() == identifier.impl())
+                if (entry->key() == impl)
                     return entry;
                 entry = entry->next();
             } while (entry);
diff --git a/Source/JavaScriptCore/runtime/NameConstructor.cpp b/Source/JavaScriptCore/runtime/NameConstructor.cpp
new file mode 100644 (file)
index 0000000..63f1f64
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NameConstructor.h"
+
+#include "JSGlobalObject.h"
+#include "NamePrototype.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(NameConstructor);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(NameConstructor);
+
+const ClassInfo NameConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(NameConstructor) };
+
+NameConstructor::NameConstructor(JSGlobalObject* globalObject, Structure* structure)
+    : InternalFunction(globalObject, structure)
+{
+}
+
+void NameConstructor::finishCreation(ExecState* exec, NamePrototype* prototype)
+{
+    Base::finishCreation(exec->globalData(), prototype->classInfo()->className);
+    putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, prototype, DontEnum | DontDelete | ReadOnly);
+    putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum);
+}
+
+static EncodedJSValue JSC_HOST_CALL constructPrivateName(ExecState* exec)
+{
+    JSValue publicName = exec->argumentCount() ? exec->argument(0) : jsUndefined();
+    return JSValue::encode(NameInstance::create(exec->globalData(), exec->lexicalGlobalObject()->privateNameStructure(), publicName.toString(exec)));
+}
+
+ConstructType NameConstructor::getConstructData(JSCell*, ConstructData& constructData)
+{
+    constructData.native.function = constructPrivateName;
+    return ConstructTypeHost;
+}
+
+CallType NameConstructor::getCallData(JSCell*, CallData& callData)
+{
+    callData.native.function = constructPrivateName;
+    return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/NameConstructor.h b/Source/JavaScriptCore/runtime/NameConstructor.h
new file mode 100644 (file)
index 0000000..16c5eef
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NameConstructor_h
+#define NameConstructor_h
+
+#include "InternalFunction.h"
+#include "NameInstance.h"
+
+namespace JSC {
+
+class NamePrototype;
+
+class NameConstructor : public InternalFunction {
+public:
+    typedef InternalFunction Base;
+
+    static NameConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, NamePrototype* prototype)
+    {
+        NameConstructor* constructor = new (NotNull, allocateCell<NameConstructor>(*exec->heap())) NameConstructor(globalObject, structure);
+        constructor->finishCreation(exec, prototype);
+        return constructor;
+    }
+
+    static const ClassInfo s_info;
+
+    static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) 
+    { 
+        return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); 
+    }
+
+protected:
+    void finishCreation(ExecState*, NamePrototype*);
+    
+private:
+    NameConstructor(JSGlobalObject*, Structure*);
+    static ConstructType getConstructData(JSCell*, ConstructData&);
+    static CallType getCallData(JSCell*, CallData&);
+};
+
+} // namespace JSC
+
+#endif // NameConstructor_h
diff --git a/Source/JavaScriptCore/runtime/NameInstance.cpp b/Source/JavaScriptCore/runtime/NameInstance.cpp
new file mode 100644 (file)
index 0000000..aae290c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NameInstance.h"
+
+namespace JSC {
+
+const ClassInfo NameInstance::s_info = { "Name", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(NameInstance) };
+
+NameInstance::NameInstance(JSGlobalData& globalData, Structure* structure, JSString* nameString)
+    : Base(globalData, structure)
+{
+    m_nameString.set(globalData, this, nameString);
+}
+
+void NameInstance::destroy(JSCell* cell)
+{
+    jsCast<NameInstance*>(cell)->NameInstance::~NameInstance();
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/NameInstance.h b/Source/JavaScriptCore/runtime/NameInstance.h
new file mode 100644 (file)
index 0000000..c5931e8
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NameInstance_h
+#define NameInstance_h
+
+#include "JSObject.h"
+#include "PrivateName.h"
+
+namespace JSC {
+
+class NameInstance : public JSNonFinalObject {
+public:
+    typedef JSNonFinalObject Base;
+
+    static const ClassInfo s_info;
+
+    static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(globalData, globalObject, prototype, TypeInfo(NameInstanceType, StructureFlags), &s_info);
+    }
+
+    static NameInstance* create(JSGlobalData& globalData, Structure* structure, JSString* nameString)
+    {
+        NameInstance* name = new (NotNull, allocateCell<NameInstance>(globalData.heap)) NameInstance(globalData, structure, nameString);
+        name->finishCreation(globalData);
+        return name;
+    }
+
+    const PrivateName& privateName() { return m_privateName; }
+    JSString* nameString() { return m_nameString.get(); }
+
+protected:
+    static void destroy(JSCell*);
+
+    NameInstance(JSGlobalData&, Structure*, JSString*);
+
+    void finishCreation(JSGlobalData& globalData)
+    {
+        Base::finishCreation(globalData);
+        ASSERT(inherits(&s_info));
+    }
+
+    PrivateName m_privateName;
+    WriteBarrier<JSString> m_nameString;
+};
+
+inline bool isName(JSValue v)
+{
+    return v.isCell() && v.asCell()->structure()->typeInfo().isName();
+}
+
+} // namespace JSC
+
+#endif // NameInstance_h
diff --git a/Source/JavaScriptCore/runtime/NamePrototype.cpp b/Source/JavaScriptCore/runtime/NamePrototype.cpp
new file mode 100644 (file)
index 0000000..3e52856
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NamePrototype.h"
+
+#include "Error.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(NamePrototype);
+
+static EncodedJSValue JSC_HOST_CALL privateNameProtoFuncToString(ExecState*);
+
+}
+
+#include "NamePrototype.lut.h"
+
+namespace JSC {
+
+const ClassInfo NamePrototype::s_info = { "Name", &Base::s_info, 0, ExecState::privateNamePrototypeTable, CREATE_METHOD_TABLE(NamePrototype) };
+
+/* Source for NamePrototype.lut.h
+@begin privateNamePrototypeTable
+  toString          privateNameProtoFuncToString         DontEnum|Function 0
+@end
+*/
+
+ASSERT_CLASS_FITS_IN_CELL(NamePrototype);
+
+NamePrototype::NamePrototype(ExecState* exec, Structure* structure)
+    : Base(exec->globalData(), structure, jsEmptyString(exec))
+{
+}
+
+void NamePrototype::finishCreation(ExecState* exec)
+{
+    Base::finishCreation(exec->globalData());
+    ASSERT(inherits(&s_info));
+}
+
+bool NamePrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
+{
+    return getStaticFunctionSlot<Base>(exec, ExecState::privateNamePrototypeTable(exec), jsCast<NamePrototype*>(cell), propertyName, slot);
+}
+
+bool NamePrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
+{
+    return getStaticFunctionDescriptor<Base>(exec, ExecState::privateNamePrototypeTable(exec), jsCast<NamePrototype*>(object), propertyName, descriptor);
+}
+
+// ------------------------------ Functions ---------------------------
+
+EncodedJSValue JSC_HOST_CALL privateNameProtoFuncToString(ExecState* exec)
+{
+    JSValue thisValue = exec->hostThisValue();
+    if (!thisValue.isObject())
+        return throwVMTypeError(exec);
+
+    JSObject* thisObject = asObject(thisValue);
+    if (!thisObject->inherits(&NameInstance::s_info))
+        return throwVMTypeError(exec);
+
+    return JSValue::encode(jsCast<NameInstance*>(thisObject)->nameString());
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/NamePrototype.h b/Source/JavaScriptCore/runtime/NamePrototype.h
new file mode 100644 (file)
index 0000000..5d86dec
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NamePrototype_h
+#define NamePrototype_h
+
+#include "NameInstance.h"
+
+namespace JSC {
+
+class NamePrototype : public NameInstance {
+public:
+    typedef NameInstance Base;
+
+    static NamePrototype* create(ExecState* exec, Structure* structure)
+    {
+        NamePrototype* prototype = new (NotNull, allocateCell<NamePrototype>(*exec->heap())) NamePrototype(exec, structure);
+        prototype->finishCreation(exec);
+        return prototype;
+    }
+    
+    static const ClassInfo s_info;
+
+    static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(globalData, globalObject, prototype, TypeInfo(NameInstanceType, StructureFlags), &s_info);
+    }
+
+protected:
+    NamePrototype(ExecState*, Structure*);
+    void finishCreation(ExecState*);
+
+    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NameInstance::StructureFlags;
+
+private:
+    static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
+    static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
+};
+
+} // namespace JSC
+
+#endif // NamePrototype_h
diff --git a/Source/JavaScriptCore/runtime/PrivateName.h b/Source/JavaScriptCore/runtime/PrivateName.h
new file mode 100644 (file)
index 0000000..91254fc
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PrivateName_h
+#define PrivateName_h
+
+#include <wtf/text/StringImpl.h>
+
+namespace JSC {
+
+class PrivateName {
+public:
+    PrivateName()
+        : m_impl(StringImpl::createEmptyUnique())
+    {
+    }
+
+    StringImpl* uid() const { return m_impl.get(); }
+
+private:
+    RefPtr<StringImpl> m_impl;
+};
+
+}
+
+#endif
index 7c8cabb..c47f347 100644 (file)
@@ -325,7 +325,7 @@ inline PropertyTable::const_iterator PropertyTable::end() const
 inline PropertyTable::find_iterator PropertyTable::find(const KeyType& key)
 {
     ASSERT(key);
-    ASSERT(key->isIdentifier());
+    ASSERT(key->isIdentifier() || key->isEmptyUnique());
     unsigned hash = key->existingHash();
     unsigned step = 0;
 
@@ -369,7 +369,8 @@ inline PropertyTable::find_iterator PropertyTable::findWithString(const KeyType&
         unsigned entryIndex = m_index[hash & m_indexMask];
         if (entryIndex == EmptyEntryIndex)
             return std::make_pair((ValueType*)0, hash & m_indexMask);
-        if (equal(key, table()[entryIndex - 1].key))
+        const KeyType& keyInMap = table()[entryIndex - 1].key;
+        if (equal(key, keyInMap) && keyInMap->isIdentifier())
             return std::make_pair(&table()[entryIndex - 1], hash & m_indexMask);
 
 #if DUMP_PROPERTYMAP_STATS
index d2258b4..7253756 100644 (file)
@@ -27,6 +27,7 @@
 #define PropertyName_h
 
 #include "Identifier.h"
+#include "PrivateName.h"
 
 namespace JSC {
 
@@ -80,15 +81,33 @@ public:
     PropertyName(const Identifier& propertyName)
         : m_impl(propertyName.impl())
     {
+        ASSERT(!m_impl || m_impl->isIdentifier());
     }
 
-    StringImpl* impl() const { return m_impl; }
-    UString ustring() const { return m_impl; }
+    PropertyName(const PrivateName& propertyName)
+        : m_impl(propertyName.uid())
+    {
+        ASSERT(m_impl && m_impl->isEmptyUnique());
+    }
+
+    StringImpl* uid() const
+    {
+        ASSERT(!m_impl || (m_impl->isIdentifier() == !m_impl->isEmptyUnique()));
+        return m_impl;
+    }
+
+    StringImpl* publicName() const
+    {
+        ASSERT(!m_impl || (m_impl->isIdentifier() == !m_impl->isEmptyUnique()));
+        return m_impl->isIdentifier() ? m_impl : 0;
+    }
 
     static const uint32_t NotAnIndex = UINT_MAX;
+
     uint32_t asIndex()
     {
-        return toUInt32FromStringImpl(m_impl);
+        ASSERT(!m_impl || (m_impl->isIdentifier() == !m_impl->isEmptyUnique()));
+        return m_impl ? toUInt32FromStringImpl(m_impl) : NotAnIndex;
     }
 
 private:
@@ -97,32 +116,32 @@ private:
 
 inline bool operator==(PropertyName a, const Identifier& b)
 {
-    return a.impl() == b.impl();
+    return a.uid() == b.impl();
 }
 
 inline bool operator==(const Identifier& a, PropertyName b)
 {
-    return a.impl() == b.impl();
+    return a.impl() == b.uid();
 }
 
 inline bool operator==(PropertyName a, PropertyName b)
 {
-    return a.impl() == b.impl();
+    return a.uid() == b.uid();
 }
 
 inline bool operator!=(PropertyName a, const Identifier& b)
 {
-    return a.impl() != b.impl();
+    return a.uid() != b.impl();
 }
 
 inline bool operator!=(const Identifier& a, PropertyName b)
 {
-    return a.impl() != b.impl();
+    return a.impl() != b.uid();
 }
 
 inline bool operator!=(PropertyName a, PropertyName b)
 {
-    return a.impl() != b.impl();
+    return a.uid() != b.uid();
 }
 
 }
index 693f3f3..e05a15f 100644 (file)
@@ -275,7 +275,7 @@ size_t Structure::suggestedNewPropertyStorageSize()
  
 void Structure::despecifyDictionaryFunction(JSGlobalData& globalData, PropertyName propertyName)
 {
-    StringImpl* rep = propertyName.impl();
+    StringImpl* rep = propertyName.uid();
 
     materializePropertyMapIfNecessary(globalData);
 
@@ -292,7 +292,7 @@ Structure* Structure::addPropertyTransitionToExistingStructure(Structure* struct
     ASSERT(!structure->isDictionary());
     ASSERT(structure->isObject());
 
-    if (Structure* existingTransition = structure->m_transitionTable.get(propertyName.impl(), attributes)) {
+    if (Structure* existingTransition = structure->m_transitionTable.get(propertyName.uid(), attributes)) {
         JSCell* specificValueInPrevious = existingTransition->m_specificValueInPrevious.get();
         if (specificValueInPrevious && specificValueInPrevious != specificValue)
             return 0;
@@ -313,7 +313,7 @@ Structure* Structure::addPropertyTransition(JSGlobalData& globalData, Structure*
     // In this case we clear the value of specificFunction which will result
     // in us adding a non-specific transition, and any subsequent lookup in
     // Structure::addPropertyTransitionToExistingStructure will just use that.
-    if (specificValue && structure->m_transitionTable.contains(propertyName.impl(), attributes))
+    if (specificValue && structure->m_transitionTable.contains(propertyName.uid(), attributes))
         specificValue = 0;
 
     ASSERT(!structure->isDictionary());
@@ -336,7 +336,7 @@ Structure* Structure::addPropertyTransition(JSGlobalData& globalData, Structure*
 
     transition->m_cachedPrototypeChain.setMayBeNull(globalData, transition, structure->m_cachedPrototypeChain.get());
     transition->m_previous.set(globalData, transition, structure);
-    transition->m_nameInPrevious = propertyName.impl();
+    transition->m_nameInPrevious = propertyName.uid();
     transition->m_attributesInPrevious = attributes;
     transition->m_specificValueInPrevious.setMayBeNull(globalData, transition, specificValue);
 
@@ -425,7 +425,7 @@ Structure* Structure::attributeChangeTransition(JSGlobalData& globalData, Struct
     }
 
     ASSERT(structure->m_propertyTable);
-    PropertyMapEntry* entry = structure->m_propertyTable->find(propertyName.impl()).first;
+    PropertyMapEntry* entry = structure->m_propertyTable->find(propertyName.uid()).first;
     ASSERT(entry);
     entry->attributes = attributes;
 
@@ -650,7 +650,7 @@ size_t Structure::get(JSGlobalData& globalData, PropertyName propertyName, unsig
     if (!m_propertyTable)
         return WTF::notFound;
 
-    PropertyMapEntry* entry = m_propertyTable->find(propertyName.impl()).first;
+    PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
     if (!entry)
         return WTF::notFound;
 
@@ -665,7 +665,7 @@ bool Structure::despecifyFunction(JSGlobalData& globalData, PropertyName propert
     if (!m_propertyTable)
         return false;
 
-    PropertyMapEntry* entry = m_propertyTable->find(propertyName.impl()).first;
+    PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
     if (!entry)
         return false;
 
@@ -693,7 +693,7 @@ size_t Structure::putSpecificValue(JSGlobalData& globalData, PropertyName proper
     if (attributes & DontEnum)
         m_hasNonEnumerableProperties = true;
 
-    StringImpl* rep = propertyName.impl();
+    StringImpl* rep = propertyName.uid();
 
     if (!m_propertyTable)
         createPropertyMap();
@@ -715,7 +715,7 @@ size_t Structure::remove(PropertyName propertyName)
 {
     checkConsistency();
 
-    StringImpl* rep = propertyName.impl();
+    StringImpl* rep = propertyName.uid();
 
     if (!m_propertyTable)
         return notFound;
@@ -753,7 +753,7 @@ void Structure::getPropertyNamesFromStructure(JSGlobalData& globalData, Property
     PropertyTable::iterator end = m_propertyTable->end();
     for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter) {
         ASSERT(m_hasNonEnumerableProperties || !(iter->attributes & DontEnum));
-        if (!(iter->attributes & DontEnum) || (mode == IncludeDontEnumProperties)) {
+        if (iter->key->isIdentifier() && (!(iter->attributes & DontEnum) || mode == IncludeDontEnumProperties)) {
             if (knownUnique)
                 propertyNames.addKnownUnique(iter->key);
             else
index 230f59d..74336a2 100644 (file)
@@ -317,7 +317,7 @@ namespace JSC {
         if (!m_propertyTable)
             return notFound;
 
-        PropertyMapEntry* entry = m_propertyTable->find(propertyName.impl()).first;
+        PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
         return entry ? entry->offset : notFound;
     }
 
index c86b4c7..04a6c25 100644 (file)
@@ -1,3 +1,20 @@
+2012-05-15  Gavin Barraclough  <barraclough@apple.com>
+
+        Add support for private names
+        https://bugs.webkit.org/show_bug.cgi?id=86509
+
+        Reviewed by Oliver Hunt.
+
+        The spec isn't final, but we can start adding support to allow property maps
+        to contain keys that aren't identifiers.
+
+        * wtf/text/StringImpl.h:
+        (WTF::StringImpl::StringImpl):
+        (StringImpl):
+        (WTF::StringImpl::createEmptyUnique):
+        (WTF::StringImpl::isEmptyUnique):
+            - Allow empty string impls to be allocated, which can be used as unique keys.
+
 2012-05-21  Emil A Eklund <eae@chromium.org> and Levi Weintraub  <leviw@chromium.org>
 
         Enable SUBPIXEL_LAYOUT feature flag on Chromium
index 3734360..b8073b3 100644 (file)
@@ -157,11 +157,11 @@ private:
 
     // Create a StringImpl adopting ownership of the provided buffer (BufferOwned)
     StringImpl(const UChar* characters, unsigned length)
-    : m_refCount(s_refCountIncrement)
-    , m_length(length)
-    , m_data16(characters)
-    , m_buffer(0)
-    , m_hashAndFlags(BufferOwned)
+        : m_refCount(s_refCountIncrement)
+        , m_length(length)
+        , m_data16(characters)
+        , m_buffer(0)
+        , m_hashAndFlags(BufferOwned)
     {
         ASSERT(m_data16);
         ASSERT(m_length);
@@ -195,6 +195,26 @@ private:
         ASSERT(m_substringBuffer->bufferOwnership() != BufferSubstring);
     }
 
+    enum CreateEmptyUnique_T { CreateEmptyUnique };
+    StringImpl(CreateEmptyUnique_T)
+        : m_refCount(s_refCountIncrement)
+        , m_length(0)
+        , m_data16(reinterpret_cast<const UChar*>(1))
+        , m_buffer(0)
+    {
+        ASSERT(m_data16);
+        // Set the hash early, so that all empty unique StringImpls have a hash,
+        // and don't use the normal hashing algorithm - the unique nature of these
+        // keys means that we don't need them to match any other string (in fact,
+        // that's exactly the oposite of what we want!), and teh normal hash would
+        // lead to lots of conflicts.
+        unsigned hash = reinterpret_cast<uintptr_t>(this);
+        hash <<= s_flagCount;
+        if (!hash)
+            hash = 1 << s_flagCount;
+        m_hashAndFlags = hash | BufferInternal;
+    }
+
 public:
     WTF_EXPORT_PRIVATE ~StringImpl();
 
@@ -257,6 +277,11 @@ public:
         return adoptRef(new (NotNull, resultImpl) StringImpl(length));
     }
 
+    static PassRefPtr<StringImpl> createEmptyUnique()
+    {
+        return adoptRef(new StringImpl(CreateEmptyUnique));
+    }
+
     // Reallocate the StringImpl. The originalString must be only owned by the PassRefPtr,
     // and the buffer ownership must be BufferInternal. Just like the input pointer of realloc(),
     // the originalString can't be used after this function.
@@ -325,6 +350,11 @@ public:
             m_hashAndFlags &= ~s_hashFlagIsIdentifier;
     }
 
+    bool isEmptyUnique() const
+    {
+        return !length() && !isStatic();
+    }
+
     bool hasTerminatingNullCharacter() const { return m_hashAndFlags & s_hashFlagHasTerminatingNullCharacter; }
 
     bool isAtomic() const { return m_hashAndFlags & s_hashFlagIsAtomic; }
index b0d316d..7a0c5f1 100644 (file)
@@ -1,3 +1,51 @@
+2012-05-15  Gavin Barraclough  <barraclough@apple.com>
+
+        Add support for private names
+        https://bugs.webkit.org/show_bug.cgi?id=86509
+
+        Reviewed by Oliver Hunt.
+
+        The spec isn't final, but we can start adding support to allow property maps
+        to contain keys that aren't identifiers.
+
+        Test: fast/js/names.html
+
+        * bindings/js/JSCSSStyleDeclarationCustom.cpp:
+        (WebCore::cssPropertyIDForJSCSSPropertyName):
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::findAtomicString):
+        (WebCore::objectToStringFunctionGetter):
+        * bindings/js/JSDOMBinding.h:
+        (WebCore::propertyNameToString):
+        (WebCore::propertyNameToAtomicString):
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::nonCachingStaticFunctionGetter):
+        * bindings/js/JSHistoryCustom.cpp:
+        (WebCore::nonCachingStaticBackFunctionGetter):
+        (WebCore::nonCachingStaticForwardFunctionGetter):
+        (WebCore::nonCachingStaticGoFunctionGetter):
+        * bindings/js/JSLocationCustom.cpp:
+        (WebCore::nonCachingStaticReplaceFunctionGetter):
+        (WebCore::nonCachingStaticReloadFunctionGetter):
+        (WebCore::nonCachingStaticAssignFunctionGetter):
+        * bridge/c/c_class.cpp:
+        (JSC::Bindings::CClass::methodsNamed):
+        (JSC::Bindings::CClass::fieldNamed):
+        * bridge/c/c_instance.cpp:
+        (JSC::Bindings::CInstance::getMethod):
+        * bridge/jni/jsc/JavaClassJSC.cpp:
+        (JavaClass::methodsNamed):
+        (JavaClass::fieldNamed):
+        * bridge/jni/jsc/JavaInstanceJSC.cpp:
+        * bridge/objc/objc_class.mm:
+        (JSC::Bindings::ObjcClass::methodsNamed):
+        (JSC::Bindings::ObjcClass::fieldNamed):
+        (JSC::Bindings::ObjcClass::fallbackObject):
+        * bridge/objc/objc_instance.mm:
+        (ObjcInstance::setValueOfUndefinedField):
+        (ObjcInstance::getValueOfUndefinedField):
+            - Removed PropertyName::impl(), call publicName() to get the string associated with a name.
+
 2012-05-21  Tim Horton  <timothy_horton@apple.com>
 
         GeneratorGeneratedImage should cache intermediate images
index 21f1ef4..464e8bb 100644 (file)
@@ -181,7 +181,9 @@ static CSSPropertyInfo cssPropertyIDForJSCSSPropertyName(PropertyName propertyNa
     CSSPropertyInfo propertyInfo = {CSSPropertyInvalid, false};
     bool hadPixelOrPosPrefix = false;
 
-    StringImpl* propertyNameString = propertyName.impl();
+    StringImpl* propertyNameString = propertyName.publicName();
+    if (!propertyNameString)
+        return propertyInfo;
     unsigned length = propertyNameString->length();
     if (!length)
         return propertyInfo;
index 7be4b83..eb5bb38 100644 (file)
@@ -109,7 +109,7 @@ JSValue jsStringOrFalse(ExecState* exec, const KURL& url)
 
 AtomicStringImpl* findAtomicString(PropertyName propertyName)
 {
-    StringImpl* impl = propertyName.impl();
+    StringImpl* impl = propertyName.publicName();
     if (!impl)
         return 0;
     ASSERT(impl->existingHash());
@@ -245,7 +245,7 @@ void printErrorMessageForFrame(Frame* frame, const String& message)
 
 JSValue objectToStringFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName.impl(), objectProtoFuncToString);
+    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName.publicName(), objectProtoFuncToString);
 }
 
 Structure* getCachedDOMStructure(JSDOMGlobalObject* globalObject, const ClassInfo* classInfo)
index 4b02621..e5b9746 100644 (file)
@@ -373,7 +373,7 @@ enum ParameterDefaultPolicy {
 
     inline String propertyNameToString(JSC::PropertyName propertyName)
     {
-        return propertyName.impl();
+        return propertyName.publicName();
     }
 
     inline AtomicString ustringToAtomicString(const JSC::UString& u)
@@ -383,7 +383,7 @@ enum ParameterDefaultPolicy {
 
     inline AtomicString propertyNameToAtomicString(JSC::PropertyName propertyName)
     {
-        return AtomicString(propertyName.impl());
+        return AtomicString(propertyName.publicName());
     }
 
     inline Vector<unsigned long> jsUnsignedLongArrayToVector(JSC::ExecState* exec, JSC::JSValue value)
index 03edadc..fb51767 100644 (file)
@@ -94,7 +94,7 @@ void JSDOMWindow::visitChildren(JSCell* cell, SlotVisitor& visitor)
 template<NativeFunction nativeFunction, int length>
 JSValue nonCachingStaticFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), length, propertyName.impl(), nativeFunction);
+    return JSFunction::create(exec, exec->lexicalGlobalObject(), length, propertyName.publicName(), nativeFunction);
 }
 
 static JSValue childFrameGetter(ExecState* exec, JSValue slotBase, PropertyName propertyName)
index 17695d5..703d1a1 100644 (file)
@@ -40,17 +40,17 @@ namespace WebCore {
 
 static JSValue nonCachingStaticBackFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName.impl(), jsHistoryPrototypeFunctionBack);
+    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName.publicName(), jsHistoryPrototypeFunctionBack);
 }
 
 static JSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName.impl(), jsHistoryPrototypeFunctionForward);
+    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName.publicName(), jsHistoryPrototypeFunctionForward);
 }
 
 static JSValue nonCachingStaticGoFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), 1, propertyName.impl(), jsHistoryPrototypeFunctionGo);
+    return JSFunction::create(exec, exec->lexicalGlobalObject(), 1, propertyName.publicName(), jsHistoryPrototypeFunctionGo);
 }
 
 bool JSHistory::getOwnPropertySlotDelegate(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
index af3f866..5cb0c07 100644 (file)
@@ -32,17 +32,17 @@ namespace WebCore {
 
 static JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), 1, propertyName.impl(), jsLocationPrototypeFunctionReplace);
+    return JSFunction::create(exec, exec->lexicalGlobalObject(), 1, propertyName.publicName(), jsLocationPrototypeFunctionReplace);
 }
 
 static JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName.impl(), jsLocationPrototypeFunctionReload);
+    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName.publicName(), jsLocationPrototypeFunctionReload);
 }
 
 static JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, JSValue, PropertyName propertyName)
 {
-    return JSFunction::create(exec, exec->lexicalGlobalObject(), 1, propertyName.impl(), jsLocationPrototypeFunctionAssign);
+    return JSFunction::create(exec, exec->lexicalGlobalObject(), 1, propertyName.publicName(), jsLocationPrototypeFunctionAssign);
 }
 
 bool JSLocation::getOwnPropertySlotDelegate(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
index 50073d1..efd7f4e 100644 (file)
@@ -73,9 +73,9 @@ CClass* CClass::classForIsA(NPClass* isa)
     return aClass;
 }
 
-MethodList CClass::methodsNamed(PropertyName identifier, Instance* instance) const
+MethodList CClass::methodsNamed(PropertyName propertyName, Instance* instance) const
 {
-    UString name(identifier.impl());
+    UString name(propertyName.publicName());
     
     MethodList methodList;
 
@@ -100,9 +100,9 @@ MethodList CClass::methodsNamed(PropertyName identifier, Instance* instance) con
     return methodList;
 }
 
-Field* CClass::fieldNamed(PropertyName identifier, Instance* instance) const
+Field* CClass::fieldNamed(PropertyName propertyName, Instance* instance) const
 {
-    UString name(identifier.impl());
+    UString name(propertyName.publicName());
     
     Field* aField = _fields.get(name.impl());
     if (aField)
index d21786a..fad386c 100644 (file)
@@ -149,7 +149,7 @@ const ClassInfo CRuntimeMethod::s_info = { "CRuntimeMethod", &RuntimeMethod::s_i
 JSValue CInstance::getMethod(ExecState* exec, PropertyName propertyName)
 {
     MethodList methodList = getClass()->methodsNamed(propertyName, this);
-    return CRuntimeMethod::create(exec, exec->lexicalGlobalObject(), propertyName.impl(), methodList);
+    return CRuntimeMethod::create(exec, exec->lexicalGlobalObject(), propertyName.publicName(), methodList);
 }
 
 JSValue CInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod)
index 6787a97..08ec6e6 100644 (file)
@@ -114,18 +114,18 @@ JavaClass::~JavaClass()
     m_methods.clear();
 }
 
-MethodList JavaClass::methodsNamed(PropertyName identifier, Instance*) const
+MethodList JavaClass::methodsNamed(PropertyName propertyName, Instance*) const
 {
-    MethodList* methodList = m_methods.get(identifier.ustring().impl());
+    MethodList* methodList = m_methods.get(propertyName.publicName());
 
     if (methodList)
         return *methodList;
     return MethodList();
 }
 
-Field* JavaClass::fieldNamed(PropertyName identifier, Instance*) const
+Field* JavaClass::fieldNamed(PropertyName propertyName, Instance*) const
 {
-    return m_fields.get(identifier.ustring().impl());
+    return m_fields.get(propertyName.publicName());
 }
 
 bool JavaClass::isNumberClass() const
index 255739e..7d2b02f 100644 (file)
@@ -153,7 +153,7 @@ const ClassInfo JavaRuntimeMethod::s_info = { "JavaRuntimeMethod", &RuntimeMetho
 JSValue JavaInstance::getMethod(ExecState* exec, PropertyName propertyName)
 {
     MethodList methodList = getClass()->methodsNamed(propertyName, this);
-    return JavaRuntimeMethod::create(exec, exec->lexicalGlobalObject(), propertyName.ustring(), methodList);
+    return JavaRuntimeMethod::create(exec, exec->lexicalGlobalObject(), propertyName.publicName(), methodList);
 }
 
 JSValue JavaInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod)
index 7080ee4..2d08704 100644 (file)
@@ -95,15 +95,19 @@ static inline void convertJSMethodNameToObjc(const CString& jsName, JSNameConver
     }
 }
 
-MethodList ObjcClass::methodsNamed(PropertyName identifier, Instance*) const
+MethodList ObjcClass::methodsNamed(PropertyName propertyName, Instance*) const
 {
+    UString name(propertyName.publicName());
+    if (name.isNull())
+        return MethodList();
+
     MethodList methodList;
-    if (Method* method = m_methodCache.get(identifier.impl())) {
+    if (Method* method = m_methodCache.get(name.impl())) {
         methodList.append(method);
         return methodList;
     }
 
-    CString jsName = identifier.ustring().ascii();
+    CString jsName = name.ascii();
     JSNameConversionBuffer buffer;
     convertJSMethodNameToObjc(jsName, buffer);
     RetainPtr<CFStringRef> methodName(AdoptCF, CFStringCreateWithCString(NULL, buffer.data(), kCFStringEncodingASCII));
@@ -132,7 +136,7 @@ MethodList ObjcClass::methodsNamed(PropertyName identifier, Instance*) const
             if ((mappedName && [mappedName isEqual:(NSString*)methodName.get()]) || strcmp(objcMethodSelectorName, buffer.data()) == 0) {
                 OwnPtr<Method> method = adoptPtr(new ObjcMethod(thisClass, objcMethodSelector));
                 methodList.append(method.get());
-                m_methodCache.add(identifier.impl(), method.release());
+                m_methodCache.add(name.impl(), method.release());
                 break;
             }
         }
@@ -143,15 +147,19 @@ MethodList ObjcClass::methodsNamed(PropertyName identifier, Instance*) const
     return methodList;
 }
 
-Field* ObjcClass::fieldNamed(PropertyName identifier, Instance* instance) const
+Field* ObjcClass::fieldNamed(PropertyName propertyName, Instance* instance) const
 {
-    Field* field = m_fieldCache.get(identifier.impl());
+    UString name(propertyName.publicName());
+    if (name.isNull())
+        return 0;
+
+    Field* field = m_fieldCache.get(name.impl());
     if (field)
         return field;
 
     ClassStructPtr thisClass = _isa;
 
-    CString jsName = identifier.ustring().ascii();
+    CString jsName = name.ascii();
     RetainPtr<CFStringRef> fieldName(AdoptCF, CFStringCreateWithCString(NULL, jsName.data(), kCFStringEncodingASCII));
     id targetObject = (static_cast<ObjcInstance*>(instance))->getObject();
     id attributes = [targetObject attributeKeys];
@@ -177,7 +185,7 @@ Field* ObjcClass::fieldNamed(PropertyName identifier, Instance* instance) const
             if ((mappedName && [mappedName isEqual:(NSString*)fieldName.get()]) || [keyName isEqual:(NSString*)fieldName.get()]) {
                 OwnPtr<Field> newField = adoptPtr(new ObjcField((CFStringRef)keyName));
                 field = newField.get();
-                m_fieldCache.add(identifier.impl(), newField.release());
+                m_fieldCache.add(name.impl(), newField.release());
                 break;
             }
         }
@@ -208,7 +216,7 @@ Field* ObjcClass::fieldNamed(PropertyName identifier, Instance* instance) const
                 if ((mappedName && [mappedName isEqual:(NSString*)fieldName.get()]) || strcmp(objcIvarName, jsName.data()) == 0) {
                     OwnPtr<Field> newField = adoptPtr(new ObjcField(objcIVar));
                     field = newField.get();
-                    m_fieldCache.add(identifier.impl(), newField.release());
+                    m_fieldCache.add(name.impl(), newField.release());
                     break;
                 }
             }
@@ -228,7 +236,7 @@ JSValue ObjcClass::fallbackObject(ExecState* exec, Instance* instance, PropertyN
     
     if (![targetObject respondsToSelector:@selector(invokeUndefinedMethodFromWebScript:withArguments:)])
         return jsUndefined();
-    return ObjcFallbackObjectImp::create(exec, exec->lexicalGlobalObject(), objcInstance, propertyName.impl());
+    return ObjcFallbackObjectImp::create(exec, exec->lexicalGlobalObject(), objcInstance, propertyName.publicName());
 }
 
 }
index cc0e689..88c359e 100644 (file)
@@ -218,7 +218,7 @@ const ClassInfo ObjCRuntimeMethod::s_info = { "ObjCRuntimeMethod", &RuntimeMetho
 JSValue ObjcInstance::getMethod(ExecState* exec, PropertyName propertyName)
 {
     MethodList methodList = getClass()->methodsNamed(propertyName, this);
-    return ObjCRuntimeMethod::create(exec, exec->lexicalGlobalObject(), propertyName.ustring(), methodList);
+    return ObjCRuntimeMethod::create(exec, exec->lexicalGlobalObject(), propertyName.publicName(), methodList);
 }
 
 JSValue ObjcInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod)
@@ -401,8 +401,12 @@ JSValue ObjcInstance::invokeDefaultMethod(ExecState* exec)
     return const_cast<JSValue&>(result);
 }
 
-bool ObjcInstance::setValueOfUndefinedField(ExecState* exec, PropertyName property, JSValue aValue)
+bool ObjcInstance::setValueOfUndefinedField(ExecState* exec, PropertyName propertyName, JSValue aValue)
 {
+    UString name(propertyName.publicName());
+    if (name.isNull())
+        return false;
+
     id targetObject = getObject();
     if (![targetObject respondsToSelector:@selector(setValue:forUndefinedKey:)])
         return false;
@@ -418,7 +422,7 @@ bool ObjcInstance::setValueOfUndefinedField(ExecState* exec, PropertyName proper
         ObjcValue objcValue = convertValueToObjcValue(exec, aValue, ObjcObjectType);
 
         @try {
-            [targetObject setValue:objcValue.objectValue forUndefinedKey:[NSString stringWithCString:property.ustring().ascii().data() encoding:NSASCIIStringEncoding]];
+            [targetObject setValue:objcValue.objectValue forUndefinedKey:[NSString stringWithCString:name.ascii().data() encoding:NSASCIIStringEncoding]];
         } @catch(NSException* localException) {
             // Do nothing.  Class did not override valueForUndefinedKey:.
         }
@@ -429,8 +433,12 @@ bool ObjcInstance::setValueOfUndefinedField(ExecState* exec, PropertyName proper
     return true;
 }
 
-JSValue ObjcInstance::getValueOfUndefinedField(ExecState* exec, PropertyName property) const
+JSValue ObjcInstance::getValueOfUndefinedField(ExecState* exec, PropertyName propertyName) const
 {
+    UString name(propertyName.publicName());
+    if (name.isNull())
+        return jsUndefined();
+
     JSValue result = jsUndefined();
     
     id targetObject = getObject();
@@ -444,7 +452,7 @@ JSValue ObjcInstance::getValueOfUndefinedField(ExecState* exec, PropertyName pro
         setGlobalException(nil);
     
         @try {
-            id objcValue = [targetObject valueForUndefinedKey:[NSString stringWithCString:property.ustring().ascii().data() encoding:NSASCIIStringEncoding]];
+            id objcValue = [targetObject valueForUndefinedKey:[NSString stringWithCString:name.ascii().data() encoding:NSASCIIStringEncoding]];
             result = convertObjcValueToValue(exec, &objcValue, ObjcObjectType, m_rootObject.get());
         } @catch(NSException* localException) {
             // Do nothing.  Class did not override valueForUndefinedKey:.
index d53d27c..105898e 100644 (file)
@@ -70,7 +70,7 @@ JSValue QtClass::fallbackObject(ExecState* exec, Instance* inst, PropertyName id
 {
     QtInstance* qtinst = static_cast<QtInstance*>(inst);
 
-    const UString& ustring = identifier.ustring();
+    UString ustring(identifier.publicName());
     const QByteArray name = QString(reinterpret_cast<const QChar*>(ustring.characters()), ustring.length()).toAscii();
 
     // First see if we have a cache hit
@@ -133,7 +133,7 @@ Field* QtClass::fieldNamed(PropertyName identifier, Instance* instance) const
     QtInstance* qtinst = static_cast<QtInstance*>(instance);
 
     QObject* obj = qtinst->getObject();
-    const UString& ustring = identifier.ustring();
+    UString ustring(identifier.publicName());
     const QString name(reinterpret_cast<const QChar*>(ustring.characters()), ustring.length());
     const QByteArray ascii = name.toAscii();
 
index 4222cc5..d498921 100644 (file)
@@ -253,7 +253,7 @@ JSValue QtInstance::getMethod(ExecState* exec, PropertyName propertyName)
     if (!getClass())
         return jsNull();
     MethodList methodList = m_class->methodsNamed(propertyName, this);
-    return RuntimeMethod::create(exec, exec->lexicalGlobalObject(), WebCore::deprecatedGetDOMStructure<RuntimeMethod>(exec), propertyName.ustring(), methodList);
+    return RuntimeMethod::create(exec, exec->lexicalGlobalObject(), WebCore::deprecatedGetDOMStructure<RuntimeMethod>(exec), propertyName.publicName(), methodList);
 }
 
 JSValue QtInstance::invokeMethod(ExecState*, RuntimeMethod*)
index ed9cea7..c00fb49 100644 (file)
@@ -242,7 +242,7 @@ Class* QtPixmapInstance::getClass() const
 JSValue QtPixmapInstance::getMethod(ExecState* exec, PropertyName propertyName)
 {
     MethodList methodList = getClass()->methodsNamed(propertyName, this);
-    return RuntimeMethod::create(exec, exec->lexicalGlobalObject(), WebCore::deprecatedGetDOMStructure<RuntimeMethod>(exec), propertyName.ustring(), methodList);
+    return RuntimeMethod::create(exec, exec->lexicalGlobalObject(), WebCore::deprecatedGetDOMStructure<RuntimeMethod>(exec), propertyName.publicName(), methodList);
 }
 
 JSValue QtPixmapInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod)
@@ -259,22 +259,24 @@ JSValue QtPixmapInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMe
 MethodList QtPixmapClass::methodsNamed(PropertyName identifier, Instance*) const
 {
     MethodList methods;
-    if (identifier.ustring() == QtPixmapToDataUrlMethod::name())
+    UString ustring(identifier.publicName());
+    if (ustring == QtPixmapToDataUrlMethod::name())
         methods.append(&qt_pixmap_metaData.toDataUrlMethod);
-    else if (identifier.ustring() == QtPixmapToImageDataMethod::name())
+    else if (ustring == QtPixmapToImageDataMethod::name())
         methods.append(&qt_pixmap_metaData.toImageDataMethod);
-    else if (identifier.ustring() == QtPixmapAssignToElementMethod::name())
+    else if (ustring == QtPixmapAssignToElementMethod::name())
         methods.append(&qt_pixmap_metaData.assignToElementMethod);
-    else if (identifier.ustring() == QtPixmapToStringMethod::name())
+    else if (ustring == QtPixmapToStringMethod::name())
         methods.append(&qt_pixmap_metaData.toStringMethod);
     return methods;
 }
 
 Field* QtPixmapClass::fieldNamed(PropertyName identifier, Instance*) const
 {
-    if (identifier.ustring() == QtPixmapWidthField::name())
+    UString ustring(identifier.publicName());
+    if (ustring == QtPixmapWidthField::name())
         return &qt_pixmap_metaData.widthField;
-    if (identifier.ustring() == QtPixmapHeightField::name())
+    if (ustring == QtPixmapHeightField::name())
         return &qt_pixmap_metaData.heightField;
     return 0;
 }
index 7bb5c02..adae7ad 100644 (file)
@@ -1521,7 +1521,7 @@ JSValue QtRuntimeMetaMethod::connectGetter(ExecState* exec, JSValue slotBase, Pr
     QW_DS(QtRuntimeMetaMethod, thisObj);
 
     if (!d->m_connect)
-        d->m_connect.set(exec->globalData(), thisObj, QtRuntimeConnectionMethod::create(exec, ident.impl(), true, d->m_instance, d->m_index, d->m_signature));
+        d->m_connect.set(exec->globalData(), thisObj, QtRuntimeConnectionMethod::create(exec, ident.publicName(), true, d->m_instance, d->m_index, d->m_signature));
     return d->m_connect.get();
 }
 
@@ -1531,7 +1531,7 @@ JSValue QtRuntimeMetaMethod::disconnectGetter(ExecState* exec, JSValue slotBase,
     QW_DS(QtRuntimeMetaMethod, thisObj);
 
     if (!d->m_disconnect)
-        d->m_disconnect.set(exec->globalData(), thisObj, QtRuntimeConnectionMethod::create(exec, ident.impl(), false, d->m_instance, d->m_index, d->m_signature));
+        d->m_disconnect.set(exec->globalData(), thisObj, QtRuntimeConnectionMethod::create(exec, ident.publicName(), false, d->m_instance, d->m_index, d->m_signature));
     return d->m_disconnect.get();
 }
 
index 6c11874..df45a21 100644 (file)
@@ -1530,7 +1530,7 @@ JSValue QtRuntimeMetaMethod::connectGetter(ExecState* exec, JSValue slotBase, Pr
     QW_DS(QtRuntimeMetaMethod, thisObj);
 
     if (!d->m_connect)
-        d->m_connect.set(exec->globalData(), thisObj, QtRuntimeConnectionMethod::create(exec, ident.ustring(), true, d->m_instance, d->m_index, d->m_signature));
+        d->m_connect.set(exec->globalData(), thisObj, QtRuntimeConnectionMethod::create(exec, ident.publicName(), true, d->m_instance, d->m_index, d->m_signature));
     return d->m_connect.get();
 }
 
@@ -1540,7 +1540,7 @@ JSValue QtRuntimeMetaMethod::disconnectGetter(ExecState* exec, JSValue slotBase,
     QW_DS(QtRuntimeMetaMethod, thisObj);
 
     if (!d->m_disconnect)
-        d->m_disconnect.set(exec->globalData(), thisObj, QtRuntimeConnectionMethod::create(exec, ident.ustring(), false, d->m_instance, d->m_index, d->m_signature));
+        d->m_disconnect.set(exec->globalData(), thisObj, QtRuntimeConnectionMethod::create(exec, ident.publicName(), false, d->m_instance, d->m_index, d->m_signature));
     return d->m_disconnect.get();
 }
 
index 7a54367..2c5c1f1 100644 (file)
@@ -1,3 +1,21 @@
+2012-05-15  Gavin Barraclough  <barraclough@apple.com>
+
+        Add support for private names
+        https://bugs.webkit.org/show_bug.cgi?id=86509
+
+        Reviewed by Oliver Hunt.
+
+        The spec isn't final, but we can start adding support to allow property maps
+        to contain keys that aren't identifiers.
+
+        * Plugins/Hosted/ProxyInstance.mm:
+        (WebKit::ProxyClass::methodsNamed):
+        (WebKit::ProxyClass::fieldNamed):
+        (WebKit::ProxyInstance::getMethod):
+        (WebKit::ProxyInstance::methodsNamed):
+        (WebKit::ProxyInstance::fieldNamed):
+            - Removed PropertyName::impl(), call publicName() to get the string associated with a name.
+
 2012-05-21  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
 
         Move setEditingBehavior() from layoutTestController to window.internals
index cfb2240..898c5e2 100644 (file)
@@ -54,14 +54,14 @@ private:
     virtual Field* fieldNamed(PropertyName, Instance*) const;
 };
 
-MethodList ProxyClass::methodsNamed(PropertyName identifier, Instance* instance) const
+MethodList ProxyClass::methodsNamed(PropertyName propertyName, Instance* instance) const
 {
-    return static_cast<ProxyInstance*>(instance)->methodsNamed(identifier);
+    return static_cast<ProxyInstance*>(instance)->methodsNamed(propertyName);
 }
 
-Field* ProxyClass::fieldNamed(PropertyName identifier, Instance* instance) const
+Field* ProxyClass::fieldNamed(PropertyName propertyName, Instance* instance) const
 {
-    return static_cast<ProxyInstance*>(instance)->fieldNamed(identifier);
+    return static_cast<ProxyInstance*>(instance)->fieldNamed(propertyName);
 }
 
 static ProxyClass* proxyClass()
@@ -216,7 +216,7 @@ const ClassInfo ProxyRuntimeMethod::s_info = { "ProxyRuntimeMethod", &RuntimeMet
 JSValue ProxyInstance::getMethod(JSC::ExecState* exec, PropertyName propertyName)
 {
     MethodList methodList = getClass()->methodsNamed(propertyName, this);
-    return ProxyRuntimeMethod::create(exec, exec->lexicalGlobalObject(), propertyName.impl(), methodList);
+    return ProxyRuntimeMethod::create(exec, exec->lexicalGlobalObject(), propertyName.publicName(), methodList);
 }
 
 JSValue ProxyInstance::invokeMethod(ExecState* exec, JSC::RuntimeMethod* runtimeMethod)
@@ -346,13 +346,17 @@ void ProxyInstance::getPropertyNames(ExecState* exec, PropertyNameArray& nameArr
     }
 }
 
-MethodList ProxyInstance::methodsNamed(PropertyName identifier)
+MethodList ProxyInstance::methodsNamed(PropertyName propertyName)
 {
+    UString name(propertyName.publicName());
+    if (name.isNull())
+        return MethodList();
+
     if (!m_instanceProxy)
         return MethodList();
     
     // If we already have an entry in the map, use it.
-    MethodMap::iterator existingMapEntry = m_methods.find(identifier.impl());
+    MethodMap::iterator existingMapEntry = m_methods.find(name.impl());
     if (existingMapEntry != m_methods.end()) {
         MethodList methodList;
         if (existingMapEntry->second)
@@ -360,7 +364,7 @@ MethodList ProxyInstance::methodsNamed(PropertyName identifier)
         return methodList;
     }
     
-    uint64_t methodName = reinterpret_cast<uint64_t>(_NPN_GetStringIdentifier(identifier.ustring().ascii().data()));
+    uint64_t methodName = reinterpret_cast<uint64_t>(_NPN_GetStringIdentifier(name.ascii().data()));
     uint32_t requestID = m_instanceProxy->nextRequestID();
     
     if (_WKPHNPObjectHasMethod(m_instanceProxy->hostProxy()->port(),
@@ -376,7 +380,7 @@ MethodList ProxyInstance::methodsNamed(PropertyName identifier)
         return MethodList();
 
     // Add a new entry to the map unless an entry was added while we were in waitForReply.
-    MethodMap::AddResult mapAddResult = m_methods.add(identifier.impl(), 0);
+    MethodMap::AddResult mapAddResult = m_methods.add(name.impl(), 0);
     if (mapAddResult.isNewEntry && reply->m_result)
         mapAddResult.iterator->second = new ProxyMethod(methodName);
 
@@ -386,22 +390,26 @@ MethodList ProxyInstance::methodsNamed(PropertyName identifier)
     return methodList;
 }
 
-Field* ProxyInstance::fieldNamed(PropertyName identifier)
+Field* ProxyInstance::fieldNamed(PropertyName propertyName)
 {
+    UString name(propertyName.publicName());
+    if (name.isNull())
+        return 0;
+
     if (!m_instanceProxy)
         return 0;
     
     // If we already have an entry in the map, use it.
-    FieldMap::iterator existingMapEntry = m_fields.find(identifier.impl());
+    FieldMap::iterator existingMapEntry = m_fields.find(name.impl());
     if (existingMapEntry != m_fields.end())
         return existingMapEntry->second;
     
-    uint64_t propertyName = reinterpret_cast<uint64_t>(_NPN_GetStringIdentifier(identifier.ustring().ascii().data()));
+    uint64_t identifier = reinterpret_cast<uint64_t>(_NPN_GetStringIdentifier(name.ascii().data()));
     uint32_t requestID = m_instanceProxy->nextRequestID();
     
     if (_WKPHNPObjectHasProperty(m_instanceProxy->hostProxy()->port(),
                                  m_instanceProxy->pluginID(), requestID,
-                                 m_objectID, propertyName) != KERN_SUCCESS)
+                                 m_objectID, identifier) != KERN_SUCCESS)
         return 0;
     
     auto_ptr<NetscapePluginInstanceProxy::BooleanReply> reply = waitForReply<NetscapePluginInstanceProxy::BooleanReply>(requestID);
@@ -412,9 +420,9 @@ Field* ProxyInstance::fieldNamed(PropertyName identifier)
         return 0;
     
     // Add a new entry to the map unless an entry was added while we were in waitForReply.
-    FieldMap::AddResult mapAddResult = m_fields.add(identifier.impl(), 0);
+    FieldMap::AddResult mapAddResult = m_fields.add(name.impl(), 0);
     if (mapAddResult.isNewEntry && reply->m_result)
-        mapAddResult.iterator->second = new ProxyField(propertyName);
+        mapAddResult.iterator->second = new ProxyField(identifier);
     return mapAddResult.iterator->second;
 }
 
index a928c78..9e2db1e 100644 (file)
@@ -1,3 +1,18 @@
+2012-05-15  Gavin Barraclough  <barraclough@apple.com>
+
+        Add support for private names
+        https://bugs.webkit.org/show_bug.cgi?id=86509
+
+        Reviewed by Oliver Hunt.
+
+        The spec isn't final, but we can start adding support to allow property maps
+        to contain keys that aren't identifiers.
+
+        * WebProcess/Plugins/Netscape/JSNPObject.cpp:
+        (WebKit::npIdentifierFromIdentifier):
+        (WebKit::JSNPObject::methodGetter):
+            - Removed PropertyName::impl(), call publicName() to get the string associated with a name.
+
 2012-05-21  Hugo Parente Lima  <hugo.lima@openbossa.org>
 
         [Qt][WK2] fast/forms/submit-to-blank-multiple-times.html fails
index 5c64527..d8c8746 100644 (file)
@@ -45,9 +45,12 @@ using namespace WebCore;
 
 namespace WebKit {
 
-static NPIdentifier npIdentifierFromIdentifier(PropertyName identifier)
+static NPIdentifier npIdentifierFromIdentifier(PropertyName propertyName)
 {
-    return static_cast<NPIdentifier>(IdentifierRep::get(identifier.ustring().utf8().data()));
+    UString name(propertyName.publicName());
+    if (name.isNull())
+        return 0;
+    return static_cast<NPIdentifier>(IdentifierRep::get(name.utf8().data()));
 }
 
 const ClassInfo JSNPObject::s_info = { "NPObject", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPObject) };
@@ -474,7 +477,7 @@ JSValue JSNPObject::propertyGetter(ExecState* exec, JSValue slotBase, PropertyNa
     return propertyValue;
 }
 
-JSValue JSNPObject::methodGetter(ExecState* exec, JSValue slotBase, PropertyName methodName)
+JSValue JSNPObject::methodGetter(ExecState* exec, JSValue slotBase, PropertyName propertyName)
 {
     JSNPObject* thisObj = static_cast<JSNPObject*>(asObject(slotBase));
     ASSERT_GC_OBJECT_INHERITS(thisObj, &s_info);
@@ -482,8 +485,8 @@ JSValue JSNPObject::methodGetter(ExecState* exec, JSValue slotBase, PropertyName
     if (!thisObj->m_npObject)
         return throwInvalidAccessError(exec);
 
-    NPIdentifier npIdentifier = npIdentifierFromIdentifier(methodName);
-    return JSNPMethod::create(exec, thisObj->globalObject(), methodName.ustring(), npIdentifier);
+    NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName);
+    return JSNPMethod::create(exec, thisObj->globalObject(), propertyName.publicName(), npIdentifier);
 }
 
 JSObject* JSNPObject::throwInvalidAccessError(ExecState* exec)