Emit the WillExecuteStatement debugger hook before the for loop body when the stateme...
[WebKit-https.git] / JavaScriptCore / kjs / nodes.cpp
index be642b5..b68b453 100644 (file)
 #include "Parser.h"
 #include "PropertyNameArray.h"
 #include "RegExpObject.h"
-#include "debugger.h"
+#include "SamplingTool.h"
+#include "Debugger.h"
 #include "lexer.h"
 #include "operations.h"
-#include "SamplingTool.h"
 #include <math.h>
 #include <wtf/Assertions.h>
 #include <wtf/HashCountedSet.h>
@@ -159,7 +159,7 @@ static void substitute(UString& string, const UString& substring)
 RegisterID* ThrowableExpressionData::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
 {
     generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
-    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalExec(), msg));
+    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), msg));
     generator.emitThrow(exception);
     return exception;
 }
@@ -169,7 +169,7 @@ RegisterID* ThrowableExpressionData::emitThrowError(CodeGenerator& generator, Er
     UString message = msg;
     substitute(message, label.ustring());
     generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
-    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalExec(), message));
+    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), message));
     generator.emitThrow(exception);
     return exception;
 }
@@ -198,20 +198,6 @@ void SourceElements::append(PassRefPtr<StatementNode> statement)
     m_statements.append(statement);
 }
 
-// ------------------------------ BreakpointCheckStatement --------------------------------
-
-BreakpointCheckStatement::BreakpointCheckStatement(JSGlobalData* globalData, PassRefPtr<StatementNode> statement)
-    : StatementNode(globalData)
-    , m_statement(statement)
-{
-    ASSERT(m_statement);
-}
-
-void BreakpointCheckStatement::streamTo(SourceStream& stream) const
-{
-    m_statement->streamTo(stream);
-}
-
 // ------------------------------ NullNode -------------------------------------
 
 RegisterID* NullNode::emitCode(CodeGenerator& generator, RegisterID* dst)
@@ -252,7 +238,7 @@ RegisterID* StringNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 
 RegisterID* RegExpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegExp> regExp = RegExp::create(generator.globalExec(), m_pattern, m_flags);
+    RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern, m_flags);
     if (!regExp->isValid())
         return emitThrowError(generator, SyntaxError, ("Invalid regular expression: " + UString(regExp->errorMessage())).UTF8String().c_str());
     if (dst == ignoredResult())
@@ -314,7 +300,7 @@ RegisterID* ArrayNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     }
 
     if (m_elision) {
-        RegisterID* value = generator.emitLoad(0, jsNumber(generator.globalExec(), m_elision + length));
+        RegisterID* value = generator.emitLoad(0, jsNumber(generator.globalData(), m_elision + length));
         generator.emitPutById(array.get(), generator.propertyNames().length, value);
     }
 
@@ -421,7 +407,7 @@ RegisterID* FunctionCallResolveNode::emitCode(CodeGenerator& generator, Register
 
     int index = 0;
     size_t depth = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
         RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
         return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
@@ -480,7 +466,7 @@ RegisterID* PostfixResolveNode::emitCode(CodeGenerator& generator, RegisterID* d
 
     int index = 0;
     size_t depth = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
         RegisterID* oldValue;
@@ -664,7 +650,7 @@ RegisterID* PrefixResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
 
     int index = 0;
     size_t depth = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
         emitPreIncOrDec(generator, propDst.get(), m_operator);
@@ -729,7 +715,7 @@ RegisterID* PrefixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
 RegisterID* UnaryOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
     RegisterID* src = generator.emitNode(m_expr.get());
-    return generator.emitUnaryOp(opcode(), generator.finalDestination(dst), src);
+    return generator.emitUnaryOp(opcode(), generator.finalDestination(dst), src, m_expr->resultDescriptor());
 }
 
 // ------------------------------ Binary Operation Nodes -----------------------------------
@@ -740,7 +726,7 @@ RegisterID* BinaryOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     if (opcode == op_neq) {
         if (m_expr1->isNull() || m_expr2->isNull()) {
             RefPtr<RegisterID> src = generator.emitNode(dst, m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
-            return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
+            return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get(), ResultType::unknown());
         }
     }
 
@@ -753,7 +739,7 @@ RegisterID* EqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
     if (m_expr1->isNull() || m_expr2->isNull()) {
         RefPtr<RegisterID> src = generator.emitNode(dst, m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
-        return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
+        return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get(), ResultType::unknown());
     }
 
     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
@@ -789,7 +775,7 @@ RegisterID* InstanceOfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     RefPtr<RegisterID> src2 = generator.emitNode(m_expr2.get());
 
     generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
-    RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalExec()->propertyNames().prototype);
+    RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
 
     generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
     return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
