Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (127773 => 127774)
--- trunk/Source/_javascript_Core/ChangeLog 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-09-06 19:45:35 UTC (rev 127774)
@@ -1,3 +1,13 @@
+2012-09-05 Geoffrey Garen <[email protected]>
+
+ Rolled out <http://trac.webkit.org/changeset/127698> because it broke
+ fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html
+
+ Named functions should not allocate scope objects for their names
+ https://bugs.webkit.org/show_bug.cgi?id=95659
+
+ Reviewed by Oliver Hunt.
+
2012-09-06 Mark Lam <[email protected]>
Renamed useYarrJIT() option to useRegExpJIT(). Also fixed regression in
@@ -26,97 +36,6 @@
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
-2012-09-05 Geoffrey Garen <[email protected]>
-
- Named functions should not allocate scope objects for their names
- https://bugs.webkit.org/show_bug.cgi?id=95659
-
- Reviewed by Oliver Hunt.
-
- In most cases, we can merge a function _expression_'s name into its symbol
- table. This reduces memory footprint per closure from three objects
- (function + activation + name scope) to two (function + activation),
- speeds up closure allocation, and speeds up recursive calls.
-
- In the case of a named function _expression_ that contains a non-strict
- eval, the rules are so bat-poop crazy that I don't know how to model
- them without an extra object. Since functions now default to not having
- such an object, this case needs to allocate the object on function
- entry.
-
- Therefore, this patch makes the slow case a bit slower so the fast case
- can be faster and more memory-efficient. (Note that the slow case already
- allocates an activation on entry, and until recently also allocated a
- scope chain node on entry, so adding one allocation on entry shouldn't
- break the bank.)
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::CodeBlock): Caught a missed initializer. No behavior change.
-
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::BytecodeGenerator::BytecodeGenerator): Put the callee in static scope
- during compilation so it doesn't need to be in dynamic scope at runtime.
-
- (JSC::BytecodeGenerator::resolveCallee):
- (JSC::BytecodeGenerator::addCallee): Helper functions for either statically
- resolving the callee or adding a dynamic scope that will resolve to it,
- depending on whether you're in the fast path.
-
- We move the callee into a var location if it's captured because activations
- prefer to have contiguous ranges of captured variables.
-
- * bytecompiler/BytecodeGenerator.h:
- (JSC::BytecodeGenerator::registerFor):
- (BytecodeGenerator):
-
- * dfg/DFGOperations.cpp:
- * interpreter/Interpreter.cpp:
- (JSC::Interpreter::privateExecute):
- * jit/JITStubs.cpp:
- (JSC::DEFINE_STUB_FUNCTION):
- * llint/LLIntSlowPaths.cpp:
- (JSC::LLInt::LLINT_SLOW_PATH_DECL): This is the point of the patch: remove
- one allocation in the case of a named function _expression_.
-
- * parser/Parser.cpp:
- (JSC::::Parser):
- * parser/Parser.h:
- (JSC::Scope::declareCallee):
- (Scope):
- (Parser):
- (JSC::parse):
- * runtime/Executable.cpp:
- (JSC::EvalExecutable::compileInternal):
- (JSC::ProgramExecutable::checkSyntax):
- (JSC::ProgramExecutable::compileInternal):
- (JSC::FunctionExecutable::produceCodeBlockFor):
- (JSC::FunctionExecutable::fromGlobalCode): Pipe the callee's name through
- the parser so we get accurate information on whether the callee was captured.
-
- (JSC::FunctionExecutable::FunctionExecutable):
- (JSC::EvalExecutable::compileInternal):
- (JSC::ProgramExecutable::checkSyntax):
- (JSC::ProgramExecutable::compileInternal):
- (JSC::FunctionExecutable::produceCodeBlockFor):
- (JSC::FunctionExecutable::fromGlobalCode):
- * runtime/Executable.h:
- (JSC::FunctionExecutable::create):
- (FunctionExecutable):
- (JSC::FunctionExecutable::finishCreation): I had to refactor function
- creation to support the following function constructor quirk: the function
- gets a name, but its name is not in lexical scope.
-
- To simplify this, FunctionExecutable now automatically extracts all the
- data it needs from the parsed node. The special "fromGlobalCode" path
- used by the function constructor creates an anonymous function, and then
- quirkily sets the value used by the .name property to be non-null, even
- though the parsed name is null.
-
- * runtime/JSNameScope.h:
- (JSC::JSNameScope::create):
- (JSC::JSNameScope::JSNameScope): Added support for explicitly specifying
- your container scope. The compiler uses this for named function expressions.
-
2012-09-05 Gavin Barraclough <[email protected]>
a = data[a]++; sets the wrong key in data
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (127773 => 127774)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-09-06 19:45:35 UTC (rev 127774)
@@ -1752,7 +1752,6 @@
, m_heap(&m_globalObject->globalData().heap)
, m_numCalleeRegisters(0)
, m_numVars(0)
- , m_numCapturedVars(0)
, m_isConstructor(isConstructor)
, m_numParameters(0)
, m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable)
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (127773 => 127774)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2012-09-06 19:45:35 UTC (rev 127774)
@@ -33,11 +33,11 @@
#include "BatchedTransitionOptimizer.h"
#include "Comment.h"
-#include "Interpreter.h"
#include "JSActivation.h"
#include "JSFunction.h"
-#include "JSNameScope.h"
+#include "Interpreter.h"
#include "LowLevelInterpreter.h"
+
#include "StrongInlines.h"
#include <wtf/text/WTFString.h>
@@ -324,7 +324,7 @@
bool propertyDidExist =
globalObject->removeDirect(*m_globalData, function->ident()); // Newly declared functions overwrite existing properties.
- JSValue value = JSFunction::create(exec, FunctionExecutable::create(*m_globalData, function), scope);
+ JSValue value = JSFunction::create(exec, makeFunction(exec, function), scope);
int index = addGlobalVar(
function->ident(), IsVariable,
!propertyDidExist ? IsFunctionToSpecialize : NotFunctionOrNotSpecializable);
@@ -419,8 +419,6 @@
}
}
- RegisterID* calleeRegister = resolveCallee(functionBody); // May push to the scope chain and/or add a captured var.
-
const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
const DeclarationStacks::VarStack& varStack = functionBody->varStack();
@@ -458,7 +456,6 @@
}
codeBlock->m_numCapturedVars = codeBlock->m_numVars;
-
m_firstLazyFunction = codeBlock->m_numVars;
for (size_t i = 0; i < functionStack.size(); ++i) {
FunctionBodyNode* function = functionStack[i];
@@ -500,9 +497,6 @@
preserveLastVar();
- // We declare the callee's name last because it should lose to a var, function, and/or parameter declaration.
- addCallee(functionBody, calleeRegister);
-
if (isConstructor()) {
prependComment("'this' because we are a Constructor function");
emitOpcode(op_create_this);
@@ -555,7 +549,7 @@
const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
for (size_t i = 0; i < functionStack.size(); ++i)
- m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, functionStack[i]));
+ m_codeBlock->addFunctionDecl(makeFunction(m_globalData, functionStack[i]));
const DeclarationStacks::VarStack& varStack = evalNode->varStack();
unsigned numVariables = varStack.size();
@@ -580,53 +574,6 @@
return reg;
}
-RegisterID* BytecodeGenerator::resolveCallee(FunctionBodyNode* functionBodyNode)
-{
- if (functionBodyNode->ident().isNull())
- return 0;
-
- m_calleeRegister.setIndex(RegisterFile::Callee);
-
- // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name.
- if ((m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks) {
- emitOpcode(op_push_name_scope);
- instructions().append(addConstant(functionBodyNode->ident()));
- instructions().append(m_calleeRegister.index());
- instructions().append(ReadOnly | DontDelete);
-
- // Put a mirror object in compilation scope, so compile-time variable resolution sees the property name we'll see at runtime.
- m_scope.set(*globalData(),
- JSNameScope::create(
- m_scope->globalObject()->globalExec(),
- functionBodyNode->ident(),
- jsUndefined(),
- ReadOnly | DontDelete,
- m_scope.get()
- )
- );
- return 0;
- }
-
- if (!functionBodyNode->captures(functionBodyNode->ident()))
- return &m_calleeRegister;
-
- // Move the callee into the captured section of the stack.
- return emitMove(addVar(), &m_calleeRegister);
-}
-
-void BytecodeGenerator::addCallee(FunctionBodyNode* functionBodyNode, RegisterID* calleeRegister)
-{
- if (functionBodyNode->ident().isNull())
- return;
-
- // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name.
- if ((m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks)
- return;
-
- ASSERT(calleeRegister);
- symbolTable().add(functionBodyNode->ident().impl(), SymbolTableEntry(calleeRegister->index(), ReadOnly));
-}
-
void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
{
// Parameters overwrite var declarations, but not function declarations.
@@ -1883,14 +1830,14 @@
RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
{
- return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, function)), false);
+ return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function)), false);
}
RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
{
FunctionOffsetMap::AddResult ptr = m_functionOffsets.add(function, 0);
if (ptr.isNewEntry)
- ptr.iterator->second = m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, function));
+ ptr.iterator->second = m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function));
return emitNewFunctionInternal(dst, ptr.iterator->second, true);
}
@@ -1915,7 +1862,7 @@
RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
{
FunctionBodyNode* function = n->body();
- unsigned index = m_codeBlock->addFunctionExpr(FunctionExecutable::create(*m_globalData, function));
+ unsigned index = m_codeBlock->addFunctionExpr(makeFunction(m_globalData, function));
createActivationIfNecessary();
emitOpcode(op_new_func_exp);
@@ -2652,7 +2599,7 @@
if (!isStrictMode())
return;
- RefPtr<RegisterID> error = emitLoad(newTemporary(), JSValue(createTypeError(scope()->globalObject()->globalExec(), StrictModeReadonlyPropertyWriteError)));
+ RefPtr<RegisterID> error = emitLoad(newTemporary(), createTypeError(scope()->globalObject()->globalExec(), StrictModeReadonlyPropertyWriteError));
emitThrow(error.get());
}
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (127773 => 127774)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2012-09-06 19:45:35 UTC (rev 127774)
@@ -617,9 +617,7 @@
int addGlobalVar(const Identifier&, ConstantMode, FunctionMode);
void addParameter(const Identifier&, int parameterIndex);
- RegisterID* resolveCallee(FunctionBodyNode*);
- void addCallee(FunctionBodyNode*, RegisterID*);
-
+
void preserveLastVar();
bool shouldAvoidResolveGlobal();
@@ -628,9 +626,6 @@
if (index >= 0)
return m_calleeRegisters[index];
- if (index == RegisterFile::Callee)
- return m_calleeRegister;
-
ASSERT(m_parameters.size());
return m_parameters[index + m_parameters.size() + RegisterFile::CallFrameHeaderSize];
}
@@ -641,6 +636,16 @@
unsigned addConstantBuffer(unsigned length);
+ FunctionExecutable* makeFunction(ExecState* exec, FunctionBodyNode* body)
+ {
+ return FunctionExecutable::create(exec, body->ident(), body->inferredName(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
+ }
+
+ FunctionExecutable* makeFunction(JSGlobalData* globalData, FunctionBodyNode* body)
+ {
+ return FunctionExecutable::create(*globalData, body->ident(), body->inferredName(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
+ }
+
JSString* addStringConstant(const Identifier&);
void addLineInfo(unsigned lineNo)
@@ -711,7 +716,6 @@
HashSet<RefPtr<StringImpl>, IdentifierRepHash> m_functions;
RegisterID m_ignoredResultRegister;
RegisterID m_thisRegister;
- RegisterID m_calleeRegister;
RegisterID* m_activationRegister;
SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
SegmentedVector<RegisterID, 32> m_calleeRegisters;
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (127773 => 127774)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2012-09-06 19:45:35 UTC (rev 127774)
@@ -1243,7 +1243,7 @@
ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
JSGlobalData& globalData = exec->globalData();
NativeCallFrameTracer tracer(&globalData, exec);
- return JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope());
+ return static_cast<FunctionExecutable*>(functionExecutable)->make(exec, exec->scope());
}
JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
@@ -1251,7 +1251,14 @@
ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info));
FunctionExecutable* functionExecutable =
static_cast<FunctionExecutable*>(functionExecutableAsCell);
- return JSFunction::create(exec, functionExecutable, exec->scope());
+ JSFunction* function = functionExecutable->make(exec, exec->scope());
+ if (!functionExecutable->name().isNull()) {
+ JSNameScope* functionScopeObject =
+ JSNameScope::create(
+ exec, functionExecutable->name(), function, ReadOnly | DontDelete);
+ function->setScope(exec->globalData(), functionScopeObject);
+ }
+ return function;
}
size_t DFG_OPERATION operationIsObject(ExecState* exec, EncodedJSValue value)
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (127773 => 127774)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2012-09-06 19:45:35 UTC (rev 127774)
@@ -1347,7 +1347,7 @@
for (int i = 0; i < numFunctions; ++i) {
FunctionExecutable* function = codeBlock->functionDecl(i);
PutPropertySlot slot;
- variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(callFrame, function, scope), slot);
+ variableObject->methodTable()->put(variableObject, callFrame, function->name(), function->make(callFrame, scope), slot);
}
}
@@ -4279,6 +4279,18 @@
FunctionExecutable* function = codeBlock->functionExpr(funcIndex);
JSFunction* func = JSFunction::create(callFrame, function, callFrame->scope());
+ /*
+ The Identifier in a FunctionExpression can be referenced from inside
+ the FunctionExpression's FunctionBody to allow the function to call
+ itself recursively. However, unlike in a FunctionDeclaration, the
+ Identifier in a FunctionExpression cannot be referenced from and
+ does not affect the scope enclosing the FunctionExpression.
+ */
+ if (!function->name().isNull()) {
+ JSNameScope* functionScopeObject = JSNameScope::create(callFrame, function->name(), func, ReadOnly | DontDelete);
+ func->setScope(*globalData, functionScopeObject);
+ }
+
callFrame->uncheckedR(dst) = JSValue(func);
vPC += OPCODE_LENGTH(op_new_func_exp);
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (127773 => 127774)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-09-06 19:45:35 UTC (rev 127774)
@@ -2141,7 +2141,7 @@
STUB_INIT_STACK_FRAME(stackFrame);
ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->uncheckedR(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
- return JSFunction::create(stackFrame.callFrame, stackFrame.args[0].function(), stackFrame.callFrame->scope());
+ return stackFrame.args[0].function()->make(stackFrame.callFrame, stackFrame.callFrame->scope());
}
inline void* jitCompileFor(CallFrame* callFrame, CodeSpecializationKind kind)
@@ -2982,9 +2982,21 @@
CallFrame* callFrame = stackFrame.callFrame;
FunctionExecutable* function = stackFrame.args[0].function();
- JSFunction* func = JSFunction::create(callFrame, function, callFrame->scope());
+ JSFunction* func = function->make(callFrame, callFrame->scope());
ASSERT(callFrame->codeBlock()->codeType() != FunctionCode || !callFrame->codeBlock()->needsFullScopeChain() || callFrame->uncheckedR(callFrame->codeBlock()->activationRegister()).jsValue());
+ /*
+ The Identifier in a FunctionExpression can be referenced from inside
+ the FunctionExpression's FunctionBody to allow the function to call
+ itself recursively. However, unlike in a FunctionDeclaration, the
+ Identifier in a FunctionExpression cannot be referenced from and
+ does not affect the scope enclosing the FunctionExpression.
+ */
+ if (!function->name().isNull()) {
+ JSNameScope* functionScopeObject = JSNameScope::create(callFrame, function->name(), func, ReadOnly | DontDelete);
+ func->setScope(callFrame->globalData(), functionScopeObject);
+ }
+
return func;
}
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (127773 => 127774)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2012-09-06 19:45:35 UTC (rev 127774)
@@ -1260,7 +1260,7 @@
#if LLINT_SLOW_PATH_TRACING
dataLog("Creating function!\n");
#endif
- LLINT_RETURN(JSFunction::create(exec, codeBlock->functionDecl(pc[2].u.operand), exec->scope()));
+ LLINT_RETURN(codeBlock->functionDecl(pc[2].u.operand)->make(exec, exec->scope()));
}
LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
@@ -1268,8 +1268,13 @@
LLINT_BEGIN();
CodeBlock* codeBlock = exec->codeBlock();
FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
- JSFunction* func = JSFunction::create(exec, function, exec->scope());
+ JSFunction* func = function->make(exec, exec->scope());
+ if (!function->name().isNull()) {
+ JSNameScope* functionScopeObject = JSNameScope::create(exec, function->name(), func, ReadOnly | DontDelete);
+ func->setScope(globalData, functionScopeObject);
+ }
+
LLINT_RETURN(func);
}
Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (127773 => 127774)
--- trunk/Source/_javascript_Core/parser/Parser.cpp 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp 2012-09-06 19:45:35 UTC (rev 127774)
@@ -40,7 +40,7 @@
namespace JSC {
template <typename LexerType>
-Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode)
+Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode)
: m_globalData(globalData)
, m_source(&source)
, m_stack(wtfThreadData().stack())
@@ -71,8 +71,6 @@
for (unsigned i = 0; i < parameters->size(); i++)
scope->declareParameter(¶meters->at(i));
}
- if (!name.isNull())
- scope->declareCallee(&name);
next();
m_lexer->setLastLineNumber(tokenLine());
}
Modified: trunk/Source/_javascript_Core/parser/Parser.h (127773 => 127774)
--- trunk/Source/_javascript_Core/parser/Parser.h 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/parser/Parser.h 2012-09-06 19:45:35 UTC (rev 127774)
@@ -208,11 +208,6 @@
bool isFunction() { return m_isFunction; }
bool isFunctionBoundary() { return m_isFunctionBoundary; }
- void declareCallee(const Identifier* ident)
- {
- m_declaredVariables.add(ident->ustring().impl());
- }
-
bool declareVariable(const Identifier* ident)
{
bool isValidStrictMode = m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident;
@@ -387,7 +382,7 @@
WTF_MAKE_FAST_ALLOCATED;
public:
- Parser(JSGlobalData*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode);
+ Parser(JSGlobalData*, const SourceCode&, FunctionParameters*, JSParserStrictness, JSParserMode);
~Parser();
template <class ParsedNode>
@@ -1025,17 +1020,17 @@
}
template <class ParsedNode>
-PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, Debugger* debugger, ExecState* execState, JSObject** exception)
+PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, const SourceCode& source, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode, Debugger* debugger, ExecState* execState, JSObject** exception)
{
SamplingRegion samplingRegion("Parsing");
ASSERT(source.provider()->data());
if (source.provider()->data()->is8Bit()) {
- Parser< Lexer<LChar> > parser(globalData, source, parameters, name, strictness, parserMode);
+ Parser< Lexer<LChar> > parser(globalData, source, parameters, strictness, parserMode);
return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception);
}
- Parser< Lexer<UChar> > parser(globalData, source, parameters, name, strictness, parserMode);
+ Parser< Lexer<UChar> > parser(globalData, source, parameters, strictness, parserMode);
return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception);
}
Modified: trunk/Source/_javascript_Core/runtime/Executable.cpp (127773 => 127774)
--- trunk/Source/_javascript_Core/runtime/Executable.cpp 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/runtime/Executable.cpp 2012-09-06 19:45:35 UTC (rev 127774)
@@ -133,18 +133,26 @@
const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
-FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, FunctionBodyNode* node)
- : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, node->source(), node->isStrictMode())
+FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)
+ : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, source, inStrictContext)
, m_numCapturedVariables(0)
- , m_forceUsesArguments(node->usesArguments())
- , m_parameters(node->parameters())
- , m_name(node->ident())
- , m_inferredName(node->inferredName().isNull() ? globalData.propertyNames->emptyIdentifier : node->inferredName())
+ , m_forceUsesArguments(forceUsesArguments)
+ , m_parameters(parameters)
+ , m_name(name)
+ , m_inferredName(inferredName.isNull() ? globalData.propertyNames->emptyIdentifier : inferredName)
{
- m_firstLine = node->lineNo();
- m_lastLine = node->lastLine();
}
+FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)
+ : ScriptExecutable(exec->globalData().functionExecutableStructure.get(), exec, source, inStrictContext)
+ , m_numCapturedVariables(0)
+ , m_forceUsesArguments(forceUsesArguments)
+ , m_parameters(parameters)
+ , m_name(name)
+ , m_inferredName(inferredName.isNull() ? exec->globalData().propertyNames->emptyIdentifier : inferredName)
+{
+}
+
void FunctionExecutable::destroy(JSCell* cell)
{
static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable();
@@ -202,7 +210,7 @@
} else {
if (!lexicalGlobalObject->evalEnabled())
return throwError(exec, createEvalError(exec, ASCIILiteral("Eval is disabled")));
- RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
+ RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
if (!evalNode) {
ASSERT(exception);
return exception;
@@ -285,7 +293,7 @@
JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
+ RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
if (programNode)
return 0;
ASSERT(exception);
@@ -327,7 +335,7 @@
newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_programCodeBlock.release()));
m_programCodeBlock = newCodeBlock.release();
} else {
- RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
+ RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
if (!programNode) {
ASSERT(exception);
return exception;
@@ -470,18 +478,7 @@
exception = 0;
JSGlobalData* globalData = scope->globalData();
JSGlobalObject* globalObject = scope->globalObject();
- RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(
- globalData,
- globalObject,
- m_source,
- m_parameters.get(),
- name(),
- isStrictMode() ? JSParseStrict : JSParseNormal,
- FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode,
- 0,
- 0,
- &exception
- );
+ RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(globalData, globalObject, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, 0, 0, &exception);
if (!body) {
ASSERT(exception);
@@ -650,16 +647,16 @@
#endif
}
-FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
+FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
{
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> program = parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception);
+ RefPtr<ProgramNode> program = parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, source, 0, JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception);
if (!program) {
ASSERT(*exception);
return 0;
}
- // This function assumes an input string that would result in a single anonymous function _expression_.
+ // Uses of this function that would not result in a single function _expression_ are invalid.
StatementNode* exprStatement = program->singleStatement();
ASSERT(exprStatement);
ASSERT(exprStatement->isExprStatement());
@@ -668,11 +665,8 @@
ASSERT(funcExpr->isFuncExprNode());
FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
ASSERT(body);
- ASSERT(body->ident().isNull());
- FunctionExecutable* functionExecutable = FunctionExecutable::create(exec->globalData(), body);
- functionExecutable->m_nameValue.set(exec->globalData(), functionExecutable, jsString(&exec->globalData(), name.ustring()));
- return functionExecutable;
+ return FunctionExecutable::create(exec->globalData(), functionName, functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
String FunctionExecutable::paramString() const
Modified: trunk/Source/_javascript_Core/runtime/Executable.h (127773 => 127774)
--- trunk/Source/_javascript_Core/runtime/Executable.h 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/runtime/Executable.h 2012-09-06 19:45:35 UTC (rev 127774)
@@ -539,16 +539,27 @@
public:
typedef ScriptExecutable Base;
- static FunctionExecutable* create(JSGlobalData& globalData, FunctionBodyNode* node)
+ static FunctionExecutable* create(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, node);
- executable->finishCreation(globalData);
+ FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(*exec->heap())) FunctionExecutable(exec, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
+ executable->finishCreation(exec->globalData(), name, firstLine, lastLine);
return executable;
}
- static FunctionExecutable* fromGlobalCode(const Identifier& name, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
+ static FunctionExecutable* create(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
+ {
+ FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
+ executable->finishCreation(globalData, name, firstLine, lastLine);
+ return executable;
+ }
+
static void destroy(JSCell*);
+ JSFunction* make(ExecState* exec, JSScope* scope)
+ {
+ return JSFunction::create(exec, this, scope);
+ }
+
// Returns either call or construct bytecode. This can be appropriate
// for answering questions that that don't vary between call and construct --
// for example, argumentsRegister().
@@ -697,6 +708,7 @@
void clearCodeIfNotCompiling();
static void visitChildren(JSCell*, SlotVisitor&);
+ static FunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
{
return Structure::create(globalData, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), &s_info);
@@ -709,14 +721,17 @@
void clearCode();
protected:
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(JSGlobalData& globalData, const Identifier& name, int firstLine, int lastLine)
{
Base::finishCreation(globalData);
- m_nameValue.set(globalData, this, jsString(&globalData, name().ustring()));
+ m_firstLine = firstLine;
+ m_lastLine = lastLine;
+ m_nameValue.set(globalData, this, jsString(&globalData, name.ustring()));
}
private:
- FunctionExecutable(JSGlobalData&, FunctionBodyNode*);
+ FunctionExecutable(JSGlobalData&, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
+ FunctionExecutable(ExecState*, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
JSObject* compileForConstructInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
Modified: trunk/Source/_javascript_Core/runtime/JSNameScope.h (127773 => 127774)
--- trunk/Source/_javascript_Core/runtime/JSNameScope.h 2012-09-06 19:29:40 UTC (rev 127773)
+++ trunk/Source/_javascript_Core/runtime/JSNameScope.h 2012-09-06 19:45:35 UTC (rev 127774)
@@ -38,18 +38,11 @@
static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes)
{
- JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec, exec->scope());
+ JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec);
scopeObject->finishCreation(exec, identifier, value, attributes);
return scopeObject;
}
- static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes, JSScope* next)
- {
- JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec, next);
- scopeObject->finishCreation(exec, identifier, value, attributes);
- return scopeObject;
- }
-
static void visitChildren(JSCell*, SlotVisitor&);
bool isDynamicScope(bool& requiresDynamicChecks) const;
static JSObject* toThisObject(JSCell*, ExecState*);
@@ -71,12 +64,12 @@
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | Base::StructureFlags;
private:
- JSNameScope(ExecState* exec, JSScope* next)
+ JSNameScope(ExecState* exec)
: Base(
exec->globalData(),
exec->lexicalGlobalObject()->nameScopeStructure(),
reinterpret_cast<Register*>(&m_registerStore + 1),
- next
+ exec->scope()
)
{
}