Changeset 127810 in webkit
- Timestamp:
- Sep 6, 2012 6:42:53 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r127808 r127810 1 2012-09-06 Geoffrey Garen <ggaren@apple.com> 2 3 Rolled back in <http://trac.webkit.org/changeset/127698> with a fix for 4 fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html. 5 6 Added a more explicit test for the feature I broke in 7 fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html. 8 9 Reviewed by Gavin Barraclough. 10 11 Named functions should not allocate scope objects for their names 12 https://bugs.webkit.org/show_bug.cgi?id=95659 13 14 Reviewed by Oliver Hunt. 15 16 * fast/dom/HTMLScriptElement/script-reexecution.html: 17 * fast/js/function-name-is-in-scope-expected.txt: Added. 18 * fast/js/function-name-is-in-scope.html: Added. 19 1 20 2012-09-06 Tim Horton <timothy_horton@apple.com> 2 21 -
trunk/Source/JavaScriptCore/ChangeLog
r127809 r127810 1 2012-09-05 Geoffrey Garen <ggaren@apple.com> 2 3 Rolled back in <http://trac.webkit.org/changeset/127698> with a fix for 4 fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html, which 5 is to make sure that function declarations don't put their names in scope. 6 7 Reviewed by Gavin Barraclough. 8 9 Named functions should not allocate scope objects for their names 10 https://bugs.webkit.org/show_bug.cgi?id=95659 11 12 Reviewed by Oliver Hunt. 13 1 14 2012-09-06 Michael Saboff <msaboff@apple.com> 2 15 … … 82 95 * interpreter/Interpreter.cpp: 83 96 (JSC::Interpreter::privateExecute): 97 98 2012-09-05 Geoffrey Garen <ggaren@apple.com> 99 100 Named functions should not allocate scope objects for their names 101 https://bugs.webkit.org/show_bug.cgi?id=95659 102 103 Reviewed by Oliver Hunt. 104 105 In most cases, we can merge a function expression's name into its symbol 106 table. This reduces memory footprint per closure from three objects 107 (function + activation + name scope) to two (function + activation), 108 speeds up closure allocation, and speeds up recursive calls. 109 110 In the case of a named function expression that contains a non-strict 111 eval, the rules are so bat-poop crazy that I don't know how to model 112 them without an extra object. Since functions now default to not having 113 such an object, this case needs to allocate the object on function 114 entry. 115 116 Therefore, this patch makes the slow case a bit slower so the fast case 117 can be faster and more memory-efficient. (Note that the slow case already 118 allocates an activation on entry, and until recently also allocated a 119 scope chain node on entry, so adding one allocation on entry shouldn't 120 break the bank.) 121 122 * bytecode/CodeBlock.cpp: 123 (JSC::CodeBlock::CodeBlock): Caught a missed initializer. No behavior change. 124 125 * bytecompiler/BytecodeGenerator.cpp: 126 (JSC::BytecodeGenerator::BytecodeGenerator): Put the callee in static scope 127 during compilation so it doesn't need to be in dynamic scope at runtime. 128 129 (JSC::BytecodeGenerator::resolveCallee): 130 (JSC::BytecodeGenerator::addCallee): Helper functions for either statically 131 resolving the callee or adding a dynamic scope that will resolve to it, 132 depending on whether you're in the fast path. 133 134 We move the callee into a var location if it's captured because activations 135 prefer to have contiguous ranges of captured variables. 136 137 * bytecompiler/BytecodeGenerator.h: 138 (JSC::BytecodeGenerator::registerFor): 139 (BytecodeGenerator): 140 141 * dfg/DFGOperations.cpp: 142 * interpreter/Interpreter.cpp: 143 (JSC::Interpreter::privateExecute): 144 * jit/JITStubs.cpp: 145 (JSC::DEFINE_STUB_FUNCTION): 146 * llint/LLIntSlowPaths.cpp: 147 (JSC::LLInt::LLINT_SLOW_PATH_DECL): This is the point of the patch: remove 148 one allocation in the case of a named function expression. 149 150 * parser/Parser.cpp: 151 (JSC::::Parser): 152 * parser/Parser.h: 153 (JSC::Scope::declareCallee): 154 (Scope): 155 (Parser): 156 (JSC::parse): 157 * runtime/Executable.cpp: 158 (JSC::EvalExecutable::compileInternal): 159 (JSC::ProgramExecutable::checkSyntax): 160 (JSC::ProgramExecutable::compileInternal): 161 (JSC::FunctionExecutable::produceCodeBlockFor): 162 (JSC::FunctionExecutable::fromGlobalCode): Pipe the callee's name through 163 the parser so we get accurate information on whether the callee was captured. 164 165 (JSC::FunctionExecutable::FunctionExecutable): 166 (JSC::EvalExecutable::compileInternal): 167 (JSC::ProgramExecutable::checkSyntax): 168 (JSC::ProgramExecutable::compileInternal): 169 (JSC::FunctionExecutable::produceCodeBlockFor): 170 (JSC::FunctionExecutable::fromGlobalCode): 171 * runtime/Executable.h: 172 (JSC::FunctionExecutable::create): 173 (FunctionExecutable): 174 (JSC::FunctionExecutable::finishCreation): I had to refactor function 175 creation to support the following function constructor quirk: the function 176 gets a name, but its name is not in lexical scope. 177 178 To simplify this, FunctionExecutable now automatically extracts all the 179 data it needs from the parsed node. The special "fromGlobalCode" path 180 used by the function constructor creates an anonymous function, and then 181 quirkily sets the value used by the .name property to be non-null, even 182 though the parsed name is null. 183 184 * runtime/JSNameScope.h: 185 (JSC::JSNameScope::create): 186 (JSC::JSNameScope::JSNameScope): Added support for explicitly specifying 187 your container scope. The compiler uses this for named function expressions. 84 188 85 189 2012-09-05 Gavin Barraclough <barraclough@apple.com> -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r127774 r127810 1753 1753 , m_numCalleeRegisters(0) 1754 1754 , m_numVars(0) 1755 , m_numCapturedVars(0) 1755 1756 , m_isConstructor(isConstructor) 1756 1757 , m_numParameters(0) -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r127774 r127810 34 34 #include "BatchedTransitionOptimizer.h" 35 35 #include "Comment.h" 36 #include "Interpreter.h" 36 37 #include "JSActivation.h" 37 38 #include "JSFunction.h" 38 #include " Interpreter.h"39 #include "JSNameScope.h" 39 40 #include "LowLevelInterpreter.h" 40 41 41 #include "StrongInlines.h" 42 42 #include <wtf/text/WTFString.h> … … 325 325 globalObject->removeDirect(*m_globalData, function->ident()); // Newly declared functions overwrite existing properties. 326 326 327 JSValue value = JSFunction::create(exec, makeFunction(exec, function), scope);327 JSValue value = JSFunction::create(exec, FunctionExecutable::create(*m_globalData, function), scope); 328 328 int index = addGlobalVar( 329 329 function->ident(), IsVariable, … … 420 420 } 421 421 422 RegisterID* calleeRegister = resolveCallee(functionBody); // May push to the scope chain and/or add a captured var. 423 422 424 const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack(); 423 425 const DeclarationStacks::VarStack& varStack = functionBody->varStack(); … … 457 459 458 460 codeBlock->m_numCapturedVars = codeBlock->m_numVars; 461 459 462 m_firstLazyFunction = codeBlock->m_numVars; 460 463 for (size_t i = 0; i < functionStack.size(); ++i) { … … 497 500 498 501 preserveLastVar(); 502 503 // We declare the callee's name last because it should lose to a var, function, and/or parameter declaration. 504 addCallee(functionBody, calleeRegister); 499 505 500 506 if (isConstructor()) { … … 550 556 const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack(); 551 557 for (size_t i = 0; i < functionStack.size(); ++i) 552 m_codeBlock->addFunctionDecl( makeFunction(m_globalData, functionStack[i]));558 m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, functionStack[i])); 553 559 554 560 const DeclarationStacks::VarStack& varStack = evalNode->varStack(); … … 573 579 instructions().append(reg->index()); 574 580 return reg; 581 } 582 583 RegisterID* BytecodeGenerator::resolveCallee(FunctionBodyNode* functionBodyNode) 584 { 585 if (functionBodyNode->ident().isNull() || !functionBodyNode->functionNameIsInScope()) 586 return 0; 587 588 m_calleeRegister.setIndex(RegisterFile::Callee); 589 590 // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name. 591 if ((m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks) { 592 emitOpcode(op_push_name_scope); 593 instructions().append(addConstant(functionBodyNode->ident())); 594 instructions().append(m_calleeRegister.index()); 595 instructions().append(ReadOnly | DontDelete); 596 597 // Put a mirror object in compilation scope, so compile-time variable resolution sees the property name we'll see at runtime. 598 m_scope.set(*globalData(), 599 JSNameScope::create( 600 m_scope->globalObject()->globalExec(), 601 functionBodyNode->ident(), 602 jsUndefined(), 603 ReadOnly | DontDelete, 604 m_scope.get() 605 ) 606 ); 607 return 0; 608 } 609 610 if (!functionBodyNode->captures(functionBodyNode->ident())) 611 return &m_calleeRegister; 612 613 // Move the callee into the captured section of the stack. 614 return emitMove(addVar(), &m_calleeRegister); 615 } 616 617 void BytecodeGenerator::addCallee(FunctionBodyNode* functionBodyNode, RegisterID* calleeRegister) 618 { 619 if (functionBodyNode->ident().isNull() || !functionBodyNode->functionNameIsInScope()) 620 return; 621 622 // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name. 623 if ((m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks) 624 return; 625 626 ASSERT(calleeRegister); 627 symbolTable().add(functionBodyNode->ident().impl(), SymbolTableEntry(calleeRegister->index(), ReadOnly)); 575 628 } 576 629 … … 1831 1884 RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function) 1832 1885 { 1833 return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl( makeFunction(m_globalData, function)), false);1886 return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, function)), false); 1834 1887 } 1835 1888 … … 1838 1891 FunctionOffsetMap::AddResult ptr = m_functionOffsets.add(function, 0); 1839 1892 if (ptr.isNewEntry) 1840 ptr.iterator->second = m_codeBlock->addFunctionDecl( makeFunction(m_globalData, function));1893 ptr.iterator->second = m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, function)); 1841 1894 return emitNewFunctionInternal(dst, ptr.iterator->second, true); 1842 1895 } … … 1863 1916 { 1864 1917 FunctionBodyNode* function = n->body(); 1865 unsigned index = m_codeBlock->addFunctionExpr( makeFunction(m_globalData, function));1918 unsigned index = m_codeBlock->addFunctionExpr(FunctionExecutable::create(*m_globalData, function)); 1866 1919 1867 1920 createActivationIfNecessary(); … … 2600 2653 return; 2601 2654 2602 RefPtr<RegisterID> error = emitLoad(newTemporary(), createTypeError(scope()->globalObject()->globalExec(), StrictModeReadonlyPropertyWriteError));2655 RefPtr<RegisterID> error = emitLoad(newTemporary(), JSValue(createTypeError(scope()->globalObject()->globalExec(), StrictModeReadonlyPropertyWriteError))); 2603 2656 emitThrow(error.get()); 2604 2657 } -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r127774 r127810 618 618 619 619 void addParameter(const Identifier&, int parameterIndex); 620 620 RegisterID* resolveCallee(FunctionBodyNode*); 621 void addCallee(FunctionBodyNode*, RegisterID*); 622 621 623 void preserveLastVar(); 622 624 bool shouldAvoidResolveGlobal(); … … 626 628 if (index >= 0) 627 629 return m_calleeRegisters[index]; 630 631 if (index == RegisterFile::Callee) 632 return m_calleeRegister; 628 633 629 634 ASSERT(m_parameters.size()); … … 637 642 unsigned addConstantBuffer(unsigned length); 638 643 639 FunctionExecutable* makeFunction(ExecState* exec, FunctionBodyNode* body)640 {641 return FunctionExecutable::create(exec, body->ident(), body->inferredName(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());642 }643 644 FunctionExecutable* makeFunction(JSGlobalData* globalData, FunctionBodyNode* body)645 {646 return FunctionExecutable::create(*globalData, body->ident(), body->inferredName(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());647 }648 649 644 JSString* addStringConstant(const Identifier&); 650 645 … … 717 712 RegisterID m_ignoredResultRegister; 718 713 RegisterID m_thisRegister; 714 RegisterID m_calleeRegister; 719 715 RegisterID* m_activationRegister; 720 716 SegmentedVector<RegisterID, 32> m_constantPoolRegisters; -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r127774 r127810 1244 1244 JSGlobalData& globalData = exec->globalData(); 1245 1245 NativeCallFrameTracer tracer(&globalData, exec); 1246 return static_cast<FunctionExecutable*>(functionExecutable)->make(exec, exec->scope());1246 return JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope()); 1247 1247 } 1248 1248 … … 1252 1252 FunctionExecutable* functionExecutable = 1253 1253 static_cast<FunctionExecutable*>(functionExecutableAsCell); 1254 JSFunction* function = functionExecutable->make(exec, exec->scope()); 1255 if (!functionExecutable->name().isNull()) { 1256 JSNameScope* functionScopeObject = 1257 JSNameScope::create( 1258 exec, functionExecutable->name(), function, ReadOnly | DontDelete); 1259 function->setScope(exec->globalData(), functionScopeObject); 1260 } 1261 return function; 1254 return JSFunction::create(exec, functionExecutable, exec->scope()); 1262 1255 } 1263 1256 -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r127774 r127810 1348 1348 FunctionExecutable* function = codeBlock->functionDecl(i); 1349 1349 PutPropertySlot slot; 1350 variableObject->methodTable()->put(variableObject, callFrame, function->name(), function->make(callFrame, scope), slot);1350 variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(callFrame, function, scope), slot); 1351 1351 } 1352 1352 } … … 4280 4280 JSFunction* func = JSFunction::create(callFrame, function, callFrame->scope()); 4281 4281 4282 /*4283 The Identifier in a FunctionExpression can be referenced from inside4284 the FunctionExpression's FunctionBody to allow the function to call4285 itself recursively. However, unlike in a FunctionDeclaration, the4286 Identifier in a FunctionExpression cannot be referenced from and4287 does not affect the scope enclosing the FunctionExpression.4288 */4289 if (!function->name().isNull()) {4290 JSNameScope* functionScopeObject = JSNameScope::create(callFrame, function->name(), func, ReadOnly | DontDelete);4291 func->setScope(*globalData, functionScopeObject);4292 }4293 4294 4282 callFrame->uncheckedR(dst) = JSValue(func); 4295 4283 -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r127774 r127810 2142 2142 2143 2143 ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->uncheckedR(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue()); 2144 return stackFrame.args[0].function()->make(stackFrame.callFrame, stackFrame.callFrame->scope());2144 return JSFunction::create(stackFrame.callFrame, stackFrame.args[0].function(), stackFrame.callFrame->scope()); 2145 2145 } 2146 2146 … … 2983 2983 2984 2984 FunctionExecutable* function = stackFrame.args[0].function(); 2985 JSFunction* func = function->make(callFrame, callFrame->scope());2985 JSFunction* func = JSFunction::create(callFrame, function, callFrame->scope()); 2986 2986 ASSERT(callFrame->codeBlock()->codeType() != FunctionCode || !callFrame->codeBlock()->needsFullScopeChain() || callFrame->uncheckedR(callFrame->codeBlock()->activationRegister()).jsValue()); 2987 2988 /*2989 The Identifier in a FunctionExpression can be referenced from inside2990 the FunctionExpression's FunctionBody to allow the function to call2991 itself recursively. However, unlike in a FunctionDeclaration, the2992 Identifier in a FunctionExpression cannot be referenced from and2993 does not affect the scope enclosing the FunctionExpression.2994 */2995 if (!function->name().isNull()) {2996 JSNameScope* functionScopeObject = JSNameScope::create(callFrame, function->name(), func, ReadOnly | DontDelete);2997 func->setScope(callFrame->globalData(), functionScopeObject);2998 }2999 2987 3000 2988 return func; -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r127774 r127810 1261 1261 dataLog("Creating function!\n"); 1262 1262 #endif 1263 LLINT_RETURN( codeBlock->functionDecl(pc[2].u.operand)->make(exec, exec->scope()));1263 LLINT_RETURN(JSFunction::create(exec, codeBlock->functionDecl(pc[2].u.operand), exec->scope())); 1264 1264 } 1265 1265 … … 1269 1269 CodeBlock* codeBlock = exec->codeBlock(); 1270 1270 FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand); 1271 JSFunction* func = function->make(exec, exec->scope()); 1272 1273 if (!function->name().isNull()) { 1274 JSNameScope* functionScopeObject = JSNameScope::create(exec, function->name(), func, ReadOnly | DontDelete); 1275 func->setScope(globalData, functionScopeObject); 1276 } 1271 JSFunction* func = JSFunction::create(exec, function, exec->scope()); 1277 1272 1278 1273 LLINT_RETURN(func); -
trunk/Source/JavaScriptCore/parser/NodeConstructors.h
r127654 r127810 750 750 , m_body(body) 751 751 { 752 m_body->finishParsing(source, parameter, ident );752 m_body->finishParsing(source, parameter, ident, FunctionNameIsInScope); 753 753 } 754 754 … … 757 757 , m_body(body) 758 758 { 759 m_body->finishParsing(source, parameter, ident );759 m_body->finishParsing(source, parameter, ident, FunctionNameIsNotInScope); 760 760 } 761 761 -
trunk/Source/JavaScriptCore/parser/Nodes.cpp
r126893 r127810 168 168 } 169 169 170 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident )170 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident, FunctionNameIsInScopeToggle functionNameIsInScopeToggle) 171 171 { 172 172 setSource(source); 173 finishParsing(FunctionParameters::create(firstParameter), ident );174 } 175 176 void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident )173 finishParsing(FunctionParameters::create(firstParameter), ident, functionNameIsInScopeToggle); 174 } 175 176 void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident, FunctionNameIsInScopeToggle functionNameIsInScopeToggle) 177 177 { 178 178 ASSERT(!source().isNull()); 179 179 m_parameters = parameters; 180 180 m_ident = ident; 181 m_functionNameIsInScopeToggle = functionNameIsInScopeToggle; 181 182 } 182 183 -
trunk/Source/JavaScriptCore/parser/Nodes.h
r127666 r127810 1404 1404 }; 1405 1405 1406 enum FunctionNameIsInScopeToggle { FunctionNameIsNotInScope, FunctionNameIsInScope }; 1406 1407 class FunctionBodyNode : public ScopeNode { 1407 1408 public: … … 1415 1416 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); 1416 1417 1417 void finishParsing(const SourceCode&, ParameterNode*, const Identifier& );1418 void finishParsing(PassRefPtr<FunctionParameters>, const Identifier& );1418 void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionNameIsInScopeToggle); 1419 void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionNameIsInScopeToggle); 1419 1420 1420 1421 const Identifier& ident() { return m_ident; } … … 1422 1423 const Identifier& inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; } 1423 1424 1425 bool functionNameIsInScope() { return m_functionNameIsInScopeToggle == FunctionNameIsInScope; } 1426 FunctionNameIsInScopeToggle functionNameIsInScopeToggle() { return m_functionNameIsInScopeToggle; } 1427 1424 1428 static const bool scopeIsFunction = true; 1425 1429 … … 1430 1434 Identifier m_ident; 1431 1435 Identifier m_inferredName; 1436 FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle; 1432 1437 RefPtr<FunctionParameters> m_parameters; 1433 1438 }; -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r127774 r127810 41 41 42 42 template <typename LexerType> 43 Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode)43 Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode) 44 44 : m_globalData(globalData) 45 45 , m_source(&source) … … 72 72 scope->declareParameter(¶meters->at(i)); 73 73 } 74 if (!name.isNull()) 75 scope->declareCallee(&name); 74 76 next(); 75 77 m_lexer->setLastLineNumber(tokenLine()); -
trunk/Source/JavaScriptCore/parser/Parser.h
r127774 r127810 209 209 bool isFunctionBoundary() { return m_isFunctionBoundary; } 210 210 211 void declareCallee(const Identifier* ident) 212 { 213 m_declaredVariables.add(ident->ustring().impl()); 214 } 215 211 216 bool declareVariable(const Identifier* ident) 212 217 { … … 383 388 384 389 public: 385 Parser(JSGlobalData*, const SourceCode&, FunctionParameters*, JSParserStrictness, JSParserMode);390 Parser(JSGlobalData*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode); 386 391 ~Parser(); 387 392 … … 1021 1026 1022 1027 template <class ParsedNode> 1023 PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, const SourceCode& source, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode, Debugger* debugger, ExecState* execState, JSObject** exception)1028 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) 1024 1029 { 1025 1030 SamplingRegion samplingRegion("Parsing"); … … 1028 1033 1029 1034 if (source.provider()->data()->is8Bit()) { 1030 Parser< Lexer<LChar> > parser(globalData, source, parameters, strictness, parserMode);1035 Parser< Lexer<LChar> > parser(globalData, source, parameters, name, strictness, parserMode); 1031 1036 return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception); 1032 1037 } 1033 Parser< Lexer<UChar> > parser(globalData, source, parameters, strictness, parserMode);1038 Parser< Lexer<UChar> > parser(globalData, source, parameters, name, strictness, parserMode); 1034 1039 return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception); 1035 1040 } -
trunk/Source/JavaScriptCore/runtime/Executable.cpp
r127774 r127810 134 134 const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) }; 135 135 136 FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext)137 : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, source, inStrictContext)136 FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, FunctionBodyNode* node) 137 : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, node->source(), node->isStrictMode()) 138 138 , m_numCapturedVariables(0) 139 , m_forceUsesArguments(forceUsesArguments) 140 , m_parameters(parameters) 141 , m_name(name) 142 , m_inferredName(inferredName.isNull() ? globalData.propertyNames->emptyIdentifier : inferredName) 143 { 144 } 145 146 FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext) 147 : ScriptExecutable(exec->globalData().functionExecutableStructure.get(), exec, source, inStrictContext) 148 , m_numCapturedVariables(0) 149 , m_forceUsesArguments(forceUsesArguments) 150 , m_parameters(parameters) 151 , m_name(name) 152 , m_inferredName(inferredName.isNull() ? exec->globalData().propertyNames->emptyIdentifier : inferredName) 153 { 139 , m_forceUsesArguments(node->usesArguments()) 140 , m_parameters(node->parameters()) 141 , m_name(node->ident()) 142 , m_inferredName(node->inferredName().isNull() ? globalData.propertyNames->emptyIdentifier : node->inferredName()) 143 , m_functionNameIsInScopeToggle(node->functionNameIsInScopeToggle()) 144 { 145 m_firstLine = node->lineNo(); 146 m_lastLine = node->lastLine(); 154 147 } 155 148 … … 211 204 if (!lexicalGlobalObject->evalEnabled()) 212 205 return throwError(exec, createEvalError(exec, ASCIILiteral("Eval is disabled"))); 213 RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);206 RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); 214 207 if (!evalNode) { 215 208 ASSERT(exception); … … 294 287 JSGlobalData* globalData = &exec->globalData(); 295 288 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 296 RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);289 RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); 297 290 if (programNode) 298 291 return 0; … … 336 329 m_programCodeBlock = newCodeBlock.release(); 337 330 } else { 338 RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);331 RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); 339 332 if (!programNode) { 340 333 ASSERT(exception); … … 479 472 JSGlobalData* globalData = scope->globalData(); 480 473 JSGlobalObject* globalObject = scope->globalObject(); 481 RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(globalData, globalObject, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, 0, 0, &exception); 474 RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>( 475 globalData, 476 globalObject, 477 m_source, 478 m_parameters.get(), 479 name(), 480 isStrictMode() ? JSParseStrict : JSParseNormal, 481 FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, 482 0, 483 0, 484 &exception 485 ); 482 486 483 487 if (!body) { … … 487 491 if (m_forceUsesArguments) 488 492 body->setUsesArguments(); 489 body->finishParsing(m_parameters, m_name );493 body->finishParsing(m_parameters, m_name, m_functionNameIsInScopeToggle); 490 494 recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine()); 491 495 … … 648 652 } 649 653 650 FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)654 FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception) 651 655 { 652 656 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 653 RefPtr<ProgramNode> program = parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, source, 0, JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception);657 RefPtr<ProgramNode> program = parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception); 654 658 if (!program) { 655 659 ASSERT(*exception); … … 657 661 } 658 662 659 // Uses of this function that would not result in a single function expression are invalid.663 // This function assumes an input string that would result in a single anonymous function expression. 660 664 StatementNode* exprStatement = program->singleStatement(); 661 665 ASSERT(exprStatement); … … 666 670 FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body(); 667 671 ASSERT(body); 668 669 return FunctionExecutable::create(exec->globalData(), functionName, functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine()); 672 ASSERT(body->ident().isNull()); 673 674 FunctionExecutable* functionExecutable = FunctionExecutable::create(exec->globalData(), body); 675 functionExecutable->m_nameValue.set(exec->globalData(), functionExecutable, jsString(&exec->globalData(), name.ustring())); 676 return functionExecutable; 670 677 } 671 678 -
trunk/Source/JavaScriptCore/runtime/Executable.h
r127774 r127810 540 540 typedef ScriptExecutable Base; 541 541 542 static FunctionExecutable* create( ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)543 { 544 FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>( *exec->heap())) FunctionExecutable(exec, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);545 executable->finishCreation( exec->globalData(), name, firstLine, lastLine);542 static FunctionExecutable* create(JSGlobalData& globalData, FunctionBodyNode* node) 543 { 544 FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, node); 545 executable->finishCreation(globalData); 546 546 return executable; 547 547 } 548 549 static FunctionExecutable* create(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine) 550 { 551 FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext); 552 executable->finishCreation(globalData, name, firstLine, lastLine); 553 return executable; 554 } 548 static FunctionExecutable* fromGlobalCode(const Identifier& name, ExecState*, Debugger*, const SourceCode&, JSObject** exception); 555 549 556 550 static void destroy(JSCell*); 557 551 558 JSFunction* make(ExecState* exec, JSScope* scope)559 {560 return JSFunction::create(exec, this, scope);561 }562 563 552 // Returns either call or construct bytecode. This can be appropriate 564 553 // for answering questions that that don't vary between call and construct -- … … 709 698 void clearCodeIfNotCompiling(); 710 699 static void visitChildren(JSCell*, SlotVisitor&); 711 static FunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);712 700 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) 713 701 { … … 722 710 723 711 protected: 724 void finishCreation(JSGlobalData& globalData , const Identifier& name, int firstLine, int lastLine)712 void finishCreation(JSGlobalData& globalData) 725 713 { 726 714 Base::finishCreation(globalData); 727 m_firstLine = firstLine; 728 m_lastLine = lastLine; 729 m_nameValue.set(globalData, this, jsString(&globalData, name.ustring())); 715 m_nameValue.set(globalData, this, jsString(&globalData, name().ustring())); 730 716 } 731 717 732 718 private: 733 FunctionExecutable(JSGlobalData&, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool); 734 FunctionExecutable(ExecState*, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool); 719 FunctionExecutable(JSGlobalData&, FunctionBodyNode*); 735 720 736 721 JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX); … … 765 750 Identifier m_name; 766 751 Identifier m_inferredName; 752 FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle; 767 753 WriteBarrier<JSString> m_nameValue; 768 754 WriteBarrier<SharedSymbolTable> m_symbolTable; -
trunk/Source/JavaScriptCore/runtime/JSNameScope.h
r127774 r127810 39 39 static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes) 40 40 { 41 JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec); 41 JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec, exec->scope()); 42 scopeObject->finishCreation(exec, identifier, value, attributes); 43 return scopeObject; 44 } 45 46 static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes, JSScope* next) 47 { 48 JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec, next); 42 49 scopeObject->finishCreation(exec, identifier, value, attributes); 43 50 return scopeObject; … … 65 72 66 73 private: 67 JSNameScope(ExecState* exec )74 JSNameScope(ExecState* exec, JSScope* next) 68 75 : Base( 69 76 exec->globalData(), 70 77 exec->lexicalGlobalObject()->nameScopeStructure(), 71 78 reinterpret_cast<Register*>(&m_registerStore + 1), 72 exec->scope()79 next 73 80 ) 74 81 {
Note: See TracChangeset
for help on using the changeset viewer.