Make it possible to implement JS builtins in JS
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jan 2014 21:34:38 +0000 (21:34 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jan 2014 21:34:38 +0000 (21:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=127887

Reviewed by Michael Saboff.

.:

CMake updates

* Source/cmake/gtest/CMakeLists.txt:

Source/JavaScriptCore:

This patch makes it possible to write builtin functions in JS.
The bindings, generators, and definitions are all created automatically
based on js files in the builtins/ directory.  This patch includes one
such case: Array.prototype.js with an implementation of every().

There's a lot of refactoring to make it possible for CommonIdentifiers
to include the output of the generated files (DerivedSources/JSCBuiltins.{h,cpp})
without breaking the offset extractor. The result of this refactoring
is that CommonIdentifiers, and a few other miscellaneous headers now
need to be included directly as they were formerly captured through other
paths.

In addition this adds a flag to the Lookup table's hashentry to indicate
that a static function is actually backed by JS. There is then a lot of
logic to thread the special nature of the functon to where it matters.
This allows toString(), .caller, etc to mimic the behaviour of a host
function.

Notes on writing builtins:
 - Each function is compiled independently of the others, and those
   implementations cannot currently capture all global properties (as
   that could be potentially unsafe). If a function does capture a
   global we will deliberately crash.
 - For those "global" properties that we do want access to, we use
   the @ prefix, e.g. Object(this) becomes @Object(this). The @ identifiers
   are private names, and behave just like regular properties, only
   without the risk of adulteration. Again, in the @Object case, we
   explicitly duplicate the ObjectConstructor reference on the GlobalObject
   so that we have guaranteed access to the original version of the
   constructor.
 - call, apply, eval, and Function are all rejected identifiers, again
   to prevent anything from accidentally using an adulterated object.
   Instead @call and @apply are available, and happily they completely
   drop the neq_ptr instruction as they're defined as always being the
   original call/apply functions.

These restrictions are just intended to make it harder to accidentally
make changes that are incorrect (for instance calling whatever has been
assigned to global.Object, instead of the original constructor function).
However, making a mistake like this should result in a purely semantic
error as fundamentally these functions are treated as though they were
regular JS code in the host global, and have no more privileges than
any other JS.

The initial proof of concept is Array.prototype.every, this shows a 65%
performance improvement, and that improvement is significantly hurt by
our poor optimisation of op_in.

As this is such a limited function, we have not yet exported all symbols
that we could possibly need, but as we implement more, the likelihood
of encountering missing features will reduce.

This did require breaking out a JSStringInlines header, and required
fixing a few objects that were trying to using PropertyName::publicName
rather than PropertyName::uid.

* API/JSCallbackObjectFunctions.h:
(JSC::JSCallbackObject<Parent>::getOwnPropertySlot):
(JSC::JSCallbackObject<Parent>::put):
(JSC::JSCallbackObject<Parent>::deleteProperty):
(JSC::JSCallbackObject<Parent>::getStaticValue):
(JSC::JSCallbackObject<Parent>::staticFunctionGetter):
(JSC::JSCallbackObject<Parent>::callbackGetter):
* CMakeLists.txt:
* DerivedSources.make:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* builtins/Array.prototype.js:
(every):
* builtins/BuiltinExecutables.cpp: Added.
(JSC::BuiltinExecutables::BuiltinExecutables):
(JSC::BuiltinExecutables::createBuiltinExecutable):
* builtins/BuiltinExecutables.h:
(JSC::BuiltinExecutables::create):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
* bytecode/CodeBlock.h:
* bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp:
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::generateFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::UnlinkedFunctionExecutable::codeBlockFor):
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h:
(JSC::ExecutableInfo::ExecutableInfo):
(JSC::UnlinkedFunctionExecutable::create):
(JSC::UnlinkedFunctionExecutable::toStrictness):
(JSC::UnlinkedFunctionExecutable::isBuiltinFunction):
(JSC::UnlinkedCodeBlock::isBuiltinFunction):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::isBuiltinFunction):
(JSC::BytecodeGenerator::makeFunction):
* bytecompiler/NodesCodegen.cpp:
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):
* create_hash_table:
* dfg/DFGOperations.cpp:
* generate-js-builtins: Added.
(getCopyright):
(getFunctions):
(generateCode):
(mangleName):
(FunctionExecutable):
(Identifier):
(JSGlobalObject):
(SourceCode):
(UnlinkedFunctionExecutable):
(VM):
* interpreter/Interpreter.cpp:
* interpreter/ProtoCallFrame.cpp:
* jit/JITOpcodes.cpp:
* jit/JITOpcodes32_64.cpp:
* jit/JITOperations.cpp:
* jit/JITPropertyAccess.cpp:
* jit/JITPropertyAccess32_64.cpp:
* jsc.cpp:
* llint/LLIntSlowPaths.cpp:
* parser/ASTBuilder.h:
(JSC::ASTBuilder::makeFunctionCallNode):
* parser/Lexer.cpp:
(JSC::Lexer<T>::Lexer):
(JSC::isSafeIdentifier):
(JSC::Lexer<LChar>::parseIdentifier):
(JSC::Lexer<UChar>::parseIdentifier):
(JSC::Lexer<T>::lex):
* parser/Lexer.h:
(JSC::isSafeIdentifier):
(JSC::Lexer<T>::lexExpectIdentifier):
* parser/Nodes.cpp:
(JSC::ProgramNode::setClosedVariables):
* parser/Nodes.h:
(JSC::ScopeNode::capturedVariables):
(JSC::ScopeNode::setClosedVariables):
(JSC::ProgramNode::closedVariables):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::Parser):
(JSC::Parser<LexerType>::parseInner):
(JSC::Parser<LexerType>::didFinishParsing):
(JSC::Parser<LexerType>::printUnexpectedTokenText):
* parser/Parser.h:
(JSC::Scope::getUsedVariables):
(JSC::Parser::closedVariables):
(JSC::parse):
* parser/ParserModes.h:
* parser/ParserTokens.h:
* runtime/ArgList.cpp:
* runtime/Arguments.cpp:
* runtime/Arguments.h:
* runtime/ArgumentsIteratorConstructor.cpp:
* runtime/ArgumentsIteratorPrototype.cpp:
* runtime/ArrayPrototype.cpp:
* runtime/CodeCache.cpp:
(JSC::CodeCache::getFunctionExecutableFromGlobalCode):
* runtime/CommonIdentifiers.cpp:
(JSC::CommonIdentifiers::CommonIdentifiers):
(JSC::CommonIdentifiers::getPrivateName):
(JSC::CommonIdentifiers::getPublicName):
* runtime/CommonIdentifiers.h:
* runtime/CommonSlowPaths.cpp:
* runtime/CommonSlowPathsExceptions.cpp:
* runtime/ExceptionHelpers.cpp:
(JSC::createUndefinedVariableError):
* runtime/Executable.h:
(JSC::EvalExecutable::executableInfo):
(JSC::ProgramExecutable::executableInfo):
(JSC::FunctionExecutable::isBuiltinFunction):
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncToString):
* runtime/JSActivation.cpp:
(JSC::JSActivation::symbolTableGet):
(JSC::JSActivation::symbolTablePut):
(JSC::JSActivation::symbolTablePutWithAttributes):
* runtime/JSArgumentsIterator.cpp:
* runtime/JSArray.cpp:
* runtime/JSArrayIterator.cpp:
* runtime/JSCJSValue.cpp:
* runtime/JSCellInlines.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::createBuiltinFunction):
(JSC::JSFunction::calculatedDisplayName):
(JSC::JSFunction::sourceCode):
(JSC::JSFunction::isHostOrBuiltinFunction):
(JSC::JSFunction::isBuiltinFunction):
(JSC::JSFunction::callerGetter):
(JSC::JSFunction::getOwnPropertySlot):
(JSC::JSFunction::getOwnNonIndexPropertyNames):
(JSC::JSFunction::put):
(JSC::JSFunction::defineOwnProperty):
* runtime/JSFunction.h:
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
* runtime/JSGenericTypedArrayViewInlines.h:
* runtime/JSGenericTypedArrayViewPrototypeInlines.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::reset):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::objectConstructor):
(JSC::JSGlobalObject::symbolTableHasProperty):
* runtime/JSObject.cpp:
(JSC::getClassPropertyNames):
(JSC::JSObject::reifyStaticFunctionsForDelete):
(JSC::JSObject::putDirectBuiltinFunction):
* runtime/JSObject.h:
* runtime/JSPropertyNameIterator.cpp:
* runtime/JSPropertyNameIterator.h:
* runtime/JSString.h:
* runtime/JSStringInlines.h: Added.
(JSC::JSString::getStringPropertySlot):
(JSC::inlineJSValueNotStringtoString):
(JSC::JSValue::toWTFStringInline):
* runtime/JSSymbolTableObject.cpp:
(JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
   Don't report private names.
* runtime/JSSymbolTableObject.h:
(JSC::symbolTableGet):
(JSC::symbolTablePut):
(JSC::symbolTablePutWithAttributes):
* runtime/Lookup.cpp:
(JSC::setUpStaticFunctionSlot):
* runtime/Lookup.h:
(JSC::HashEntry::builtinGenerator):
(JSC::HashEntry::propertyGetter):
(JSC::HashEntry::propertyPutter):
(JSC::HashTable::entry):
(JSC::getStaticPropertySlot):
(JSC::getStaticValueSlot):
(JSC::putEntry):
* runtime/NativeErrorConstructor.cpp:
(JSC::NativeErrorConstructor::finishCreation):
* runtime/NativeErrorConstructor.h:
* runtime/PropertySlot.h:
* runtime/RegExpPrototype.cpp:
* runtime/SetConstructor.cpp:
* runtime/StringObject.cpp:
* runtime/Structure.cpp:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
(JSC::VM::builtinExecutables):

Source/WebCore:

Updating for the newly required headers.

Test: js/regress/array-prototype-every.html

* ForwardingHeaders/runtime/JSStringInlines.h: Added.
* Modules/plugins/QuickTimePluginReplacement.cpp:
* bindings/js/JSIDBAnyCustom.cpp:
* bindings/js/JSIDBDatabaseCustom.cpp:
* bindings/js/JSIDBObjectStoreCustom.cpp:

Source/WebKit:

CMake updates

* CMakeLists.txt:

Source/WebKit2:

CMake updates

* CMakeLists.txt:

Tools:

CMake updates

* DumpRenderTree/CMakeLists.txt:
* WebKitTestRunner/CMakeLists.txt:
* WinCELauncher/CMakeLists.txt:

LayoutTests:

Updated the test results for new error messages (now that they're
actually helpful), and added a js-regress test to track performance.

* js/array-every-expected.txt:
* js/dom/array-prototype-properties-expected.txt:
* js/regress/array-prototype-every-expected.txt: Added.
* js/regress/array-prototype-every.html: Added.
* js/regress/script-tests/array-prototype-every.js: Added.
(test1):
(test2):
(test3):

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

120 files changed:
ChangeLog
GNUmakefile.am
LayoutTests/ChangeLog
LayoutTests/js/array-every-expected.txt
LayoutTests/js/dom/array-prototype-properties-expected.txt
LayoutTests/js/regress/array-prototype-every-expected.txt [new file with mode: 0644]
LayoutTests/js/regress/array-prototype-every.html [new file with mode: 0644]
LayoutTests/js/regress/script-tests/array-prototype-every.js [new file with mode: 0644]
Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/DerivedSources.make
Source/JavaScriptCore/GNUmakefile.am
Source/JavaScriptCore/GNUmakefile.list.am
Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCommon.props
Source/JavaScriptCore/JavaScriptCore.vcxproj/copy-files.cmd
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/builtins/Array.prototype.js [new file with mode: 0644]
Source/JavaScriptCore/builtins/BuiltinExecutables.cpp [new file with mode: 0644]
Source/JavaScriptCore/builtins/BuiltinExecutables.h [new file with mode: 0644]
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
Source/JavaScriptCore/create_hash_table
Source/JavaScriptCore/dfg/DFGDominators.cpp
Source/JavaScriptCore/dfg/DFGJITCode.cpp
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/generate-js-builtins [new file with mode: 0644]
Source/JavaScriptCore/interpreter/CachedCall.h
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/interpreter/ProtoCallFrame.cpp
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/jit/JITPropertyAccess.cpp
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/parser/ASTBuilder.h
Source/JavaScriptCore/parser/Lexer.cpp
Source/JavaScriptCore/parser/Lexer.h
Source/JavaScriptCore/parser/Nodes.cpp
Source/JavaScriptCore/parser/Nodes.h
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/Parser.h
Source/JavaScriptCore/parser/ParserModes.h
Source/JavaScriptCore/parser/ParserTokens.h
Source/JavaScriptCore/runtime/Arguments.h
Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.cpp
Source/JavaScriptCore/runtime/ArrayPrototype.cpp
Source/JavaScriptCore/runtime/CodeCache.cpp
Source/JavaScriptCore/runtime/CommonIdentifiers.cpp
Source/JavaScriptCore/runtime/CommonIdentifiers.h
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/CommonSlowPathsExceptions.cpp
Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
Source/JavaScriptCore/runtime/Executable.h
Source/JavaScriptCore/runtime/FunctionPrototype.cpp
Source/JavaScriptCore/runtime/JSActivation.cpp
Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp
Source/JavaScriptCore/runtime/JSArray.cpp
Source/JavaScriptCore/runtime/JSArrayIterator.cpp
Source/JavaScriptCore/runtime/JSCJSValue.cpp
Source/JavaScriptCore/runtime/JSCellInlines.h
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSFunction.h
Source/JavaScriptCore/runtime/JSFunctionInlines.h
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeInlines.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp
Source/JavaScriptCore/runtime/JSPromiseDeferred.cpp
Source/JavaScriptCore/runtime/JSPromisePrototype.cpp
Source/JavaScriptCore/runtime/JSPromiseReaction.h
Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
Source/JavaScriptCore/runtime/JSString.h
Source/JavaScriptCore/runtime/JSStringInlines.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp
Source/JavaScriptCore/runtime/JSSymbolTableObject.h
Source/JavaScriptCore/runtime/Lookup.cpp
Source/JavaScriptCore/runtime/Lookup.h
Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
Source/JavaScriptCore/runtime/NativeErrorConstructor.h
Source/JavaScriptCore/runtime/PropertySlot.h
Source/JavaScriptCore/runtime/RegExpConstructor.cpp
Source/JavaScriptCore/runtime/RegExpPrototype.cpp
Source/JavaScriptCore/runtime/SetConstructor.cpp
Source/JavaScriptCore/runtime/StringObject.cpp
Source/JavaScriptCore/runtime/Structure.cpp
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/ForwardingHeaders/runtime/JSStringInlines.h [new file with mode: 0644]
Source/WebCore/Modules/plugins/QuickTimePluginReplacement.cpp
Source/WebCore/bindings/js/JSIDBAnyCustom.cpp
Source/WebCore/bindings/js/JSIDBDatabaseCustom.cpp
Source/WebCore/bindings/js/JSIDBObjectStoreCustom.cpp
Source/WebCore/bindings/js/JSNodeFilterCondition.cpp
Source/WebKit/CMakeLists.txt
Source/WebKit/ChangeLog
Source/WebKit2/CMakeLists.txt
Source/WebKit2/ChangeLog
Source/cmake/gtest/CMakeLists.txt
Tools/ChangeLog
Tools/DumpRenderTree/CMakeLists.txt
Tools/WebKitTestRunner/CMakeLists.txt
Tools/WinCELauncher/CMakeLists.txt

index db281c8..63236c0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2014-01-29  Oliver Hunt  <oliver@apple.com>
+
+        Make it possible to implement JS builtins in JS
+        https://bugs.webkit.org/show_bug.cgi?id=127887
+
+        Reviewed by Michael Saboff.
+
+        CMake updates
+
+        * Source/cmake/gtest/CMakeLists.txt:
+
 2014-01-30  Martin Robinson  <mrobinson@igalia.com>
 
         [GTK] [CMake] Add support for building against GTK+ 2
index 73fc492..08c9115 100644 (file)
@@ -68,6 +68,7 @@ ALL_MOFILES :=
 dom_binding_idls :=
 wtf_sources :=
 javascriptcore_h_api :=
+javascriptcore_builtins_js_nosources :=
 javascriptcore_cppflags:=
 javascriptcore_cflags :=
 javascriptcore_sources :=
index bb4f527..55bbe2b 100644 (file)
@@ -1,3 +1,22 @@
+2014-01-29  Oliver Hunt  <oliver@apple.com>
+
+        Make it possible to implement JS builtins in JS
+        https://bugs.webkit.org/show_bug.cgi?id=127887
+
+        Reviewed by Michael Saboff.
+
+        Updated the test results for new error messages (now that they're
+        actually helpful), and added a js-regress test to track performance.
+
+        * js/array-every-expected.txt:
+        * js/dom/array-prototype-properties-expected.txt:
+        * js/regress/array-prototype-every-expected.txt: Added.
+        * js/regress/array-prototype-every.html: Added.
+        * js/regress/script-tests/array-prototype-every.js: Added.
+        (test1):
+        (test2):
+        (test3):
+
 2014-01-30  Beth Dakin  <bdakin@apple.com>
 
         Extended background should only create margin tiles for pages with background 
index 541b8c3..cca363d 100644 (file)
@@ -30,12 +30,12 @@ PASS [12, 5, 8, 130, 44].every(isBigEnoughAndException) threw exception exceptio
 PASS [12, 54, 18, 130, 44].every(isBigEnoughAndException) threw exception exception from function.
 
 5.0 Wrong Type for Callback Test
-PASS [12, 5, 8, 130, 44].every(5) threw exception TypeError: Type error.
-PASS [12, 5, 8, 130, 44].every('wrong') threw exception TypeError: Type error.
-PASS [12, 5, 8, 130, 44].every(new Object()) threw exception TypeError: Type error.
-PASS [12, 5, 8, 130, 44].every(null) threw exception TypeError: Type error.
-PASS [12, 5, 8, 130, 44].every(undefined) threw exception TypeError: Type error.
-PASS [12, 5, 8, 130, 44].every() threw exception TypeError: Type error.
+PASS [12, 5, 8, 130, 44].every(5) threw exception TypeError: Array.prototype.every callback must be a function.
+PASS [12, 5, 8, 130, 44].every('wrong') threw exception TypeError: Array.prototype.every callback must be a function.
+PASS [12, 5, 8, 130, 44].every(new Object()) threw exception TypeError: Array.prototype.every callback must be a function.
+PASS [12, 5, 8, 130, 44].every(null) threw exception TypeError: Array.prototype.every callback must be a function.
+PASS [12, 5, 8, 130, 44].every(undefined) threw exception TypeError: Array.prototype.every callback must be a function.
+PASS [12, 5, 8, 130, 44].every() threw exception TypeError: Array.prototype.every callback must be a function.
 
 6.0 Early Exit ("Short Circuiting")
 PASS [12, 5, 8, 130, 44].every(isBigEnoughShortCircuit) is false
index 2c2a68c..5d9ecb7 100644 (file)
@@ -15,7 +15,7 @@ PASS Array.prototype.slice.call(undefined, 0, 1) threw exception TypeError: unde
 PASS Array.prototype.sort.call(undefined) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.sort.call(undefined)').
 PASS Array.prototype.splice.call(undefined, 0, 1) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.splice.call(undefined, 0, 1)').
 PASS Array.prototype.unshift.call(undefined, {}) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.unshift.call(undefined, {})').
-PASS Array.prototype.every.call(undefined, toString) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.every.call(undefined, toString)').
+PASS Array.prototype.every.call(undefined, toString) threw exception TypeError: Array.prototype.every requires that |this| not be undefined.
 PASS Array.prototype.forEach.call(undefined, toString) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.forEach.call(undefined, toString)').
 PASS Array.prototype.some.call(undefined, toString) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.some.call(undefined, toString)').
 PASS Array.prototype.indexOf.call(undefined, 0) threw exception TypeError: undefined is not an object (evaluating 'Array.prototype.indexOf.call(undefined, 0)').
diff --git a/LayoutTests/js/regress/array-prototype-every-expected.txt b/LayoutTests/js/regress/array-prototype-every-expected.txt
new file mode 100644 (file)
index 0000000..1290c0e
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/array-prototype-every
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/regress/array-prototype-every.html b/LayoutTests/js/regress/array-prototype-every.html
new file mode 100644 (file)
index 0000000..6e5cc17
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="resources/regress-pre.js"></script>
+<script src="script-tests/array-prototype-every.js"></script>
+<script src="resources/regress-post.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/js/regress/script-tests/array-prototype-every.js b/LayoutTests/js/regress/script-tests/array-prototype-every.js
new file mode 100644 (file)
index 0000000..294aa16
--- /dev/null
@@ -0,0 +1,29 @@
+var result = 0;
+function test1(a) {
+    result << 1;
+    result++;
+    return true;
+}
+function test2(a,b) {
+    result ^= 3;
+    result *= 3;
+    return true;
+}
+function test3(a,b,c) {
+    result ^= result >> 1;
+    return true;
+}
+
+var result = 0;
+var array = []
+for (var i = 0; i < 100000; ++i)
+    array[i] = 1;
+
+for (var i = 0; i < 10; i++) {
+    array.every(test1);
+    array.every(test2);
+    array.every(test3);
+}
+
+if (result != 1428810496)
+    throw "Error: bad result: " + result;
index 5be053f..0eced51 100644 (file)
@@ -136,7 +136,7 @@ bool JSCallbackObject<Parent>::getOwnPropertySlot(JSObject* object, ExecState* e
     JSObjectRef thisRef = toRef(thisObject);
     RefPtr<OpaqueJSString> propertyNameRef;
     
-    if (StringImpl* name = propertyName.publicName()) {
+    if (StringImpl* name = propertyName.uid()) {
         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) {
@@ -228,7 +228,7 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
     RefPtr<OpaqueJSString> propertyNameRef;
     JSValueRef valueRef = toRef(exec, value);
     
-    if (StringImpl* name = propertyName.publicName()) {
+    if (StringImpl* name = propertyName.uid()) {
         for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
             if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
                 if (!propertyNameRef)
@@ -343,7 +343,7 @@ bool JSCallbackObject<Parent>::deleteProperty(JSCell* cell, ExecState* exec, Pro
     JSObjectRef thisRef = toRef(thisObject);
     RefPtr<OpaqueJSString> propertyNameRef;
     
-    if (StringImpl* name = propertyName.publicName()) {
+    if (StringImpl* name = propertyName.uid()) {
         for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
             if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
                 if (!propertyNameRef)
@@ -564,7 +564,7 @@ JSValue JSCallbackObject<Parent>::getStaticValue(ExecState* exec, PropertyName p
 {
     JSObjectRef thisRef = toRef(this);
     
-    if (StringImpl* name = propertyName.publicName()) {
+    if (StringImpl* name = propertyName.uid()) {
         for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
             if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
                 if (StaticValueEntry* entry = staticValues->get(name)) {
@@ -600,7 +600,7 @@ EncodedJSValue JSCallbackObject<Parent>::staticFunctionGetter(ExecState* exec, E
     if (Parent::getOwnPropertySlot(thisObj, exec, propertyName, slot2))
         return JSValue::encode(slot2.getValue(exec, propertyName));
 
-    if (StringImpl* name = propertyName.publicName()) {
+    if (StringImpl* name = propertyName.uid()) {
         for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
             if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
                 if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
@@ -626,7 +626,7 @@ EncodedJSValue JSCallbackObject<Parent>::callbackGetter(ExecState* exec, Encoded
     JSObjectRef thisRef = toRef(thisObj);
     RefPtr<OpaqueJSString> propertyNameRef;
     
-    if (StringImpl* name = propertyName.publicName()) {
+    if (StringImpl* name = propertyName.uid()) {
         for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
             if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
                 if (!propertyNameRef)
index 27bc4c1..b43e05c 100644 (file)
@@ -5,6 +5,7 @@ set(JavaScriptCore_INCLUDE_DIRECTORIES
     "${JAVASCRIPTCORE_DIR}/ForwardingHeaders"
     "${JAVASCRIPTCORE_DIR}/assembler"
     "${JAVASCRIPTCORE_DIR}/bindings"
+    "${JAVASCRIPTCORE_DIR}/builtins"
     "${JAVASCRIPTCORE_DIR}/bytecode"
     "${JAVASCRIPTCORE_DIR}/bytecompiler"
     "${JAVASCRIPTCORE_DIR}/dfg"
@@ -52,6 +53,8 @@ set(JavaScriptCore_SOURCES
     bindings/ScriptObject.cpp
     bindings/ScriptValue.cpp
 
+    builtins/BuiltinExecutables.cpp
+
     bytecode/ArrayAllocationProfile.cpp
     bytecode/ArrayProfile.cpp
     bytecode/BytecodeBasicBlock.cpp
@@ -707,7 +710,7 @@ set(HASH_LUT_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/create_hash_table)
 macro(GENERATE_HASH_LUT _input _output)
     add_custom_command(
         OUTPUT ${_output}
-        DEPENDS ${HASH_LUT_GENERATOR} ${_input}
+        DEPENDS ${HASH_LUT_GENERATOR} ${_input} ${CMAKE_CURRENT_SOURCE_DIR}/generate-js-builtins
         COMMAND ${PERL_EXECUTABLE} ${HASH_LUT_GENERATOR} ${_input} -i > ${_output}
         VERBATIM)
     list(APPEND JavaScriptCore_HEADERS ${_output})
@@ -736,6 +739,7 @@ set(JavaScriptCore_FORWARDING_HEADERS_DIRECTORIES
     yarr
 
     collector/handles
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}
 )
 
 set(JavaScriptCore_FORWARDING_HEADERS_FILES
@@ -763,8 +767,11 @@ set(JavaScriptCore_FORWARDING_HEADERS_FILES
     assembler/LinkBuffer.h
     assembler/MacroAssembler.h
     assembler/MacroAssemblerCodeRef.h
+    assembler/MacroAssemblerCodeRef.h
     jit/GPRInfo.h
     runtime/VM.h
+
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.h
 )
 
 
@@ -815,16 +822,27 @@ add_custom_command(
     COMMAND ${PYTHON_EXECUTABLE} ${JavaScriptCore_INSPECTOR_SCRIPTS_DIR}/CodeGeneratorInspector.py ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJS.json --output_h_dir "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}" --output_cpp_dir "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}" --output_js_dir "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}" --output_type JavaScript --write_always && mkdir -p ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector && cp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSBackendDispatchers.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSFrontendDispatchers.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSTypeBuilders.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector
     VERBATIM)
 
+# JSCBuiltins
+file(GLOB JSCBuiltins_js_files "${CMAKE_CURRENT_SOURCE_DIR}/builtins/*.js")
+add_custom_command(
+   OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.h
+   MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/generate-js-builtins
+   DEPENDS ${JSCBuiltins_js_files}
+   COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generate-js-builtins ${JSCBuiltins_js_files} ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.cpp
+   VERBATIM)
+
 list(APPEND JavaScriptCore_SOURCES
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSBackendDispatchers.cpp
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSFrontendDispatchers.cpp
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSTypeBuilders.cpp
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.cpp
 )
 
 list(APPEND JavaScriptCore_HEADERS
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSBackendDispatchers.h
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSFrontendDispatchers.h
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InspectorJSTypeBuilders.h
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSCBuiltins.h
 )
 
 add_custom_command(
index 0c75270..e197402 100644 (file)
@@ -1,3 +1,254 @@
+2014-01-29  Oliver Hunt  <oliver@apple.com>
+
+        Make it possible to implement JS builtins in JS
+        https://bugs.webkit.org/show_bug.cgi?id=127887
+
+        Reviewed by Michael Saboff.
+
+        This patch makes it possible to write builtin functions in JS.
+        The bindings, generators, and definitions are all created automatically
+        based on js files in the builtins/ directory.  This patch includes one
+        such case: Array.prototype.js with an implementation of every().
+
+        There's a lot of refactoring to make it possible for CommonIdentifiers
+        to include the output of the generated files (DerivedSources/JSCBuiltins.{h,cpp})
+        without breaking the offset extractor. The result of this refactoring
+        is that CommonIdentifiers, and a few other miscellaneous headers now
+        need to be included directly as they were formerly captured through other
+        paths.
+
+        In addition this adds a flag to the Lookup table's hashentry to indicate
+        that a static function is actually backed by JS. There is then a lot of
+        logic to thread the special nature of the functon to where it matters.
+        This allows toString(), .caller, etc to mimic the behaviour of a host
+        function.
+
+        Notes on writing builtins:
+         - Each function is compiled independently of the others, and those
+           implementations cannot currently capture all global properties (as
+           that could be potentially unsafe). If a function does capture a
+           global we will deliberately crash.
+         - For those "global" properties that we do want access to, we use
+           the @ prefix, e.g. Object(this) becomes @Object(this). The @ identifiers
+           are private names, and behave just like regular properties, only
+           without the risk of adulteration. Again, in the @Object case, we
+           explicitly duplicate the ObjectConstructor reference on the GlobalObject
+           so that we have guaranteed access to the original version of the
+           constructor.
+         - call, apply, eval, and Function are all rejected identifiers, again
+           to prevent anything from accidentally using an adulterated object.
+           Instead @call and @apply are available, and happily they completely
+           drop the neq_ptr instruction as they're defined as always being the
+           original call/apply functions.
+
+        These restrictions are just intended to make it harder to accidentally
+        make changes that are incorrect (for instance calling whatever has been
+        assigned to global.Object, instead of the original constructor function).
+        However, making a mistake like this should result in a purely semantic
+        error as fundamentally these functions are treated as though they were
+        regular JS code in the host global, and have no more privileges than
+        any other JS.
+
+        The initial proof of concept is Array.prototype.every, this shows a 65%
+        performance improvement, and that improvement is significantly hurt by
+        our poor optimisation of op_in.
+
+        As this is such a limited function, we have not yet exported all symbols
+        that we could possibly need, but as we implement more, the likelihood
+        of encountering missing features will reduce.
+
+        This did require breaking out a JSStringInlines header, and required
+        fixing a few objects that were trying to using PropertyName::publicName
+        rather than PropertyName::uid.
+
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::JSCallbackObject<Parent>::getOwnPropertySlot):
+        (JSC::JSCallbackObject<Parent>::put):
+        (JSC::JSCallbackObject<Parent>::deleteProperty):
+        (JSC::JSCallbackObject<Parent>::getStaticValue):
+        (JSC::JSCallbackObject<Parent>::staticFunctionGetter):
+        (JSC::JSCallbackObject<Parent>::callbackGetter):
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * builtins/Array.prototype.js:
+        (every):
+        * builtins/BuiltinExecutables.cpp: Added.
+        (JSC::BuiltinExecutables::BuiltinExecutables):
+        (JSC::BuiltinExecutables::createBuiltinExecutable):
+        * builtins/BuiltinExecutables.h:
+        (JSC::BuiltinExecutables::create):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * bytecode/CodeBlock.h:
+        * bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp:
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::generateFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        (JSC::UnlinkedFunctionExecutable::codeBlockFor):
+        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::ExecutableInfo::ExecutableInfo):
+        (JSC::UnlinkedFunctionExecutable::create):
+        (JSC::UnlinkedFunctionExecutable::toStrictness):
+        (JSC::UnlinkedFunctionExecutable::isBuiltinFunction):
+        (JSC::UnlinkedCodeBlock::isBuiltinFunction):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::isBuiltinFunction):
+        (JSC::BytecodeGenerator::makeFunction):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        * create_hash_table:
+        * dfg/DFGOperations.cpp:
+        * generate-js-builtins: Added.
+        (getCopyright):
+        (getFunctions):
+        (generateCode):
+        (mangleName):
+        (FunctionExecutable):
+        (Identifier):
+        (JSGlobalObject):
+        (SourceCode):
+        (UnlinkedFunctionExecutable):
+        (VM):
+        * interpreter/Interpreter.cpp:
+        * interpreter/ProtoCallFrame.cpp:
+        * jit/JITOpcodes.cpp:
+        * jit/JITOpcodes32_64.cpp:
+        * jit/JITOperations.cpp:
+        * jit/JITPropertyAccess.cpp:
+        * jit/JITPropertyAccess32_64.cpp:
+        * jsc.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::makeFunctionCallNode):
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::Lexer):
+        (JSC::isSafeIdentifier):
+        (JSC::Lexer<LChar>::parseIdentifier):
+        (JSC::Lexer<UChar>::parseIdentifier):
+        (JSC::Lexer<T>::lex):
+        * parser/Lexer.h:
+        (JSC::isSafeIdentifier):
+        (JSC::Lexer<T>::lexExpectIdentifier):
+        * parser/Nodes.cpp:
+        (JSC::ProgramNode::setClosedVariables):
+        * parser/Nodes.h:
+        (JSC::ScopeNode::capturedVariables):
+        (JSC::ScopeNode::setClosedVariables):
+        (JSC::ProgramNode::closedVariables):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        (JSC::Parser<LexerType>::parseInner):
+        (JSC::Parser<LexerType>::didFinishParsing):
+        (JSC::Parser<LexerType>::printUnexpectedTokenText):
+        * parser/Parser.h:
+        (JSC::Scope::getUsedVariables):
+        (JSC::Parser::closedVariables):
+        (JSC::parse):
+        * parser/ParserModes.h:
+        * parser/ParserTokens.h:
+        * runtime/ArgList.cpp:
+        * runtime/Arguments.cpp:
+        * runtime/Arguments.h:
+        * runtime/ArgumentsIteratorConstructor.cpp:
+        * runtime/ArgumentsIteratorPrototype.cpp:
+        * runtime/ArrayPrototype.cpp:
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+        * runtime/CommonIdentifiers.cpp:
+        (JSC::CommonIdentifiers::CommonIdentifiers):
+        (JSC::CommonIdentifiers::getPrivateName):
+        (JSC::CommonIdentifiers::getPublicName):
+        * runtime/CommonIdentifiers.h:
+        * runtime/CommonSlowPaths.cpp:
+        * runtime/CommonSlowPathsExceptions.cpp:
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::createUndefinedVariableError):
+        * runtime/Executable.h:
+        (JSC::EvalExecutable::executableInfo):
+        (JSC::ProgramExecutable::executableInfo):
+        (JSC::FunctionExecutable::isBuiltinFunction):
+        * runtime/FunctionPrototype.cpp:
+        (JSC::functionProtoFuncToString):
+        * runtime/JSActivation.cpp:
+        (JSC::JSActivation::symbolTableGet):
+        (JSC::JSActivation::symbolTablePut):
+        (JSC::JSActivation::symbolTablePutWithAttributes):
+        * runtime/JSArgumentsIterator.cpp:
+        * runtime/JSArray.cpp:
+        * runtime/JSArrayIterator.cpp:
+        * runtime/JSCJSValue.cpp:
+        * runtime/JSCellInlines.h:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::createBuiltinFunction):
+        (JSC::JSFunction::calculatedDisplayName):
+        (JSC::JSFunction::sourceCode):
+        (JSC::JSFunction::isHostOrBuiltinFunction):
+        (JSC::JSFunction::isBuiltinFunction):
+        (JSC::JSFunction::callerGetter):
+        (JSC::JSFunction::getOwnPropertySlot):
+        (JSC::JSFunction::getOwnNonIndexPropertyNames):
+        (JSC::JSFunction::put):
+        (JSC::JSFunction::defineOwnProperty):
+        * runtime/JSFunction.h:
+        * runtime/JSGenericTypedArrayViewConstructorInlines.h:
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        * runtime/JSGenericTypedArrayViewPrototypeInlines.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::objectConstructor):
+        (JSC::JSGlobalObject::symbolTableHasProperty):
+        * runtime/JSObject.cpp:
+        (JSC::getClassPropertyNames):
+        (JSC::JSObject::reifyStaticFunctionsForDelete):
+        (JSC::JSObject::putDirectBuiltinFunction):
+        * runtime/JSObject.h:
+        * runtime/JSPropertyNameIterator.cpp:
+        * runtime/JSPropertyNameIterator.h:
+        * runtime/JSString.h:
+        * runtime/JSStringInlines.h: Added.
+        (JSC::JSString::getStringPropertySlot):
+        (JSC::inlineJSValueNotStringtoString):
+        (JSC::JSValue::toWTFStringInline):
+        * runtime/JSSymbolTableObject.cpp:
+        (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
+           Don't report private names.
+        * runtime/JSSymbolTableObject.h:
+        (JSC::symbolTableGet):
+        (JSC::symbolTablePut):
+        (JSC::symbolTablePutWithAttributes):
+        * runtime/Lookup.cpp:
+        (JSC::setUpStaticFunctionSlot):
+        * runtime/Lookup.h:
+        (JSC::HashEntry::builtinGenerator):
+        (JSC::HashEntry::propertyGetter):
+        (JSC::HashEntry::propertyPutter):
+        (JSC::HashTable::entry):
+        (JSC::getStaticPropertySlot):
+        (JSC::getStaticValueSlot):
+        (JSC::putEntry):
+        * runtime/NativeErrorConstructor.cpp:
+        (JSC::NativeErrorConstructor::finishCreation):
+        * runtime/NativeErrorConstructor.h:
+        * runtime/PropertySlot.h:
+        * runtime/RegExpPrototype.cpp:
+        * runtime/SetConstructor.cpp:
+        * runtime/StringObject.cpp:
+        * runtime/Structure.cpp:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        (JSC::VM::builtinExecutables):
+
 2014-01-31  Gabor Rapcsanyi  <rgabor@webkit.org>
 
         Fix the ARM Thumb2 build after jsCStack branch merge
index 1156e97..a83bdca 100644 (file)
@@ -28,8 +28,9 @@ VPATH = \
     $(JavaScriptCore) \
     $(JavaScriptCore)/parser \
     $(JavaScriptCore)/runtime \
-    $(JavaScriptCore)/interpreter \
-    $(JavaScriptCore)/jit \
+       $(JavaScriptCore)/interpreter \
+       $(JavaScriptCore)/jit \
+       $(JavaScriptCore)/builtins \
 #
 
 .PHONY : all
@@ -57,8 +58,18 @@ all : \
     RegExpObject.lut.h \
     StringConstructor.lut.h \
     udis86_itab.h \
+    JSCBuiltins \
 #
 
+# builtin functions
+.PHONY: JSCBuiltins
+
+JSCBuiltins: $(JavaScriptCore)/generate-js-builtins JSCBuiltins.h JSCBuiltins.cpp
+JSCBuiltins.h: $(JavaScriptCore)/generate-js-builtins $(JavaScriptCore)/builtins/*.js
+       python $^ $@
+                                                                                                                                                                
+JSCBuiltins.cpp: JSCBuiltins.h
+
 # lookup tables for classes
 
 %.lut.h: create_hash_table %.cpp
index fe5448d..5569f50 100644 (file)
@@ -51,6 +51,7 @@ javascriptcore_cppflags += \
        -I$(srcdir)/Source/JavaScriptCore/ForwardingHeaders \
        -I$(srcdir)/Source/JavaScriptCore/assembler \
        -I$(srcdir)/Source/JavaScriptCore/bindings \
+       -I$(srcdir)/Source/JavaScriptCore/builtins \
        -I$(srcdir)/Source/JavaScriptCore/bytecode \
        -I$(srcdir)/Source/JavaScriptCore/bytecompiler \
        -I$(srcdir)/Source/JavaScriptCore/debugger \
@@ -110,12 +111,16 @@ DerivedSources/JavaScriptCore/LLIntDesiredOffsets.h: $(javascriptcore_sources) $
        $(AM_V_GEN)$(RUBY) $(srcdir)/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb $(srcdir)/Source/JavaScriptCore/llint/LowLevelInterpreter.asm $@
        $(AM_V_at)touch $@
 
-$(Programs_LLIntOffsetsExtractor_OBJECTS): DerivedSources/JavaScriptCore/LLIntDesiredOffsets.h
+$(Programs_LLIntOffsetsExtractor_OBJECTS): DerivedSources/JavaScriptCore/LLIntDesiredOffsets.h 
 
 DerivedSources/JavaScriptCore/LLIntAssembly.h: Programs/LLIntOffsetsExtractor$(EXEEXT)
        $(AM_V_GEN)$(RUBY) $(srcdir)/Source/JavaScriptCore/offlineasm/asm.rb $(srcdir)/Source/JavaScriptCore/llint/LowLevelInterpreter.asm Programs/LLIntOffsetsExtractor$(EXEEXT) $@
        $(AM_V_at)touch $@
 
+DerivedSources/JavaScriptCore/JSCBuiltins.h: DerivedSources/JavaScriptCore/JSCBuiltins.cpp
+DerivedSources/JavaScriptCore/JSCBuiltins.cpp: $(srcdir)/Source/JavaScriptCore/generate-js-builtins $(javascriptcore_builtins_js_nosources)
+       $(AM_V_GEN)$(PYTHON) $^ $@
+
 $(libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_OBJECTS): DerivedSources/JavaScriptCore/LLIntAssembly.h
 
 jsc: $(javascriptcore_built_nosources) Programs/jsc$(EXEEXT)
@@ -216,6 +221,7 @@ EXTRA_DIST += \
        Source/JavaScriptCore/KeywordLookupGenerator.py \
        Source/JavaScriptCore/parser/Keywords.table \
        Source/JavaScriptCore/THANKS \
+       $(javascriptcore_builtins_js_nosources) \
        $(llint_nosources) \
        $(offlineasm_nosources)
 
index cdb5426..98faaa7 100644 (file)
@@ -20,6 +20,8 @@ javascriptcore_built_nosources += \
        DerivedSources/JavaScriptCore/ErrorPrototype.lut.h \
        DerivedSources/JavaScriptCore/JSDataViewPrototype.lut.h \
        DerivedSources/JavaScriptCore/JSGlobalObject.lut.h \
+       DerivedSources/JavaScriptCore/JSCBuiltins.cpp \
+       DerivedSources/JavaScriptCore/JSCBuiltins.h \
        DerivedSources/JavaScriptCore/JSONObject.lut.h \
        DerivedSources/JavaScriptCore/JSPromiseConstructor.lut.h \
        DerivedSources/JavaScriptCore/JSPromisePrototype.lut.h \
@@ -35,6 +37,9 @@ javascriptcore_built_nosources += \
        DerivedSources/JavaScriptCore/LLIntDesiredOffsets.h \
        DerivedSources/JavaScriptCore/LLIntAssembly.h
 
+javascriptcore_builtins_js_nosources += \
+       Source/JavaScriptCore/builtins/Array.prototype.js
+
 javascriptcore_sources += \
        Source/JavaScriptCore/API/APICallbackFunction.h \
        Source/JavaScriptCore/API/APICast.h \
@@ -102,6 +107,8 @@ javascriptcore_sources += \
     Source/JavaScriptCore/bindings/ScriptObject.h \
     Source/JavaScriptCore/bindings/ScriptValue.cpp \
     Source/JavaScriptCore/bindings/ScriptValue.h \
+    Source/JavaScriptCore/builtins/BuiltinExecutables.cpp \
+    Source/JavaScriptCore/builtins/BuiltinExecutables.h \
        Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp \
        Source/JavaScriptCore/bytecode/ArrayAllocationProfile.h \
        Source/JavaScriptCore/bytecode/ArrayProfile.cpp \
@@ -1241,7 +1248,9 @@ javascriptcore_sources += \
        DerivedSources/JavaScriptCore/InspectorJSFrontendDispatchers.cpp \
        DerivedSources/JavaScriptCore/InspectorJSFrontendDispatchers.h \
        DerivedSources/JavaScriptCore/InspectorJSTypeBuilders.cpp \
-       DerivedSources/JavaScriptCore/InspectorJSTypeBuilders.h
+       DerivedSources/JavaScriptCore/InspectorJSTypeBuilders.h \
+       DerivedSources/JavaScriptCore/JSCBuiltins.cpp \
+       DerivedSources/JavaScriptCore/JSCBuiltins.h
 
 llint_nosources += \
        Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm \
index 5edefdb..a12db18 100644 (file)
     <ClCompile Include="..\bindings\ScriptFunctionCall.cpp" />
     <ClCompile Include="..\bindings\ScriptObject.cpp" />
     <ClCompile Include="..\bindings\ScriptValue.cpp" />
+    <ClInclude Include="..\builtins\BuiltinExecutables.cpp" />
     <ClCompile Include="..\bytecode\ArrayAllocationProfile.cpp" />
     <ClCompile Include="..\bytecode\ArrayProfile.cpp" />
     <ClCompile Include="..\bytecode\BytecodeBasicBlock.cpp" />
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSBackendDispatchers.cpp" />
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSFrontendDispatchers.cpp" />
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSTypeBuilders.cpp" />
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSCBuiltins.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayConstructor.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\RegExpObject.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\RegExpPrototype.lut.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\StringConstructor.lut.h" />
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSCBuiltins.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\API\APICallbackFunction.h" />
     <ClInclude Include="..\bindings\ScriptFunctionCall.h" />
     <ClInclude Include="..\bindings\ScriptObject.h" />
     <ClInclude Include="..\bindings\ScriptValue.h" />
+    <ClInclude Include="..\builtins\BuiltinExecutables.h" />
     <ClInclude Include="..\bytecode\ArrayAllocationProfile.h" />
     <ClInclude Include="..\bytecode\ArrayProfile.h" />
     <ClInclude Include="..\bytecode\ByValInfo.h" />
index 87e12a4..869c1f5 100644 (file)
@@ -7,6 +7,9 @@
     <Filter Include="bindings">
       <UniqueIdentifier>{0bace123-4582-eebc-9314-7819b376c198}</UniqueIdentifier>
     </Filter>
+    <Filter Include="builtins">
+      <UniqueIdentifier>{3b9d72a5-135b-43b3-a524-c6d2b9d29d35}</UniqueIdentifier>
+    </Filter>
     <Filter Include="bytecode">
       <UniqueIdentifier>{766088a0-1216-4854-aa43-560c5e283668}</UniqueIdentifier>
     </Filter>
     <ClCompile Include="..\assembler\MacroAssembler.cpp">
       <Filter>assembler</Filter>
     </ClCompile>
+    <ClCompile Include="..\builtins\BuiltinExecutables.cpp">
+      <Filter>builtins</Filter>
+    </ClCompile>
     <ClCompile Include="..\bytecode\ArrayAllocationProfile.cpp">
       <Filter>bytecode</Filter>
     </ClCompile>
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\InspectorJSTypeBuilders.cpp">
       <Filter>Derived Sources</Filter>
     </ClCompile>
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSCBuiltins.cpp">
+      <Filter>Derived Sources</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\API\APICallbackFunction.h">
     <ClInclude Include="..\assembler\X86Assembler.h">
       <Filter>assembler</Filter>
     </ClInclude>
+    <ClCompile Include="..\builtins\BuiltinExecutables.h">
+      <Filter>builtins</Filter>
+    </ClCompile>
     <ClInclude Include="..\bytecode\ArrayAllocationProfile.h">
       <Filter>bytecode</Filter>
     </ClInclude>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\ArrayPrototype.lut.h">
       <Filter>Derived Sources</Filter>
     </ClInclude>
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSCBuiltins.h">
+      <Filter>Derived Sources</Filter>
+    </ClInclude>
     <ClInclude Include="..\runtime\VM.h">
       <Filter>runtime</Filter>
     </ClInclude>
index 3622ffc..c588870 100644 (file)
@@ -5,7 +5,7 @@
   <PropertyGroup />
   <ItemDefinitionGroup>
     <ClCompile>
-      <AdditionalIncludeDirectories>..\;..\tools\;..\runtime\;..\llint\;..\jit\;..\disassembler\;..\heap\;..\debugger\;..\assembler\;..\profiler\;..\yarr\;..\interpreter\;..\bytecode\;..\dfg\;..\bytecompiler\;..\parser\;..\API\;..\ftl\;..\bindings\;..\inspector\;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\JavaScriptCore\DerivedSources\;$(ConfigurationBuildDir)\include\;$(ConfigurationBuildDir)\include\JavaScriptCore\;$(ConfigurationBuildDir)\include\private\;$(WebKit_Libraries)\include;$(WebKit_Libraries)\include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\;..\tools\;..\runtime\;..\llint\;..\jit\;..\disassembler\;..\heap\;..\debugger\;..\assembler\;..\profiler\;..\yarr\;..\interpreter\;..\bytecode\;..\builtins\;..\dfg\;..\bytecompiler\;..\parser\;..\API\;..\ftl\;..\bindings\;..\inspector\;$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\JavaScriptCore\DerivedSources\;$(ConfigurationBuildDir)\include\;$(ConfigurationBuildDir)\include\JavaScriptCore\;$(ConfigurationBuildDir)\include\private\;$(WebKit_Libraries)\include;$(WebKit_Libraries)\include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
     </ClCompile>
     <Link>
index 943343a..e0c1f29 100755 (executable)
@@ -42,6 +42,7 @@ for %%d in (
     assembler\r
     bindings\r
     bytecode\r
+    builtins\r
     dfg\r
     disassembler\r
     heap\r
@@ -72,6 +73,9 @@ xcopy /y "%DerivedSourcesDirectory%\InspectorJSTypeBuilders.h" "%PrivateHeadersD
 xcopy /y "%DerivedSourcesDirectory%\InspectorJSBackendDispatchers.h" "%PrivateHeadersDirectory%" >NUL\r
 xcopy /y "%DerivedSourcesDirectory%\InspectorJSFrontendDispatchers.h" "%PrivateHeadersDirectory%" >NUL\r
 \r
+echo Copying builtins header as if it were a private header...\r
+xcopy /y "%DerivedSourcesDirectory%\JSCBuiltins.h" "%PrivateHeadersDirectory%" >NUL\r
+\r
 echo Copying resources...\r
 mkdir "%ResourcesDirectory%" 2>NUL\r
 xcopy /y /d JavaScriptCore.resources\* "%ResourcesDirectory%" >NUL\r
index 27e8767..911573a 100644 (file)
                A503FA19188E0FB000110F14 /* JavaScriptCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A503FA13188E0FAF00110F14 /* JavaScriptCallFrame.cpp */; };
                A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */; };
                A503FA1B188E0FB000110F14 /* JSJavaScriptCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A503FA15188E0FB000110F14 /* JSJavaScriptCallFrame.cpp */; };
-               A503FA1C188E0FB000110F14 /* JSJavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA16188E0FB000110F14 /* JSJavaScriptCallFrame.h */; };
                A503FA1D188E0FB000110F14 /* JSJavaScriptCallFramePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A503FA17188E0FB000110F14 /* JSJavaScriptCallFramePrototype.cpp */; };
                A503FA1E188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA18188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h */; };
                A503FA21188EFF6800110F14 /* ScriptBreakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA1F188EFF6800110F14 /* ScriptBreakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A70B083217A0B79B00DAF14B /* DFGBinarySwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A70B083017A0B79B00DAF14B /* DFGBinarySwitch.cpp */; };
                A70B083317A0B79B00DAF14B /* DFGBinarySwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = A70B083117A0B79B00DAF14B /* DFGBinarySwitch.h */; };
                A71236E51195F33C00BD2174 /* JITOpcodes32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A71236E41195F33C00BD2174 /* JITOpcodes32_64.cpp */; };
+               A71DA80F1880DBAB00D1F299 /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A71DA80E1880DBAB00D1F299 /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A72028B61797601E0098028C /* JSCTestRunnerUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72028B41797601E0098028C /* JSCTestRunnerUtils.cpp */; };
                A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = A72028B51797601E0098028C /* JSCTestRunnerUtils.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A72028BA1797603D0098028C /* JSFunctionInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A72028B91797603D0098028C /* JSFunctionInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CA3AE217DA41AE006538AF /* JSWeakMap.h */; };
                A7CA3AEB17DA5168006538AF /* WeakMapData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7CA3AE917DA5168006538AF /* WeakMapData.cpp */; };
                A7CA3AEC17DA5168006538AF /* WeakMapData.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CA3AEA17DA5168006538AF /* WeakMapData.h */; };
+               A7D801A41880D66E0026C39B /* BuiltinExecutables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D801A11880D66E0026C39B /* BuiltinExecutables.cpp */; };
+               A7D801A51880D66E0026C39B /* BuiltinExecutables.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D801A21880D66E0026C39B /* BuiltinExecutables.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A7D801A81880D6A80026C39B /* JSCBuiltins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D801A61880D6A80026C39B /* JSCBuiltins.cpp */; };
+               A7D801A91880D6A80026C39B /* JSCBuiltins.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D801A71880D6A80026C39B /* JSCBuiltins.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A7D89CF217A0B8CC00773AD8 /* DFGBasicBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D89CE317A0B8CC00773AD8 /* DFGBasicBlock.cpp */; };
                A7D89CF317A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D89CE417A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp */; };
                A7D89CF417A0B8CC00773AD8 /* DFGBlockInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D89CE517A0B8CC00773AD8 /* DFGBlockInsertionSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A71236E41195F33C00BD2174 /* JITOpcodes32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITOpcodes32_64.cpp; sourceTree = "<group>"; };
                A718F61A11754A21002465A7 /* RegExpJitTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpJitTables.h; sourceTree = "<group>"; };
                A718F8211178EB4B002465A7 /* create_regex_tables */ = {isa = PBXFileReference; explicitFileType = text.script.python; fileEncoding = 4; path = create_regex_tables; sourceTree = "<group>"; };
