diff options
author | Ben Murdoch <benm@google.com> | 2010-07-22 15:37:06 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-07-27 10:20:25 +0100 |
commit | 967717af5423377c967781471ee106e2bb4e11c8 (patch) | |
tree | 1e701dc0a12f7f07cce1df4a7681717de77a211b /JavaScriptCore/bytecompiler | |
parent | dcc30a9fca45f634b1d3a12b276d3a0ccce99fc3 (diff) | |
download | external_webkit-967717af5423377c967781471ee106e2bb4e11c8.zip external_webkit-967717af5423377c967781471ee106e2bb4e11c8.tar.gz external_webkit-967717af5423377c967781471ee106e2bb4e11c8.tar.bz2 |
Merge WebKit at r63859 : Initial merge by git.
Change-Id: Ie8096c63ec7c991c9a9cba8bdd9c3b74a3b8ed62
Diffstat (limited to 'JavaScriptCore/bytecompiler')
-rw-r--r-- | JavaScriptCore/bytecompiler/BytecodeGenerator.cpp | 17 | ||||
-rw-r--r-- | JavaScriptCore/bytecompiler/BytecodeGenerator.h | 7 | ||||
-rw-r--r-- | JavaScriptCore/bytecompiler/NodesCodegen.cpp | 35 |
3 files changed, 52 insertions, 7 deletions
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index 8ff1b5d..a3fa937 100644 --- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -152,8 +152,6 @@ void BytecodeGenerator::generate() if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode) symbolTable().clear(); - - m_codeBlock->setIsNumericCompareFunction(instructions() == m_globalData->numericCompareFunction(m_scopeChain->globalObject()->globalExec())); #if !ENABLE(OPCODE_SAMPLING) if (!m_regeneratingForExceptionInfo && !m_usesExceptions && (m_codeType == FunctionCode || m_codeType == EvalCode)) @@ -2045,4 +2043,19 @@ RegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException() return exception; } +void BytecodeGenerator::setIsNumericCompareFunction(bool isNumericCompareFunction) +{ + m_codeBlock->setIsNumericCompareFunction(isNumericCompareFunction); +} + +int BytecodeGenerator::argumentNumberFor(const Identifier& ident) +{ + int parameterCount = m_parameters.size(); // includes 'this' + RegisterID* registerID = registerFor(ident); + if (!registerID) + return 0; + int index = registerID->index() + RegisterFile::CallFrameHeaderSize + parameterCount; + return (index > 0 && index < parameterCount) ? index : 0; +} + } // namespace JSC diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h index 2b231a7..ad0ae4e 100644 --- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -108,7 +108,12 @@ namespace JSC { // such register exists. Registers returned by registerFor do not // require explicit reference counting. RegisterID* registerFor(const Identifier&); - + + // Returns the agument number if this is an argument, or 0 if not. + int argumentNumberFor(const Identifier&); + + void setIsNumericCompareFunction(bool isNumericCompareFunction); + bool willResolveToArguments(const Identifier&); RegisterID* uncheckedRegisterForArguments(); diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp index e50ce2d..277562d 100644 --- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp +++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp @@ -1359,6 +1359,11 @@ inline StatementNode* BlockNode::lastStatement() const return m_statements ? m_statements->lastStatement() : 0; } +inline StatementNode* BlockNode::singleStatement() const +{ + return m_statements ? m_statements->singleStatement() : 0; +} + RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { if (m_statements) @@ -2011,16 +2016,38 @@ RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, Registe { generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine()); emitStatementsBytecode(generator, generator.ignoredResult()); + StatementNode* singleStatement = this->singleStatement(); + ReturnNode* returnNode = 0; + + // Check for a return statement at the end of a function composed of a single block. if (singleStatement && singleStatement->isBlock()) { StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement(); if (lastStatementInBlock && lastStatementInBlock->isReturnNode()) - return 0; + returnNode = static_cast<ReturnNode*>(lastStatementInBlock); + } + + // If there is no return we must automatically insert one. + if (!returnNode) { + RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined()); + generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine()); + generator.emitReturn(r0); + return 0; + } + + // If there is a return statment, and it is the only statement in the function, check if this is a numeric compare. + if (static_cast<BlockNode*>(singleStatement)->singleStatement()) { + ExpressionNode* returnValueExpression = returnNode->value(); + if (returnValueExpression && returnValueExpression->isSubtract()) { + ExpressionNode* lhsExpression = static_cast<SubNode*>(returnValueExpression)->lhs(); + ExpressionNode* rhsExpression = static_cast<SubNode*>(returnValueExpression)->rhs(); + if (lhsExpression->isResolveNode() && rhsExpression->isResolveNode()) { + generator.setIsNumericCompareFunction(generator.argumentNumberFor(static_cast<ResolveNode*>(lhsExpression)->identifier()) == 1 + && generator.argumentNumberFor(static_cast<ResolveNode*>(rhsExpression)->identifier()) == 2); + } + } } - RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined()); - generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine()); - generator.emitReturn(r0); return 0; } |