Diff
Modified: trunk/LayoutTests/ChangeLog (166391 => 166392)
--- trunk/LayoutTests/ChangeLog 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/LayoutTests/ChangeLog 2014-03-28 01:10:25 UTC (rev 166392)
@@ -1,3 +1,27 @@
+2014-03-27 Oliver Hunt <[email protected]>
+
+ Support spread operand in |new| expressions
+ https://bugs.webkit.org/show_bug.cgi?id=130877
+
+ Reviewed by Michael Saboff.
+
+ Correctness and performance tests for spread operands
+
+ * js/parser-syntax-check-expected.txt:
+ * js/regress/call-spread-expected.txt: Added.
+ * js/regress/call-spread.html: Added.
+ * js/regress/new-spread-expected.txt: Added.
+ * js/regress/new-spread.html: Added.
+ * js/regress/script-tests/call-spread.js: Added.
+ (testFunction):
+ (test2):
+ (test3):
+ * js/regress/script-tests/new-spread.js: Added.
+ (testFunction):
+ (test2):
+ (test3):
+ * js/script-tests/parser-syntax-check.js:
+
2014-03-27 Bem Jones-Bey <[email protected]>
[CSS Shapes][css clip-path] rounded corner calculation for box shapes is wrong
Modified: trunk/LayoutTests/js/parser-syntax-check-expected.txt (166391 => 166392)
--- trunk/LayoutTests/js/parser-syntax-check-expected.txt 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/LayoutTests/js/parser-syntax-check-expected.txt 2014-03-28 01:10:25 UTC (rev 166392)
@@ -668,12 +668,12 @@
PASS Valid: "function f() { o.foo(...bar) }"
PASS Valid: "o[foo](...bar)"
PASS Valid: "function f() { o[foo](...bar) }"
-PASS Invalid: "new foo(...bar)"
-PASS Invalid: "function f() { new foo(...bar) }"
-PASS Invalid: "new o.foo(...bar)"
-PASS Invalid: "function f() { new o.foo(...bar) }"
-PASS Invalid: "new o[foo](...bar)"
-PASS Invalid: "function f() { new o[foo](...bar) }"
+PASS Valid: "new foo(...bar)"
+PASS Valid: "function f() { new foo(...bar) }"
+PASS Valid: "new o.foo(...bar)"
+PASS Valid: "function f() { new o.foo(...bar) }"
+PASS Valid: "new o[foo](...bar)"
+PASS Valid: "function f() { new o[foo](...bar) }"
PASS Invalid: "foo(...)"
PASS Invalid: "function f() { foo(...) }"
PASS Invalid: "o.foo(...)"
Added: trunk/LayoutTests/js/regress/call-spread-expected.txt (0 => 166392)
--- trunk/LayoutTests/js/regress/call-spread-expected.txt (rev 0)
+++ trunk/LayoutTests/js/regress/call-spread-expected.txt 2014-03-28 01:10:25 UTC (rev 166392)
@@ -0,0 +1,10 @@
+JSRegress/call-spread
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/regress/call-spread.html (0 => 166392)
--- trunk/LayoutTests/js/regress/call-spread.html (rev 0)
+++ trunk/LayoutTests/js/regress/call-spread.html 2014-03-28 01:10:25 UTC (rev 166392)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/regress/new-spread-expected.txt (0 => 166392)
--- trunk/LayoutTests/js/regress/new-spread-expected.txt (rev 0)
+++ trunk/LayoutTests/js/regress/new-spread-expected.txt 2014-03-28 01:10:25 UTC (rev 166392)
@@ -0,0 +1,10 @@
+JSRegress/new-spread
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/regress/new-spread.html (0 => 166392)
--- trunk/LayoutTests/js/regress/new-spread.html (rev 0)
+++ trunk/LayoutTests/js/regress/new-spread.html 2014-03-28 01:10:25 UTC (rev 166392)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/regress/script-tests/call-spread.js (0 => 166392)
--- trunk/LayoutTests/js/regress/script-tests/call-spread.js (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/call-spread.js 2014-03-28 01:10:25 UTC (rev 166392)
@@ -0,0 +1,34 @@
+
+function testFunction(a, b)
+{
+ "use strict"
+ result |= 0;
+ return a * 1000 + b * 100 + arguments[2] * 10 + arguments.length ^ (result & 1024);
+}
+
+var arrayArguments = [2, 3, 4]
+var result = 0;
+for (var i = 0; i < 1000000; i++)
+ result += testFunction(...arrayArguments);
+
+for (var i = 0; i < 1000000; i++)
+ result += testFunction(...[1, 2, result, 4]);
+
+function test2() {
+ for (var i = 0; i < 1000000; i++)
+ result += testFunction(...arguments);
+}
+
+test2(1,2,3,4)
+
+
+function test3() {
+ aliasedArguments = arguments;
+ for (var i = 0; i < 1000000; i++)
+ result += testFunction(...aliasedArguments);
+}
+
+test3(1,2,result,4)
+
+if (result != -856444619779264)
+ throw "Result was " + result + " expected -856444619779264";
\ No newline at end of file
Added: trunk/LayoutTests/js/regress/script-tests/new-spread.js (0 => 166392)
--- trunk/LayoutTests/js/regress/script-tests/new-spread.js (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/new-spread.js 2014-03-28 01:10:25 UTC (rev 166392)
@@ -0,0 +1,34 @@
+
+function testFunction(a, b)
+{
+ "use strict"
+ result |= 0;
+ result += a * 1000 + b * 100 + arguments[2] * 10 + arguments.length ^ (result & 1024);
+}
+
+var arrayArguments = [2, 3, 4]
+var result = 0;
+for (var i = 0; i < 1000000; i++)
+ new testFunction(...arrayArguments);
+
+for (var i = 0; i < 1000000; i++)
+ new testFunction(...[1, 2, result, 4]);
+
+function test2() {
+ for (var i = 0; i < 1000000; i++)
+ new testFunction(...arguments);
+}
+
+test2(1,2,3,4)
+
+
+function test3() {
+ aliasedArguments = arguments;
+ for (var i = 0; i < 1000000; i++)
+ new testFunction(...aliasedArguments);
+}
+
+test3(1,2,result,4)
+
+if (result != -2371153088)
+ throw "Result was " + result + " expected -2371153088";
\ No newline at end of file
Modified: trunk/LayoutTests/js/script-tests/parser-syntax-check.js (166391 => 166392)
--- trunk/LayoutTests/js/script-tests/parser-syntax-check.js 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/LayoutTests/js/script-tests/parser-syntax-check.js 2014-03-28 01:10:25 UTC (rev 166392)
@@ -418,9 +418,9 @@
valid("foo(...bar)")
valid("o.foo(...bar)")
valid("o[foo](...bar)")
-invalid("new foo(...bar)")
-invalid("new o.foo(...bar)")
-invalid("new o[foo](...bar)")
+valid("new foo(...bar)")
+valid("new o.foo(...bar)")
+valid("new o[foo](...bar)")
invalid("foo(...)")
invalid("o.foo(...)")
invalid("o[foo](...)")
Modified: trunk/Source/_javascript_Core/ChangeLog (166391 => 166392)
--- trunk/Source/_javascript_Core/ChangeLog 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/ChangeLog 2014-03-28 01:10:25 UTC (rev 166392)
@@ -1,3 +1,54 @@
+2014-03-27 Oliver Hunt <[email protected]>
+
+ Support spread operand in |new| expressions
+ https://bugs.webkit.org/show_bug.cgi?id=130877
+
+ Reviewed by Michael Saboff.
+
+ Add support for the spread operator being applied in
+ |new| expressions. This required adding support for
+ a new opcode, op_construct_varargs. This is a relatively
+ simple refactoring of the call_varargs implementation.
+
+ * bytecode/BytecodeList.json:
+ * bytecode/BytecodeUseDef.h:
+ (JSC::computeUsesForBytecodeOffset):
+ (JSC::computeDefsForBytecodeOffset):
+ * bytecode/CallLinkInfo.cpp:
+ (JSC::CallLinkInfo::unlink):
+ * bytecode/CallLinkInfo.h:
+ (JSC::CallLinkInfo::callTypeFor):
+ (JSC::CallLinkInfo::specializationKind):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::CodeBlock):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitCallVarargs):
+ (JSC::BytecodeGenerator::emitConstructVarargs):
+ (JSC::BytecodeGenerator::emitConstruct):
+ * bytecompiler/BytecodeGenerator.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ (JSC::JIT::emit_op_construct_varargs):
+ (JSC::JIT::emitSlow_op_construct_varargs):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::emitSlow_op_construct_varargs):
+ (JSC::JIT::emit_op_construct_varargs):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITOperations.cpp:
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LLIntSlowPaths.h:
+ * llint/LowLevelInterpreter.asm:
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::parseMemberExpression):
+
2014-03-27 Filip Pizlo <[email protected]>
Revert http://trac.webkit.org/changeset/166386 because it broke builds.
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeList.json (166391 => 166392)
--- trunk/Source/_javascript_Core/bytecode/BytecodeList.json 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeList.json 2014-03-28 01:10:25 UTC (rev 166392)
@@ -104,6 +104,7 @@
{ "name" : "op_ret", "length" : 2 },
{ "name" : "op_ret_object_or_this", "length" : 3 },
{ "name" : "op_construct", "length" : 9 },
+ { "name" : "op_construct_varargs", "length" : 9 },
{ "name" : "op_strcat", "length" : 4 },
{ "name" : "op_to_primitive", "length" : 3 },
{ "name" : "op_get_pnames", "length" : 6 },
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h (166391 => 166392)
--- trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2014-03-28 01:10:25 UTC (rev 166392)
@@ -176,6 +176,7 @@
functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
return;
}
+ case op_construct_varargs:
case op_call_varargs: {
functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
@@ -307,6 +308,7 @@
case op_new_captured_func:
case op_new_func_exp:
case op_call_varargs:
+ case op_construct_varargs:
case op_get_from_scope:
case op_call:
case op_call_eval:
Modified: trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp (166391 => 166392)
--- trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp 2014-03-28 01:10:25 UTC (rev 166392)
@@ -46,7 +46,7 @@
repatchBuffer.relink(
callReturnLocation,
repatchBuffer.codeBlock()->vm()->getCTIStub(linkThunkGeneratorFor(
- callType == Construct ? CodeForConstruct : CodeForCall,
+ (callType == Construct || callType == ConstructVarargs)? CodeForConstruct : CodeForCall,
isFTL ? MustPreserveRegisters : RegisterPreservationNotRequired)).code());
hasSeenShouldRepatch = false;
callee.clear();
Modified: trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h (166391 => 166392)
--- trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h 2014-03-28 01:10:25 UTC (rev 166392)
@@ -42,13 +42,15 @@
class RepatchBuffer;
struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
- enum CallType { None, Call, CallVarargs, Construct };
+ enum CallType { None, Call, CallVarargs, Construct, ConstructVarargs };
static CallType callTypeFor(OpcodeID opcodeID)
{
if (opcodeID == op_call || opcodeID == op_call_eval)
return Call;
if (opcodeID == op_construct)
return Construct;
+ if (opcodeID == op_construct_varargs)
+ return ConstructVarargs;
ASSERT(opcodeID == op_call_varargs);
return CallVarargs;
}
@@ -70,7 +72,7 @@
CodeSpecializationKind specializationKind() const
{
- return specializationFromIsConstruct(callType == Construct);
+ return specializationFromIsConstruct(callType == Construct || callType == ConstructVarargs);
}
CodeLocationNearCall callReturnLocation;
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (166391 => 166392)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2014-03-28 01:10:25 UTC (rev 166392)
@@ -627,7 +627,8 @@
{
int location = it - begin;
bool hasPrintedProfiling = false;
- switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
+ OpcodeID opcode = exec->interpreter()->getOpcodeID(it->u.opcode);
+ switch (opcode) {
case op_enter: {
printLocationAndOp(out, exec, location, it, "enter");
break;
@@ -1188,6 +1189,8 @@
printCallOp(out, exec, location, it, "call_eval", DontDumpCaches, hasPrintedProfiling, callLinkInfos);
break;
}
+
+ case op_construct_varargs:
case op_call_varargs: {
int result = (++it)->u.operand;
int callee = (++it)->u.operand;
@@ -1196,11 +1199,12 @@
int firstFreeRegister = (++it)->u.operand;
int varArgOffset = (++it)->u.operand;
++it;
- printLocationAndOp(out, exec, location, it, "call_varargs");
+ printLocationAndOp(out, exec, location, it, opcode == op_call_varargs ? "call_varargs" : "construct_varargs");
out.printf("%s, %s, %s, %s, %d, %d", registerName(result).data(), registerName(callee).data(), registerName(thisValue).data(), registerName(arguments).data(), firstFreeRegister, varArgOffset);
dumpValueProfiling(out, it, hasPrintedProfiling);
break;
}
+
case op_tear_off_activation: {
int r0 = (++it)->u.operand;
printLocationOpAndRegisterOperand(out, exec, location, it, "tear_off_activation", r0);
@@ -1640,6 +1644,7 @@
}
switch (pc[0].u.opcode) {
case op_call_varargs:
+ case op_construct_varargs:
case op_get_by_val:
case op_get_argument_by_val: {
int arrayProfileIndex = pc[opLength - 2].u.operand;
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (166391 => 166392)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2014-03-28 01:10:25 UTC (rev 166392)
@@ -1788,6 +1788,16 @@
RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
{
+ return emitCallVarargs(op_call_varargs, dst, func, thisRegister, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
+}
+
+RegisterID* BytecodeGenerator::emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
+{
+ return emitCallVarargs(op_construct_varargs, dst, func, 0, arguments, firstFreeRegister, firstVarArgOffset, profileHookRegister, divot, divotStart, divotEnd);
+}
+
+RegisterID* BytecodeGenerator::emitCallVarargs(OpcodeID opcode, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
+{
if (m_shouldEmitProfileHooks) {
emitMove(profileHookRegister, func);
emitOpcode(op_profile_will_call);
@@ -1798,11 +1808,11 @@
// Emit call.
UnlinkedArrayProfile arrayProfile = newArrayProfile();
- UnlinkedValueProfile profile = ""
+ UnlinkedValueProfile profile = ""
ASSERT(dst != ignoredResult());
instructions().append(dst->index());
instructions().append(func->index());
- instructions().append(thisRegister->index());
+ instructions().append(thisRegister ? thisRegister->index() : 0);
instructions().append(arguments->index());
instructions().append(firstFreeRegister->index());
instructions().append(firstVarArgOffset);
@@ -1857,6 +1867,19 @@
// Generate code for arguments.
unsigned argument = 0;
if (ArgumentsNode* argumentsNode = callArguments.argumentsNode()) {
+
+ ArgumentListNode* n = callArguments.argumentsNode()->m_listNode;
+ if (n && n->m_expr->isSpreadExpression()) {
+ RELEASE_ASSERT(!n->m_next);
+ auto _expression_ = static_cast<SpreadExpressionNode*>(n->m_expr)->_expression_();
+ RefPtr<RegisterID> argumentRegister;
+ if (_expression_->isResolveNode() && willResolveToArguments(static_cast<ResolveNode*>(_expression_)->identifier()) && !symbolTable().slowArguments())
+ argumentRegister = uncheckedRegisterForArguments();
+ else
+ argumentRegister = _expression_->emitBytecode(*this, callArguments.argumentRegister(0));
+ return emitConstructVarargs(dst, func, argumentRegister.get(), newTemporary(), 0, callArguments.profileHookRegister(), divot, divotStart, divotEnd);
+ }
+
for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next)
emitNode(callArguments.argumentRegister(argument++), n);
}
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (166391 => 166392)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2014-03-28 01:10:25 UTC (rev 166392)
@@ -551,7 +551,10 @@
}
RegisterID* emitInitLazyRegister(RegisterID*);
-
+
+ RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
+ RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
+
public:
JSString* addStringConstant(const Identifier&);
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (166391 => 166392)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2014-03-28 01:10:25 UTC (rev 166392)
@@ -186,6 +186,7 @@
DEFINE_OP(op_call)
DEFINE_OP(op_call_eval)
DEFINE_OP(op_call_varargs)
+ DEFINE_OP(op_construct_varargs)
DEFINE_OP(op_catch)
DEFINE_OP(op_construct)
DEFINE_OP(op_get_callee)
@@ -353,6 +354,7 @@
DEFINE_SLOWCASE_OP(op_call)
DEFINE_SLOWCASE_OP(op_call_eval)
DEFINE_SLOWCASE_OP(op_call_varargs)
+ DEFINE_SLOWCASE_OP(op_construct_varargs)
DEFINE_SLOWCASE_OP(op_construct)
DEFINE_SLOWCASE_OP(op_to_this)
DEFINE_SLOWCASE_OP(op_create_this)
Modified: trunk/Source/_javascript_Core/jit/JIT.h (166391 => 166392)
--- trunk/Source/_javascript_Core/jit/JIT.h 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2014-03-28 01:10:25 UTC (rev 166392)
@@ -455,6 +455,7 @@
void emit_op_call(Instruction*);
void emit_op_call_eval(Instruction*);
void emit_op_call_varargs(Instruction*);
+ void emit_op_construct_varargs(Instruction*);
void emit_op_captured_mov(Instruction*);
void emit_op_catch(Instruction*);
void emit_op_construct(Instruction*);
@@ -554,6 +555,7 @@
void emitSlow_op_call(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_call_eval(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_construct_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_captured_mov(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_to_this(Instruction*, Vector<SlowCaseEntry>::iterator&);
Modified: trunk/Source/_javascript_Core/jit/JITCall.cpp (166391 => 166392)
--- trunk/Source/_javascript_Core/jit/JITCall.cpp 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/jit/JITCall.cpp 2014-03-28 01:10:25 UTC (rev 166392)
@@ -186,7 +186,8 @@
*/
COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct), call_and_construct_opcodes_must_be_same_length);
COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_varargs), call_and_call_varargs_opcodes_must_be_same_length);
- if (opcodeID == op_call_varargs)
+ COMPILE_ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct_varargs), call_and_construct_varargs_opcodes_must_be_same_length);
+ if (opcodeID == op_call_varargs || opcodeID == op_construct_varargs)
compileLoadVarargs(instruction);
else {
int argCount = instruction[3].u.operand;
@@ -252,7 +253,7 @@
linkSlowCase(iter);
ThunkGenerator generator = linkThunkGeneratorFor(
- opcodeID == op_construct ? CodeForConstruct : CodeForCall,
+ (opcodeID == op_construct || opcodeID == op_construct_varargs) ? CodeForConstruct : CodeForCall,
RegisterPreservationNotRequired);
move(TrustedImmPtr(m_callCompilationInfo[callLinkInfoIndex].callLinkInfo), regT2);
@@ -326,6 +327,11 @@
{
compileOpCall(op_call_varargs, currentInstruction, m_callLinkInfoIndex++);
}
+
+void JIT::emit_op_construct_varargs(Instruction* currentInstruction)
+{
+ compileOpCall(op_construct_varargs, currentInstruction, m_callLinkInfoIndex++);
+}
void JIT::emit_op_construct(Instruction* currentInstruction)
{
@@ -346,7 +352,12 @@
{
compileOpCallSlowCase(op_call_varargs, currentInstruction, iter, m_callLinkInfoIndex++);
}
-
+
+void JIT::emitSlow_op_construct_varargs(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ compileOpCallSlowCase(op_construct_varargs, currentInstruction, iter, m_callLinkInfoIndex++);
+}
+
void JIT::emitSlow_op_construct(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
compileOpCallSlowCase(op_construct, currentInstruction, iter, m_callLinkInfoIndex++);
Modified: trunk/Source/_javascript_Core/jit/JITCall32_64.cpp (166391 => 166392)
--- trunk/Source/_javascript_Core/jit/JITCall32_64.cpp 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/jit/JITCall32_64.cpp 2014-03-28 01:10:25 UTC (rev 166392)
@@ -99,7 +99,12 @@
{
compileOpCallSlowCase(op_call_varargs, currentInstruction, iter, m_callLinkInfoIndex++);
}
-
+
+void JIT::emitSlow_op_construct_varargs(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ compileOpCallSlowCase(op_construct_varargs, currentInstruction, iter, m_callLinkInfoIndex++);
+}
+
void JIT::emitSlow_op_construct(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
compileOpCallSlowCase(op_construct, currentInstruction, iter, m_callLinkInfoIndex++);
@@ -119,7 +124,12 @@
{
compileOpCall(op_call_varargs, currentInstruction, m_callLinkInfoIndex++);
}
-
+
+void JIT::emit_op_construct_varargs(Instruction* currentInstruction)
+{
+ compileOpCall(op_construct_varargs, currentInstruction, m_callLinkInfoIndex++);
+}
+
void JIT::emit_op_construct(Instruction* currentInstruction)
{
compileOpCall(op_construct, currentInstruction, m_callLinkInfoIndex++);
@@ -263,7 +273,7 @@
- Caller restores callFrameRegister after return.
*/
- if (opcodeID == op_call_varargs)
+ if (opcodeID == op_call_varargs || opcodeID == op_construct_varargs)
compileLoadVarargs(instruction);
else {
int argCount = instruction[3].u.operand;
@@ -334,7 +344,7 @@
linkSlowCase(iter);
ThunkGenerator generator = linkThunkGeneratorFor(
- opcodeID == op_construct ? CodeForConstruct : CodeForCall,
+ (opcodeID == op_construct || opcodeID == op_construct_varargs) ? CodeForConstruct : CodeForCall,
RegisterPreservationNotRequired);
move(TrustedImmPtr(m_callCompilationInfo[callLinkInfoIndex].callLinkInfo), regT2);
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (166391 => 166392)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2014-03-28 01:10:25 UTC (rev 166392)
@@ -705,7 +705,7 @@
}
codeBlock = functionExecutable->codeBlockFor(kind);
ArityCheckMode arity;
- if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo->callType == CallLinkInfo::CallVarargs)
+ if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo->callType == CallLinkInfo::CallVarargs || callLinkInfo->callType == CallLinkInfo::ConstructVarargs)
arity = MustCheckArity;
else
arity = ArityCheckNotRequired;
@@ -802,7 +802,7 @@
codeBlock = 0;
else {
codeBlock = jsCast<FunctionExecutable*>(callee->executable())->codeBlockForCall();
- if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.callType == CallLinkInfo::CallVarargs)
+ if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.callType == CallLinkInfo::CallVarargs || callLinkInfo.callType == CallLinkInfo::ConstructVarargs)
return false;
}
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (166391 => 166392)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2014-03-28 01:10:25 UTC (rev 166392)
@@ -1192,7 +1192,28 @@
return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
}
-
+
+LLINT_SLOW_PATH_DECL(slow_path_construct_varargs)
+{
+ LLINT_BEGIN_NO_SET_PC();
+ // This needs to:
+ // - Figure out what to call and compile it if necessary.
+ // - Return a tuple of machine code address to call and the new call frame.
+
+ JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
+
+ ExecState* execCallee = vm.newCallFrameReturnValue;
+
+ loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
+ LLINT_CALL_CHECK_EXCEPTION(exec);
+
+ execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
+ execCallee->setCallerFrame(exec);
+ exec->setCurrentVPC(pc);
+
+ return setUpCall(execCallee, pc, CodeForConstruct, calleeAsValue);
+}
+
LLINT_SLOW_PATH_DECL(slow_path_call_eval)
{
LLINT_BEGIN_NO_SET_PC();
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h (166391 => 166392)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.h 2014-03-28 01:10:25 UTC (rev 166392)
@@ -103,6 +103,7 @@
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_size_frame_for_varargs);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_varargs);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct_varargs);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_eval);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_activation);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_tear_off_arguments);
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (166391 => 166392)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2014-03-28 01:10:25 UTC (rev 166392)
@@ -991,7 +991,25 @@
end
slowPathForCall(_llint_slow_path_call_varargs)
+_llint_op_construct_varargs:
+ traceExecution()
+ callSlowPath(_llint_slow_path_size_frame_for_varargs)
+ branchIfException(_llint_throw_from_slow_path_trampoline)
+ # calleeFrame in t1
+ if JSVALUE64
+ move t1, sp
+ else
+ # The calleeFrame is not stack aligned, move down by CallerFrameAndPCSize to align
+ if ARMv7
+ subp t1, CallerFrameAndPCSize, t2
+ move t2, sp
+ else
+ subp t1, CallerFrameAndPCSize, sp
+ end
+ end
+ slowPathForCall(_llint_slow_path_construct_varargs)
+
_llint_op_call_eval:
traceExecution()
Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (166391 => 166392)
--- trunk/Source/_javascript_Core/parser/Parser.cpp 2014-03-28 01:00:35 UTC (rev 166391)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp 2014-03-28 01:10:25 UTC (rev 166392)
@@ -2144,7 +2144,7 @@
if (newCount) {
newCount--;
JSTextPosition expressionEnd = lastTokenEndPosition();
- TreeArguments arguments = parseArguments(context, DontAllowSpread);
+ TreeArguments arguments = parseArguments(context, AllowSpread);
failIfFalse(arguments, "Cannot parse call arguments");
base = context.createNewExpr(location, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition());
} else {