+               A71DA80D1880D71F00D1F299 /* generate-js-builtins */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = "generate-js-builtins"; sourceTree = "<group>"; };
+               A71DA80E1880DBAB00D1F299 /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = "<group>"; };
                A72028B41797601E0098028C /* JSCTestRunnerUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCTestRunnerUtils.cpp; sourceTree = "<group>"; };
                A72028B51797601E0098028C /* JSCTestRunnerUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCTestRunnerUtils.h; sourceTree = "<group>"; };
                A72028B91797603D0098028C /* JSFunctionInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFunctionInlines.h; sourceTree = "<group>"; };
                A7CA3AE217DA41AE006538AF /* JSWeakMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakMap.h; sourceTree = "<group>"; };
                A7CA3AE917DA5168006538AF /* WeakMapData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakMapData.cpp; sourceTree = "<group>"; };
                A7CA3AEA17DA5168006538AF /* WeakMapData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakMapData.h; sourceTree = "<group>"; };
+               A7D801A01880D66E0026C39B /* Array.prototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = Array.prototype.js; sourceTree = "<group>"; };
+               A7D801A11880D66E0026C39B /* BuiltinExecutables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BuiltinExecutables.cpp; sourceTree = "<group>"; };
+               A7D801A21880D66E0026C39B /* BuiltinExecutables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltinExecutables.h; sourceTree = "<group>"; };
+               A7D801A61880D6A80026C39B /* JSCBuiltins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCBuiltins.cpp; sourceTree = "<group>"; };
+               A7D801A71880D6A80026C39B /* JSCBuiltins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCBuiltins.h; sourceTree = "<group>"; };
                A7D89CE317A0B8CC00773AD8 /* DFGBasicBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBasicBlock.cpp; path = dfg/DFGBasicBlock.cpp; sourceTree = "<group>"; };
                A7D89CE417A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBlockInsertionSet.cpp; path = dfg/DFGBlockInsertionSet.cpp; sourceTree = "<group>"; };
                A7D89CE517A0B8CC00773AD8 /* DFGBlockInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockInsertionSet.h; path = dfg/DFGBlockInsertionSet.h; sourceTree = "<group>"; };
                                8604F4F2143A6C4400B295F5 /* ChangeLog */,
                                F692A8540255597D01FF60F7 /* create_hash_table */,
                                A718F8211178EB4B002465A7 /* create_regex_tables */,
