Title: [164835] trunk/Source/_javascript_Core
Revision
164835
Author
[email protected]
Date
2014-02-27 15:25:29 -0800 (Thu, 27 Feb 2014)

Log Message

Slow cases for function.apply and function.call should not require vm re-entry
https://bugs.webkit.org/show_bug.cgi?id=129454

Reviewed by Geoffrey Garen.

Implement call and apply using builtins. Happily the use
of @call and @apply don't perform function equality checks
and just plant direct var_args calls. This did expose a few
codegen issues, but they're all covered by existing tests
once call and apply are implemented in JS.

* _javascript_Core.xcodeproj/project.pbxproj:
* builtins/Function.prototype.js: Added.
(call):
(apply):
* bytecompiler/NodesCodegen.cpp:
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* interpreter/Interpreter.cpp:
(JSC::sizeFrameForVarargs):
(JSC::loadVarargs):
* interpreter/Interpreter.h:
* jit/JITCall.cpp:
(JSC::JIT::compileLoadVarargs):
* parser/ASTBuilder.h:
(JSC::ASTBuilder::makeFunctionCallNode):
* parser/Lexer.cpp:
(JSC::isSafeBuiltinIdentifier):
* runtime/CommonIdentifiers.h:
* runtime/FunctionPrototype.cpp:
(JSC::FunctionPrototype::addFunctionProperties):
* runtime/JSObject.cpp:
(JSC::JSObject::putDirectBuiltinFunction):
(JSC::JSObject::putDirectBuiltinFunctionWithoutTransition):
* runtime/JSObject.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (164834 => 164835)


--- trunk/Source/_javascript_Core/ChangeLog	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-02-27 23:25:29 UTC (rev 164835)
@@ -1,3 +1,43 @@
+2014-02-27  Oliver Hunt  <[email protected]>
+
+        Slow cases for function.apply and function.call should not require vm re-entry
+        https://bugs.webkit.org/show_bug.cgi?id=129454
+
+        Reviewed by Geoffrey Garen.
+
+        Implement call and apply using builtins. Happily the use
+        of @call and @apply don't perform function equality checks
+        and just plant direct var_args calls. This did expose a few
+        codegen issues, but they're all covered by existing tests
+        once call and apply are implemented in JS.
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * builtins/Function.prototype.js: Added.
+        (call):
+        (apply):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::CallFunctionCallDotNode::emitBytecode):
+        (JSC::ApplyFunctionCallDotNode::emitBytecode):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeFrameForVarargs):
+        (JSC::loadVarargs):
+        * interpreter/Interpreter.h:
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileLoadVarargs):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::makeFunctionCallNode):
+        * parser/Lexer.cpp:
+        (JSC::isSafeBuiltinIdentifier):
+        * runtime/CommonIdentifiers.h:
+        * runtime/FunctionPrototype.cpp:
+        (JSC::FunctionPrototype::addFunctionProperties):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putDirectBuiltinFunction):
+        (JSC::JSObject::putDirectBuiltinFunctionWithoutTransition):
+        * runtime/JSObject.h:
+
 2014-02-27  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: Better name for RemoteInspectorDebuggableConnection dispatch queue

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (164834 => 164835)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2014-02-27 23:25:29 UTC (rev 164835)
@@ -2729,6 +2729,7 @@
 		A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Uint8ClampedArray.h; sourceTree = "<group>"; };
 		A7A8AF3217ADB5F3005AB174 /* Uint16Array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Uint16Array.h; sourceTree = "<group>"; };
 		A7A8AF3317ADB5F3005AB174 /* Uint32Array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Uint32Array.h; sourceTree = "<group>"; };
+		A7A979C418BE8D9E002C3733 /* Function.prototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = Function.prototype.js; sourceTree = "<group>"; };
 		A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableAllocator.h; sourceTree = "<group>"; };
 		A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocator.cpp; sourceTree = "<group>"; };
 		A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSExportMacros.h; sourceTree = "<group>"; };
@@ -4833,6 +4834,7 @@
 				A7D801A21880D66E0026C39B /* BuiltinExecutables.h */,
 				A75EE9B018AAB7E200AAD043 /* BuiltinNames.h */,
 				7CFBAC1C18B535E500D00750 /* Promise.prototype.js */,