@@ -907,7 +893,7 @@ RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID
 
     int index = 0;
     size_t depth = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
         RegisterID* src2 = generator.emitNode(m_right.get());
@@ -939,7 +925,7 @@ RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
 
     int index = 0;
     size_t depth = 0;
-    JSValue* globalObject = 0;
+    JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
         if (dst == ignoredResult())
             dst = 0;
@@ -1071,7 +1057,7 @@ RegisterID* ConstStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
 
 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
 
-static inline RegisterID* statementListEmitCode(StatementVector& statements, CodeGenerator& generator, RegisterID* dst = 0)
+static inline RegisterID* statementListEmitCode(StatementVector& statements, CodeGenerator& generator, RegisterID* dst)
 {
     StatementVector::iterator end = statements.end();
     for (StatementVector::iterator it = statements.begin(); it != end; ++it) {
@@ -1093,23 +1079,6 @@ static inline void statementListPushFIFO(StatementVector& statements, Declaratio
     }
 }
 
-static inline Node* statementListInitializeVariableAccessStack(StatementVector& statements, DeclarationStacks::NodeStack& stack)
-{
-    if (statements.isEmpty())
-        return 0;
-
-    StatementVector::iterator it = statements.end();
-    StatementVector::iterator begin = statements.begin();
-    StatementVector::iterator beginPlusOne = begin + 1;
-
-    while (it != beginPlusOne) {
-        --it;
-        stack.append((*it).get());
-    }
-
-    return (*begin).get();
-}
-
 // ------------------------------ BlockNode ------------------------------------
 
 BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
@@ -1189,6 +1158,10 @@ RegisterID* IfElseNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     generator.emitJump(afterElse.get());
 
     generator.emitLabel(beforeElse.get());
+
+    if (!m_elseBlock->isBlock())
+        generator.emitDebugHook(WillExecuteStatement, m_elseBlock->firstLine(), m_elseBlock->lastLine());
+
     generator.emitNode(dst, m_elseBlock.get());
 
     generator.emitLabel(afterElse.get());
@@ -1258,6 +1231,9 @@ RegisterID* WhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 
 RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
+    if (dst == ignoredResult())
+        dst = 0;
+
     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
 
     if (m_expr1)
@@ -1271,6 +1247,8 @@ RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 
     generator.emitLabel(topOfLoop.get());
     generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
+    if (!m_statement->isBlock())
+        generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
     generator.popJumpContext();
     generator.emitLabel(continueTarget.get());
@@ -1285,9 +1263,6 @@ RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
         generator.emitJump(topOfLoop.get());
     }
 
-    if (!m_statement->isBlock())
-        generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
-
     generator.emitLabel(breakTarget.get());
     
     return result.get();
@@ -1329,6 +1304,8 @@ RegisterID* ForInNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     RefPtr<LabelID> continueTarget = generator.newLabel(); 
     RefPtr<LabelID> breakTarget = generator.newLabel(); 
 
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
     if (m_init)
         generator.emitNode(ignoredResult(), m_init.get());
     RegisterID* forInBase = generator.emitNode(m_expr.get());
@@ -1367,15 +1344,12 @@ RegisterID* ForInNode::emitCode(CodeGenerator& generator, RegisterID* dst)
         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
         generator.emitPutByVal(base.get(), subscript, propertyName);
     }   
-    
-    generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
-    generator.emitNode(dst, m_statement.get());
-    generator.popJumpContext();
-
-    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
 
+    generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
     if (!m_statement->isBlock())
         generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
+    generator.emitNode(dst, m_statement.get());
+    generator.popJumpContext();
 
     generator.emitLabel(continueTarget.get());
     generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