+                               A71DA80D1880D71F00D1F299 /* generate-js-builtins */,
                                45E12D8806A49B0F00E9DF84 /* jsc.cpp */,
                                F68EBB8C0255D4C601FF60F7 /* config.h */,
                                F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */,
                                1432EBD70A34CAD400717B9F /* API */,
                                9688CB120ED12B4E001D649F /* assembler */,
                                A54CF2EA184EA73900237F19 /* bindings */,
+                               A7D8019F1880D66E0026C39B /* builtins */,
                                969A078F0ED1D3AE00F1F681 /* bytecode */,
                                7E39D81D0EC38EFA003AF11A /* bytecompiler */,
                                1C90513E0BA9E8830081E9D0 /* Configurations */,
                650FDF8D09D0FCA700769E54 /* Derived Sources */ = {
                        isa = PBXGroup;
                        children = (
+                               A7D801A61880D6A80026C39B /* JSCBuiltins.cpp */,
+                               A7D801A71880D6A80026C39B /* JSCBuiltins.h */,
                                BC18C5230E16FC8A00B34460 /* ArrayPrototype.lut.h */,
                                BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */,
                                A513E5C6185F9436007E95AD /* InjectedScriptSource.h */,
                                A790DD6A182F499700588807 /* JSSetIterator.h */,
                                BC02E9B60E1842FA000F9297 /* JSString.cpp */,
                                F692A8620255597D01FF60F7 /* JSString.h */,
+                               A71DA80E1880DBAB00D1F299 /* JSStringInlines.h */,
                                86E85538111B9968001AF51E /* JSStringBuilder.h */,
                                2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */,
                                2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */,
                        path = remote;
                        sourceTree = "<group>";
                };
+               A7D8019F1880D66E0026C39B /* builtins */ = {
+                       isa = PBXGroup;
+                       children = (
+                               A7D801A01880D66E0026C39B /* Array.prototype.js */,
+                               A7D801A11880D66E0026C39B /* BuiltinExecutables.cpp */,
+                               A7D801A21880D66E0026C39B /* BuiltinExecutables.h */,
+                       );
+                       path = builtins;
+                       sourceTree = "<group>";
+               };
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
                                86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
                                A5CEEE15187F3BAD00E55C99 /* InspectorAgent.h in Headers */,
                                65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */,
-                               2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */,
-                2A4EC90C1860D6C20094F782 /* WriteBarrierBuffer.h in Headers */,
+                               2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */,
+                               2A4EC90C1860D6C20094F782 /* WriteBarrierBuffer.h in Headers */,
                                FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */,
                                A532439318569709002ED692 /* CodeGeneratorInspectorStrings.py in Headers */,
-                               A532439218569709002ED692 /* CodeGeneratorInspector.py in Headers */,
+                               A532439218569709002ED692 /* CodeGeneratorInspector.py in Headers */,
                                0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */,
                                A50E4B6418809DD50068A46D /* JSGlobalObjectRuntimeAgent.h in Headers */,
                                FEB58C15187B8B160098EF0B /* ErrorHandlingScope.h in Headers */,
                                0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */,
                                A5840E29187CA5E600843B10 /* inline-and-minify-stylesheets-and-scripts.py in Headers */,
                                A5840E2B187CA75B00843B10 /* jsmin.py in Headers */,
-                               A53243981856A489002ED692 /* InspectorJS.json in Headers */,
+                               A53243981856A489002ED692 /* InspectorJS.json in Headers */,
                                A5840E2A187CA75900843B10 /* xxd.pl in Headers */,
                                FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */,
                                A7A8AF3517ADB5F3005AB174 /* ArrayBuffer.h in Headers */,
                                A1A009C01831A22D00CF8711 /* MacroAssemblerARM64.h in Headers */,
                                86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */,
                                0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */,
-                A593CF87184038CA00BFCE27 /* InspectorAgentRegistry.h in Headers */,
+                               A593CF87184038CA00BFCE27 /* InspectorAgentRegistry.h in Headers */,
                                0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */,
                                0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
                                0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */,
                                0FEA0A1D1708B00700BB722C /* FTLAbstractHeap.h in Headers */,
                                0FEA0A1F1708B00700BB722C /* FTLAbstractHeapRepository.h in Headers */,
                                A59455931824744700CC3843 /* JSGlobalObjectDebuggable.h in Headers */,
+                               A7D801A91880D6A80026C39B /* JSCBuiltins.h in Headers */,
                                0FEA0A0A170513DB00BB722C /* FTLCapabilities.h in Headers */,
                                0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */,
                                0FEA0A231709606900BB722C /* FTLCommonValues.h in Headers */,
                                BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
                                C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
                                0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */,
+                               A7D801A51880D66E0026C39B /* BuiltinExecutables.h in Headers */,
                                0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
                                0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */,
                                0FCEFAB01805CA6D00472CE4 /* InitializeLLVM.h in Headers */,
                                A532438818568335002ED692 /* InspectorJSBackendDispatchers.h in Headers */,
                                BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
                                1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */,
+                               A71DA80F1880DBAB00D1F299 /* JSStringInlines.h in Headers */,
                                0F9332A414CA7DD90085F3C6 /* PutByIdStatus.h in Headers */,
                                0F0CD4C215F1A6070032F1C0 /* PutDirectIndexMode.h in Headers */,
                                7C008CE7187631B600955C24 /* Microtask.h in Headers */,
                                A7D89CF217A0B8CC00773AD8 /* DFGBasicBlock.cpp in Sources */,
                                A70B083217A0B79B00DAF14B /* DFGBinarySwitch.cpp in Sources */,
                                A7D89CF317A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp in Sources */,
+                               A7D801A41880D66E0026C39B /* BuiltinExecutables.cpp in Sources */,
                                86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */,
                                0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */,
                                0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */,
                                0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */,
                                0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */,
                                0F8F2B99172F04FF007DBDA5 /* DFGDesiredIdentifiers.cpp in Sources */,
+                               A7D801A81880D6A80026C39B /* JSCBuiltins.cpp in Sources */,
                                A73E1330179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp in Sources */,
                                C2C0F7CD17BBFC5B00464FE4 /* DFGDesiredTransitions.cpp in Sources */,
                                0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */,
                                0F6B1CC51862C47800845D97 /* FTLUnwindInfo.cpp in Sources */,
                                0F9D339A1803ADB70073C2BC /* FTLStackMaps.cpp in Sources */,
                                0FEA0A161706BB9000BB722C /* FTLState.cpp in Sources */,
-                               7C008CD2186F8A9300955C24 /* JSPromiseFunctions.cpp in Sources */,
+                               7C008CD2186F8A9300955C24 /* JSPromiseFunctions.cpp in Sources */,
                                0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */,
                                0F235BE117178E1C00690C7F /* FTLThunks.cpp in Sources */,
                                A593CF7C1840360300BFCE27 /* InspectorBackendDispatcher.cpp in Sources */,
diff --git a/Source/JavaScriptCore/builtins/Array.prototype.js b/Source/JavaScriptCore/builtins/Array.prototype.js
new file mode 100644 (file)
index 0000000..3eb42f5
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 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. ``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
+ * 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.
+ */
+
+function every(callback /*, thisArg */) {
+    "use strict";
+    if (this === null)
+        throw new @TypeError("Array.prototype.every requires that |this| not be null");
+    
+    if (this === undefined)
+        throw new @TypeError("Array.prototype.every requires that |this| not be undefined");
+    
+    var array = @Object(this);
+    var length = array.length >>> 0;
+    
+    if (typeof callback !== "function")
+        throw new @TypeError("Array.prototype.every callback must be a function");
+
+    var thisArg = arguments.length > 1 ? arguments[1] : undefined;
+    
+    for (var i = 0; i < length; i++) {
+        if (!(i in array))
+            continue;
+        if (!callback.@call(thisArg, array[i], i, array))
+            return false;
+    }
+    
+    return true;
+}
+
diff --git a/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp b/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
new file mode 100644 (file)
index 0000000..341dbb5
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 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. ``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
+ * 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 "BuiltinExecutables.h"
+
+#include "Executable.h"
+#include "JSCellInlines.h"
+#include "JSFunctionInlines.h"
+#include "Parser.h"
+
+namespace JSC {
+
+BuiltinExecutables::BuiltinExecutables(VM& vm)
+    : m_vm(vm)
+#define INITIALIZE_BUILTIN_SOURCE_MEMBERS(name, functionName, length) , m_##name##Source(makeSource(StringImpl::createFromLiteral(s_##name, length), StringImpl::createFromLiteral("<builtin>")))
+    JSC_FOREACH_BUILTIN(INITIALIZE_BUILTIN_SOURCE_MEMBERS)
+#undef EXPOSE_BUILTIN_STRINGS
+{
+}
+
+UnlinkedFunctionExecutable* BuiltinExecutables::createBuiltinExecutable(const SourceCode& source, const Identifier& name)
+{
+    JSTextPosition positionBeforeLastNewline;
+    ParserError error;
+    RefPtr<ProgramNode> program = parse<ProgramNode>(&m_vm, source, 0, Identifier(), JSParseBuiltin, JSParseProgramCode, error, &positionBeforeLastNewline);
+
+    if (!program) {
+        dataLog("Fatal error compiling builtin function '", name.string(), "': ", error.m_message);
+        CRASH();
+    }
+
+    StatementNode* exprStatement = program->singleStatement();
+    RELEASE_ASSERT(exprStatement);
+    RELEASE_ASSERT(exprStatement->isExprStatement());
+    ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
+    RELEASE_ASSERT(funcExpr);
+    RELEASE_ASSERT(funcExpr->isFuncExprNode());
+    FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
+    RELEASE_ASSERT(!program->hasCapturedVariables());
+    
+    body->setEndPosition(positionBeforeLastNewline);
+    RELEASE_ASSERT(body);
+    RELEASE_ASSERT(body->ident().isNull());
+    
+    // This function assumes an input string that would result in a single anonymous function expression.
+    body->setEndPosition(positionBeforeLastNewline);
+    RELEASE_ASSERT(body);
+    for (const auto& closedVariable : program->closedVariables()) {
+        if (closedVariable == m_vm.propertyNames->arguments.impl())
+        continue;
+        
+        if (closedVariable == m_vm.propertyNames->undefinedKeyword.impl())
+            continue;
+        RELEASE_ASSERT(closedVariable->isEmptyUnique());
+    }
+    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&m_vm, source, body, true, UnlinkedBuiltinFunction);
+    functionExecutable->m_nameValue.set(m_vm, functionExecutable, jsString(&m_vm, name.string()));
+    return functionExecutable;
+}
+
+#define DEFINE_BUILTIN_EXECUTABLES(name, functionName, length) \
+UnlinkedFunctionExecutable* BuiltinExecutables::name##Executable() \
+{\
+    if (!m_##name##Executable)\
+        m_##name##Executable = createBuiltinExecutable(m_##name##Source, m_vm.propertyNames->functionName);\
+    return m_##name##Executable.get();\
+}
+JSC_FOREACH_BUILTIN(DEFINE_BUILTIN_EXECUTABLES)
+#undef EXPOSE_BUILTIN_SOURCES
+
+}
diff --git a/Source/JavaScriptCore/builtins/BuiltinExecutables.h b/Source/JavaScriptCore/builtins/BuiltinExecutables.h
new file mode 100644 (file)
index 0000000..d9a19e2
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 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. ``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
+ * 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 BuiltinExecutables_h
+#define BuiltinExecutables_h
+
+#include "JSCBuiltins.h"
+#include "SourceCode.h"
+#include "Weak.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace JSC {
+
+class UnlinkedFunctionExecutable;
+class Identifier;
+class VM;
+
+class BuiltinExecutables {
+public:
+    static PassOwnPtr<BuiltinExecutables> create(VM& vm)
+    {
+        return adoptPtr(new BuiltinExecutables(vm));
+    }
+    
+#define EXPOSE_BUILTIN_EXECUTABLES(name, functionName, length) \
+UnlinkedFunctionExecutable* name##Executable(); \
+const SourceCode& name##Source() { return m_##name##Source; }
+    
+    JSC_FOREACH_BUILTIN(EXPOSE_BUILTIN_EXECUTABLES)
+#undef EXPOSE_BUILTIN_SOURCES
+    
+private:
+    BuiltinExecutables(VM&);
+    VM& m_vm;
+    UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode&, const Identifier&);
+#define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, length)\
+    SourceCode m_##name##Source; \
+    Weak<UnlinkedFunctionExecutable> m_##name##Executable;
+    JSC_FOREACH_BUILTIN(DECLARE_BUILTIN_SOURCE_MEMBERS)
+#undef DECLARE_BUILTIN_SOURCE_MEMBERS
+};
+
+}
+
+#endif
index cb0dc6f..8600f19 100644 (file)
 #include "JIT.h"
 #include "JITStubs.h"
 #include "JSActivation.h"