+				A7A979C418BE8D9E002C3733 /* Function.prototype.js */,
 			);
 			path = builtins;
 			sourceTree = "<group>";

Added: trunk/Source/_javascript_Core/builtins/Function.prototype.js (0 => 164835)


--- trunk/Source/_javascript_Core/builtins/Function.prototype.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/builtins/Function.prototype.js	2014-02-27 23:25:29 UTC (rev 164835)
@@ -0,0 +1,34 @@
+/*
+ * 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 call(thisArgument) {
+    "use strict";
+    return this.@call(...arguments);
+}
+
+function apply(thisValue, argumentValues) {
+    "use strict";
+    return this.@apply(thisValue, argumentValues);
+}

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (164834 => 164835)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2014-02-27 23:25:29 UTC (rev 164835)
@@ -28,6 +28,7 @@
 #include "Nodes.h"
 #include "NodeConstructors.h"
 
+#include "BuiltinNames.h"
 #include "BytecodeGenerator.h"
 #include "CallFrame.h"
 #include "Debugger.h"
@@ -549,7 +550,7 @@
     RefPtr<RegisterID> function;
     bool emitCallCheck = !generator.isBuiltinFunction();
     if (emitCallCheck) {
-        function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().call);
+        function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().callPublicName());
         generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
     }
     RefPtr<RegisterID> returnValue = generator.finalDestination(dst);
@@ -620,7 +621,7 @@
     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
     bool emitCallCheck = !generator.isBuiltinFunction();
     if (emitCallCheck) {
-        function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().apply);
+        function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().applyPublicName());
         generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
     }
     if (mayBeCall) {

Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp (164834 => 164835)


--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2014-02-27 23:25:29 UTC (rev 164835)
@@ -211,7 +211,8 @@
     }
 
     case op_call_varargs:
-        if (codeBlock->usesArguments() && pc[4].u.operand == codeBlock->argumentsRegister().offset())
+        if (codeBlock->usesArguments() && pc[4].u.operand == codeBlock->argumentsRegister().offset()
+            && !pc[6].u.operand)
             return CanInline;
         // FIXME: We should handle this.
         // https://bugs.webkit.org/show_bug.cgi?id=127626

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (164834 => 164835)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2014-02-27 23:25:29 UTC (rev 164835)
@@ -137,10 +137,14 @@
     return interpreter->execute(eval, callFrame, thisValue, callerScopeChain);
 }
 
-CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, int firstFreeRegister, int32_t firstVarArgOffset)
+CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, int firstFreeRegister, uint32_t firstVarArgOffset)
 {
     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
-        unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis() - firstVarArgOffset;
+        unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
+        if (argumentCountIncludingThis > firstVarArgOffset)
+            argumentCountIncludingThis -= firstVarArgOffset;
+        else
+            argumentCountIncludingThis = 1;
         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
         if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->ensureCapacityFor(newCallFrame->registers())) {
@@ -168,7 +172,11 @@
 
     if (asObject(arguments)->classInfo() == Arguments::info()) {
         Arguments* argsObject = asArguments(arguments);
-        unsigned argCount = argsObject->length(callFrame) - firstVarArgOffset;
+        unsigned argCount = argsObject->length(callFrame);
+        if (argCount >= firstVarArgOffset)
+            argCount -= firstVarArgOffset;
+        else
+            argCount = 0;
         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
         if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
@@ -180,7 +188,11 @@
 
     if (isJSArray(arguments)) {
         JSArray* array = asArray(arguments);
-        unsigned argCount = array->length() - firstVarArgOffset;
+        unsigned argCount = array->length();
+        if (argCount >= firstVarArgOffset)
+            argCount -= firstVarArgOffset;
+        else
+            argCount = 0;
         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
         if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
@@ -191,7 +203,11 @@
     }
 
     JSObject* argObject = asObject(arguments);
-    unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame) - firstVarArgOffset;
+    unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+    if (argCount >= firstVarArgOffset)
+        argCount -= firstVarArgOffset;
+    else
+        argCount = 0;
     unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
     CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
     if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
@@ -201,11 +217,14 @@
     return newCallFrame;
 }
 
-void loadVarargs(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, int32_t firstVarArgOffset)
+void loadVarargs(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset)
 {
     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
-        unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis() - firstVarArgOffset;
-
+        unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
+        if (argumentCountIncludingThis > firstVarArgOffset)
+            argumentCountIncludingThis -= firstVarArgOffset;
+        else
+            argumentCountIncludingThis = 1;
         newCallFrame->setArgumentCountIncludingThis(argumentCountIncludingThis);
         newCallFrame->setThisValue(thisValue);
         for (size_t i = firstVarArgOffset; i < callFrame->argumentCount(); ++i)
@@ -221,25 +240,38 @@
     
     if (asObject(arguments)->classInfo() == Arguments::info()) {
         Arguments* argsObject = asArguments(arguments);
-        unsigned argCount = argsObject->length(callFrame) - firstVarArgOffset;
-        newCallFrame->setArgumentCountIncludingThis(argCount + 1);
+        unsigned argCount = argsObject->length(callFrame);
+        if (argCount >= firstVarArgOffset) {
+            argCount -= firstVarArgOffset;
+            newCallFrame->setArgumentCountIncludingThis(argCount + 1);
+            argsObject->copyToArguments(callFrame, newCallFrame, argCount, firstVarArgOffset);
+        } else
+            newCallFrame->setArgumentCountIncludingThis(1);
         newCallFrame->setThisValue(thisValue);
-        argsObject->copyToArguments(callFrame, newCallFrame, argCount, firstVarArgOffset);
         return;
     }
     
     if (isJSArray(arguments)) {
         JSArray* array = asArray(arguments);
-        unsigned argCount = array->length() - firstVarArgOffset;
-        newCallFrame->setArgumentCountIncludingThis(argCount + 1);
+        unsigned argCount = array->length();
+        if (argCount >= firstVarArgOffset) {
+            argCount -= firstVarArgOffset;
+            newCallFrame->setArgumentCountIncludingThis(argCount + 1);
+            array->copyToArguments(callFrame, newCallFrame, argCount, firstVarArgOffset);
+        } else
+            newCallFrame->setArgumentCountIncludingThis(1);
         newCallFrame->setThisValue(thisValue);
-        array->copyToArguments(callFrame, newCallFrame, argCount, firstVarArgOffset);
         return;
     }
     
     JSObject* argObject = asObject(arguments);
-    unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame) - firstVarArgOffset;
-    newCallFrame->setArgumentCountIncludingThis(argCount + 1);
+    unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+    if (argCount >= firstVarArgOffset) {
+        argCount -= firstVarArgOffset;
+        newCallFrame->setArgumentCountIncludingThis(argCount + 1);
+    } else
+        newCallFrame->setArgumentCountIncludingThis(1);
+
     newCallFrame->setThisValue(thisValue);
     for (size_t i = 0; i < argCount; ++i) {
         newCallFrame->setArgument(i, asObject(arguments)->get(callFrame, i + firstVarArgOffset));

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.h (164834 => 164835)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.h	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.h	2014-02-27 23:25:29 UTC (rev 164835)
@@ -285,8 +285,8 @@
     };
 
     JSValue eval(CallFrame*);
-    CallFrame* sizeFrameForVarargs(CallFrame*, JSStack*, JSValue, int, int32_t firstVarArgOffset);
-    void loadVarargs(CallFrame*, CallFrame*, JSValue, JSValue, int32_t firstVarArgOffset);
+    CallFrame* sizeFrameForVarargs(CallFrame*, JSStack*, JSValue, int, uint32_t firstVarArgOffset);
+    void loadVarargs(CallFrame*, CallFrame*, JSValue, JSValue, uint32_t firstVarArgOffset);
 } // namespace JSC
 
 #endif // Interpreter_h

Modified: trunk/Source/_javascript_Core/jit/JITCall.cpp (164834 => 164835)


--- trunk/Source/_javascript_Core/jit/JITCall.cpp	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/jit/JITCall.cpp	2014-02-27 23:25:29 UTC (rev 164835)
@@ -71,8 +71,14 @@
         slowCase.append(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(JSValue()))));
 
         emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0);
-        if (firstVarArgOffset)
+        if (firstVarArgOffset) {
+            Jump sufficientArguments = branch32(GreaterThan, regT0, TrustedImm32(firstVarArgOffset + 1));
+            move(TrustedImm32(1), regT0);
+            Jump endVarArgs = jump();
+            sufficientArguments.link(this);
             sub32(TrustedImm32(firstVarArgOffset), regT0);
+            endVarArgs.link(this);
+        }
         slowCase.append(branch32(Above, regT0, TrustedImm32(Arguments::MaxArguments + 1)));
         // regT0: argumentCountIncludingThis
         move(regT0, regT1);

Modified: trunk/Source/_javascript_Core/parser/ASTBuilder.h (164834 => 164835)


--- trunk/Source/_javascript_Core/parser/ASTBuilder.h	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/parser/ASTBuilder.h	2014-02-27 23:25:29 UTC (rev 164835)
@@ -26,6 +26,7 @@
 #ifndef ASTBuilder_h
 #define ASTBuilder_h
 
+#include "BuiltinNames.h"
 #include "NodeConstructors.h"
 #include "SyntaxChecker.h"
 #include <utility>
@@ -888,9 +889,9 @@
     ASSERT(func->isDotAccessorNode());
     DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
     FunctionCallDotNode* node;
-    if (dot->identifier() == m_vm->propertyNames->call || dot->identifier() == m_vm->propertyNames->callPrivateName)
+    if (dot->identifier() == m_vm->propertyNames->builtinNames().callPublicName() || dot->identifier() == m_vm->propertyNames->builtinNames().callPrivateName())
         node = new (m_vm) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd);
-    else if (dot->identifier() == m_vm->propertyNames->apply || dot->identifier() == m_vm->propertyNames->applyPrivateName)
+    else if (dot->identifier() == m_vm->propertyNames->builtinNames().applyPublicName() || dot->identifier() == m_vm->propertyNames->builtinNames().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);

Modified: trunk/Source/_javascript_Core/parser/Lexer.cpp (164834 => 164835)


--- trunk/Source/_javascript_Core/parser/Lexer.cpp	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/parser/Lexer.cpp	2014-02-27 23:25:29 UTC (rev 164835)
@@ -27,6 +27,7 @@
 
 #include "JSFunctionInlines.h"
 
+#include "BuiltinNames.h"
 #include "JSGlobalObjectFunctions.h"
 #include "Identifier.h"
 #include "NodeInfo.h"
@@ -765,9 +766,9 @@
     /* 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)
+    if (*ident == vm.propertyNames->builtinNames().callPublicName())
         return false;
-    if (*ident == vm.propertyNames->apply)
+    if (*ident == vm.propertyNames->builtinNames().applyPublicName())
         return false;
     if (*ident == vm.propertyNames->eval)
         return false;

Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (164834 => 164835)


--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2014-02-27 23:25:29 UTC (rev 164835)
@@ -63,7 +63,6 @@
     macro(__lookupSetter__) \
     macro(add) \
     macro(anonymous) \
-    macro(apply) \
     macro(arguments) \
     macro(bind) \
     macro(buffer) \
@@ -73,7 +72,6 @@
     macro(bytecodeIndex) \
     macro(bytecodes) \
     macro(bytecodesID) \
-    macro(call) \
     macro(callee) \
     macro(caller) \
     macro(cast) \
@@ -207,8 +205,6 @@
     macro(yield)
 
 #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
-    macro(apply) \
-    macro(call) \
     macro(iterator) \
     macro(iteratorNext) \
     macro(resolve) \

Modified: trunk/Source/_javascript_Core/runtime/FunctionPrototype.cpp (164834 => 164835)


--- trunk/Source/_javascript_Core/runtime/FunctionPrototype.cpp	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/runtime/FunctionPrototype.cpp	2014-02-27 23:25:29 UTC (rev 164835)
@@ -22,6 +22,8 @@
 #include "FunctionPrototype.h"
 
 #include "Arguments.h"
+#include "BuiltinExecutables.h"
+#include "BuiltinNames.h"
 #include "JSArray.h"
 #include "JSBoundFunction.h"
 #include "JSFunction.h"
@@ -38,8 +40,6 @@
 const ClassInfo FunctionPrototype::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionPrototype) };
 
 static EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState*);
-static EncodedJSValue JSC_HOST_CALL functionProtoFuncApply(ExecState*);
-static EncodedJSValue JSC_HOST_CALL functionProtoFuncCall(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState*);
 
 FunctionPrototype::FunctionPrototype(VM& vm, Structure* structure)
@@ -60,12 +60,9 @@
     JSFunction* toStringFunction = JSFunction::create(vm, globalObject, 0, vm.propertyNames->toString.string(), functionProtoFuncToString);
     putDirectWithoutTransition(vm, vm.propertyNames->toString, toStringFunction, DontEnum);
 
-    *applyFunction = JSFunction::create(vm, globalObject, 2, vm.propertyNames->apply.string(), functionProtoFuncApply);
-    putDirectWithoutTransition(vm, vm.propertyNames->apply, *applyFunction, DontEnum);
+    *applyFunction = putDirectBuiltinFunctionWithoutTransition(vm, globalObject, vm.propertyNames->builtinNames().applyPublicName(), functionPrototypeApplyCodeGenerator(vm), DontEnum);
+    *callFunction = putDirectBuiltinFunctionWithoutTransition(vm, globalObject, vm.propertyNames->builtinNames().callPublicName(), functionPrototypeCallCodeGenerator(vm), DontEnum);
 
-    *callFunction = JSFunction::create(vm, globalObject, 1, vm.propertyNames->call.string(), functionProtoFuncCall);
-    putDirectWithoutTransition(vm, vm.propertyNames->call, *callFunction, DontEnum);
-
     JSFunction* bindFunction = JSFunction::create(vm, globalObject, 1, vm.propertyNames->bind.string(), functionProtoFuncBind);
     putDirectWithoutTransition(vm, vm.propertyNames->bind, bindFunction, DontEnum);
 }
@@ -124,55 +121,6 @@
     return throwVMTypeError(exec);
 }
 
-EncodedJSValue JSC_HOST_CALL functionProtoFuncApply(ExecState* exec)
-{
-    JSValue thisValue = exec->hostThisValue();
-    CallData callData;
-    CallType callType = getCallData(thisValue, callData);
-    if (callType == CallTypeNone)
-        return throwVMTypeError(exec);
-
-    JSValue array = exec->argument(1);
-
-    MarkedArgumentBuffer applyArgs;
-    if (!array.isUndefinedOrNull()) {
-        if (!array.isObject())
-            return throwVMTypeError(exec);
-        if (asObject(array)->classInfo() == Arguments::info()) {
-            if (asArguments(array)->length(exec) > Arguments::MaxArguments)
-                return JSValue::encode(throwStackOverflowError(exec));
-            asArguments(array)->fillArgList(exec, applyArgs);
-        } else if (isJSArray(array)) {
-            if (asArray(array)->length() > Arguments::MaxArguments)
-                return JSValue::encode(throwStackOverflowError(exec));
-            asArray(array)->fillArgList(exec, applyArgs);
-        } else {
-            unsigned length = asObject(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
-            if (length > Arguments::MaxArguments)
-                return JSValue::encode(throwStackOverflowError(exec));
-
-            for (unsigned i = 0; i < length; ++i)
-                applyArgs.append(asObject(array)->get(exec, i));
-        }
-    }
-    
-    return JSValue::encode(call(exec, thisValue, callType, callData, exec->argument(0), applyArgs));
-}
-
-EncodedJSValue JSC_HOST_CALL functionProtoFuncCall(ExecState* exec)
-{
-    JSValue thisValue = exec->hostThisValue();
-    CallData callData;
-    CallType callType = getCallData(thisValue, callData);
-    if (callType == CallTypeNone)
-        return throwVMTypeError(exec);
-
-    ArgList args(exec);
-    ArgList callArgs;
-    args.getSlice(1, callArgs);
-    return JSValue::encode(call(exec, thisValue, callType, callData, exec->argument(0), callArgs));
-}
-
 // 15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]])
 EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec)
 {

Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (164834 => 164835)


--- trunk/Source/_javascript_Core/runtime/JSObject.cpp	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp	2014-02-27 23:25:29 UTC (rev 164835)
@@ -2245,7 +2245,7 @@
     putDirect(vm, propertyName, function, attributes);
 }
 
-void JSObject::putDirectBuiltinFunction(VM& vm, JSGlobalObject* globalObject, const PropertyName& propertyName, FunctionExecutable* functionExecutable, unsigned attributes)
+JSFunction* JSObject::putDirectBuiltinFunction(VM& vm, JSGlobalObject* globalObject, const PropertyName& propertyName, FunctionExecutable* functionExecutable, unsigned attributes)
 {
     StringImpl* name = propertyName.publicName();
     if (!name)
@@ -2253,8 +2253,20 @@
     ASSERT(name);
     JSFunction* function = JSFunction::createBuiltinFunction(vm, static_cast<FunctionExecutable*>(functionExecutable), globalObject);
     putDirect(vm, propertyName, function, attributes);
+    return function;
 }
 
+JSFunction* JSObject::putDirectBuiltinFunctionWithoutTransition(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);
+    putDirectWithoutTransition(vm, propertyName, function, attributes);
+    return function;
+}
+
 void JSObject::putDirectNativeFunctionWithoutTransition(VM& vm, JSGlobalObject* globalObject, const PropertyName& propertyName, unsigned functionLength, NativeFunction nativeFunction, Intrinsic intrinsic, unsigned attributes)
 {
     StringImpl* name = propertyName.publicName();

Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (164834 => 164835)


--- trunk/Source/_javascript_Core/runtime/JSObject.h	2014-02-27 23:24:05 UTC (rev 164834)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h	2014-02-27 23:25:29 UTC (rev 164835)
@@ -67,6 +67,7 @@
 class GetterSetter;
 class HashEntry;
 class InternalFunction;
+class JSFunction;
 class LLIntOffsetsExtractor;
 class MarkedBlock;
 class PropertyDescriptor;
@@ -585,7 +586,8 @@
     void putDirectUndefined(PropertyOffset offset) { locationForOffset(offset)->setUndefined(); }
 
     JS_EXPORT_PRIVATE void putDirectNativeFunction(VM&, JSGlobalObject*, const PropertyName&, unsigned functionLength, NativeFunction, Intrinsic, unsigned attributes);
-    void putDirectBuiltinFunction(VM&, JSGlobalObject*, const PropertyName&, FunctionExecutable*, unsigned attributes);
+    JSFunction* putDirectBuiltinFunction(VM&, JSGlobalObject*, const PropertyName&, FunctionExecutable*, unsigned attributes);
+    JSFunction* putDirectBuiltinFunctionWithoutTransition(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);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to