@@ -1438,7 +1412,9 @@ RegisterID* ReturnNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
     if (generator.codeType() != FunctionCode)
         return emitThrowError(generator, SyntaxError, "Invalid return statement.");
-        
+
+    if (dst == ignoredResult())
+        dst = 0;
     RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(dst, jsUndefined());
     if (generator.scopeDepth()) {
         RefPtr<LabelID> l0 = generator.newLabel();
@@ -1643,6 +1619,8 @@ RegisterID* LabelNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 
 RegisterID* ThrowNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
+    if (dst == ignoredResult())
+        dst = 0;
     RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
     generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
     generator.emitThrow(expr.get());
@@ -1712,40 +1690,37 @@ RegisterID* TryNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 
 // ------------------------------ ScopeNode -----------------------------
 
-ScopeNode::ScopeNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure, int numConstants)
+ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
     : BlockNode(globalData, children)
-    , m_sourceURL(globalData->parser->sourceURL())
-    , m_sourceId(globalData->parser->sourceId())
-    , m_usesEval(usesEval)
-    , m_needsClosure(needsClosure)
+    , m_source(source)
+    , m_features(features)
     , m_numConstants(numConstants)
 {
     if (varStack)
         m_varStack = *varStack;
     if (funcStack)
         m_functionStack = *funcStack;
-
-    SCOPENODE_SAMPLING_notifyOfScope(globalData->machine->m_sampler);
+#if ENABLE(OPCODE_SAMPLING)
+    globalData->machine->sampler()->notifyOfScope(this);
+#endif
 }
 
 // ------------------------------ ProgramNode -----------------------------
 
-ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure, int numConstants)
-    : ScopeNode(globalData, children, varStack, funcStack, usesEval, needsClosure, numConstants)
-    , m_sourceProvider(sourceProvider)
+ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
+    : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
 {
 }
 
-ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure, int numConstants)
+ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
 {
-    return new ProgramNode(globalData, children, varStack, funcStack, sourceProvider, usesEval, needsClosure, numConstants);
+    return new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
 }
 
 // ------------------------------ EvalNode -----------------------------
 
-EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure, int numConstants)
-    : ScopeNode(globalData, children, varStack, funcStack, usesEval, needsClosure, numConstants)
-    , m_sourceProvider(sourceProvider)
+EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
+    : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
 {
 }
 
@@ -1762,55 +1737,79 @@ RegisterID* EvalNode::emitCode(CodeGenerator& generator, RegisterID*)
     return 0;
 }
 
-void EvalNode::generateCode(ScopeChainNode* sc)
+void EvalNode::generateCode(ScopeChainNode* scopeChainNode)
 {
-    ScopeChain scopeChain(sc);
+    ScopeChain scopeChain(scopeChainNode);
     JSGlobalObject* globalObject = scopeChain.globalObject();
 
     SymbolTable symbolTable;
-    ASSERT(m_sourceProvider);
-    m_code.set(new EvalCodeBlock(this, globalObject, m_sourceProvider));
+    m_code.set(new EvalCodeBlock(this, globalObject, source().provider()));
 
     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &symbolTable, m_code.get());
     generator.generate();
 }
 
-EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure, int numConstants)
+EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
 {
-    return new EvalNode(globalData, children, varStack, funcStack, sourceProvider, usesEval, needsClosure, numConstants);
+    return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
 }
 
 // ------------------------------ FunctionBodyNode -----------------------------
 
-FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure, int numConstants)
-    : ScopeNode(globalData, children, varStack, funcStack, usesEval, needsClosure, numConstants)
+FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+    : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
+    , m_parameters(0)
+    , m_parameterCount(0)
     , m_refCount(0)
 {
 }
 
+FunctionBodyNode::~FunctionBodyNode()
+{
+    if (m_parameters)
+        fastFree(m_parameters);
+}
+
+void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter)
+{
+    Vector<Identifier> parameters;
+    for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
+        parameters.append(parameter->ident());
+    size_t count = parameters.size();
+
+    setSource(source);
+    finishParsing(parameters.releaseBuffer(), count);
+}
+
+void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount)
+{
+    ASSERT(!source().isNull());
+    m_parameters = parameters;
+    m_parameterCount = parameterCount;
+}
+
 void FunctionBodyNode::mark()
 {
     if (m_code)
         m_code->mark();
 }
 
-FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure, int numConstants)
+FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
 {
-    return new FunctionBodyNode(globalData, children, varStack, funcStack, usesEval, needsClosure, numConstants);
+    return new FunctionBodyNode(globalData, children, varStack, funcStack, SourceCode(), features, numConstants);
 }
 
-FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider*, bool usesEval, bool needsClosure, int numConstants)
+FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
 {
-    return new FunctionBodyNode(globalData, children, varStack, funcStack, usesEval, needsClosure, numConstants);
+    return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
 }
 
-void FunctionBodyNode::generateCode(ScopeChainNode* sc)
+void FunctionBodyNode::generateCode(ScopeChainNode* scopeChainNode)
 {
-    ScopeChain scopeChain(sc);
+    ScopeChain scopeChain(scopeChainNode);
     JSGlobalObject* globalObject = scopeChain.globalObject();
 
-    ASSERT(m_source.sourceProvider());
-    m_code.set(new CodeBlock(this, FunctionCode, m_source.sourceProvider(), m_source.startOffset()));
+    m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
 
     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_symbolTable, m_code.get());
     generator.generate();
@@ -1819,7 +1818,7 @@ void FunctionBodyNode::generateCode(ScopeChainNode* sc)
 RegisterID* FunctionBodyNode::emitCode(CodeGenerator& generator, RegisterID*)
 {
     generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
-    statementListEmitCode(m_children, generator);
+    statementListEmitCode(m_children, generator, ignoredResult());
     if (!m_children.size() || !m_children.last()->isReturnNode()) {
         RegisterID* r0 = generator.emitLoad(0, jsUndefined());
         generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
@@ -1841,13 +1840,12 @@ RegisterID* ProgramNode::emitCode(CodeGenerator& generator, RegisterID*)
     return 0;
 }
 
-void ProgramNode::generateCode(ScopeChainNode* sc)
+void ProgramNode::generateCode(ScopeChainNode* scopeChainNode)
 {
-    ScopeChain scopeChain(sc);
+    ScopeChain scopeChain(scopeChainNode);
     JSGlobalObject* globalObject = scopeChain.globalObject();
     
-    ASSERT(m_sourceProvider);
-    m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, m_sourceProvider));
+    m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
     
     CodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get(), m_varStack, m_functionStack);
     generator.generate();
@@ -1856,32 +1854,27 @@ void ProgramNode::generateCode(ScopeChainNode* sc)
 UString FunctionBodyNode::paramString() const
 {
     UString s("");
-    size_t count = m_parameters.size();
-    for (size_t pos = 0; pos < count; ++pos) {
+    for (size_t pos = 0; pos < m_parameterCount; ++pos) {
         if (!s.isEmpty())
             s += ", ";
-        s += m_parameters[pos].ustring();
+        s += parameters()[pos].ustring();
     }
 
     return s;
 }
 
-// ------------------------------ FuncDeclNode ---------------------------------
-
-void FuncDeclNode::addParams()
+Identifier* FunctionBodyNode::copyParameters()
 {
-    for (ParameterNode* p = m_parameter.get(); p; p = p->nextParam())
-        m_body->parameters().append(p->ident());
+    Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier)));
+    VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters);
+    return parameters;
 }
 
+// ------------------------------ FuncDeclNode ---------------------------------
+
 JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
 {
-    JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
-
-    JSObject* proto = constructEmptyObject(exec);
-    proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
-    func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
-    return func;
+    return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
 }
 
 RegisterID* FuncDeclNode::emitCode(CodeGenerator&, RegisterID* dst)
@@ -1899,9 +1892,6 @@ RegisterID* FuncExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
 {
     JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
-    JSObject* proto = constructEmptyObject(exec);
-    proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
-    func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
 
     /* 
         The Identifier in a FunctionExpression can be referenced from inside
@@ -1919,11 +1909,4 @@ JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeCha
     return func;
 }
 
-// ECMA 13
-void FuncExprNode::addParams()
-{
-    for (ParameterNode* p = m_parameter.get(); p; p = p->nextParam())
-        m_body->parameters().append(p->ident());
-}
-
 } // namespace JSC