-#include "JSCJSValue.h"
+#include "JSCJSValueInlines.h"
 #include "JSFunction.h"
 #include "JSNameScope.h"
 #include "LLIntEntrypoint.h"
 #include "LowLevelInterpreter.h"
+#include "NativeErrorConstructor.h"
+#include "ObjectConstructor.h"
 #include "Operations.h"
 #include "PolymorphicPutByIdList.h"
 #include "ReduceWhitespace.h"
@@ -1569,7 +1571,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
 
     setConstantRegisters(unlinkedCodeBlock->constantRegisters());
     if (unlinkedCodeBlock->usesGlobalObject())
-        m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().offset()].set(*m_vm, ownerExecutable, m_globalObject.get());
+        m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, ownerExecutable, m_globalObject.get());
     m_functionDecls.resizeToFit(unlinkedCodeBlock->numberOfFunctionDecls());
     for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
index 68bc037..4995c52 100644 (file)
@@ -56,7 +56,6 @@
 #include "HandlerInfo.h"
 #include "ObjectAllocationProfile.h"
 #include "Options.h"
-#include "Operations.h"
 #include "PutPropertySlot.h"
 #include "Instruction.h"
 #include "JITCode.h"
index 1dfb5ac..43390d9 100644 (file)
@@ -49,9 +49,9 @@ const ClassInfo UnlinkedProgramCodeBlock::s_info = { "UnlinkedProgramCodeBlock",
 const ClassInfo UnlinkedEvalCodeBlock::s_info = { "UnlinkedEvalCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedEvalCodeBlock) };
 const ClassInfo UnlinkedFunctionCodeBlock::s_info = { "UnlinkedFunctionCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedFunctionCodeBlock) };
 
-static UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
+static UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, UnlinkedFunctionKind functionKind, ParserError& error)
 {
-    RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(&vm, source, executable->parameters(), executable->name(), executable->isInStrictContext() ? JSParseStrict : JSParseNormal, JSParseFunctionCode, error);
+    RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(&vm, source, executable->parameters(), executable->name(), executable->toStrictness(), JSParseFunctionCode, error);
 
     if (!body) {
         ASSERT(error.m_type != ParserError::ErrorNone);
@@ -63,7 +63,7 @@ static UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(VM& vm, UnlinkedFunc
     body->finishParsing(executable->parameters(), executable->name(), executable->functionNameIsInScopeToggle());
     executable->recordParse(body->features(), body->hasCapturedVariables());
     
-    UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(body->needsActivation(), body->usesEval(), body->isStrictMode(), kind == CodeForConstruct));
+    UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(body->needsActivation(), body->usesEval(), body->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction));
     OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(vm, body.get(), result, debuggerMode, profilerMode)));
     error = generator->generate();
     body->destroyData();
@@ -82,13 +82,14 @@ unsigned UnlinkedCodeBlock::addOrFindConstant(JSValue v)
     return addConstant(v);
 }
 
-UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, FunctionBodyNode* node, bool isFromGlobalCode)
+UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, FunctionBodyNode* node, bool isFromGlobalCode, UnlinkedFunctionKind kind)
     : Base(*vm, structure)
     , m_numCapturedVariables(node->capturedVariableCount())
     , m_forceUsesArguments(node->usesArguments())
     , m_isInStrictContext(node->isStrictMode())
     , m_hasCapturedVariables(node->hasCapturedVariables())
     , m_isFromGlobalCode(isFromGlobalCode)
+    , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction)
     , m_name(node->ident())
     , m_inferredName(node->inferredName())
     , m_parameters(node->parameters())
@@ -166,7 +167,7 @@ UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(VM& vm, cons
         break;
     }
 
-    UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(vm, this, source, specializationKind, debuggerMode, profilerMode, error);
+    UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(vm, this, source, specializationKind, debuggerMode, profilerMode, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, error);
     
     if (error.m_type != ParserError::ErrorNone)
         return 0;
@@ -210,6 +211,7 @@ UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType code
     , m_isStrictMode(info.m_isStrictMode)
     , m_isConstructor(info.m_isConstructor)
     , m_hasCapturedVariables(false)
+    , m_isBuiltinFunction(info.m_isBuiltinFunction)
     , m_firstLine(0)
     , m_lineCount(0)
     , m_endColumn(UINT_MAX)
index b9dae2d..abf6cf3 100644 (file)
@@ -66,26 +66,35 @@ typedef unsigned UnlinkedObjectAllocationProfile;
 typedef unsigned UnlinkedLLIntCallLinkInfo;
 
 struct ExecutableInfo {
-    ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor)
+    ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction)
         : m_needsActivation(needsActivation)
         , m_usesEval(usesEval)
         , m_isStrictMode(isStrictMode)
         , m_isConstructor(isConstructor)
+        , m_isBuiltinFunction(isBuiltinFunction)
     {
     }
-    bool m_needsActivation;
-    bool m_usesEval;
-    bool m_isStrictMode;
-    bool m_isConstructor;
+    bool m_needsActivation : 1;
+    bool m_usesEval : 1;
+    bool m_isStrictMode : 1;
+    bool m_isConstructor : 1;
+    bool m_isBuiltinFunction : 1;
+};
+
+enum UnlinkedFunctionKind {
+    UnlinkedNormalFunction,
+    UnlinkedBuiltinFunction,
 };
 
 class UnlinkedFunctionExecutable : public JSCell {
 public:
+    friend class BuiltinExecutables;
     friend class CodeCache;
+    friend class VM;
     typedef JSCell Base;
-    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, bool isFromGlobalCode = false)
+    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, bool isFromGlobalCode, UnlinkedFunctionKind unlinkedFunctionKind)
     {
-        UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, isFromGlobalCode);
+        UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, isFromGlobalCode, unlinkedFunctionKind);
         instance->finishCreation(*vm);
         return instance;
     }
@@ -99,6 +108,14 @@ public:
     }
     size_t parameterCount() const;
     bool isInStrictContext() const { return m_isInStrictContext; }
+    JSParserStrictness toStrictness() const
+    {
+        if (m_isBuiltinFunction)
+            return JSParseBuiltin;
+        if (m_isInStrictContext)
+            return JSParseStrict;
+        return JSParseNormal;
+    }
     FunctionNameIsInScopeToggle functionNameIsInScopeToggle() const { return m_functionNameIsInScopeToggle; }
 
     unsigned firstLineOffset() const { return m_firstLineOffset; }
@@ -142,8 +159,10 @@ public:
     static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);
 
+    bool isBuiltinFunction() const { return m_isBuiltinFunction; }
+
 private:
-    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, bool isFromGlobalCode);
+    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, bool isFromGlobalCode, UnlinkedFunctionKind);
     WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
     WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
 
@@ -152,6 +171,7 @@ private:
     bool m_isInStrictContext : 1;
     bool m_hasCapturedVariables : 1;
     bool m_isFromGlobalCode : 1;
+    bool m_isBuiltinFunction : 1;
 
     Identifier m_name;
     Identifier m_inferredName;
@@ -319,6 +339,8 @@ public:
     void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
     bool isNumericCompareFunction() const { return m_isNumericCompareFunction; }
 
+    bool isBuiltinFunction() const { return m_isBuiltinFunction; }
+    
     void shrinkToFit()
     {
         m_jumpTargets.shrinkToFit();
@@ -500,6 +522,7 @@ private:
     bool m_isStrictMode : 1;
     bool m_isConstructor : 1;
     bool m_hasCapturedVariables : 1;
+    bool m_isBuiltinFunction : 1;
     unsigned m_firstLine;
     unsigned m_lineCount;
     unsigned m_endColumn;
index 6810ab8..ec521b5 100644 (file)
@@ -175,6 +175,7 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedP
 #endif
     , m_usesExceptions(false)
     , m_expressionTooDeep(false)
+    , m_isBuiltinFunction(false)
 {
     if (m_shouldEmitDebugHooks)
         m_codeBlock->setNeedsFullScopeChain(true);
@@ -222,7 +223,13 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionBodyNode* functionBody, Unl
 #endif
     , m_usesExceptions(false)
     , m_expressionTooDeep(false)
+    , m_isBuiltinFunction(codeBlock->isBuiltinFunction())
 {
+    if (m_isBuiltinFunction) {
+        m_shouldEmitProfileHooks = false;
+        m_shouldEmitDebugHooks = false;
+    }
+
     if (m_shouldEmitDebugHooks)
         m_codeBlock->setNeedsFullScopeChain(true);
 
@@ -438,6 +445,7 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCod
 #endif
     , m_usesExceptions(false)
     , m_expressionTooDeep(false)
+    , m_isBuiltinFunction(false)
 {
     m_codeBlock->setNeedsFullScopeChain(true);
 
index 4e9f213..1584274 100644 (file)
@@ -461,7 +461,9 @@ namespace JSC {
         bool shouldEmitDebugHooks() { return m_shouldEmitDebugHooks; }
         
         bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
-
+        
+        bool isBuiltinFunction() const { return m_isBuiltinFunction; }
+        
     private:
         friend class Label;
         
@@ -543,7 +545,7 @@ namespace JSC {
         
         UnlinkedFunctionExecutable* makeFunction(FunctionBodyNode* body)
         {
-            return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), body);
+            return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), body, false, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction);
         }
 
         RegisterID* emitInitLazyRegister(RegisterID*);
@@ -677,6 +679,7 @@ namespace JSC {
 
         bool m_usesExceptions;
         bool m_expressionTooDeep;
+        bool m_isBuiltinFunction;
     };
 
 }
index 1ffd4f3..62eca36 100644 (file)
 
 #include "config.h"
 #include "Nodes.h"
-#include "NodeConstructors.h"
 
 #include "BytecodeGenerator.h"
 #include "CallFrame.h"
+#include "CommonIdentifiers.h"
 #include "Debugger.h"
 #include "JIT.h"
 #include "JSFunction.h"
@@ -38,6 +38,7 @@
 #include "JSONObject.h"
 #include "LabelScope.h"
 #include "Lexer.h"
+#include "NodeConstructors.h"
 #include "Operations.h"
 #include "Parser.h"
 #include "PropertyNameArray.h"
@@ -535,36 +536,39 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
     RefPtr<Label> end = generator.newLabel();
     RefPtr<RegisterID> base = generator.emitNode(m_base);
     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
-    RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
+    RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().call);
     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
-    generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
+    bool emitCallCheck = !generator.isBuiltinFunction();
+    if (emitCallCheck)
+        generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
+
     {
         if (m_args->m_listNode && m_args->m_listNode->m_expr) {
             ArgumentListNode* oldList = m_args->m_listNode;
             m_args->m_listNode = m_args->m_listNode->m_next;
-
+            
             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
             CallArguments callArguments(generator, m_args);
             generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
             generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
-            generator.emitJump(end.get());
-
             m_args->m_listNode = oldList;
         } else {
             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
             CallArguments callArguments(generator, m_args);
             generator.emitLoad(callArguments.thisRegister(), jsUndefined());
             generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
-            generator.emitJump(end.get());
         }
     }
-    generator.emitLabel(realCall.get());
-    {
-        CallArguments callArguments(generator, m_args);
-        generator.emitMove(callArguments.thisRegister(), base.get());
-        generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+    if (emitCallCheck) {
+        generator.emitJump(end.get());
+        generator.emitLabel(realCall.get());
+        {
+            CallArguments callArguments(generator, m_args);
+            generator.emitMove(callArguments.thisRegister(), base.get());
+            generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+        }
+        generator.emitLabel(end.get());
     }
-    generator.emitLabel(end.get());
     return returnValue.get();
 }
 
@@ -585,65 +589,67 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
     RefPtr<Label> end = generator.newLabel();
     RefPtr<RegisterID> base = generator.emitNode(m_base);
     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
-    RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
+    RefPtr<RegisterID> function;
     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
-    generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
-    {
-        if (mayBeCall) {
-            if (m_args->m_listNode && m_args->m_listNode->m_expr) {
-                ArgumentListNode* oldList = m_args->m_listNode;
-                if (m_args->m_listNode->m_next) {
-                    ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
-                    ASSERT(!m_args->m_listNode->m_next->m_next);
-                    m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.vm(), 0, 0);
-                    RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
-                    CallArguments callArguments(generator, m_args);
-                    generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
-                    generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
-                } else {
-                    m_args->m_listNode = m_args->m_listNode->m_next;
-                    RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
-                    CallArguments callArguments(generator, m_args);
-                    generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
-                    generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
-                }
-                m_args->m_listNode = oldList;
+    bool emitCallCheck = !generator.isBuiltinFunction();
+    if (emitCallCheck) {
+        function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().apply);
+        generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
+    }
+    if (mayBeCall) {
+        if (m_args->m_listNode && m_args->m_listNode->m_expr) {
+            ArgumentListNode* oldList = m_args->m_listNode;
+            if (m_args->m_listNode->m_next) {
+                ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
+                ASSERT(!m_args->m_listNode->m_next->m_next);
+                m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.vm(), 0, 0);
+                RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+                CallArguments callArguments(generator, m_args);
+                generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
+                generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
             } else {
+                m_args->m_listNode = m_args->m_listNode->m_next;
                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
                 CallArguments callArguments(generator, m_args);
-                generator.emitLoad(callArguments.thisRegister(), jsUndefined());
+                generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
                 generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
             }
+            m_args->m_listNode = oldList;
         } else {
-            ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
-            RefPtr<RegisterID> profileHookRegister;
-            if (generator.shouldEmitProfileHooks())
-                profileHookRegister = generator.newTemporary();
             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
-            RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
-            RefPtr<RegisterID> argsRegister;
-            ArgumentListNode* args = m_args->m_listNode->m_next;
-            if (args->m_expr->isResolveNode() && generator.willResolveToArguments(static_cast<ResolveNode*>(args->m_expr)->identifier()))
-                argsRegister = generator.uncheckedRegisterForArguments();
-            else
-                argsRegister = generator.emitNode(args->m_expr);
-
-            // Function.prototype.apply ignores extra arguments, but we still
-            // need to evaluate them for side effects.
-            while ((args = args->m_next))
-                generator.emitNode(args->m_expr);
-
-            generator.emitCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), profileHookRegister.get(), divot(), divotStart(), divotEnd());
+            CallArguments callArguments(generator, m_args);
+            generator.emitLoad(callArguments.thisRegister(), jsUndefined());
+            generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
         }
-        generator.emitJump(end.get());
+    } else {
+        ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
+        RefPtr<RegisterID> profileHookRegister;
+        if (generator.shouldEmitProfileHooks())
+            profileHookRegister = generator.newTemporary();
+        RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+        RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
+        RefPtr<RegisterID> argsRegister;
+        ArgumentListNode* args = m_args->m_listNode->m_next;
+        if (args->m_expr->isResolveNode() && generator.willResolveToArguments(static_cast<ResolveNode*>(args->m_expr)->identifier()))
+            argsRegister = generator.uncheckedRegisterForArguments();
+        else
+            argsRegister = generator.emitNode(args->m_expr);
+
+        // Function.prototype.apply ignores extra arguments, but we still
+        // need to evaluate them for side effects.
+        while ((args = args->m_next))
+            generator.emitNode(args->m_expr);
+
+        generator.emitCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), profileHookRegister.get(), divot(), divotStart(), divotEnd());
     }
-    generator.emitLabel(realCall.get());
-    {
+    if (emitCallCheck) {
+        generator.emitJump(end.get());
+        generator.emitLabel(realCall.get());
         CallArguments callArguments(generator, m_args);
         generator.emitMove(callArguments.thisRegister(), base.get());
         generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
+        generator.emitLabel(end.get());
     }
-    generator.emitLabel(end.get());
     return returnValue.get();
 }
 
index 397976b..cad65bc 100755 (executable)
@@ -289,7 +289,17 @@ sub output() {
             $intrinsic = "RegExpTestIntrinsic" if ($key eq "test");
         }
 
+        if ($values[$i]{"type"} eq "Function")  {
+            my $tableHead = $name;
+            $tableHead =~ s/Table$//;
+            print " #if JSC_BUILTIN_EXISTS(" . uc($tableHead . $key) .")\n";
+            print "   { \"$key\", (($attrs[$i]) & ~Function) | Builtin, $intrinsic, (intptr_t)static_cast<BuiltinGenerator>(" . $tableHead . ucfirst($key) . "CodeGenerator), (intptr_t)$secondValue },\n";
+            print " #else\n"
+        }
         print "   { \"$key\", $attrs[$i], $intrinsic, (intptr_t)" . $firstCastStr . "($firstValue), (intptr_t)" . $secondCastStr . "($secondValue) },\n";
+        if ($values[$i]{"type"} eq "Function")  {
+            print " #endif\n"
+        }
         $i++;
     }
     print "   { 0, 0, NoIntrinsic, 0, 0 }\n";
index a5ae614..20096e7 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 #include "DFGDominators.h"
+#include "JSFunctionInlines.h"
 
 #if ENABLE(DFG_JIT)
 
index 93c41fb..d86ac8b 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(DFG_JIT)
 
 #include "CodeBlock.h"
