Changeset 133688 in webkit for trunk/Source/JavaScriptCore/runtime/Executable.cpp
- Timestamp:
- Nov 6, 2012, 4:13:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/Executable.cpp
r129453 r133688 27 27 #include "Executable.h" 28 28 29 #include "BatchedTransitionOptimizer.h" 29 30 #include "BytecodeGenerator.h" 30 31 #include "CodeBlock.h" … … 134 135 const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) }; 135 136 136 FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, FunctionBodyNode* node) 137 : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, node->source(), node->isStrictMode()) 138 , m_forceUsesArguments(node->usesArguments()) 139 , m_parameters(node->parameters()) 140 , m_name(node->ident()) 141 , m_inferredName(node->inferredName().isNull() ? globalData.propertyNames->emptyIdentifier : node->inferredName()) 142 , m_functionNameIsInScopeToggle(node->functionNameIsInScopeToggle()) 143 { 144 m_firstLine = node->lineNo(); 145 m_lastLine = node->lastLine(); 137 FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine) 138 : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, source, unlinkedExecutable->isInStrictContext()) 139 , m_unlinkedExecutable(globalData, this, unlinkedExecutable) 140 { 141 ASSERT(!source.isNull()); 142 ASSERT(source.length()); 143 m_firstLine = firstLine; 144 m_lastLine = lastLine; 146 145 } 147 146 … … 192 191 UNUSED_PARAM(bytecodeIndex); 193 192 #endif 194 JSObject* exception = 0;195 193 JSGlobalData* globalData = &exec->globalData(); 196 194 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); … … 201 199 m_evalCodeBlock = newCodeBlock.release(); 202 200 } else { 201 UNUSED_PARAM(scope); 202 UNUSED_PARAM(globalData); 203 UNUSED_PARAM(lexicalGlobalObject); 203 204 if (!lexicalGlobalObject->evalEnabled()) 204 205 return throwError(exec, createEvalError(exec, lexicalGlobalObject->evalDisabledErrorMessage())); 205 RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); 206 if (!evalNode) { 207 ASSERT(exception); 206 207 JSObject* exception = 0; 208 UnlinkedEvalCodeBlock* unlinkedEvalCode = lexicalGlobalObject->createEvalCodeBlock(exec, this, &exception); 209 if (!unlinkedEvalCode) 208 210 return exception; 209 } 210 recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine()); 211 212 JSGlobalObject* globalObject = scope->globalObject(); 213 211 214 212 OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release(); 215 213 ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock); 216 m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scope->localDepth(), previousCodeBlock.release())); 217 OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scope, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); 218 if ((exception = generator->generate())) { 219 m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative()); 220 evalNode->destroyData(); 221 return exception; 222 } 223 224 evalNode->destroyData(); 214 m_unlinkedEvalCodeBlock.set(*globalData, this, unlinkedEvalCode); 215 m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, unlinkedEvalCode, lexicalGlobalObject, source().provider(), scope->localDepth(), previousCodeBlock.release())); 225 216 m_evalCodeBlock->copyPostParseDataFromAlternative(); 226 217 } … … 258 249 if (thisObject->m_evalCodeBlock) 259 250 thisObject->m_evalCodeBlock->visitAggregate(visitor); 251 visitor.append(&thisObject->m_unlinkedEvalCodeBlock); 260 252 } 261 253 … … 273 265 { 274 266 m_evalCodeBlock.clear(); 267 m_unlinkedEvalCodeBlock.clear(); 275 268 Base::clearCode(); 276 269 } … … 278 271 JSObject* ProgramExecutable::checkSyntax(ExecState* exec) 279 272 { 280 JSObject* exception = 0;273 ParserError error; 281 274 JSGlobalData* globalData = &exec->globalData(); 282 275 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 283 RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);276 RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, error); 284 277 if (programNode) 285 278 return 0; 286 ASSERT(e xception);287 return e xception;279 ASSERT(error.m_type != ParserError::ErrorNone); 280 return error.toErrorObject(lexicalGlobalObject, m_source); 288 281 } 289 282 … … 311 304 312 305 #if !ENABLE(JIT) 306 UNUSED_PARAM(exec); 313 307 UNUSED_PARAM(jitType); 314 308 UNUSED_PARAM(bytecodeIndex); 315 309 #endif 316 JSObject* exception = 0;317 JSGlobalData* globalData = &exec->globalData();318 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();319 320 310 if (!!m_programCodeBlock) { 321 311 OwnPtr<ProgramCodeBlock> newCodeBlock = adoptPtr(new ProgramCodeBlock(CodeBlock::CopyParsedBlock, *m_programCodeBlock)); … … 323 313 m_programCodeBlock = newCodeBlock.release(); 324 314 } else { 325 RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);326 if (!programNode) {327 ASSERT(exception);328 return exception;329 }330 recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine());331 332 315 JSGlobalObject* globalObject = scope->globalObject(); 333 334 OwnPtr<CodeBlock> previousCodeBlock = m_programCodeBlock.release(); 335 ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock); 336 m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider(), previousCodeBlock.release())); 337 OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scope, globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); 338 if ((exception = generator->generate())) { 339 m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative()); 340 programNode->destroyData(); 341 return exception; 342 } 343 344 programNode->destroyData(); 316 m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, m_unlinkedProgramCodeBlock.get(), globalObject, source().provider(), m_programCodeBlock.release())); 345 317 m_programCodeBlock->copyPostParseDataFromAlternative(); 346 318 } … … 377 349 m_programCodeBlock->unlinkCalls(); 378 350 #endif 351 } 352 353 int ProgramExecutable::addGlobalVar(JSGlobalObject* globalObject, const Identifier& ident, ConstantMode constantMode, FunctionMode functionMode) 354 { 355 // Try to share the symbolTable if possible 356 SharedSymbolTable* symbolTable = globalObject->symbolTable(); 357 UNUSED_PARAM(functionMode); 358 int index = symbolTable->size(); 359 SymbolTableEntry newEntry(index, (constantMode == IsConstant) ? ReadOnly : 0); 360 if (functionMode == IsFunctionToSpecialize) 361 newEntry.attemptToWatch(); 362 SymbolTable::AddResult result = symbolTable->add(ident.impl(), newEntry); 363 if (!result.isNewEntry) { 364 result.iterator->value.notifyWrite(); 365 index = result.iterator->value.getIndex(); 366 } 367 return index; 368 } 369 370 JSObject* ProgramExecutable::initalizeGlobalProperties(JSGlobalData& globalData, CallFrame* callFrame, JSScope* scope) 371 { 372 ASSERT(scope); 373 JSGlobalObject* globalObject = scope->globalObject(); 374 ASSERT(globalObject); 375 ASSERT(&globalObject->globalData() == &globalData); 376 377 JSObject* exception = 0; 378 UnlinkedProgramCodeBlock* unlinkedCode = globalObject->createProgramCodeBlock(callFrame, this, &exception); 379 if (exception) 380 return exception; 381 382 m_unlinkedProgramCodeBlock.set(globalData, this, unlinkedCode); 383 384 BatchedTransitionOptimizer optimizer(globalData, globalObject); 385 386 const UnlinkedProgramCodeBlock::VariableDeclations& variableDeclarations = unlinkedCode->variableDeclarations(); 387 const UnlinkedProgramCodeBlock::FunctionDeclations& functionDeclarations = unlinkedCode->functionDeclarations(); 388 389 size_t newGlobals = variableDeclarations.size() + functionDeclarations.size(); 390 if (!newGlobals) 391 return 0; 392 globalObject->addRegisters(newGlobals); 393 CallFrame* globalExec = globalObject->globalExec(); 394 395 for (size_t i = 0; i < functionDeclarations.size(); ++i) { 396 bool propertyDidExist = globalObject->removeDirect(globalData, functionDeclarations[i].first); // Newly declared functions overwrite existing properties. 397 UnlinkedFunctionExecutable* unlinkedFunctionExecutable = functionDeclarations[i].second.get(); 398 JSValue value = JSFunction::create(globalExec, unlinkedFunctionExecutable->link(globalData, m_source, lineNo(), 0), scope); 399 int index = addGlobalVar(globalObject, functionDeclarations[i].first, IsVariable, 400 !propertyDidExist ? IsFunctionToSpecialize : NotFunctionOrNotSpecializable); 401 globalObject->registerAt(index).set(globalData, globalObject, value); 402 } 403 404 for (size_t i = 0; i < variableDeclarations.size(); ++i) { 405 if (globalObject->hasProperty(globalExec, variableDeclarations[i].first)) 406 continue; 407 addGlobalVar(globalObject, variableDeclarations[i].first, 408 (variableDeclarations[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, 409 NotFunctionOrNotSpecializable); 410 } 411 return 0; 379 412 } 380 413 … … 386 419 ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); 387 420 ScriptExecutable::visitChildren(thisObject, visitor); 421 visitor.append(&thisObject->m_unlinkedProgramCodeBlock); 388 422 if (thisObject->m_programCodeBlock) 389 423 thisObject->m_programCodeBlock->visitAggregate(visitor); … … 393 427 { 394 428 m_programCodeBlock.clear(); 429 m_unlinkedProgramCodeBlock.clear(); 395 430 Base::clearCode(); 396 431 } … … 439 474 bool FunctionExecutable::jitCompileForCall(ExecState* exec) 440 475 { 441 return jitCompileFunctionIfAppropriate(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable,JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);476 return jitCompileFunctionIfAppropriate(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail); 442 477 } 443 478 444 479 bool FunctionExecutable::jitCompileForConstruct(ExecState* exec) 445 480 { 446 return jitCompileFunctionIfAppropriate(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable,JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail);481 return jitCompileFunctionIfAppropriate(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, JITCode::bottomTierJIT(), UINT_MAX, JITCompilationCanFail); 447 482 } 448 483 #endif … … 453 488 } 454 489 455 PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, Co mpilationKind compilationKind, CodeSpecializationKind specializationKind, JSObject*& exception)490 PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, CodeSpecializationKind specializationKind, JSObject*& exception) 456 491 { 457 492 if (!!codeBlockFor(specializationKind)) 458 493 return adoptPtr(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind))); 459 460 exception = 0; 494 461 495 JSGlobalData* globalData = scope->globalData(); 462 496 JSGlobalObject* globalObject = scope->globalObject(); 463 RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>( 464 globalData, 465 globalObject, 466 m_source, 467 m_parameters.get(), 468 name(), 469 isStrictMode() ? JSParseStrict : JSParseNormal, 470 FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, 471 0, 472 0, 473 &exception 474 ); 475 476 if (!body) { 477 ASSERT(exception); 497 ParserError error; 498 DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff; 499 ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff; 500 UnlinkedFunctionCodeBlock* unlinkedCodeBlock = m_unlinkedExecutable->codeBlockFor(*globalData, m_source, specializationKind, debuggerMode, profilerMode, error); 501 recordParse(m_unlinkedExecutable->features(), m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine()); 502 503 if (!unlinkedCodeBlock) { 504 exception = error.toErrorObject(globalObject, m_source); 478 505 return nullptr; 479 506 } 480 if (m_forceUsesArguments) 481 body->setUsesArguments(); 482 body->finishParsing(m_parameters, m_name, m_functionNameIsInScopeToggle); 483 recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine()); 484 485 OwnPtr<FunctionCodeBlock> result; 486 ASSERT((compilationKind == FirstCompilation) == !codeBlockFor(specializationKind)); 487 result = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), specializationKind == CodeForConstruct)); 488 OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scope, result->symbolTable(), result.get(), compilationKind))); 489 exception = generator->generate(); 490 body->destroyData(); 491 if (exception) 492 return nullptr; 493 507 508 OwnPtr<FunctionCodeBlock> result = adoptPtr(new FunctionCodeBlock(this, unlinkedCodeBlock, globalObject, source().provider(), source().startOffset())); 494 509 result->copyPostParseDataFrom(codeBlockFor(specializationKind).get()); 495 510 return result.release(); 496 511 } 512 497 513 498 514 JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, unsigned bytecodeIndex) … … 508 524 ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForCall); 509 525 JSObject* exception; 510 OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, !!m_codeBlockForCall ? OptimizingCompilation : FirstCompilation,CodeForCall, exception);526 OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForCall, exception); 511 527 if (!newCodeBlock) 512 528 return exception; … … 517 533 m_numParametersForCall = m_codeBlockForCall->numParameters(); 518 534 ASSERT(m_numParametersForCall); 519 m_symbolTable.set(exec->globalData(), this, m_codeBlockForCall->symbolTable()); 520 521 #if ENABLE(JIT) 522 if (!prepareFunctionForExecution(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType, bytecodeIndex, CodeForCall)) 535 536 #if ENABLE(JIT) 537 if (!prepareFunctionForExecution(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, jitType, bytecodeIndex, CodeForCall)) 523 538 return 0; 524 539 #endif … … 545 560 ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForConstruct); 546 561 JSObject* exception; 547 OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, !!m_codeBlockForConstruct ? OptimizingCompilation : FirstCompilation,CodeForConstruct, exception);562 OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForConstruct, exception); 548 563 if (!newCodeBlock) 549 564 return exception; … … 554 569 m_numParametersForConstruct = m_codeBlockForConstruct->numParameters(); 555 570 ASSERT(m_numParametersForConstruct); 556 m_symbolTable.set(exec->globalData(), this, m_codeBlockForConstruct->symbolTable()); 557 558 #if ENABLE(JIT) 559 if (!prepareFunctionForExecution(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType, bytecodeIndex, CodeForConstruct)) 571 572 #if ENABLE(JIT) 573 if (!prepareFunctionForExecution(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, jitType, bytecodeIndex, CodeForConstruct)) 560 574 return 0; 561 575 #endif … … 593 607 ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); 594 608 ScriptExecutable::visitChildren(thisObject, visitor); 595 visitor.append(&thisObject->m_nameValue);596 visitor.append(&thisObject->m_symbolTable);597 609 if (thisObject->m_codeBlockForCall) 598 610 thisObject->m_codeBlockForCall->visitAggregate(visitor); 599 611 if (thisObject->m_codeBlockForConstruct) 600 612 thisObject->m_codeBlockForConstruct->visitAggregate(visitor); 613 visitor.append(&thisObject->m_unlinkedExecutable); 601 614 } 602 615 … … 608 621 } 609 622 623 void FunctionExecutable::clearUnlinkedCodeIfNotCompiling() 624 { 625 if (isCompiling()) 626 return; 627 m_unlinkedExecutable->clearCode(); 628 } 629 610 630 void FunctionExecutable::clearCode() 611 631 { 612 632 m_codeBlockForCall.clear(); 613 633 m_codeBlockForConstruct.clear(); 634 m_unlinkedExecutable->clearCode(); 614 635 Base::clearCode(); 615 636 } … … 631 652 FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception) 632 653 { 633 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 634 RefPtr<ProgramNode> program = parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception); 635 if (!program) { 636 ASSERT(*exception); 637 return 0; 638 } 639 640 // This function assumes an input string that would result in a single anonymous function expression. 641 StatementNode* exprStatement = program->singleStatement(); 642 ASSERT(exprStatement); 643 ASSERT(exprStatement->isExprStatement()); 644 ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr(); 645 ASSERT(funcExpr); 646 ASSERT(funcExpr->isFuncExprNode()); 647 FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body(); 648 ASSERT(body); 649 ASSERT(body->ident().isNull()); 650 651 FunctionExecutable* functionExecutable = FunctionExecutable::create(exec->globalData(), body); 652 functionExecutable->m_nameValue.set(exec->globalData(), functionExecutable, jsString(&exec->globalData(), name.string())); 653 return functionExecutable; 654 UnlinkedFunctionExecutable* unlinkedFunction = UnlinkedFunctionExecutable::fromGlobalCode(name, exec, debugger, source, exception); 655 if (!unlinkedFunction) 656 return 0; 657 unsigned firstLine = source.firstLine() + unlinkedFunction->firstLineOffset(); 658 unsigned startOffset = source.startOffset() + unlinkedFunction->startOffset(); 659 unsigned sourceLength = unlinkedFunction->sourceLength(); 660 SourceCode functionSource(source.provider(), startOffset, startOffset + sourceLength, firstLine); 661 return FunctionExecutable::create(exec->globalData(), functionSource, unlinkedFunction, firstLine, unlinkedFunction->lineCount()); 654 662 } 655 663 656 664 String FunctionExecutable::paramString() const 657 665 { 658 FunctionParameters& parameters = *m_parameters; 659 StringBuilder builder; 660 for (size_t pos = 0; pos < parameters.size(); ++pos) { 661 if (!builder.isEmpty()) 662 builder.appendLiteral(", "); 663 builder.append(parameters[pos].string()); 664 } 665 return builder.toString(); 666 } 667 668 } 666 return m_unlinkedExecutable->paramString(); 667 } 668 669 }
Note:
See TracChangeset
for help on using the changeset viewer.