summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/parser
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2009-08-11 17:01:47 +0100
committerBen Murdoch <benm@google.com>2009-08-11 18:21:02 +0100
commit0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5 (patch)
tree2943df35f62d885c89d01063cc528dd73b480fea /JavaScriptCore/parser
parent7e7a70bfa49a1122b2597a1e6367d89eb4035eca (diff)
downloadexternal_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.zip
external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.gz
external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.bz2
Merge in WebKit r47029.
Diffstat (limited to 'JavaScriptCore/parser')
-rw-r--r--JavaScriptCore/parser/Grammar.y28
-rw-r--r--JavaScriptCore/parser/Lexer.h6
-rw-r--r--JavaScriptCore/parser/NodeConstructors.h9
-rw-r--r--JavaScriptCore/parser/Nodes.cpp108
-rw-r--r--JavaScriptCore/parser/Nodes.h34
-rw-r--r--JavaScriptCore/parser/Parser.h2
6 files changed, 102 insertions, 85 deletions
diff --git a/JavaScriptCore/parser/Grammar.y b/JavaScriptCore/parser/Grammar.y
index 52dddde..354c786 100644
--- a/JavaScriptCore/parser/Grammar.y
+++ b/JavaScriptCore/parser/Grammar.y
@@ -36,8 +36,12 @@
#include "CommonIdentifiers.h"
#include "NodeInfo.h"
#include "Parser.h"
+#include <wtf/FastMalloc.h>
#include <wtf/MathExtras.h>
+#define YYMALLOC fastMalloc
+#define YYFREE fastFree
+
#define YYMAXDEPTH 10000
#define YYENABLE_NLS 0
@@ -80,7 +84,7 @@ static ExpressionNode* makeSubNode(void*, ExpressionNode*, ExpressionNode*, bool
static ExpressionNode* makeLeftShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
static ExpressionNode* makeRightShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
static StatementNode* makeVarStatementNode(void*, ExpressionNode*);
-static ExpressionNode* combineVarInitializers(void*, ExpressionNode* list, AssignResolveNode* init);
+static ExpressionNode* combineCommaNodes(void*, ExpressionNode* list, ExpressionNode* init);
#if COMPILER(MSVC)
@@ -88,12 +92,6 @@ static ExpressionNode* combineVarInitializers(void*, ExpressionNode* list, Assig
#pragma warning(disable: 4244)
#pragma warning(disable: 4702)
-// At least some of the time, the declarations of malloc and free that bison
-// generates are causing warnings. A way to avoid this is to explicitly define
-// the macros so that bison doesn't try to declare malloc and free.
-#define YYMALLOC malloc
-#define YYFREE free
-
#endif
#define YYPARSE_PARAM globalPtr
@@ -778,17 +776,17 @@ AssignmentOperator:
Expr:
AssignmentExpr
- | Expr ',' AssignmentExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) CommaNode(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+ | Expr ',' AssignmentExpr { $$ = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
;
ExprNoIn:
AssignmentExprNoIn
- | ExprNoIn ',' AssignmentExprNoIn { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) CommaNode(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+ | ExprNoIn ',' AssignmentExprNoIn { $$ = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
;
ExprNoBF:
AssignmentExprNoBF
- | ExprNoBF ',' AssignmentExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) CommaNode(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+ | ExprNoBF ',' AssignmentExpr { $$ = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
;
Statement:
@@ -854,7 +852,7 @@ VariableDeclarationList:
| VariableDeclarationList ',' IDENT Initializer
{ AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature);
SET_EXCEPTION_LOCATION(node, @3.first_column, @4.first_column + 1, @4.last_column);
- $$.m_node = combineVarInitializers(GLOBAL_DATA, $1.m_node, node);
+ $$.m_node = combineCommaNodes(GLOBAL_DATA, $1.m_node, node);
$$.m_varDeclarations = $1.m_varDeclarations;
appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer);
$$.m_funcDeclarations = 0;
@@ -891,7 +889,7 @@ VariableDeclarationListNoIn:
| VariableDeclarationListNoIn ',' IDENT InitializerNoIn
{ AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature);
SET_EXCEPTION_LOCATION(node, @3.first_column, @4.first_column + 1, @4.last_column);
- $$.m_node = combineVarInitializers(GLOBAL_DATA, $1.m_node, node);
+ $$.m_node = combineCommaNodes(GLOBAL_DATA, $1.m_node, node);
$$.m_varDeclarations = $1.m_varDeclarations;
appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer);
$$.m_funcDeclarations = 0;
@@ -2071,10 +2069,14 @@ static bool allowAutomaticSemicolon(Lexer& lexer, int yychar)
return yychar == CLOSEBRACE || yychar == 0 || lexer.prevTerminator();
}
-static ExpressionNode* combineVarInitializers(void* globalPtr, ExpressionNode* list, AssignResolveNode* init)
+static ExpressionNode* combineCommaNodes(void* globalPtr, ExpressionNode* list, ExpressionNode* init)
{
if (!list)
return init;
+ if (list->isCommaNode()) {
+ static_cast<CommaNode*>(list)->append(init);
+ return list;
+ }
return new (GLOBAL_DATA) CommaNode(GLOBAL_DATA, list, init);
}
diff --git a/JavaScriptCore/parser/Lexer.h b/JavaScriptCore/parser/Lexer.h
index 9c22a9c..2583162 100644
--- a/JavaScriptCore/parser/Lexer.h
+++ b/JavaScriptCore/parser/Lexer.h
@@ -23,9 +23,9 @@
#define Lexer_h
#include "Lookup.h"
-#include "SegmentedVector.h"
#include "SourceCode.h"
#include <wtf/ASCIICType.h>
+#include <wtf/SegmentedVector.h>
#include <wtf/Vector.h>
#include <wtf/unicode/Unicode.h>
@@ -33,7 +33,7 @@ namespace JSC {
class RegExp;
- class Lexer : Noncopyable {
+ class Lexer : public Noncopyable {
public:
// Character manipulation functions.
static bool isWhiteSpace(int character);
@@ -108,7 +108,7 @@ namespace JSC {
int m_next2;
int m_next3;
- SegmentedVector<JSC::Identifier, initialIdentifierTableCapacity> m_identifiers;
+ WTF::SegmentedVector<JSC::Identifier, initialIdentifierTableCapacity> m_identifiers;
JSGlobalData* m_globalData;
diff --git a/JavaScriptCore/parser/NodeConstructors.h b/JavaScriptCore/parser/NodeConstructors.h
index ea1579b..780a624 100644
--- a/JavaScriptCore/parser/NodeConstructors.h
+++ b/JavaScriptCore/parser/NodeConstructors.h
@@ -39,6 +39,11 @@ namespace JSC {
return fastMalloc(size);
}
+ inline void ParserArenaDeletable::operator delete(void* p)
+ {
+ fastFree(p);
+ }
+
inline ParserArenaRefCounted::ParserArenaRefCounted(JSGlobalData* globalData)
{
globalData->parser->arena().derefWithArena(adoptRef(this));
@@ -659,9 +664,9 @@ namespace JSC {
inline CommaNode::CommaNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2)
: ExpressionNode(globalData)
- , m_expr1(expr1)
- , m_expr2(expr2)
{
+ m_expressions.append(expr1);
+ m_expressions.append(expr2);
}
inline ConstStatementNode::ConstStatementNode(JSGlobalData* globalData, ConstDeclNode* next)
diff --git a/JavaScriptCore/parser/Nodes.cpp b/JavaScriptCore/parser/Nodes.cpp
index 4ddf13a..4324a06 100644
--- a/JavaScriptCore/parser/Nodes.cpp
+++ b/JavaScriptCore/parser/Nodes.cpp
@@ -355,7 +355,7 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator,
RefPtr<RegisterID> thisRegister = generator.newTemporary();
int identifierStart = divot() - startOffset();
generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
- generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident);
+ generator.emitResolveWithBase(thisRegister.get(), func.get(), m_ident);
return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
}
@@ -375,11 +375,12 @@ RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator,
RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<RegisterID> base = generator.emitNode(m_base);
+ RefPtr<RegisterID> function = generator.tempDestination(dst);
+ RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ generator.emitNode(thisRegister.get(), m_base);
generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
generator.emitMethodCheck();
- RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
- RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
+ generator.emitGetById(function.get(), thisRegister.get(), m_ident);
return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
}
@@ -495,6 +496,8 @@ static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* src
static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
{
+ if (srcDst == dst)
+ return generator.emitToJSNumber(dst, srcDst);
return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
}
@@ -601,7 +604,7 @@ RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, Registe
RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (generator.registerFor(m_ident))
- return generator.emitUnexpectedLoad(generator.finalDestination(dst), false);
+ return generator.emitLoad(generator.finalDestination(dst), false);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
@@ -636,7 +639,7 @@ RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, Register
generator.emitNode(generator.ignoredResult(), m_expr);
// delete on a non-location expression ignores the value and returns true
- return generator.emitUnexpectedLoad(generator.finalDestination(dst), true);
+ return generator.emitLoad(generator.finalDestination(dst), true);
}
// ------------------------------ VoidNode -------------------------------------
@@ -688,7 +691,7 @@ RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
if (generator.isLocalConstant(m_ident)) {
if (dst == generator.ignoredResult())
return 0;
- RefPtr<RegisterID> r0 = generator.emitUnexpectedLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
+ RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
}
@@ -1186,8 +1189,10 @@ RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, Re
RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitNode(generator.ignoredResult(), m_expr1);
- return generator.emitNode(dst, m_expr2);
+ ASSERT(m_expressions.size() > 1);
+ for (size_t i = 0; i < m_expressions.size() - 1; i++)
+ generator.emitNode(generator.ignoredResult(), m_expressions[i]);
+ return generator.emitNode(dst, m_expressions.last());
}
// ------------------------------ ConstDeclNode ------------------------------------
@@ -1369,9 +1374,6 @@ RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (dst == generator.ignoredResult())
- dst = 0;
-
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
@@ -1559,13 +1561,11 @@ static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>&
literalVector.append(clauseExpression);
if (clauseExpression->isNumber()) {
double value = static_cast<NumberNode*>(clauseExpression)->value();
- JSValue jsValue = JSValue::makeInt32Fast(static_cast<int32_t>(value));
- if ((typeForTable & ~SwitchNumber) || !jsValue || (jsValue.getInt32Fast() != value)) {
+ int32_t intVal = static_cast<int32_t>(value);
+ if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
typeForTable = SwitchNeither;
break;
}
- int32_t intVal = static_cast<int32_t>(value);
- ASSERT(intVal == value);
if (intVal < min_num)
min_num = intVal;
if (intVal > max_num)
@@ -1736,10 +1736,12 @@ RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ // NOTE: The catch and finally blocks must be labeled explicitly, so the
+ // optimizer knows they may be jumped to from anywhere.
+
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
RefPtr<Label> tryStartLabel = generator.newLabel();
- RefPtr<Label> tryEndLabel = generator.newLabel();
RefPtr<Label> finallyStart;
RefPtr<RegisterID> finallyReturnAddr;
if (m_finallyBlock) {
@@ -1747,14 +1749,19 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
finallyReturnAddr = generator.newTemporary();
generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
}
+
generator.emitLabel(tryStartLabel.get());
generator.emitNode(dst, m_tryBlock);
- generator.emitLabel(tryEndLabel.get());
if (m_catchBlock) {
- RefPtr<Label> handlerEndLabel = generator.newLabel();
- generator.emitJump(handlerEndLabel.get());
- RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
+ RefPtr<Label> catchEndLabel = generator.newLabel();
+
+ // Normal path: jump over the catch block.
+ generator.emitJump(catchEndLabel.get());
+
+ // Uncaught exception path: the catch block.
+ RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
+ RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
if (m_catchHasEval) {
RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
@@ -1764,7 +1771,7 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
generator.emitNode(dst, m_catchBlock);
generator.emitPopScope();
- generator.emitLabel(handlerEndLabel.get());
+ generator.emitLabel(catchEndLabel.get());
}
if (m_finallyBlock) {
@@ -1775,21 +1782,18 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
// approach to not clobbering anything important
RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
RefPtr<Label> finallyEndLabel = generator.newLabel();
+
+ // Normal path: invoke the finally block, then jump over it.
generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
- // Use a label to record the subtle fact that sret will return to the
- // next instruction. sret is the only way to jump without an explicit label.
- generator.emitLabel(generator.newLabel().get());
generator.emitJump(finallyEndLabel.get());
- // Finally block for exception path
- RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
+ // Uncaught exception path: invoke the finally block, then re-throw the exception.
+ RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
+ RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
- // Use a label to record the subtle fact that sret will return to the
- // next instruction. sret is the only way to jump without an explicit label.
- generator.emitLabel(generator.newLabel().get());
generator.emitThrow(tempExceptionRegister.get());
- // emit the finally block itself
+ // The finally block.
generator.emitLabel(finallyStart.get());
generator.emitNode(dst, m_finallyBlock);
generator.emitSubroutineReturn(finallyReturnAddr.get());
@@ -1814,14 +1818,14 @@ ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* children, VarSt
children->releaseContentsIntoVector(m_children);
}
-void ScopeNodeData::mark()
+void ScopeNodeData::markAggregate(MarkStack& markStack)
{
FunctionStack::iterator end = m_functionStack.end();
for (FunctionStack::iterator ptr = m_functionStack.begin(); ptr != end; ++ptr) {
FunctionBodyNode* body = (*ptr)->body();
if (!body->isGenerated())
continue;
- body->generatedBytecode().mark();
+ body->generatedBytecode().markAggregate(markStack);
}
}
@@ -1889,8 +1893,8 @@ void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode)
m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
- BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
- generator.generate();
+ OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get()));
+ generator->generate();
destroyData();
}
@@ -1944,8 +1948,8 @@ void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode)
m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
- BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
- generator.generate();
+ OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get()));
+ generator->generate();
// Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
// so the entire ScopeNodeData cannot be destoyed.
@@ -1961,17 +1965,17 @@ EvalCodeBlock& EvalNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeCh
m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
- BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
- generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
- generator.generate();
+ OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get()));
+ generator->setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
+ generator->generate();
return *m_code;
}
-void EvalNode::mark()
+void EvalNode::markAggregate(MarkStack& markStack)
{
// We don't need to mark our own CodeBlock as the JSGlobalObject takes care of that
- data()->mark();
+ data()->markAggregate(markStack);
}
#if ENABLE(JIT)
@@ -2026,10 +2030,10 @@ void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCou
m_parameterCount = parameterCount;
}
-void FunctionBodyNode::mark()
+void FunctionBodyNode::markAggregate(MarkStack& markStack)
{
if (m_code)
- m_code->mark();
+ m_code->markAggregate(markStack);
}
#if ENABLE(JIT)
@@ -2037,11 +2041,17 @@ PassRefPtr<FunctionBodyNode> FunctionBodyNode::createNativeThunk(JSGlobalData* g
{
RefPtr<FunctionBodyNode> body = new FunctionBodyNode(globalData);
globalData->parser->arena().reset();
+ body->m_code.set(new CodeBlock(body.get()));
body->m_jitCode = JITCode(JITCode::HostFunction(globalData->jitStubs.ctiNativeCallThunk()));
return body.release();
}
#endif
+bool FunctionBodyNode::isHostFunction() const
+{
+ return m_code && m_code->codeType() == NativeCode;
+}
+
FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
{
return new FunctionBodyNode(globalData);
@@ -2071,8 +2081,8 @@ void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
- BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
- generator.generate();
+ OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get()));
+ generator->generate();
destroyData();
}
@@ -2097,9 +2107,9 @@ CodeBlock& FunctionBodyNode::bytecodeForExceptionInfoReparse(ScopeChainNode* sco
m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
- BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
- generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
- generator.generate();
+ OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get()));
+ generator->setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
+ generator->generate();
return *m_code;
}
diff --git a/JavaScriptCore/parser/Nodes.h b/JavaScriptCore/parser/Nodes.h
index cda1ee4..703b384 100644
--- a/JavaScriptCore/parser/Nodes.h
+++ b/JavaScriptCore/parser/Nodes.h
@@ -109,9 +109,11 @@ namespace JSC {
// Objects created with this version of new are not deleted when the arena is deleted.
// Other arrangements must be made.
void* operator new(size_t);
+
+ void operator delete(void*);
};
- class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
+ class ParserArenaRefCounted : public RefCountedCustomAllocated<ParserArenaRefCounted> {
protected:
ParserArenaRefCounted(JSGlobalData*);
@@ -169,7 +171,8 @@ namespace JSC {
virtual bool isResolveNode() const { return false; }
virtual bool isBracketAccessorNode() const { return false; }
virtual bool isDotAccessorNode() const { return false; }
- virtual bool isFuncExprNode() const { return false; }
+ virtual bool isFuncExprNode() const { return false; }
+ virtual bool isCommaNode() const { return false; }
virtual bool isSimpleArray() const { return false; }
virtual bool isAdd() const { return false; }
@@ -1087,16 +1090,20 @@ namespace JSC {
Operator m_operator;
ExpressionNode* m_right;
};
+
+ typedef Vector<ExpressionNode*, 8> ExpressionVector;
class CommaNode : public ExpressionNode {
public:
CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2);
+ void append(ExpressionNode* expr) { m_expressions.append(expr); }
+
private:
+ virtual bool isCommaNode() const { return true; }
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- ExpressionNode* m_expr1;
- ExpressionNode* m_expr2;
+ ExpressionVector m_expressions;
};
class ConstDeclNode : public ExpressionNode {
@@ -1371,7 +1378,7 @@ namespace JSC {
ParameterNode* m_next;
};
- struct ScopeNodeData {
+ struct ScopeNodeData : FastAllocBase {
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
@@ -1383,7 +1390,7 @@ namespace JSC {
int m_numConstants;
StatementVector m_children;
- void mark();
+ void markAggregate(MarkStack&);
};
class ScopeNode : public StatementNode, public ParserArenaRefCounted {
@@ -1429,7 +1436,7 @@ namespace JSC {
return m_data->m_numConstants + 2;
}
- virtual void mark() { }
+ virtual void markAggregate(MarkStack&) { }
#if ENABLE(JIT)
JITCode& generatedJITCode()
@@ -1508,7 +1515,7 @@ namespace JSC {
EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*);
- virtual void mark();
+ virtual void markAggregate(MarkStack&);
#if ENABLE(JIT)
JITCode& jitCode(ScopeChainNode* scopeChain)
@@ -1554,16 +1561,9 @@ namespace JSC {
return m_code;
}
- bool isHostFunction() const
- {
-#if ENABLE(JIT)
- return !!m_jitCode && !m_code;
-#else
- return true;
-#endif
- }
+ bool isHostFunction() const;
- virtual void mark();
+ virtual void markAggregate(MarkStack&);
void finishParsing(const SourceCode&, ParameterNode*);
void finishParsing(Identifier* parameters, size_t parameterCount);
diff --git a/JavaScriptCore/parser/Parser.h b/JavaScriptCore/parser/Parser.h
index 6f4c2b7..373dc00 100644
--- a/JavaScriptCore/parser/Parser.h
+++ b/JavaScriptCore/parser/Parser.h
@@ -39,7 +39,7 @@ namespace JSC {
template <typename T> struct ParserArenaData : ParserArenaDeletable { T data; };
- class Parser : Noncopyable {
+ class Parser : public Noncopyable {
public:
template <class ParsedNode> PassRefPtr<ParsedNode> parse(ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
template <class ParsedNode> PassRefPtr<ParsedNode> reparse(JSGlobalData*, ParsedNode*);