+#include "JSCJSValueInlines.h"
 
 namespace JSC { namespace DFG {
 
index 2ff0c34..9044cdc 100644 (file)
@@ -48,6 +48,7 @@
 #include "JSActivation.h"
 #include "VM.h"
 #include "JSNameScope.h"
+#include "JSStringInlines.h"
 #include "NameInstance.h"
 #include "ObjectConstructor.h"
 #include "Operations.h"
diff --git a/Source/JavaScriptCore/generate-js-builtins b/Source/JavaScriptCore/generate-js-builtins
new file mode 100644 (file)
index 0000000..eee1c7a
--- /dev/null
@@ -0,0 +1,304 @@
+#!/usr/bin/python
+# Copyright (C) 2014 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. ``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
+# 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.
+
+import filecmp
+import fnmatch
+import os
+import re
+import shutil
+import sys
+import datetime
+import json
+
+copyrightText = """ *
+ * 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. ``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
+ * 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. 
+ */\n
+"""
+
+generatorString = "/* Generated by %s do not hand edit. */\n" % os.path.basename(__file__)
+
+functionHeadRegExp = re.compile(r"function\s+\w+\s*\(.*?\)", re.MULTILINE | re.S)
+functionNameRegExp = re.compile(r"function\s+(\w+)\s*\(", re.MULTILINE | re.S)
+functionParameterFinder = re.compile(r"^function\s+(?:\w+)\s*\(((?:\s*\w+)?\s*(?:\s*,\s*\w+)*)?\)", re.MULTILINE | re.S)
+
+multilineCommentRegExp = re.compile(r"\/\*.*?\*\/", re.MULTILINE | re.S)
+singleLineCommentRegExp = re.compile(r"\/\/.*?\n", re.MULTILINE | re.S)
+
+def getCopyright(source):
+    copyrightBlock = multilineCommentRegExp.findall(source)[0]
+    copyrightBlock = copyrightBlock[:copyrightBlock.index("Redistribution")]
+    copyRightLines = []
+
+    for line in copyrightBlock.split("\n"):
+        line = line.replace("/*", "")
+        line = line.replace("*/", "")
+        line = line.replace("*", "")
+        line = line.replace("Copyright", "")
+        line = line.replace("copyright", "")
+        line = line.replace("(C)", "")
+        line = line.replace("(c)", "")
+        line = line.strip()
+        if len(line) == 0:
+            continue
+
+        copyRightLines.append(line)
+    
+    return list(set(copyRightLines))
+
+
+
+def getFunctions(source):
+
+    source = multilineCommentRegExp.sub("/**/", singleLineCommentRegExp.sub("//\n", source))
+
+    matches = [ f for f in functionHeadRegExp.finditer(source)]
+    functionBounds = []
+    start = 0
+    end = 0
+    for match in matches:
+        start = match.start()
+        if start < end:
+            continue
+        end = match.end()
+        while source[end] != '{':
+            end = end + 1
+        depth = 1
+        end = end + 1
+        while depth > 0:
+            if source[end] == '{':
+                depth = depth + 1
+            elif source[end] == '}':
+                depth = depth - 1
+            end = end + 1
+        functionBounds.append((start, end))
+
+    functions = [source[start:end].strip() for (start, end) in functionBounds]
+    result = []
+    for function in functions:
+        function = multilineCommentRegExp.sub("", function)
+        functionName = functionNameRegExp.findall(function)[0]
+        functionParameters = functionParameterFinder.findall(function)[0].split(',')
+        if len(functionParameters[0]) == 0:
+            functionParameters = []
+            
+        result.append((functionName, function, functionParameters))
+    return result
+        
+
+def generateCode(source):
+    inputFile = open(source, "r")
+    baseName = os.path.basename(source).replace(".js", "")
+    
+    source = ""
+    for line in inputFile:
+        source = source + line
+    
+    if sys.platform == "cygwin":
+        source = source.replace("\r\n", "\n")
+    return (baseName, getFunctions(source), getCopyright(source))
+
+def mangleName(object, name):
+    qName = object + "." + name
+    mangledName = ""
+    i = 0
+    while i < len(qName):
+        if qName[i] == '.':
+            mangledName = mangledName + qName[i + 1].upper()
+            i = i + 1
+        else:
+            mangledName = mangledName + qName[i]
+        i = i + 1
+    return mangledName
+
+builtins = []
+
+baseName = sys.argv[-1]
+builtin_definitions = sys.argv[1:-1]
+(output_base, _) = os.path.splitext(sys.argv[-1])
+
+copyrights = []
+for file in builtin_definitions:
+    if fnmatch.fnmatch(file, '*.js'):
+        (baseName, functions, objectCopyrights) = generateCode(file)
+        copyrights.extend(objectCopyrights)
+        builtins.append((baseName, functions))
+
+copyrights = list(set(copyrights))
+
+copyrightBody = ""
+for copyright in copyrights:
+    copyrightBody = copyrightBody +" * Copyright (C) " + copyright + "\n"
+
+builtinsHeader = open(output_base + ".h.tmp", "w")
+builtinsImplementation = open(output_base + ".cpp.tmp", "w")
+copyrightText = "/*\n" + copyrightBody + copyrightText
+builtinsHeader.write("""%s
+%s
+
+#ifndef JSCBuiltins_H
+#define JSCBuiltins_H
+
+namespace JSC {
+
+class FunctionExecutable;
+class Identifier;
+class JSGlobalObject;
+class SourceCode;
+class UnlinkedFunctionExecutable;
+class VM;
+
+FunctionExecutable* createBuiltinExecutable(VM&, UnlinkedFunctionExecutable*, const SourceCode&);
+
+""" % (generatorString, copyrightText))
+
+codeReferences = []
+
+for (objectName, functions) in builtins:
+    print("Generating bindings for the %s builtin." % objectName)
+    builtinsHeader.write("/* %s functions */\n" % objectName)
+    for (name, implementation, _) in functions:
+        mangledName = mangleName(objectName, name)
+        mangledName = mangledName[0].lower() + mangledName[1:] + "Code"
+        codeReferences.append((mangledName, name, implementation))
+        builtinsHeader.write("extern const char* s_%s;\n" % mangledName)
+        builtinsHeader.write("extern const int s_%sLength;\n" % mangledName)
+    builtinsHeader.write("\n")
+    builtinsHeader.write("#define JSC_FOREACH_%s_BUILTIN(macro) \\\n" % objectName.replace(".", "_").upper())
+    for (name, implementation, arguments) in functions:
+        mangledName = mangleName(objectName, name)
+        builtinsHeader.write("    macro(%s, %s, %d) \\\n" % (name, mangledName, len(arguments)))
+    builtinsHeader.write("\n")
+    for (name, implementation, arguments) in functions:
+        builtinsHeader.write("#define JSC_BUILTIN_%s 1\n" % mangleName(objectName, name).upper())
+    builtinsHeader.write("\n\n")
+names = []
+builtinsHeader.write("#define JSC_FOREACH_BUILTIN(macro)\\\n")
+for (codeReference, functionName, source) in codeReferences:
+    builtinsHeader.write("    macro(%s, %s, s_%sLength) \\\n" % (codeReference, functionName, codeReference))
+    names.append(functionName)
+
+builtinsHeader.write("\n\n")
+builtinsHeader.write("#define JSC_FOREACH_BUILTIN_FUNCTION_NAME(macro) \\\n")
+for name in sorted(set(names)):
+    builtinsHeader.write("    macro(%s) \\\n" % name)
+builtinsHeader.write("""
+
+#define JSC_DECLARE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\
+    FunctionExecutable* codeName##Generator(VM&);
+
+JSC_FOREACH_BUILTIN(JSC_DECLARE_BUILTIN_GENERATOR)
+#undef JSC_DECLARE_BUILTIN_GENERATOR
+
+#define JSC_BUILTIN_EXISTS(name) defined(JSC_BUILTIN_##name)
+
+}
+
+#endif
+
+""")
+
+builtinsImplementation.write("""%s
+%s
+
+#include "config.h"
+
+#include "JSCBuiltins.h"
+
+#include "BuiltinExecutables.h"
+#include "Executable.h"
+#include "JSCellInlines.h"
+#include "VM.h"
+
+namespace JSC {
+
+"""  % (generatorString, copyrightText))
+
+for (codeReference, name, source) in codeReferences:
+    source = "(function " + source[source.index("("):] + ")"
+    lines = json.dumps(source)[1:-1].split("\\n")
+    sourceLength = len(source)
+    source = ""
+    for line in lines:
+        source = source + ("    \"%s\\n\" \\\n" % line)
+    builtinsImplementation.write("const char* s_%s =\n%s;\n\n" % (codeReference, source))
+    builtinsImplementation.write("const int s_%sLength = %d;\n\n" % (codeReference, sourceLength + 1)) # + 1 for \n
+
+builtinsImplementation.write("""
+FunctionExecutable* createBuiltinExecutable(VM& vm, UnlinkedFunctionExecutable* unlinkedExecutable, const SourceCode& source)
+{
+    unsigned lineCount = unlinkedExecutable->lineCount();
+    unsigned startColumn = 1;
+    unsigned sourceLength = unlinkedExecutable->sourceLength();
+    bool endColumnIsOnStartLine = !lineCount;
+    unsigned endColumnExcludingBraces = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? 0 : 1);
+    unsigned startOffset = unlinkedExecutable->startOffset();
+    unsigned startOffsetExcludingOpenBrace = startOffset + 1;
+    unsigned endOffsetExcludingCloseBrace = startOffset + sourceLength - 1;
+    SourceCode bodySource(source.provider(), startOffsetExcludingOpenBrace, endOffsetExcludingCloseBrace, 0, startColumn);
+    return FunctionExecutable::create(vm, bodySource, unlinkedExecutable, 0, lineCount, startColumn, endColumnExcludingBraces, false);
+}
+
+#define JSC_DEFINE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\
+FunctionExecutable* codeName##Generator(VM& vm) \\
+{ \\
+    return createBuiltinExecutable(vm, vm.builtinExecutables()->codeName##Executable(), vm.builtinExecutables()->codeName##Source()); \\
+}
+
+JSC_FOREACH_BUILTIN(JSC_DEFINE_BUILTIN_GENERATOR)
+#undef JSC_DEFINE_BUILTIN_GENERATOR
+}
+
+""")
+
+builtinsHeader.close()
+builtinsImplementation.close()
+
+if (not os.path.exists(output_base + ".h")) or (not filecmp.cmp(output_base + ".h.tmp", output_base + ".h", shallow=False)):
+    os.rename(output_base + ".h.tmp", output_base + ".h")
+else:
+    os.remove(output_base + ".h.tmp")
+
+if (not os.path.exists(output_base + ".cpp")) or (not filecmp.cmp(output_base + ".cpp.tmp", output_base + ".cpp", shallow=False)):
+    os.rename(output_base + ".cpp.tmp", output_base + ".cpp")
+else:
+    os.remove(output_base + ".cpp.tmp")
index 2ca3e97..30cad2a 100644 (file)
@@ -43,7 +43,7 @@ namespace JSC {
             , m_interpreter(callFrame->interpreter())
             , m_entryScope(callFrame->vm(), function->scope()->globalObject())
         {
-            ASSERT(!function->isHostFunction());
+            ASSERT(!function->isHostFunctionNonInline());
             if (callFrame->vm().isSafeToRecurse()) {
                 m_arguments.resize(argumentCount);
                 m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, &m_protoCallFrame, function, argumentCount + 1, function->scope(), m_arguments.data());
index fa88e0f..9d2c5d5 100644 (file)
@@ -51,6 +51,7 @@
 #include "JSPropertyNameIterator.h"
 #include "JSStackInlines.h"
 #include "JSString.h"
+#include "JSStringInlines.h"
 #include "JSWithScope.h"
 #include "LLIntCLoop.h"
 #include "LLIntThunks.h"
index f0e02ba..1c240dc 100644 (file)
@@ -27,6 +27,7 @@
 #include "ProtoCallFrame.h"
 
 #include "CodeBlock.h"
+#include "JSCJSValueInlines.h"
 #include "StackAlignment.h"
 
 namespace JSC {
index ca7ad11..cb5507b 100644 (file)
@@ -34,6 +34,7 @@
 #include "Heap.h"
 #include "JITInlines.h"
 #include "JSArray.h"
+#include "JSCJSValueInlines.h"
 #include "JSCell.h"
 #include "JSFunction.h"
 #include "JSPropertyNameIterator.h"
index 98d10a3..dd03537 100644 (file)
@@ -34,6 +34,7 @@
 #include "Debugger.h"
 #include "JITInlines.h"
 #include "JSArray.h"
+#include "JSCJSValueInlines.h"
 #include "JSCell.h"
 #include "JSFunction.h"
 #include "JSPropertyNameIterator.h"
index 928dd50..99f5db0 100644 (file)
 #include "JIT.h"
 #include "JITOperationWrappers.h"
 #include "JITToDFGDeferredCompilationCallback.h"
+#include "JSCJSValueInlines.h"
+#include "JSFunctionInlines.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSNameScope.h"
 #include "JSPropertyNameIterator.h"
 #include "JSStackInlines.h"
+#include "JSStringInlines.h"
 #include "JSWithScope.h"
 #include "ObjectConstructor.h"
 #include "Operations.h"
index 26dd4d1..df1bd3a 100644 (file)
 #include "JIT.h"
 
 #include "CodeBlock.h"
+#include "CommonIdentifiers.h"
 #include "GCAwareJITStubRoutine.h"
 #include "GetterSetter.h"
 #include "Interpreter.h"
 #include "JITInlines.h"
 #include "JSArray.h"
+#include "JSCJSValueInlines.h"
 #include "JSFunction.h"
 #include "JSPropertyNameIterator.h"
 #include "JSVariableObject.h"
index 40784b4..2f79555 100644 (file)
@@ -38,6 +38,7 @@
 #include "JSLock.h"
 #include "JSProxy.h"
 #include "JSString.h"
+#include "JSStringInlines.h"
 #include "Operations.h"
 #include "SamplingTool.h"
 #include "StackVisitor.h"
index 604cc26..8166e7f 100644 (file)
@@ -35,7 +35,7 @@
 #include "JITStubs.h"
 #include "JSArray.h"
 #include "JSCell.h"
-#include "JSFunction.h"
+#include "JSFunctionInlines.h"
 #include "VM.h"
 #include "JSGlobalObject.h"
 #include "JSObject.h"
index 66444ba..83c98df 100644 (file)
@@ -45,7 +45,7 @@
 #include "JSNameScope.h"
 #include "JSPropertyNameIterator.h"
 #include "JSStackInlines.h"
-#include "JSString.h"
+#include "JSStringInlines.h"
 #include "JSWithScope.h"
 #include "LLIntCommon.h"
 #include "LLIntExceptions.h"
index 8ec1fd3..46a7c76 100644 (file)
@@ -888,9 +888,9 @@ ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location
     ASSERT(func->isDotAccessorNode());
     DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
     FunctionCallDotNode* node;
-    if (dot->identifier() == m_vm->propertyNames->call)
+    if (dot->identifier() == m_vm->propertyNames->call || dot->identifier() == m_vm->propertyNames->callPrivateName)
         node = new (m_vm) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
-    else if (dot->identifier() == m_vm->propertyNames->apply)
+    else if (dot->identifier() == m_vm->propertyNames->apply || dot->identifier() == m_vm->propertyNames->applyPrivateName)
         node = new (m_vm) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
     else
         node = new (m_vm) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
index ca4bb4f..ccb079d 100644 (file)
 #include "config.h"
 #include "Lexer.h"
 
+#include "CommonIdentifiers.h"
+#include "Identifier.h"
 #include "JSFunctionInlines.h"
-
 #include "JSGlobalObjectFunctions.h"
-#include "Identifier.h"
 #include "NodeInfo.h"
 #include "Nodes.h"
 #include <wtf/dtoa.h>
@@ -90,6 +90,7 @@ enum CharacterType {
 
     // Other types (only one so far)
     CharacterWhiteSpace,
+    CharacterPrivateIdentifierStart
 };
 
 // 256 Latin-1 codes
@@ -158,7 +159,7 @@ static const unsigned short typesOfLatin1Characters[256] = {
 /*  61 - =                  */ CharacterEqual,
 /*  62 - >                  */ CharacterGreater,
 /*  63 - ?                  */ CharacterQuestion,
-/*  64 - @                  */ CharacterInvalid,
+/*  64 - @                  */ CharacterPrivateIdentifierStart,
 /*  65 - A                  */ CharacterIdentifierStart,
 /*  66 - B                  */ CharacterIdentifierStart,
 /*  67 - C                  */ CharacterIdentifierStart,
@@ -486,9 +487,10 @@ static const LChar singleCharacterEscapeValuesForASCII[128] = {
 };
 
 template <typename T>
-Lexer<T>::Lexer(VM* vm)
+Lexer<T>::Lexer(VM* vm, JSParserStrictness strictness)
     : m_isReparsing(false)
     , m_vm(vm)
+    , m_parsingBuiltinFunction(strictness == JSParseBuiltin)
 {
 }
 
@@ -753,7 +755,27 @@ inline void Lexer<T>::record16(int c)
     ASSERT(c <= static_cast<int>(USHRT_MAX));
     m_buffer16.append(static_cast<UChar>(c));
 }
-
+    
+#if !ASSERT_DISABLED
+bool isSafeIdentifier(VM& vm, const Identifier* ident)
+{
+    if (!ident)
+        return true;
+    /* Just block any use of suspicious identifiers.  This is intended to
+     * be used as a safety net while implementing builtins.
+     */
+    if (*ident == vm.propertyNames->call)
+        return false;
+    if (*ident == vm.propertyNames->apply)
+        return false;
+    if (*ident == vm.propertyNames->eval)
+        return false;
+    if (*ident == vm.propertyNames->Function)
+        return false;
+    return true;
+}
+#endif
+    
 template <>
 template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::parseIdentifier(JSTokenData* tokenData, unsigned lexerFlags, bool strictMode)
 {
@@ -765,7 +787,11 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::p
             return keyword == RESERVED_IF_STRICT && !strictMode ? IDENT : keyword;
         }
     }
-
+    
+    bool isPrivateName = m_current == '@' && m_parsingBuiltinFunction;
+    if (isPrivateName)
+        shift();
+    
     const LChar* identifierStart = currentSourcePtr();
     unsigned identifierLineStart = currentLineStartOffset();
     
@@ -779,15 +805,26 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::p
 
     const Identifier* ident = 0;
     
-    if (shouldCreateIdentifier) {
+    if (shouldCreateIdentifier || m_parsingBuiltinFunction) {
         int identifierLength = currentSourcePtr() - identifierStart;
         ident = makeIdentifier(identifierStart, identifierLength);
-
+        if (m_parsingBuiltinFunction) {
+            if (!isSafeIdentifier(*m_vm, ident) && !isPrivateName) {
+                m_lexErrorMessage = makeString("The use of '", ident->string(), "' is disallowed in builtin functions.");
+                return ERRORTOK;
+            }
+            if (isPrivateName)
+                ident = m_vm->propertyNames->getPrivateName(*ident);
+            else if (*ident == m_vm->propertyNames->undefinedKeyword)
+                tokenData->ident = &m_vm->propertyNames->undefinedKeywordPrivateName;
+            if (!ident)
+                return INVALID_PRIVATE_NAME_ERRORTOK;
+        }
         tokenData->ident = ident;
     } else
         tokenData->ident = 0;
 
-    if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords))) {
+    if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords)) && !isPrivateName) {
         ASSERT(shouldCreateIdentifier);
         if (remaining < maxTokenLength) {
             const HashEntry* entry = m_vm->keywords->getKeyword(*ident);
@@ -814,6 +851,10 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
             return keyword == RESERVED_IF_STRICT && !strictMode ? IDENT : keyword;
         }
     }
+    
+    bool isPrivateName = m_current == '@' && m_parsingBuiltinFunction;
+    if (isPrivateName)
+        shift();
 
     const UChar* identifierStart = currentSourcePtr();
     int identifierLineStart = currentLineStartOffset();
@@ -826,6 +867,7 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
     }
     
     if (UNLIKELY(m_current == '\\')) {
+        ASSERT(!isPrivateName);
         setOffsetFromSourcePtr(identifierStart, identifierLineStart);
         return parseIdentifierSlowCase<shouldCreateIdentifier>(tokenData, lexerFlags, strictMode);
     }
@@ -837,18 +879,29 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
 
     const Identifier* ident = 0;
     
-    if (shouldCreateIdentifier) {
+    if (shouldCreateIdentifier || m_parsingBuiltinFunction) {
         int identifierLength = currentSourcePtr() - identifierStart;
         if (isAll8Bit)
             ident = makeIdentifierLCharFromUChar(identifierStart, identifierLength);
         else
             ident = makeIdentifier(identifierStart, identifierLength);
-        
+        if (m_parsingBuiltinFunction) {
+            if (!isSafeIdentifier(*m_vm, ident) && !isPrivateName) {
+                m_lexErrorMessage = makeString("The use of '", ident->string(), "' is disallowed in builtin functions.");
+                return ERRORTOK;
+            }
+            if (isPrivateName)
+                ident = m_vm->propertyNames->getPrivateName(*ident);
+            else if (*ident == m_vm->propertyNames->undefinedKeyword)
+                tokenData->ident = &m_vm->propertyNames->undefinedKeywordPrivateName;
+            if (!ident)
+                return INVALID_PRIVATE_NAME_ERRORTOK;
+        }
         tokenData->ident = ident;
     } else
         tokenData->ident = 0;
     
-    if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords))) {
+    if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords)) && !isPrivateName) {
         ASSERT(shouldCreateIdentifier);
         if (remaining < maxTokenLength) {
             const HashEntry* entry = m_vm->keywords->getKeyword(*ident);
@@ -1658,6 +1711,7 @@ inNumberAfterDecimalPoint:
         ASSERT(isIdentStart(m_current));
         FALLTHROUGH;
     case CharacterBackSlash:
+        parseIdent:
         if (lexerFlags & LexexFlagsDontBuildKeywords)
             token = parseIdentifier<false>(tokenData, lexerFlags, strictMode);
         else
@@ -1670,6 +1724,11 @@ inNumberAfterDecimalPoint:
         m_terminator = true;
         m_lineStart = m_code;
         goto start;
+    case CharacterPrivateIdentifierStart:
+        if (m_parsingBuiltinFunction)
+            goto parseIdent;
+
+        FALLTHROUGH;
     case CharacterInvalid:
         m_lexErrorMessage = invalidCharacterMessage();
         token = ERRORTOK;
index 28c61ba..b8873e9 100644 (file)
@@ -72,7 +72,7 @@ class Lexer {
     WTF_MAKE_FAST_ALLOCATED;
 
 public:
-    Lexer(VM*);
+    Lexer(VM*, JSParserStrictness);
     ~Lexer();
 
     // Character manipulation functions.
@@ -238,6 +238,7 @@ private:
     IdentifierArena* m_arena;
 
     VM* m_vm;
+    bool m_parsingBuiltinFunction;
 };
 
 template <>
@@ -335,6 +336,12 @@ ALWAYS_INLINE const Identifier* Lexer<T>::makeLCharIdentifier(const UChar* chara
     return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length);
 }
 
+#if ASSERT_DISABLED
+ALWAYS_INLINE bool isSafeIdentifier(VM&, const Identifier*) { return true; }
+#else
+bool isSafeIdentifier(VM&, const Identifier*);
+#endif
+
 template <typename T>
 ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSToken* tokenRecord, unsigned lexerFlags, bool strictMode)
 {
@@ -370,10 +377,15 @@ ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSToken* tokenRecord, un
     ASSERT(currentOffset() >= currentLineStartOffset());
 
     // Create the identifier if needed
-    if (lexerFlags & LexexFlagsDontBuildKeywords)
+    if (lexerFlags & LexexFlagsDontBuildKeywords
+#if !ASSERT_DISABLED
+        && !m_parsingBuiltinFunction
+#endif
+        )
         tokenData->ident = 0;
     else
         tokenData->ident = makeLCharIdentifier(start, ptr - start);
+
     tokenLocation->line = m_lineNumber;
     tokenLocation->lineStartOffset = currentLineStartOffset();
     tokenLocation->startOffset = offsetFromSourcePtr(start);
@@ -381,6 +393,13 @@ ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSToken* tokenRecord, un
     ASSERT(tokenLocation->startOffset >= tokenLocation->lineStartOffset);
     tokenRecord->m_startPosition = startPosition;
     tokenRecord->m_endPosition = currentPosition();
+#if !ASSERT_DISABLED
+    if (m_parsingBuiltinFunction) {
+        if (!isSafeIdentifier(*m_vm, tokenData->ident))
+            return ERRORTOK;
+    }
+#endif
+
     m_lastToken = IDENT;
     return IDENT;
     
index fc9ccd9..d952ba6 100644 (file)
@@ -132,6 +132,12 @@ PassRefPtr<ProgramNode> ProgramNode::create(VM* vm, const JSTokenLocation& start
     return node.release();
 }
 
+
+void ProgramNode::setClosedVariables(const Vector<RefPtr<StringImpl>>&& closedVariables)
+{
+    m_closedVariables = std::move(closedVariables);
+}
+
 // ------------------------------ EvalNode -----------------------------
 
 inline EvalNode::EvalNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
index d779a17..816ff00 100644 (file)
@@ -1431,6 +1431,7 @@ namespace JSC {
         bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
         bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
         size_t capturedVariableCount() const { return m_capturedVariables.size(); }
+        const IdentifierSet& capturedVariables() const { return m_capturedVariables; }
         bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
 
         VarStack& varStack() { return m_varStack; }
@@ -1446,6 +1447,8 @@ namespace JSC {
         StatementNode* singleStatement() const;
 
         void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
+        
+        void setClosedVariables(const Vector<RefPtr<StringImpl>>&&) { }
 
     protected:
         void setSource(const SourceCode& source) { m_source = source; }
@@ -1475,11 +1478,13 @@ namespace JSC {
 
         static const bool scopeIsFunction = false;
 
+        void setClosedVariables(const Vector<RefPtr<StringImpl>>&&);
+        const Vector<RefPtr<StringImpl>>& closedVariables() const { return m_closedVariables; }
     private:
         ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
 
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
-
+        Vector<RefPtr<StringImpl>> m_closedVariables;
         unsigned m_startColumn;
         unsigned m_endColumn;
     };
index 297666e..50bec79 100644 (file)
@@ -204,8 +204,9 @@ Parser<LexerType>::Parser(VM* vm, const SourceCode& source, FunctionParameters*
     , m_lastIdentifier(0)
     , m_lastFunctionName(nullptr)
     , m_sourceElements(0)
+    , m_parsingBuiltin(strictness == JSParseBuiltin)
 {
-    m_lexer = adoptPtr(new LexerType(vm));
+    m_lexer = adoptPtr(new LexerType(vm, strictness));
     m_arena = m_vm->parserArena.get();
     m_lexer->setCode(source, m_arena);
     m_token.m_location.line = source.firstLine();
@@ -256,6 +257,7 @@ String Parser<LexerType>::parseInner()
     IdentifierSet capturedVariables;
     bool modifiedParameter = false;
     scope->getCapturedVariables(capturedVariables, modifiedParameter);
+    
     CodeFeatures features = context.features();
     if (scope->strictMode())
         features |= StrictModeFeature;
@@ -263,21 +265,36 @@ String Parser<LexerType>::parseInner()
         features |= ShadowsArgumentsFeature;
     if (modifiedParameter)
         features |= ModifiedParameterFeature;
-
+    
+    Vector<RefPtr<StringImpl>> closedVariables;
+    if (m_parsingBuiltin) {
+        RELEASE_ASSERT(!capturedVariables.size());
+        IdentifierSet usedVariables;
+        scope->getUsedVariables(usedVariables);
+        for (const auto& variable : usedVariables) {
+            if (scope->hasDeclaredVariable(Identifier(m_vm, variable.get())))
+                continue;
+            
+            if (scope->hasDeclaredParameter(Identifier(m_vm, variable.get())))
+                continue;
+            closedVariables.append(variable);
+        }
+    }
     didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features,
-        context.numConstants(), capturedVariables);
+        context.numConstants(), capturedVariables, std::move(closedVariables));
 
     return parseError;
 }
 
 template <typename LexerType>
 void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack, 
-    ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int numConstants, IdentifierSet& capturedVars)
+    ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int numConstants, IdentifierSet& capturedVars, const Vector<RefPtr<StringImpl>>&& closedVariables)
 {
     m_sourceElements = sourceElements;
     m_varDeclarations = varStack;
     m_funcDeclarations = funcStack;
     m_capturedVariables.swap(capturedVars);
+    m_closedVariables = closedVariables;
     m_features = features;
     m_numConstants = numConstants;
 }
