Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (201824 => 201825)
--- trunk/Source/_javascript_Core/ChangeLog 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-06-08 19:40:34 UTC (rev 201825)
@@ -1,3 +1,58 @@
+2016-06-08 Keith Miller <keith_mil...@apple.com>
+
+ We should be able to lookup symbols by identifier in builtins
+ https://bugs.webkit.org/show_bug.cgi?id=158530
+
+ Reviewed by Mark Lam.
+
+ This patch allows us to lookup the value of a symbol property on a
+ object by identifier in builtins. Before, it was only possible to
+ do so if we were directly emitting the bytecodes, such as in a
+ for-of loop looking for Symbol.iterator. As we tier up we convert
+ the builtin's get_by_val symbol lookups into get_by_id
+ lookups. However, there is still a significant performance
+ difference between get_by_id and get_by_val in the LLInt, where
+ this transformation does not take place.
+
+ In order to make this work we hijack BuiltinNames'
+ m_publicToPrivateMap so that it points the @<symbol>Symbol to the
+ appropriate vm symbol. This way when we lex the identifier it will
+ become the appropriate symbol's identifier. Currently, if the
+ symbol is used to name a property in an object literal we will not
+ keep a cache of the Symbol objects we have already seen. We could
+ add a map for symbols but since we can only load symbols by
+ identifier in builtins its likely not worth it. Additionally, even
+ in builtins it is extremely rare to use Symbols in object
+ literals.
+
+ * builtins/ArrayConstructor.js:
+ (from):
+ * builtins/ArrayPrototype.js:
+ (filter):
+ (map):
+ * builtins/BuiltinNames.h:
+ (JSC::BuiltinNames::BuiltinNames):
+ * builtins/BuiltinUtils.h:
+ * builtins/GlobalObject.js:
+ (speciesConstructor):
+ * builtins/StringPrototype.js:
+ (match):
+ (intrinsic.StringPrototypeReplaceIntrinsic.replace):
+ (search):
+ (split):
+ * builtins/TypedArrayConstructor.js:
+ (from):
+ * builtins/TypedArrayPrototype.js:
+ (map):
+ (filter):
+ * bytecode/BytecodeIntrinsicRegistry.cpp:
+ (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry): Deleted.
+ * bytecode/BytecodeIntrinsicRegistry.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitLoad):
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::parseInner):
+
2016-06-08 Rawinder Singh <rawinder.singh-web...@cisra.canon.com.au>
[web-animations] Add Animatable, AnimationEffect, KeyframeEffect and Animation interface
Modified: trunk/Source/_javascript_Core/builtins/ArrayConstructor.js (201824 => 201825)
--- trunk/Source/_javascript_Core/builtins/ArrayConstructor.js 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/builtins/ArrayConstructor.js 2016-06-08 19:40:34 UTC (rev 201825)
@@ -57,7 +57,7 @@
if (items == null)
throw new @TypeError("Array.from requires an array-like object - not null or undefined");
- var iteratorMethod = items[@symbolIterator];
+ var iteratorMethod = items.@iteratorSymbol;
if (iteratorMethod != null) {
if (typeof iteratorMethod !== "function")
throw new @TypeError("Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
@@ -71,11 +71,8 @@
// Since for-of loop once more looks up the @@iterator property of a given iterable,
// it could be observable if the user defines a getter for @@iterator.
// To avoid this situation, we define a wrapper object that @@iterator just returns a given iterator.
- var wrapper = {
- [@symbolIterator]() {
- return iterator;
- }
- };
+ var wrapper = {}
+ wrapper.@iteratorSymbol = function() { return iterator; };
for (var value of wrapper) {
if (mapFn)
Modified: trunk/Source/_javascript_Core/builtins/ArrayPrototype.js (201824 => 201825)
--- trunk/Source/_javascript_Core/builtins/ArrayPrototype.js 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/builtins/ArrayPrototype.js 2016-06-08 19:40:34 UTC (rev 201825)
@@ -226,7 +226,7 @@
if (@isArrayConstructor(constructor) && @Array !== constructor)
constructor = @undefined;
if (@isObject(constructor)) {
- constructor = constructor[@symbolSpecies];
+ constructor = constructor.@speciesSymbol;
if (constructor === null)
constructor = @undefined;
}
@@ -278,7 +278,7 @@
if (@isArrayConstructor(constructor) && @Array !== constructor)
constructor = @undefined;
if (@isObject(constructor)) {
- constructor = constructor[@symbolSpecies];
+ constructor = constructor.@speciesSymbol;
if (constructor === null)
constructor = @undefined;
}
Modified: trunk/Source/_javascript_Core/builtins/BuiltinNames.h (201824 => 201825)
--- trunk/Source/_javascript_Core/builtins/BuiltinNames.h 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/builtins/BuiltinNames.h 2016-06-08 19:40:34 UTC (rev 201825)
@@ -35,6 +35,11 @@
#define INITIALIZE_PRIVATE_TO_PUBLIC_ENTRY(name) m_privateToPublicMap.add(m_##name##PrivateName.impl(), &m_##name);
#define INITIALIZE_PUBLIC_TO_PRIVATE_ENTRY(name) m_publicToPrivateMap.add(m_##name.impl(), &m_##name##PrivateName);
+// We commandeer the publicToPrivateMap to allow us to convert private symbol names into the appropriate symbol.
+// e.g. @iteratorSymbol points to Symbol.iterator in this map rather than to a an actual private name.
+// FIXME: This is a weird hack and we shouldn't need to do this.
+#define INITIALIZE_SYMBOL_PUBLIC_TO_PRIVATE_ENTRY(name) m_publicToPrivateMap.add(m_##name##SymbolPrivateIdentifier.impl(), &m_##name##Symbol);
+
class BuiltinNames {
WTF_MAKE_NONCOPYABLE(BuiltinNames); WTF_MAKE_FAST_ALLOCATED;
@@ -54,6 +59,7 @@
JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PRIVATE_TO_PUBLIC_ENTRY)
JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALIZE_PUBLIC_TO_PRIVATE_ENTRY)
JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PUBLIC_TO_PRIVATE_ENTRY)
+ JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALIZE_SYMBOL_PUBLIC_TO_PRIVATE_ENTRY)
m_privateToPublicMap.add(m_dollarVMPrivateName.impl(), &m_dollarVMName);
m_publicToPrivateMap.add(m_dollarVMName.impl(), &m_dollarVMPrivateName);
}
Modified: trunk/Source/_javascript_Core/builtins/BuiltinUtils.h (201824 => 201825)
--- trunk/Source/_javascript_Core/builtins/BuiltinUtils.h 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/builtins/BuiltinUtils.h 2016-06-08 19:40:34 UTC (rev 201825)
@@ -37,8 +37,8 @@
const JSC::Identifier& name##PublicName() const { return m_##name; } \
const JSC::Identifier& name##PrivateName() const { return m_##name##PrivateName; }
-#define INITIALIZE_BUILTIN_SYMBOLS(name) , m_##name##Symbol(JSC::Identifier::fromUid(JSC::PrivateName(JSC::PrivateName::Description, ASCIILiteral("Symbol." #name))))
-#define DECLARE_BUILTIN_SYMBOLS(name) const JSC::Identifier m_##name##Symbol;
+#define INITIALIZE_BUILTIN_SYMBOLS(name) , m_##name##Symbol(JSC::Identifier::fromUid(JSC::PrivateName(JSC::PrivateName::Description, ASCIILiteral("Symbol." #name)))), m_##name##SymbolPrivateIdentifier(JSC::Identifier::fromString(vm, #name "Symbol"))
+#define DECLARE_BUILTIN_SYMBOLS(name) const JSC::Identifier m_##name##Symbol; const JSC::Identifier m_##name##SymbolPrivateIdentifier;
#define DECLARE_BUILTIN_SYMBOL_ACCESSOR(name) \
const JSC::Identifier& name##Symbol() const { return m_##name##Symbol; }
Modified: trunk/Source/_javascript_Core/builtins/GlobalObject.js (201824 => 201825)
--- trunk/Source/_javascript_Core/builtins/GlobalObject.js 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/builtins/GlobalObject.js 2016-06-08 19:40:34 UTC (rev 201825)
@@ -69,7 +69,7 @@
return defaultConstructor;
if (!@isObject(constructor))
throw new @TypeError("|this|.constructor is not an Object or undefined");
- constructor = constructor[@symbolSpecies];
+ constructor = constructor.@speciesSymbol;
if (constructor == null)
return defaultConstructor;
if (@isConstructor(constructor))
Modified: trunk/Source/_javascript_Core/builtins/StringPrototype.js (201824 => 201825)
--- trunk/Source/_javascript_Core/builtins/StringPrototype.js 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/builtins/StringPrototype.js 2016-06-08 19:40:34 UTC (rev 201825)
@@ -36,14 +36,14 @@
}
if (regexp != null) {
- var matcher = regexp[@symbolMatch];
+ var matcher = regexp.@matchSymbol;
if (matcher != @undefined)
return matcher.@call(regexp, this);
}
let thisString = @toString(this);
let createdRegExp = @regExpCreate(regexp, @undefined);
- return createdRegExp[@symbolMatch](thisString);
+ return createdRegExp.@matchSymbol(thisString);
}
function repeatSlowPath(string, count)
@@ -233,7 +233,7 @@
}
if (search != null) {
- let replacer = search[@symbolReplace];
+ let replacer = search.@replaceSymbol;
if (replacer !== @undefined) {
if (!@hasObservableSideEffectsForStringReplace(search, replacer))
return @toString(this).@replaceUsingRegExp(search, replace);
@@ -291,14 +291,14 @@
}
if (regexp != null) {
- var searcher = regexp[@symbolSearch];
+ var searcher = regexp.@searchSymbol;
if (searcher != @undefined)
return searcher.@call(regexp, this);
}
var thisString = @toString(this);
var createdRegExp = @regExpCreate(regexp, @undefined);
- return createdRegExp[@symbolSearch](thisString);
+ return createdRegExp.@searchSymbol(thisString);
}
function split(separator, limit)
@@ -312,7 +312,7 @@
}
if (separator != null) {
- var splitter = separator[@symbolSplit];
+ var splitter = separator.@splitSymbol;
if (splitter != @undefined)
return splitter.@call(separator, this, limit);
}
Modified: trunk/Source/_javascript_Core/builtins/TypedArrayConstructor.js (201824 => 201825)
--- trunk/Source/_javascript_Core/builtins/TypedArrayConstructor.js 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/builtins/TypedArrayConstructor.js 2016-06-08 19:40:34 UTC (rev 201825)
@@ -63,7 +63,7 @@
if (items == null)
throw new @TypeError("TypedArray.from requires an array-like object - not null or undefined");
- let iteratorMethod = items[@symbolIterator];
+ let iteratorMethod = items.@iteratorSymbol;
if (iteratorMethod != null) {
if (typeof iteratorMethod !== "function")
throw new @TypeError("TypedArray.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
@@ -76,13 +76,9 @@
// Since for-of loop once more looks up the @@iterator property of a given iterable,
// it could be observable if the user defines a getter for @@iterator.
// To avoid this situation, we define a wrapper object that @@iterator just returns a given iterator.
- let wrapper = {
- [@symbolIterator]() {
- return iterator;
- }
- };
+ let wrapper = {};
+ wrapper.@iteratorSymbol = function() { return iterator; }
-
for (let value of wrapper) {
if (mapFn)
@putByValDirect(accumulator, k, thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
Modified: trunk/Source/_javascript_Core/builtins/TypedArrayPrototype.js (201824 => 201825)
--- trunk/Source/_javascript_Core/builtins/TypedArrayPrototype.js 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/builtins/TypedArrayPrototype.js 2016-06-08 19:40:34 UTC (rev 201825)
@@ -261,7 +261,7 @@
if (constructor === @undefined)
result = new (@typedArrayGetOriginalConstructor(this))(length);
else {
- var speciesConstructor = @Object(constructor)[@symbolSpecies];
+ var speciesConstructor = @Object(constructor).@speciesSymbol;
if (speciesConstructor === null || speciesConstructor === @undefined)
result = new (@typedArrayGetOriginalConstructor(this))(length);
else {
@@ -302,7 +302,7 @@
if (constructor === @undefined)
result = new (@typedArrayGetOriginalConstructor(this))(resultLength);
else {
- var speciesConstructor = @Object(constructor)[@symbolSpecies];
+ var speciesConstructor = @Object(constructor).@speciesSymbol;
if (speciesConstructor === null || speciesConstructor === @undefined)
result = new (@typedArrayGetOriginalConstructor(this))(resultLength);
else {
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp (201824 => 201825)
--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp 2016-06-08 19:40:34 UTC (rev 201825)
@@ -54,12 +54,6 @@
m_promiseStatePending.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Pending)));
m_promiseStateFulfilled.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Fulfilled)));
m_promiseStateRejected.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Rejected)));
- m_symbolIterator.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->iteratorSymbol.impl())));
- m_symbolMatch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->matchSymbol.impl())));
- m_symbolReplace.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->replaceSymbol.impl())));
- m_symbolSearch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->searchSymbol.impl())));
- m_symbolSpecies.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->speciesSymbol.impl())));
- m_symbolSplit.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->splitSymbol.impl())));
m_GeneratorResumeModeNormal.set(m_vm, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode)));
m_GeneratorResumeModeThrow.set(m_vm, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::ThrowMode)));
m_GeneratorResumeModeReturn.set(m_vm, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::ReturnMode)));
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h (201824 => 201825)
--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h 2016-06-08 19:40:34 UTC (rev 201825)
@@ -57,12 +57,6 @@
macro(promiseStatePending) \
macro(promiseStateFulfilled) \
macro(promiseStateRejected) \
- macro(symbolIterator) \
- macro(symbolMatch) \
- macro(symbolReplace) \
- macro(symbolSearch) \
- macro(symbolSpecies) \
- macro(symbolSplit) \
macro(GeneratorResumeModeNormal) \
macro(GeneratorResumeModeThrow) \
macro(GeneratorResumeModeReturn) \
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (201824 => 201825)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2016-06-08 19:40:34 UTC (rev 201825)
@@ -1727,9 +1727,11 @@
RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
{
+ ASSERT(!identifier.isSymbol());
JSString*& stringInMap = m_stringMap.add(identifier.impl(), nullptr).iterator->value;
if (!stringInMap)
stringInMap = jsOwnedString(vm(), identifier.string());
+
return emitLoad(dst, JSValue(stringInMap));
}
Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (201824 => 201825)
--- trunk/Source/_javascript_Core/parser/Parser.cpp 2016-06-08 19:20:52 UTC (rev 201824)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp 2016-06-08 19:40:34 UTC (rev 201825)
@@ -321,9 +321,8 @@
if (m_parsingBuiltin && isProgramParseMode(parseMode)) {
VariableEnvironment& lexicalVariables = scope->lexicalVariables();
const HashSet<UniquedStringImpl*>& closedVariableCandidates = scope->closedVariableCandidates();
- const BuiltinNames& builtinNames = m_vm->propertyNames->builtinNames();
for (UniquedStringImpl* candidate : closedVariableCandidates) {
- if (!lexicalVariables.contains(candidate) && !varDeclarations.contains(candidate) && !builtinNames.isPrivateName(*candidate)) {
+ if (!lexicalVariables.contains(candidate) && !varDeclarations.contains(candidate) && !candidate->isSymbol()) {
dataLog("Bad global capture in builtin: '", candidate, "'\n");
dataLog(m_source->view());
CRASH();