@@ -2346,6 +2363,10 @@ template <typename LexerType> void Parser<LexerType>::printUnexpectedTokenText(W
     case RESERVED:
         out.print("Unexpected use of reserved word '", getToken(), "'");
         return;
+
+    case INVALID_PRIVATE_NAME_ERRORTOK:
+        out.print("Invalid private name '", getToken(), "'");
+        return;
             
     case IDENT:
         out.print("Unexpected identifier '", getToken(), "'");
index b698ef9..9033850 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef Parser_h
 #define Parser_h
 
+#include "CommonIdentifiers.h"
 #include "Debugger.h"
 #include "ExceptionHelpers.h"
 #include "Executable.h"
@@ -259,6 +260,10 @@ struct Scope {
         return isValidStrictMode ? BindingSucceeded : StrictBindingFailed;
     }
 
+    void getUsedVariables(IdentifierSet& usedVariables)
+    {
+        usedVariables.swap(m_usedVariables);
+    }
 
     void useVariable(const Identifier* ident, bool isEval)
     {
@@ -414,6 +419,7 @@ public:
     PassRefPtr<ParsedNode> parse(ParserError&);
 
     JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
+    const Vector<RefPtr<StringImpl>>&& closedVariables() { return std::move(m_closedVariables); }
 
 private:
     struct AllowInOverride {
@@ -540,7 +546,7 @@ private:
     String parseInner();
 
     void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, 
-        ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures, int, IdentifierSet&);
+        ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures, int, IdentifierSet&, const Vector<RefPtr<StringImpl>>&&);
 
     // Used to determine type of error to report.
     bool isFunctionBodyNode(ScopeNode*) { return false; }
@@ -840,9 +846,11 @@ private:
     const Identifier* m_lastFunctionName;
     RefPtr<SourceProviderCache> m_functionCache;
     SourceElements* m_sourceElements;
+    bool m_parsingBuiltin;
     ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
     ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
     IdentifierSet m_capturedVariables;
+    Vector<RefPtr<StringImpl>> m_closedVariables;
     CodeFeatures m_features;
     int m_numConstants;
     
@@ -957,6 +965,10 @@ PassRefPtr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameter
         RefPtr<ParsedNode> result = parser.parse<ParsedNode>(error);
         if (positionBeforeLastNewline)
             *positionBeforeLastNewline = parser.positionBeforeLastNewline();
+        if (strictness == JSParseBuiltin) {
+            RELEASE_ASSERT(result);
+            result->setClosedVariables(std::move(parser.closedVariables()));
+        }
         return result.release();
     }
     Parser<Lexer<UChar>> parser(vm, source, parameters, name, strictness, parserMode);
index 4e9a17c..f7a75bf 100644 (file)
@@ -29,7 +29,7 @@
 
 namespace JSC {
 
-enum JSParserStrictness { JSParseNormal, JSParseStrict };
+enum JSParserStrictness { JSParseNormal, JSParseBuiltin, JSParseStrict };
 enum JSParserMode { JSParseProgramCode, JSParseFunctionCode };
 
 enum ProfilerMode { ProfilerOff, ProfilerOn };
index 82a2663..8c87ad9 100644 (file)
@@ -149,6 +149,7 @@ enum JSTokenType {
     INVALID_NUMERIC_LITERAL_ERRORTOK = 7 | ErrorTokenFlag,
     UNTERMINATED_STRING_LITERAL_ERRORTOK = 8 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
     INVALID_STRING_LITERAL_ERRORTOK = 9 | ErrorTokenFlag,
+    INVALID_PRIVATE_NAME_ERRORTOK = 10 | ErrorTokenFlag
 };
 
 struct JSTextPosition {
index 18f3891..f16fd3d 100644 (file)
@@ -25,6 +25,7 @@
 #define Arguments_h
 
 #include "CodeOrigin.h"
+#include "CommonIdentifiers.h"
 #include "JSActivation.h"
 #include "JSDestructibleObject.h"
 #include "JSFunction.h"
index dd0894f..5b4ae87 100644 (file)
@@ -26,7 +26,9 @@
 #include "config.h"
 #include "ArgumentsIteratorPrototype.h"
 
+#include "CommonIdentifiers.h"
 #include "JSArgumentsIterator.h"
+#include "JSCJSValueInlines.h"
 
 namespace JSC {
 
index 27ac6d4..6dc7be5 100644 (file)
@@ -33,6 +33,7 @@
 #include "JIT.h"
 #include "JSArrayIterator.h"
 #include "JSStringBuilder.h"
+#include "JSStringInlines.h"
 #include "JSStringJoiner.h"
 #include "Lookup.h"
 #include "ObjectPrototype.h"
@@ -56,7 +57,6 @@ static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState*);
 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState*);
 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState*);
 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState*);
 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState*);
 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState*);
 static EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState*);
@@ -954,69 +954,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec)
     return JSValue::encode(resultArray);
 }
 
-// Documentation for these three is available at:
-// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:every
-// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach
-// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some
-
-EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec)
-{
-    JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec);
-    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    JSValue function = exec->argument(0);
-    CallData callData;
-    CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone)
-        return throwVMTypeError(exec);
-
-    JSValue applyThis = exec->argument(1);
-
-    JSValue result = jsBoolean(true);
-
-    unsigned k = 0;
-    if (callType == CallTypeJS && isJSArray(thisObj)) {
-        JSFunction* f = jsCast<JSFunction*>(function);
-        JSArray* array = asArray(thisObj);
-        CachedCall cachedCall(exec, f, 3);
-        for (; k < length && !exec->hadException(); ++k) {
-            if (UNLIKELY(!array->canGetIndexQuickly(k)))
-                break;
-            
-            cachedCall.setThis(applyThis);
-            cachedCall.setArgument(0, array->getIndexQuickly(k));
-            cachedCall.setArgument(1, jsNumber(k));
-            cachedCall.setArgument(2, thisObj);
-            JSValue result = cachedCall.call();
-            if (!result.toBoolean(exec))
-                return JSValue::encode(jsBoolean(false));
-        }
-    }
-    for (; k < length && !exec->hadException(); ++k) {
-        PropertySlot slot(thisObj);
-        if (!thisObj->getPropertySlot(exec, k, slot))
-            continue;
-
-        MarkedArgumentBuffer eachArguments;
-        eachArguments.append(slot.getValue(exec, k));
-        eachArguments.append(jsNumber(k));
-        eachArguments.append(thisObj);
-
-        if (exec->hadException())
-            return JSValue::encode(jsUndefined());
-
-        bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
-        if (!predicateResult) {
-            result = jsBoolean(false);
-            break;
-        }
-    }
-
-    return JSValue::encode(result);
-}
-
 EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
 {
     JSObject* thisObj = exec->hostThisValue().toThis(exec, StrictMode).toObject(exec);
index 510e383..d304877 100644 (file)
@@ -144,24 +144,26 @@ UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& v
     JSTextPosition positionBeforeLastNewline;
     RefPtr<ProgramNode> program = parse<ProgramNode>(&vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error, &positionBeforeLastNewline);
     if (!program) {
-        ASSERT(error.m_type != ParserError::ErrorNone);
+        RELEASE_ASSERT(error.m_type != ParserError::ErrorNone);
         m_sourceCode.remove(addResult.iterator);
         return 0;
     }
 
     // This function assumes an input string that would result in a single anonymous function expression.
     StatementNode* exprStatement = program->singleStatement();
-    ASSERT(exprStatement);
-    ASSERT(exprStatement->isExprStatement());
+    RELEASE_ASSERT(exprStatement);
+    RELEASE_ASSERT(exprStatement->isExprStatement());
     ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
-    ASSERT(funcExpr);
+    RELEASE_ASSERT(funcExpr);
     RELEASE_ASSERT(funcExpr->isFuncExprNode());
     FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
+    RELEASE_ASSERT(!program->hasCapturedVariables());
+    
     body->setEndPosition(positionBeforeLastNewline);
-    ASSERT(body);
-    ASSERT(body->ident().isNull());
+    RELEASE_ASSERT(body);
+    RELEASE_ASSERT(body->ident().isNull());
 
-    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, body, true);
+    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, body, true, UnlinkedNormalFunction);
     functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string()));
 
     addResult.iterator->value = SourceCodeValue(vm, functionExecutable, m_sourceCode.age());
index 3f5c645..2fc2b72 100644 (file)
@@ -27,7 +27,10 @@ namespace JSC {
 
 #define INITIALIZE_PROPERTY_NAME(name) , name(vm, #name)
 #define INITIALIZE_KEYWORD(name) , name##Keyword(vm, #name)
-#define INITIALIZE_PRIVATE_NAME(name) , name##PrivateName(Identifier::from(PrivateName()))
+#define INITIALIZE_PRIVATE_NAME(name) \
+    , name##PrivateName(Identifier::from(PrivateName())) \
+    , m_##name##PublicStringPair(name, name##PrivateName) \
+
 
 CommonIdentifiers::CommonIdentifiers(VM* vm)
     : nullIdentifier()
@@ -38,8 +41,26 @@ CommonIdentifiers::CommonIdentifiers(VM* vm)
     , hasNextIdentifier(vm, "hasNext")
     JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(INITIALIZE_KEYWORD)
     JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
+    JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALIZE_PROPERTY_NAME)
     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PRIVATE_NAME)
 {
 }
 
+const Identifier* CommonIdentifiers::getPrivateName(const Identifier& ident) const
+{
+#define RETURN_IF_PRIVATE_NAME_MATCHES(name) if (m_##name##PublicStringPair.first == ident) return &m_##name##PublicStringPair.second;
+    JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(RETURN_IF_PRIVATE_NAME_MATCHES)
+#undef RETURN_IF_PRIVATE_NAME_MATCHES
+    return 0;
+}
+
+Identifier CommonIdentifiers::getPublicName(const Identifier& ident) const
+{
+#define RETURN_IF_PRIVATE_NAME_MATCHES(name) if (m_##name##PublicStringPair.second == ident) return m_##name##PublicStringPair.first;
+    JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(RETURN_IF_PRIVATE_NAME_MATCHES)
+#undef RETURN_IF_PRIVATE_NAME_MATCHES
+    RELEASE_ASSERT_NOT_REACHED();
+    return emptyIdentifier;
+}
+
 } // namespace JSC
index e8f9ed8..924d36a 100644 (file)
@@ -22,6 +22,7 @@
 #define CommonIdentifiers_h
 
 #include "Identifier.h"
+#include "JSCBuiltins.h"
 #include <wtf/Noncopyable.h>
 
 // MarkedArgumentBuffer of property names, passed to a macro so we can do set them up various
     macro(osrExits) \
     macro(parse) \
     macro(profiledBytecodes) \
+    macro(promise) \
     macro(propertyIsEnumerable) \
     macro(prototype) \
+    macro(resolve) \
     macro(set) \
     macro(size) \
     macro(slice) \
     macro(values) \
     macro(valueOf) \
     macro(window) \
-    macro(writable)
+    macro(writable) \
+    macro(iterator) \
+    macro(iteratorNext) \
+    macro(reject) \
+    macro(fulfillmentHandler) \
+    macro(rejectionHandler) \
+    macro(deferred) \
+    macro(countdownHolder) \
 
 #define JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(macro) \
     macro(break) \
     macro(void) \
     macro(while) \
     macro(with) \
-    macro(yield)
+    macro(yield) \
 
 #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
     macro(iterator) \
     macro(index) \
     macro(values) \
     macro(deferred) \
-    macro(countdownHolder)
+    macro(countdownHolder) \
+    macro(Object) \
+    macro(TypeError) \
+    macro(undefinedKeyword) \
+    macro(call) \
+    macro(apply)
 
 namespace JSC {
 
@@ -240,11 +255,15 @@ namespace JSC {
         
 #define JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL(name) const Identifier name;
         JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL)
+        JSC_FOREACH_BUILTIN_FUNCTION_NAME(JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL)
 #undef JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL
 
-#define JSC_IDENTIFIER_DECLARE_PRIVATE_PROPERTY_NAME_GLOBAL(name) const Identifier name##PrivateName;
+#define JSC_IDENTIFIER_DECLARE_PRIVATE_PROPERTY_NAME_GLOBAL(name) const Identifier name##PrivateName; const std::pair<Identifier, Identifier> m_##name##PublicStringPair;
         JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(JSC_IDENTIFIER_DECLARE_PRIVATE_PROPERTY_NAME_GLOBAL)
 #undef JSC_IDENTIFIER_DECLARE_PRIVATE_PROPERTY_NAME_GLOBAL
+        
+        const Identifier* getPrivateName(const Identifier&) const;
+        Identifier getPublicName(const Identifier&) const;
     };
 
 } // namespace JSC
index 075875f..5af9087 100644 (file)
@@ -41,7 +41,7 @@
 #include "JIT.h"
 #include "JITStubs.h"
 #include "JSActivation.h"
-#include "JSCJSValue.h"
+#include "JSCJSValueInlines.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSNameScope.h"
 #include "JSPropertyNameIterator.h"
index 55334be..fa57c02 100644 (file)
@@ -29,6 +29,8 @@
 #include "CallFrame.h"
 #include "CodeBlock.h"
 #include "JITExceptions.h"
+#include "JSCJSValueInlines.h"
+#include "JSFunctionInlines.h"
 #include "LLIntCommon.h"
 
 namespace JSC { namespace CommonSlowPaths {
index 05e11e0..364cc71 100644 (file)
@@ -81,6 +81,11 @@ JSObject* createStackOverflowError(JSGlobalObject* globalObject)
 
 JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident)
 {
+    
+    if (ident.impl()->isEmptyUnique()) {
+        String message(makeString("Can't find private variable: @", exec->propertyNames().getPublicName(ident).string()));
+        return createReferenceError(exec, message);
+    }
     String message(makeString("Can't find variable: ", ident.string()));
     return createReferenceError(exec, message);
 }
index 198976b..8d590ef 100644 (file)
@@ -484,7 +484,7 @@ public:
 
     void clearCode();
 
-    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); }
+    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false); }
 
     unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); }
     unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
@@ -540,7 +540,7 @@ public:
 
     void clearCode();
 
-    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); }
+    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false); }
 
 private:
     friend class ScriptExecutable;
@@ -628,7 +628,8 @@ public:
     {
         return baselineCodeBlockFor(kind);
     }
-        
+
+    bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); }
     const Identifier& name() { return m_unlinkedExecutable->name(); }
     const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
     JSString* nameValue() const { return m_unlinkedExecutable->nameValue(); }
@@ -675,14 +676,6 @@ private:
     bool m_bodyIncludesBraces;
 };
 
-inline bool isHostFunction(JSValue value, NativeFunction nativeFunction)
-{
-    JSFunction* function = jsCast<JSFunction*>(getJSFunction(value));
-    if (!function || !function->isHostFunction())
-        return false;
-    return function->nativeFunction() == nativeFunction;
-}
-
 inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
 {
     switch (executable->structure()->typeInfo().type()) {
index c1b08af..12490c4 100644 (file)
 #include "FunctionPrototype.h"
 
 #include "Arguments.h"
+#include "Interpreter.h"
 #include "JSArray.h"
 #include "JSBoundFunction.h"
 #include "JSFunction.h"
 #include "JSString.h"
 #include "JSStringBuilder.h"
-#include "Interpreter.h"
+#include "JSStringInlines.h"
 #include "Lexer.h"
 #include "Operations.h"
 
@@ -108,7 +109,7 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec)
     JSValue thisValue = exec->hostThisValue();
     if (thisValue.inherits(JSFunction::info())) {
         JSFunction* function = jsCast<JSFunction*>(thisValue);
-        if (function->isHostFunction())
+        if (function->isHostOrBuiltinFunction())
             return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n    [native code]\n}"));
         FunctionExecutable* executable = function->jsExecutable();
         String sourceString = executable->source().toString();
index 72ed1c7..b374943 100644 (file)
@@ -58,7 +58,7 @@ void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
 
 inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
 {
-    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
+    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
     if (entry.isNull())
         return false;
 
@@ -72,7 +72,7 @@ inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertySlot
 
 inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertyDescriptor& descriptor)
 {
-    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
+    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
     if (entry.isNull())
         return false;
 
@@ -89,7 +89,7 @@ inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyN
     VM& vm = exec->vm();
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
     
-    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
+    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
     if (entry.isNull())
         return false;
     if (entry.isReadOnly()) {
@@ -136,7 +136,7 @@ inline bool JSActivation::symbolTablePutWithAttributes(VM& vm, PropertyName prop
     WriteBarrierBase<Unknown>* reg;
     {
         ConcurrentJITLocker locker(symbolTable()->m_lock);
-        SymbolTable::Map::iterator iter = symbolTable()->find(locker, propertyName.publicName());
+        SymbolTable::Map::iterator iter = symbolTable()->find(locker, propertyName.uid());
         if (iter == symbolTable()->end(locker))
             return false;
         SymbolTableEntry& entry = iter->value;
index 2fcf881..9a92583 100644 (file)
@@ -27,6 +27,7 @@
 #include "JSArgumentsIterator.h"
 
 #include "Arguments.h"
+#include "JSCJSValueInlines.h"
 
 namespace JSC {
 
index 9007b5f..ba0a2d3 100644 (file)
@@ -32,6 +32,7 @@
 #include "Executable.h"
 #include "GetterSetter.h"
 #include "IndexingHeaderInlines.h"
+#include "JSStringInlines.h"
 #include "PropertyNameArray.h"
 #include "Reject.h"
 #include <wtf/AVLTree.h>
index d506c4e..cf37097 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "JSCJSValueInlines.h"
 #include "JSCellInlines.h"
+#include "JSStringInlines.h"
 #include "SlotVisitorInlines.h"
 
 namespace JSC {
index cca6888..339a7ab 100644 (file)
@@ -32,7 +32,9 @@
 #include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSNotAnObject.h"
+#include "JSStringInlines.h"
 #include "NumberObject.h"
+#include "Operations.h"
 #include <wtf/MathExtras.h>
 #include <wtf/StringExtras.h>
 
index f7c8446..d795dd5 100644 (file)
 #define JSCellInlines_h
 
 #include "CallFrame.h"
+#include "CommonIdentifiers.h"
 #include "DeferGC.h"
 #include "Handle.h"
+#include "JSCJSValueInlines.h"
 #include "JSCell.h"
 #include "JSObject.h"
 #include "JSString.h"
index 2419646..ace6c14 100644 (file)
@@ -34,7 +34,8 @@
 #include "FunctionPrototype.h"
 #include "GetterSetter.h"
 #include "JSArray.h"
-#include "JSBoundFunction.h" 
+#include "JSBoundFunction.h"
+#include "JSFunctionInlines.h"
 #include "JSGlobalObject.h"
 #include "JSNotAnObject.h"
 #include "Interpreter.h"
@@ -109,6 +110,14 @@ void JSFunction::finishCreation(VM& vm, NativeExecutable* executable, int length
     putDirect(vm, vm.propertyNames->length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
 }
 
+JSFunction* JSFunction::createBuiltinFunction(VM& vm, FunctionExecutable* executable, JSGlobalObject* globalObject)
+{
+    JSFunction* function = create(vm, executable, globalObject);
+    function->putDirect(vm, vm.propertyNames->name, jsString(&vm, executable->name().string()), DontDelete | ReadOnly | DontEnum);
+    function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), DontDelete | ReadOnly | DontEnum);
+    return function;
+}
+
 ObjectAllocationProfile* JSFunction::createAllocationProfile(ExecState* exec, size_t inlineCapacity)
 {
     VM& vm = exec->vm();
@@ -142,7 +151,7 @@ const String JSFunction::calculatedDisplayName(ExecState* exec)
         return explicitName;
     
     const String actualName = name(exec);
-    if (!actualName.isEmpty() || isHostFunction())
+    if (!actualName.isEmpty() || isHostOrBuiltinFunction())
         return actualName;
     
     return jsExecutable()->inferredName().string();
@@ -150,10 +159,20 @@ const String JSFunction::calculatedDisplayName(ExecState* exec)
 
 const SourceCode* JSFunction::sourceCode() const
 {
-    if (isHostFunction())
+    if (isHostOrBuiltinFunction())
         return 0;
     return &jsExecutable()->source();
 }
+    
+bool JSFunction::isHostOrBuiltinFunction() const
+{
+    return isHostFunction() || isBuiltinFunction();
+}
+
+bool JSFunction::isBuiltinFunction() const
+{
+    return !isHostFunction() && jsExecutable()->isBuiltinFunction();
+}
 
 void JSFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
@@ -277,7 +296,7 @@ EncodedJSValue JSFunction::callerGetter(ExecState* exec, EncodedJSValue slotBase
     if (!caller.isObject() || !asObject(caller)->inherits(JSFunction::info()))
         return JSValue::encode(caller);
     JSFunction* function = jsCast<JSFunction*>(caller);
-    if (function->isHostFunction() || !function->jsExecutable()->isStrictMode())
+    if (function->isHostOrBuiltinFunction() || !function->jsExecutable()->isStrictMode())
         return JSValue::encode(caller);
     return JSValue::encode(throwTypeError(exec, ASCIILiteral("Function.caller used to retrieve strict caller")));
 }
@@ -299,7 +318,7 @@ EncodedJSValue JSFunction::nameGetter(ExecState*, EncodedJSValue slotBase, Encod
 bool JSFunction::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
     JSFunction* thisObject = jsCast<JSFunction*>(object);
-    if (thisObject->isHostFunction())
+    if (thisObject->isHostOrBuiltinFunction())
         return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
 
     if (propertyName == exec->propertyNames().prototype) {
@@ -361,7 +380,7 @@ bool JSFunction::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyN
 void JSFunction::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     JSFunction* thisObject = jsCast<JSFunction*>(object);
-    if (!thisObject->isHostFunction() && (mode == IncludeDontEnumProperties)) {
+    if (!thisObject->isHostOrBuiltinFunction() && (mode == IncludeDontEnumProperties)) {
         // Make sure prototype has been reified.
         PropertySlot slot(thisObject);
         thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, exec->propertyNames().prototype, slot);
@@ -377,7 +396,7 @@ void JSFunction::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec,
 void JSFunction::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
 {
     JSFunction* thisObject = jsCast<JSFunction*>(cell);
-    if (thisObject->isHostFunction()) {
+    if (thisObject->isHostOrBuiltinFunction()) {
         Base::put(thisObject, exec, propertyName, value, slot);
         return;
     }
@@ -425,7 +444,7 @@ bool JSFunction::deleteProperty(JSCell* cell, ExecState* exec, PropertyName prop
 bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool throwException)
 {
     JSFunction* thisObject = jsCast<JSFunction*>(object);
-    if (thisObject->isHostFunction())
+    if (thisObject->isHostOrBuiltinFunction())
         return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
 
     if (propertyName == exec->propertyNames().prototype) {
index 7cd14b8..9b58b74 100644 (file)
@@ -68,6 +68,8 @@ namespace JSC {
             return function;
         }
         
+        static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*);
+        
         static void destroy(JSCell*);
         
         JS_EXPORT_PRIVATE String name(ExecState*);
@@ -97,7 +99,7 @@ namespace JSC {
         ExecutableBase* executable() const { return m_executable.get(); }
 
         // To call either of these methods include Executable.h
-        inline bool isHostFunction() const;
+        bool isHostFunction() const;
         FunctionExecutable* jsExecutable() const;
 
         JS_EXPORT_PRIVATE const SourceCode* sourceCode() const;
@@ -145,6 +147,10 @@ namespace JSC {
             return m_allocationProfileWatchpoint;
         }
 
+        bool isHostOrBuiltinFunction() const;
+        bool isBuiltinFunction() const;
+        JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
+
     protected:
         const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
 
@@ -169,8 +175,6 @@ namespace JSC {
     private:
         friend class LLIntOffsetsExtractor;
         
-        JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
-
         static EncodedJSValue argumentsGetter(ExecState*, EncodedJSValue, EncodedJSValue, PropertyName);
         static EncodedJSValue callerGetter(ExecState*, EncodedJSValue, EncodedJSValue, PropertyName);
         static EncodedJSValue lengthGetter(ExecState*, EncodedJSValue, EncodedJSValue, PropertyName);
index fe4e114..69f0d4f 100644 (file)
@@ -53,16 +53,24 @@ inline bool JSFunction::isHostFunction() const
 
 inline NativeFunction JSFunction::nativeFunction()
 {
-    ASSERT(isHostFunction());
+    ASSERT(isHostFunctionNonInline());
     return static_cast<NativeExecutable*>(m_executable.get())->function();
 }
 
 inline NativeFunction JSFunction::nativeConstructor()
 {
-    ASSERT(isHostFunction());
+    ASSERT(isHostFunctionNonInline());
     return static_cast<NativeExecutable*>(m_executable.get())->constructor();
 }
 
+inline bool isHostFunction(JSValue value, NativeFunction nativeFunction)
+{
+    JSFunction* function = jsCast<JSFunction*>(getJSFunction(value));
+    if (!function || !function->isHostFunction())
+        return false;
+    return function->nativeFunction() == nativeFunction;
+}
+
 } // namespace JSC
 
 #endif // JSFunctionInlines_h
index 2ddc29f..edd3449 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef JSGenericTypedArrayViewConstructorInlines_h
 #define JSGenericTypedArrayViewConstructorInlines_h
 
+#include "CommonIdentifiers.h"
 #include "Error.h"
 #include "JSArrayBuffer.h"
 #include "JSGenericTypedArrayViewConstructor.h"
index 6db8627..f24ea73 100644 (file)
@@ -27,6 +27,7 @@
 #define JSGenericTypedArrayViewInlines_h
 
 #include "ArrayBufferView.h"
+#include "CommonIdentifiers.h"
 #include "DeferGC.h"
 #include "Error.h"
 #include "ExceptionHelpers.h"
index 459997a..8e5ff82 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef JSGenericTypedArrayViewPrototypeInlines_h
 #define JSGenericTypedArrayViewPrototypeInlines_h
 
+#include "CommonIdentifiers.h"
 #include "Error.h"
 #include "ExceptionHelpers.h"
 #include "JSFunction.h"
index 2c274c1..06e54c8 100644 (file)
@@ -346,7 +346,8 @@ void JSGlobalObject::reset(JSValue prototype)
 
     // Constructors
 
-    JSCell* objectConstructor = ObjectConstructor::create(vm, ObjectConstructor::createStructure(vm, this, m_functionPrototype.get()), m_objectPrototype.get());
+    ObjectConstructor* objectConstructor = ObjectConstructor::create(vm, ObjectConstructor::createStructure(vm, this, m_functionPrototype.get()), m_objectPrototype.get());
+    m_objectConstructor.set(vm, this, objectConstructor);
     JSCell* functionConstructor = FunctionConstructor::create(vm, FunctionConstructor::createStructure(vm, this, m_functionPrototype.get()), m_functionPrototype.get());
     JSCell* arrayConstructor = ArrayConstructor::create(vm, ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayPrototype.get());
 
@@ -432,7 +433,10 @@ void JSGlobalObject::reset(JSValue prototype)
     GlobalPropertyInfo staticGlobals[] = {
         GlobalPropertyInfo(vm.propertyNames->NaN, jsNaN(), DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->Infinity, jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly),
-        GlobalPropertyInfo(vm.propertyNames->undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly)
+        GlobalPropertyInfo(vm.propertyNames->undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->undefinedKeywordPrivateName, jsUndefined(), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->ObjectPrivateName, objectConstructor, DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->TypeErrorPrivateName, m_typeErrorConstructor.get(), DontEnum | DontDelete | ReadOnly)
     };
     addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
     
@@ -608,6 +612,7 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.append(&thisObject->m_syntaxErrorConstructor);
     visitor.append(&thisObject->m_typeErrorConstructor);
     visitor.append(&thisObject->m_URIErrorConstructor);
+    visitor.append(&thisObject->m_objectConstructor);
     visitor.append(&thisObject->m_promiseConstructor);
 
     visitor.append(&thisObject->m_evalFunction);
index b0cad3d..3a616c6 100644 (file)
@@ -67,6 +67,7 @@ class JSStack;
 class LLIntOffsetsExtractor;
 class Microtask;
 class NativeErrorConstructor;
+class ObjectConstructor;
 class ProgramCodeBlock;
 class ProgramExecutable;
 class RegExpConstructor;
@@ -158,6 +159,7 @@ protected:
     WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor;
     WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor;
     WriteBarrier<JSPromiseConstructor> m_promiseConstructor;
+    WriteBarrier<ObjectConstructor> m_objectConstructor;
 
     WriteBarrier<JSFunction> m_evalFunction;
     WriteBarrier<JSFunction> m_callFunction;
@@ -330,6 +332,7 @@ public:
     RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); }
 
     ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); }
+    ObjectConstructor* objectConstructor() const { return m_objectConstructor.get(); }
     NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); }
     NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); }
     NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); }
@@ -581,7 +584,7 @@ inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName
 
 inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName)
 {
-    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
+    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
     return !entry.isNull();
 }
 
index 2b67a1d..2ea2c24 100644 (file)
@@ -87,7 +87,7 @@ static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* class
         int hashSizeMask = table->compactSize - 1;
         const HashEntry* entry = table->table;
         for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
-            if (entry->key() && (!(entry->attributes() & DontEnum) || (mode == IncludeDontEnumProperties)) && !((entry->attributes() & Function) && didReify))
+            if (entry->key() && (!(entry->attributes() & DontEnum) || (mode == IncludeDontEnumProperties)) && !((entry->attributes() & BuiltinOrFunction) && didReify))
                 propertyNames.add(entry->key());
         }
     }
@@ -1618,7 +1618,7 @@ void JSObject::reifyStaticFunctionsForDelete(ExecState* exec)
             continue;
         PropertySlot slot(this);
         for (HashTable::ConstIterator iter = hashTable->begin(vm); iter != hashTable->end(vm); ++iter) {
-            if (iter->attributes() & Function)
+            if (iter->attributes() & BuiltinOrFunction)
                 setUpStaticFunctionSlot(globalObject()->globalExec(), *iter, this, Identifier(&vm, iter->key()), slot);
         }
     }
@@ -2236,6 +2236,16 @@ void JSObject::putDirectNativeFunction(VM& vm, JSGlobalObject* globalObject, con
     putDirect(vm, propertyName, function, attributes);
 }
 
+void JSObject::putDirectBuiltinFunction(VM& vm, JSGlobalObject* globalObject, const PropertyName& propertyName, FunctionExecutable* functionExecutable, unsigned attributes)
+{
+    StringImpl* name = propertyName.publicName();
+    if (!name)
+        name = vm.propertyNames->anonymous.impl();
+    ASSERT(name);
+    JSFunction* function = JSFunction::createBuiltinFunction(vm, static_cast<FunctionExecutable*>(functionExecutable), globalObject);
+    putDirect(vm, propertyName, function, attributes);
+}
+
 void JSObject::putDirectNativeFunctionWithoutTransition(VM& vm, JSGlobalObject* globalObject, const PropertyName& propertyName, unsigned functionLength, NativeFunction nativeFunction, Intrinsic intrinsic, unsigned attributes)
 {
     StringImpl* name = propertyName.publicName();
index 02b137b..dde597e 100644 (file)
@@ -29,7 +29,6 @@
 #include "Butterfly.h"
 #include "CallFrame.h"
 #include "ClassInfo.h"
-#include "CommonIdentifiers.h"
 #include "CopyWriteBarrier.h"
 #include "DeferGC.h"
 #include "Heap.h"
@@ -581,6 +580,7 @@ public:
     void putDirectUndefined(PropertyOffset offset) { locationForOffset(offset)->setUndefined(); }
 
     void putDirectNativeFunction(VM&, JSGlobalObject*, const PropertyName&, unsigned functionLength, NativeFunction, Intrinsic, unsigned attributes);
+    void putDirectBuiltinFunction(VM&, JSGlobalObject*, const PropertyName&, FunctionExecutable*, unsigned attributes);
     void putDirectNativeFunctionWithoutTransition(VM&, JSGlobalObject*, const PropertyName&, unsigned functionLength, NativeFunction, Intrinsic, unsigned attributes);
 
     JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
index 4026196..17d2ab6 100644 (file)
@@ -35,6 +35,7 @@
 #include "JSPromiseDeferred.h"
 #include "JSPromiseFunctions.h"
 #include "JSPromisePrototype.h"
+#include "JSStringInlines.h"
 #include "Lookup.h"
 #include "NumberObject.h"
 #include "StructureInlines.h"
index cbc42eb..42710c3 100644 (file)
@@ -32,6 +32,7 @@
 #include "JSPromise.h"
 #include "JSPromiseConstructor.h"
 #include "JSPromiseFunctions.h"
+#include "JSStringInlines.h"
 #include "SlotVisitorInlines.h"
 
 namespace JSC {
index 9df4578..e4ca5a4 100644 (file)
@@ -36,6 +36,7 @@
 #include "JSPromiseDeferred.h"
 #include "JSPromiseFunctions.h"
 #include "JSPromiseReaction.h"
+#include "JSStringInlines.h"
 #include "Microtask.h"
 #include "StructureInlines.h"
 
index fc7146c..42d2496 100644 (file)
@@ -27,6 +27,7 @@
 #define JSPromiseReaction_h
 
 #include "JSCell.h"
+#include "JSStringInlines.h"
 #include "Structure.h"
 
 namespace JSC {
index 68a8bd8..237c42b 100644 (file)
@@ -29,7 +29,9 @@
 #include "config.h"
 #include "JSPropertyNameIterator.h"
 
+#include "JSCJSValueInlines.h"
 #include "JSGlobalObject.h"
+#include "Operations.h"
 #include <wtf/StdLibExtras.h>
 
 namespace JSC {
index f4362ff..d073719 100644 (file)
@@ -31,7 +31,6 @@
 
 #include "JSObject.h"
 #include "JSString.h"
-#include "Operations.h"
 #include "PropertyNameArray.h"
 #include <memory>
 
index 2b1cddd..e393416 100644 (file)
@@ -24,7 +24,6 @@
 #define JSString_h
 
 #include "CallFrame.h"
-#include "CommonIdentifiers.h"
 #include "Identifier.h"
 #include "PropertyDescriptor.h"
 #include "PropertySlot.h"
@@ -472,33 +471,6 @@ namespace JSC {
     inline JSString* jsNontrivialString(ExecState* exec, const String& s) { return jsNontrivialString(&exec->vm(), s); }
     inline JSString* jsOwnedString(ExecState* exec, const String& s) { return jsOwnedString(&exec->vm(), s); }
 
-    ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-    {
-        if (propertyName == exec->propertyNames().length) {
-            slot.setValue(this, DontEnum | DontDelete | ReadOnly, jsNumber(m_length));
-            return true;
-        }
-
-        unsigned i = propertyName.asIndex();
-        if (i < m_length) {
-            ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
-            slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, i));
-            return true;
-        }
-
-        return false;
-    }
-            
-    ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
-    {
-        if (propertyName < m_length) {
-            slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, propertyName));
-            return true;
-        }
-
-        return false;
-    }
-
     inline bool isJSString(JSValue v) { return v.isCell() && v.asCell()->classInfo() == JSString::info(); }
 
     // --- JSValue inlines ----------------------------
@@ -528,32 +500,6 @@ namespace JSC {
         return toWTFStringSlowCase(exec);
     }
 
-    ALWAYS_INLINE String inlineJSValueNotStringtoString(const JSValue& value, ExecState* exec)
-    {
-        VM& vm = exec->vm();
-        if (value.isInt32())
-            return vm.numericStrings.add(value.asInt32());
-        if (value.isDouble())
-            return vm.numericStrings.add(value.asDouble());
-        if (value.isTrue())
-            return vm.propertyNames->trueKeyword.string();
-        if (value.isFalse())
-            return vm.propertyNames->falseKeyword.string();
-        if (value.isNull())
-            return vm.propertyNames->nullKeyword.string();
-        if (value.isUndefined())
-            return vm.propertyNames->undefinedKeyword.string();
-        return value.toString(exec)->value(exec);
-    }
-
-    ALWAYS_INLINE String JSValue::toWTFStringInline(ExecState* exec) const
-    {
-        if (isString())
-            return static_cast<JSString*>(asCell())->value(exec);
-
-        return inlineJSValueNotStringtoString(*this, exec);
-    }
-
 } // namespace JSC
 
 #endif // JSString_h
diff --git a/Source/JavaScriptCore/runtime/JSStringInlines.h b/Source/JavaScriptCore/runtime/JSStringInlines.h
new file mode 100644 (file)
index 0000000..378c05f
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012, 2013 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. ``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
+ * 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 JSStringInlines_h
+#define JSStringInlines_h
+
+#include "CommonIdentifiers.h"
+#include "JSCJSValueInlines.h"
+#include "JSString.h"
+
+namespace JSC {
+
+ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
+{
+    if (propertyName == exec->propertyNames().length) {
+        slot.setValue(this, DontEnum | DontDelete | ReadOnly, jsNumber(m_length));
+        return true;
+    }
+    
+    unsigned i = propertyName.asIndex();
+    if (i < m_length) {
+        ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
+        slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, i));
+        return true;
+    }
+    
+    return false;
+}
+
+ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+    if (propertyName < m_length) {
+        slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, propertyName));
+        return true;
+    }
+    
+    return false;
+}
+
+ALWAYS_INLINE String inlineJSValueNotStringtoString(const JSValue& value, ExecState* exec)
+{
+    VM& vm = exec->vm();
+    if (value.isInt32())
+        return vm.numericStrings.add(value.asInt32());
+    if (value.isDouble())
+        return vm.numericStrings.add(value.asDouble());
+    if (value.isTrue())
+        return vm.propertyNames->trueKeyword.string();
+    if (value.isFalse())
+        return vm.propertyNames->falseKeyword.string();
+    if (value.isNull())
+        return vm.propertyNames->nullKeyword.string();
+    if (value.isUndefined())
+        return vm.propertyNames->undefinedKeyword.string();
+    return value.toString(exec)->value(exec);
+}
+    
+ALWAYS_INLINE String JSValue::toWTFStringInline(ExecState* exec) const
+{
+    if (isString())
+        return static_cast<JSString*>(asCell())->value(exec);
+    
+    return inlineJSValueNotStringtoString(*this, exec);
+}
+
+}
+
+#endif
index 2ac2524..fbc8b89 100644 (file)
@@ -64,6 +64,8 @@ void JSSymbolTableObject::getOwnNonIndexPropertyNames(JSObject* object, ExecStat
         ConcurrentJITLocker locker(thisObject->symbolTable()->m_lock);
         SymbolTable::Map::iterator end = thisObject->symbolTable()->end(locker);
         for (SymbolTable::Map::iterator it = thisObject->symbolTable()->begin(locker); it != end; ++it) {
+            if (it->key->isEmptyUnique())
+                continue;
             if (!(it->value.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))
                 propertyNames.add(Identifier(exec, it->key.get()));
         }
index b5b20a8..d03b245 100644 (file)
@@ -72,7 +72,7 @@ inline bool symbolTableGet(
 {
     SymbolTable& symbolTable = *object->symbolTable();
     ConcurrentJITLocker locker(symbolTable.m_lock);
-    SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName());
+    SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.uid());
     if (iter == symbolTable.end(locker))
         return false;
     SymbolTableEntry::Fast entry = iter->value;
@@ -87,7 +87,7 @@ inline bool symbolTableGet(
 {
     SymbolTable& symbolTable = *object->symbolTable();
     ConcurrentJITLocker locker(symbolTable.m_lock);
-    SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName());
+    SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.uid());
     if (iter == symbolTable.end(locker))
         return false;
     SymbolTableEntry::Fast entry = iter->value;
@@ -104,7 +104,7 @@ inline bool symbolTableGet(
 {
     SymbolTable& symbolTable = *object->symbolTable();
     ConcurrentJITLocker locker(symbolTable.m_lock);
-    SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName());
+    SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.uid());
     if (iter == symbolTable.end(locker))
         return false;
     SymbolTableEntry::Fast entry = iter->value;
@@ -126,7 +126,7 @@ inline bool symbolTablePut(
     {
         SymbolTable& symbolTable = *object->symbolTable();
         GCSafeConcurrentJITLocker locker(symbolTable.m_lock, exec->vm().heap);
-        SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName());
+        SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.uid());
         if (iter == symbolTable.end(locker))
             return false;
         bool wasFat;
@@ -159,7 +159,7 @@ inline bool symbolTablePutWithAttributes(
     {
         SymbolTable& symbolTable = *object->symbolTable();
         ConcurrentJITLocker locker(symbolTable.m_lock);
-        SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName());
+        SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.uid());
         if (iter == symbolTable.end(locker))
             return false;
         SymbolTableEntry& entry = iter->value;
index a806dd0..a976520 100644 (file)
@@ -68,7 +68,7 @@ void HashTable::deleteTable() const
 bool setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject* thisObj, PropertyName propertyName, PropertySlot& slot)
 {
     ASSERT(thisObj->globalObject());
-    ASSERT(entry->attributes() & Function);
+    ASSERT(entry->attributes() & BuiltinOrFunction);
     VM& vm = exec->vm();
     unsigned attributes;
     PropertyOffset offset = thisObj->getDirectOffset(vm, propertyName, attributes);
@@ -79,9 +79,13 @@ bool setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject*
         if (thisObj->staticFunctionsReified())
             return false;
     
-        thisObj->putDirectNativeFunction(
-            vm, thisObj->globalObject(), propertyName, entry->functionLength(),
-            entry->function(), entry->intrinsic(), entry->attributes());
+        if (entry->attributes() & Builtin)
+            thisObj->putDirectBuiltinFunction(vm, thisObj->globalObject(), propertyName, entry->builtinGenerator()(vm), entry->attributes());
+        else {
+            thisObj->putDirectNativeFunction(
+                vm, thisObj->globalObject(), propertyName, entry->functionLength(),
+                entry->function(), entry->intrinsic(), entry->attributes());
+        }
         offset = thisObj->getDirectOffset(vm, propertyName, attributes);
         ASSERT(isValidOffset(offset));
     }
index bde83d4..dba389e 100644 (file)
@@ -43,6 +43,7 @@ namespace JSC {
     // ie. typedef JSValue (*GetFunction)(ExecState*, JSObject* baseObject)
     typedef PropertySlot::GetValueFunc GetFunction;
     typedef PutPropertySlot::PutValueFunc PutFunction;
+    typedef FunctionExecutable* (*BuiltinGenerator)(VM&);
 
     class HashEntry {
         WTF_MAKE_FAST_ALLOCATED;
@@ -68,11 +69,12 @@ namespace JSC {
             return m_intrinsic;
         }
 
+        BuiltinGenerator builtinGenerator() const { ASSERT(m_attributes & Builtin); return m_u.builtinGenerator.generatorValue; }
         NativeFunction function() const { ASSERT(m_attributes & Function); return m_u.function.functionValue; }
         unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_u.function.length); }
 
-        GetFunction propertyGetter() const { ASSERT(!(m_attributes & Function)); return m_u.property.get; }
-        PutFunction propertyPutter() const { ASSERT(!(m_attributes & Function)); return m_u.property.put; }
+        GetFunction propertyGetter() const { ASSERT(!(m_attributes & BuiltinOrFunction)); return m_u.property.get; }
+        PutFunction propertyPutter() const { ASSERT(!(m_attributes & BuiltinOrFunction)); return m_u.property.put; }
 
         intptr_t lexerValue() const { ASSERT(!m_attributes); return m_u.lexer.value; }
 
@@ -94,6 +96,10 @@ namespace JSC {
                 intptr_t length; // number of arguments for function
             } function;
             struct {
+                BuiltinGenerator generatorValue;
+                intptr_t unused;
+            } builtinGenerator;
+            struct {
                 GetFunction get;
                 PutFunction put;
             } property;
@@ -209,7 +215,7 @@ namespace JSC {
     private:
         ALWAYS_INLINE const HashEntry* entry(PropertyName propertyName) const
         {
-            StringImpl* impl = propertyName.publicName();
+            StringImpl* impl = propertyName.uid();
             if (!impl)
                 return 0;
         
@@ -249,7 +255,7 @@ namespace JSC {
         if (!entry) // not found, forward to parent
             return ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot);
 
-        if (entry->attributes() & Function)
+        if (entry->attributes() & BuiltinOrFunction)
             return setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
 
         slot.setCacheableCustom(thisObj, entry->attributes(), entry->propertyGetter());
@@ -286,7 +292,7 @@ namespace JSC {
         if (!entry) // not found, forward to parent
             return ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot);
 
-        ASSERT(!(entry->attributes() & Function));
+        ASSERT(!(entry->attributes() & BuiltinOrFunction));
 
         slot.setCacheableCustom(thisObj, entry->attributes(), entry->propertyGetter());
         return true;
@@ -295,7 +301,7 @@ namespace JSC {
     inline void putEntry(ExecState* exec, const HashEntry* entry, JSObject* base, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
     {
         // If this is a function put it as an override property.
-        if (entry->attributes() & Function) {
+        if (entry->attributes() & BuiltinOrFunction) {
             if (JSObject* thisObject = jsDynamicCast<JSObject*>(slot.thisValue()))
                 thisObject->putDirect(exec->vm(), propertyName, value);
         } else if (!(entry->attributes() & ReadOnly)) {
index d5e728c..dca2fd8 100644 (file)
@@ -38,6 +38,20 @@ NativeErrorConstructor::NativeErrorConstructor(VM& vm, Structure* structure)
 {
 }
 
+void NativeErrorConstructor::finishCreation(VM& vm, JSGlobalObject* globalObject, Structure* prototypeStructure, const String& name)
+{
+    Base::finishCreation(vm, name);
+    ASSERT(inherits(info()));
+    
+    NativeErrorPrototype* prototype = NativeErrorPrototype::create(vm, globalObject, prototypeStructure, name, this);
+    
+    putDirect(vm, vm.propertyNames->length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
+    putDirect(vm, vm.propertyNames->prototype, prototype, DontDelete | ReadOnly | DontEnum);
+    m_errorStructure.set(vm, this, ErrorInstance::createStructure(vm, globalObject, prototype));
+    ASSERT(m_errorStructure);
+    ASSERT(m_errorStructure->isObject());
+}
+
 void NativeErrorConstructor::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     NativeErrorConstructor* thisObject = jsCast<NativeErrorConstructor*>(cell);
index 740d3f9..438a3af 100644 (file)
@@ -51,19 +51,7 @@ namespace JSC {
         Structure* errorStructure() { return m_errorStructure.get(); }
 
     protected:
-        void finishCreation(VM& vm, JSGlobalObject* globalObject, Structure* prototypeStructure, const String& name)
-        {
-            Base::finishCreation(vm, name);
-            ASSERT(inherits(info()));
-
-            NativeErrorPrototype* prototype = NativeErrorPrototype::create(vm, globalObject, prototypeStructure, name, this);
-
-            putDirect(vm, vm.propertyNames->length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
-            putDirect(vm, vm.propertyNames->prototype, prototype, DontDelete | ReadOnly | DontEnum);
-            m_errorStructure.set(vm, this, ErrorInstance::createStructure(vm, globalObject, prototype));
-            ASSERT(m_errorStructure);
-            ASSERT(m_errorStructure->isObject());
-        }
+        void finishCreation(VM&, JSGlobalObject*, Structure* prototypeStructure, const String& name);
 
     private:
         NativeErrorConstructor(VM&, Structure*);
index d938fa3..cfe9c4d 100644 (file)
@@ -42,6 +42,8 @@ enum Attribute {
     Function     = 1 << 4,  // property is a function - only used by static hashtables
     Accessor     = 1 << 5,  // property is a getter/setter
     CustomAccessor = 1 << 6,
+    Builtin         = 1 << 7, // property is a builtin function - only used by static hashtables
+    BuiltinOrFunction = Builtin | Function, // helper only used by static hashtables
 };
 
 class PropertySlot {
index bc516b0..2c2434b 100644 (file)
@@ -23,6 +23,7 @@
 #include "RegExpConstructor.h"
 
 #include "Error.h"
+#include "JSStringInlines.h"
 #include "Operations.h"
 #include "RegExpMatchesArray.h"
 #include "RegExpPrototype.h"
index 89d7ac1..9dda0ba 100644 (file)
@@ -24,7 +24,7 @@
 #include "ArrayPrototype.h"
 #include "Error.h"
 #include "JSArray.h"
-#include "JSCJSValue.h"
+#include "JSCJSValueInlines.h"
 #include "JSFunction.h"
 #include "JSObject.h"
 #include "JSString.h"
index b203888..d0266a5 100644 (file)
@@ -31,6 +31,7 @@
 #include "JSCellInlines.h"
 #include "JSGlobalObject.h"
 #include "JSSet.h"
+#include "JSStringInlines.h"
 #include "MapData.h"
 #include "SetPrototype.h"
 
index 440a609..80e7eaa 100644 (file)
@@ -22,7 +22,9 @@
 #include "StringObject.h"
 
 #include "Error.h"
+#include "JSCJSValueInlines.h"
 #include "JSGlobalObject.h"
+#include "JSStringInlines.h"
 #include "Operations.h"
 #include "PropertyNameArray.h"
 
index 04291f7..1ecab85 100644 (file)
 #include "Structure.h"
 
 #include "CodeBlock.h"
+#include "CommonIdentifiers.h"
 #include "DumpContext.h"
+#include "JSCellInlines.h"
 #include "JSObject.h"
 #include "JSPropertyNameIterator.h"
+#include "JSStringInlines.h"
 #include "Lookup.h"
+#include "PropertyMapHashTable.h"
 #include "PropertyNameArray.h"
+#include "SlotVisitorInlines.h"
 #include "StructureChain.h"
+#include "StructureInlines.h"
 #include "StructureRareDataInlines.h"
 #include <wtf/CommaPrinter.h>
 #include <wtf/RefCountedLeakCounter.h>
index 52ccf42..020695f 100644 (file)
@@ -32,6 +32,7 @@
 #include "ArgList.h"
 #include "ArityCheckFailReturnThunks.h"
 #include "ArrayBufferNeuteringWatchpoint.h"
+#include "BuiltinExecutables.h"
 #include "CallFrameInlines.h"
 #include "CodeBlock.h"
 #include "CodeCache.h"
@@ -55,7 +56,9 @@
 #include "JSAPIValueWrapper.h"
 #include "JSActivation.h"
 #include "JSArray.h"
-#include "JSFunction.h"
+#include "JSCJSValueInlines.h"
+#include "JSCellInlines.h"
+#include "JSFunctionInlines.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSLock.h"
 #include "JSNameScope.h"
 #include "Lookup.h"
 #include "MapData.h"
 #include "Nodes.h"
+#include "Parser.h"
 #include "ParserArena.h"
+#include "PropertyMapHashTable.h"
 #include "RegExpCache.h"
 #include "RegExpObject.h"
 #include "SimpleTypedArrayController.h"
 #include "SourceProviderCache.h"
 #include "StrictEvalActivation.h"
 #include "StrongInlines.h"
+#include "StructureInlines.h"
 #include "UnlinkedCodeBlock.h"
 #include "WeakMapData.h"
 #include <wtf/ProcessID.h>
@@ -226,6 +232,7 @@ VM::VM(VMType vmType, HeapType heapType)
     , m_inDefineOwnProperty(false)
     , m_codeCache(CodeCache::create())
     , m_enabledProfiler(nullptr)
+    , m_builtinExecutables(BuiltinExecutables::create(*this))
 {
     interpreter = new Interpreter(*this);
     StackBounds stack = wtfThreadData().stack();
index 5a84105..6958ac3 100644 (file)
@@ -44,6 +44,7 @@
 #include "PrivateName.h"
 #include "PrototypeMap.h"
 #include "SmallStrings.h"
+#include "SourceCode.h"
 #include "Strong.h"
 #include "ThunkGenerators.h"
 #include "TypedArrayController.h"
@@ -69,6 +70,7 @@
 namespace JSC {
 
     class ArityCheckFailReturnThunks;
+    class BuiltinExecutables;
     class CodeBlock;
     class CodeCache;
     class CommonIdentifiers;
@@ -497,6 +499,8 @@ namespace JSC {
         void registerWatchpointForImpureProperty(const Identifier&, Watchpoint*);
         // FIXME: Use AtomicString once it got merged with Identifier.
         JS_EXPORT_PRIVATE void addImpureProperty(const String&);
+        
+        BuiltinExecutables* builtinExecutables() { return m_builtinExecutables.get(); }
 
     private:
         friend class LLIntOffsetsExtractor;
@@ -537,10 +541,9 @@ namespace JSC {
         JSValue m_exception;
         bool m_inDefineOwnProperty;
         OwnPtr<CodeCache> m_codeCache;
-        RefCountedArray<StackFrame> m_exceptionStack;
-
         LegacyProfiler* m_enabledProfiler;
-
+        OwnPtr<BuiltinExecutables> m_builtinExecutables;
+        RefCountedArray<StackFrame> m_exceptionStack;
         HashMap<String, RefPtr<WatchpointSet>> m_impurePropertyWatchpointSets;
     };
 
index 7cc6483..f6de693 100644 (file)
@@ -101,6 +101,7 @@ set(WebCore_INCLUDE_DIRECTORIES
     "${JAVASCRIPTCORE_DIR}/API"
     "${JAVASCRIPTCORE_DIR}/assembler"
     "${JAVASCRIPTCORE_DIR}/bytecode"
+    "${JAVASCRIPTCORE_DIR}/builtins"
     "${JAVASCRIPTCORE_DIR}/bytecompiler"
     "${JAVASCRIPTCORE_DIR}/dfg"
     "${JAVASCRIPTCORE_DIR}/disassembler"
index 93cddbf..6cc1a46 100644 (file)
@@ -1,3 +1,20 @@
+2014-01-29  Oliver Hunt  <oliver@apple.com>
+
+        Make it possible to implement JS builtins in JS
+        https://bugs.webkit.org/show_bug.cgi?id=127887
+
+        Reviewed by Michael Saboff.
+
+        Updating for the newly required headers.
+
+        Test: js/regress/array-prototype-every.html
+
+        * ForwardingHeaders/runtime/JSStringInlines.h: Added.
+        * Modules/plugins/QuickTimePluginReplacement.cpp:
+        * bindings/js/JSIDBAnyCustom.cpp:
+        * bindings/js/JSIDBDatabaseCustom.cpp:
+        * bindings/js/JSIDBObjectStoreCustom.cpp:
+
 2014-01-31  Beth Dakin  <bdakin@apple.com>
 
         Build fix.
diff --git a/Source/WebCore/ForwardingHeaders/runtime/JSStringInlines.h b/Source/WebCore/ForwardingHeaders/runtime/JSStringInlines.h
new file mode 100644 (file)
index 0000000..70fcc38
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_JSStringInlines_h
+#define WebCore_FWD_JSStringInlines_h
+#include <JavaScriptCore/JSStringInlines.h>
+#endif
index 2eddcdb..3c4e0d7 100644 (file)
@@ -46,6 +46,7 @@
 #include <JavaScriptCore/APICast.h>
 #include <JavaScriptCore/JSBase.h>
 #include <JavaScriptCore/JSCJSValueInlines.h>
+#include <JavaScriptCore/JSStringInlines.h>
 
 using namespace JSC;
 
index 5649c85..3f4d8ef 100644 (file)
@@ -47,6 +47,7 @@
 #include "JSIDBObjectStore.h"
 #include "JSIDBTransaction.h"
 #include "SerializedScriptValue.h"
+#include <runtime/JSStringInlines.h>
 
 using namespace JSC;
 
index 9eae756..f49dfe9 100644 (file)
@@ -37,7 +37,7 @@
 #include "IDBObjectStore.h"
 #include "JSIDBObjectStore.h"
 #include <runtime/Error.h>
-#include <runtime/JSString.h>
+#include <runtime/JSStringInlines.h>
 
 using namespace JSC;
 
index 74fd354..5434b3b 100644 (file)
@@ -36,7 +36,7 @@
 #include "IDBObjectStore.h"
 #include "JSIDBIndex.h"
 #include <runtime/Error.h>
-#include <runtime/JSString.h>
+#include <runtime/JSStringInlines.h>
 
 using namespace JSC;
 
index d1b4721..f1daa8a 100644 (file)
@@ -26,6 +26,7 @@
 #include "NodeFilter.h"
 #include <runtime/Error.h>
 #include <runtime/JSLock.h>
+#include <runtime/JSStringInlines.h>
 
 namespace WebCore {
 
index fb4ad95..1b84f2b 100644 (file)
@@ -66,6 +66,7 @@ set(WebKit_INCLUDE_DIRECTORIES
     "${JAVASCRIPTCORE_DIR}/API"
     "${JAVASCRIPTCORE_DIR}/assembler"
     "${JAVASCRIPTCORE_DIR}/bytecode"
+    "${JAVASCRIPTCORE_DIR}/builtins"
     "${JAVASCRIPTCORE_DIR}/bytecompiler"
     "${JAVASCRIPTCORE_DIR}/disassembler"
     "${JAVASCRIPTCORE_DIR}/dfg"
@@ -78,6 +79,7 @@ set(WebKit_INCLUDE_DIRECTORIES
     "${JAVASCRIPTCORE_DIR}/profiler"
     "${JAVASCRIPTCORE_DIR}/runtime"
     "${WTF_DIR}"
+    "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}"
     "${DERIVED_SOURCES_WEBCORE_DIR}"
     "${DERIVED_SOURCES_DIR}/ForwardingHeaders"
     "${CMAKE_BINARY_DIR}"
index fb92551..f66e806 100644 (file)
@@ -1,3 +1,14 @@
+2014-01-29  Oliver Hunt  <oliver@apple.com>
+
+        Make it possible to implement JS builtins in JS
+        https://bugs.webkit.org/show_bug.cgi?id=127887
+
+        Reviewed by Michael Saboff.
+
+        CMake updates
+
+        * CMakeLists.txt:
+
 2014-01-30  Martin Robinson  <mrobinson@igalia.com>
 
         [GTK] [CMake] Add support for building against GTK+ 2
index 67181c8..df8f12e 100644 (file)
@@ -121,6 +121,7 @@ set(WebKit2_INCLUDE_DIRECTORIES
     "${JAVASCRIPTCORE_DIR}/API"
     "${JAVASCRIPTCORE_DIR}/assembler"
     "${JAVASCRIPTCORE_DIR}/bytecode"
+    "${JAVASCRIPTCORE_DIR}/builtins"
     "${JAVASCRIPTCORE_DIR}/bytecompiler"
     "${JAVASCRIPTCORE_DIR}/collector/handles"
     "${JAVASCRIPTCORE_DIR}/dfg"
@@ -133,6 +134,7 @@ set(WebKit2_INCLUDE_DIRECTORIES
     "${JAVASCRIPTCORE_DIR}/runtime"
     "${WTF_DIR}"
     "${DERIVED_SOURCES_DIR}"
+    "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}"
     "${DERIVED_SOURCES_WEBCORE_DIR}"
     "${DERIVED_SOURCES_WEBKIT2_DIR}"
     "${DERIVED_SOURCES_WEBKIT2_DIR}/include"
index 690a93a..68cfeaf 100644 (file)
@@ -1,3 +1,14 @@
+2014-01-29  Oliver Hunt  <oliver@apple.com>
+
+        Make it possible to implement JS builtins in JS
+        https://bugs.webkit.org/show_bug.cgi?id=127887
+
+        Reviewed by Michael Saboff.
+
+        CMake updates
+
+        * CMakeLists.txt:
+
 2014-01-31  Tim Horton  <timothy_horton@apple.com>
 
         WebKit2 View Gestures (Swipe): Crashes swiping around a Google Docs spreadsheet
index 56bf447..7f521a8 100644 (file)
@@ -6,6 +6,7 @@
 include_directories(${THIRDPARTY_DIR}/gtest
     ${THIRDPARTY_DIR}/gtest/include
     ${JAVASCRIPTCORE_DIR}
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}
     ${WTF_DIR}
 )
 
index 4ee26b6..6557366 100644 (file)
@@ -1,3 +1,16 @@
+2014-01-29  Oliver Hunt  <oliver@apple.com>
+
+        Make it possible to implement JS builtins in JS
+        https://bugs.webkit.org/show_bug.cgi?id=127887
+
+        Reviewed by Michael Saboff.
+
+        CMake updates
+
+        * DumpRenderTree/CMakeLists.txt:
+        * WebKitTestRunner/CMakeLists.txt:
+        * WinCELauncher/CMakeLists.txt:
+
 2014-01-31  Filip Pizlo  <fpizlo@apple.com>
 
         Allow more flexibility for copy-webkitlibraries-to-product-directory
index 7b8aa18..549cd40 100644 (file)
@@ -58,6 +58,7 @@ set(DumpRenderTree_INCLUDE_DIRECTORIES
     ${JAVASCRIPTCORE_DIR}/profiler
     ${JAVASCRIPTCORE_DIR}/runtime
     ${JAVASCRIPTCORE_DIR}/ForwardingHeaders
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}
     ${TOOLS_DIR}/DumpRenderTree
     ${WTF_DIR}
     ${CMAKE_SOURCE_DIR}/Source
index 5a346d7..cb4b191 100644 (file)
@@ -28,6 +28,7 @@ set(WebKitTestRunner_INCLUDE_DIRECTORIES
     ${WEBKIT_TESTRUNNER_DIR}/InjectedBundle/atk
     ${JAVASCRIPTCORE_DIR}
     ${JAVASCRIPTCORE_DIR}/ForwardingHeaders
+    ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}
     ${WEBCORE_DIR}/editing
     ${WEBCORE_DIR}/platform
     ${WEBCORE_DIR}/platform/graphics
index 914bb2b..b19fc61 100644 (file)
@@ -6,6 +6,7 @@ set(WinCELauncher_INCLUDE_DIRECTORIES
     "${WEBCORE_DIR}/platform/network"
     "${WEBCORE_DIR}/platform/text"
     "${JAVASCRIPTCORE_DIR}"
+    "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}"
     "${WTF_DIR}"
     "${DERIVED_SOURCES_DIR}"
     "${CMAKE_BINARY_DIR}"