Changeset 127939 in webkit
- Timestamp:
- Sep 7, 2012, 4:59:10 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r127938 r127939 1 2012-09-07 Geoffrey Garen <[email protected]> 2 3 Refactored bytecode generator initialization to support moving captured vars around 4 https://bugs.webkit.org/show_bug.cgi?id=96159 5 6 Reviewed by Gavin Barraclough. 7 8 This patch separates the stages of allocating registers, declaring identifiers 9 in the symbol table, and initializing registers, so you can change 10 allocation decisions without breaking the world. 11 12 * bytecompiler/BytecodeGenerator.cpp: 13 (JSC::BytecodeGenerator::BytecodeGenerator): Call a set of helper functions 14 instead of inlining all the code, to help clarity. 15 16 (JSC::BytecodeGenerator::allocateCapturedVars): 17 (JSC::BytecodeGenerator::allocateUncapturedVars): 18 (JSC::BytecodeGenerator::allocateActivationVar): 19 (JSC::BytecodeGenerator::allocateArgumentsVars): 20 (JSC::BytecodeGenerator::allocateCalleeVarUndeclared): 21 (JSC::BytecodeGenerator::declareParameters): 22 (JSC::BytecodeGenerator::declareCallee): 23 (JSC::BytecodeGenerator::initCalleeVar): 24 (JSC::BytecodeGenerator::initArgumentsVars): 25 (JSC::BytecodeGenerator::initActivationVar): 26 (JSC::BytecodeGenerator::initThisParameter): 27 (JSC::BytecodeGenerator::initFunctionDeclarations): 28 (JSC::BytecodeGenerator::declareParameter): 29 (JSC::BytecodeGenerator::createLazyRegisterIfNecessary): 30 (JSC::BytecodeGenerator::createActivationIfNecessary): Factored these 31 helper functions out from pre-existing code. 32 33 * bytecompiler/BytecodeGenerator.h: 34 (BytecodeGenerator): 35 * parser/ASTBuilder.h: 36 (JSC::ASTBuilder::createFuncDeclStatement): 37 (JSC::ASTBuilder::addVar): 38 * parser/Nodes.h: 39 (JSC::DeclarationStacks::VarDeclaration::VarDeclaration): 40 (VarDeclaration): 41 (JSC::DeclarationStacks::FunctionDeclaration::FunctionDeclaration): 42 (FunctionDeclaration): Declaration stacks get a little more data now, 43 to support allocating registers before putting things in the symbol 44 table. I'm convinced that we should eventually just expand the symbol 45 table to understand these things. 46 1 47 2012-09-07 Mark Lam <[email protected]> 2 48 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r127810 r127939 279 279 , m_nextConstantOffset(0) 280 280 , m_globalConstantIndex(0) 281 , m_hasCreatedActivation(true)282 , m_firstLazyFunction(0)283 , m_lastLazyFunction(0)284 281 , m_globalData(scope->globalData()) 285 282 , m_lastOpcodeID(op_end) … … 321 318 322 319 for (size_t i = 0; i < functionStack.size(); ++i) { 323 FunctionBodyNode* function = functionStack[i] ;320 FunctionBodyNode* function = functionStack[i].node; 324 321 bool propertyDidExist = 325 322 globalObject->removeDirect(*m_globalData, function->ident()); // Newly declared functions overwrite existing properties. … … 333 330 334 331 for (size_t i = 0; i < varStack.size(); ++i) { 335 if (globalObject->hasProperty(exec, *varStack[i]. first))332 if (globalObject->hasProperty(exec, *varStack[i].name)) 336 333 continue; 337 334 addGlobalVar( 338 *varStack[i]. first,339 (varStack[i]. second& DeclarationStacks::IsConstant) ? IsConstant : IsVariable,335 *varStack[i].name, 336 (varStack[i].attributes & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, 340 337 NotFunctionOrNotSpecializable); 338 } 339 } 340 341 void BytecodeGenerator::allocateCapturedVars() 342 { 343 FunctionBodyNode* node = static_cast<FunctionBodyNode*>(m_scopeNode); 344 if (!node->hasCapturedVariables()) 345 return; 346 347 DeclarationStacks::FunctionStack& functionStack = node->functionStack(); 348 for (size_t i = 0; i < functionStack.size(); ++i) { 349 if (!node->captures(functionStack[i].node->ident())) 350 continue; 351 functionStack[i].reg = addVar(functionStack[i].node->ident(), false); 352 m_functions.add(functionStack[i].node->ident().impl()); 353 } 354 355 DeclarationStacks::VarStack& varStack = node->varStack(); 356 for (size_t i = 0; i < varStack.size(); ++i) { 357 if (!node->captures(*varStack[i].name)) 358 continue; 359 varStack[i].reg = addVar(*varStack[i].name, varStack[i].attributes & DeclarationStacks::IsConstant); 360 } 361 } 362 363 void BytecodeGenerator::allocateUncapturedVars() 364 { 365 FunctionBodyNode* node = static_cast<FunctionBodyNode*>(m_scopeNode); 366 367 DeclarationStacks::FunctionStack& functionStack = node->functionStack(); 368 for (size_t i = 0; i < functionStack.size(); ++i) { 369 if (node->captures(functionStack[i].node->ident())) 370 continue; 371 functionStack[i].reg = addVar(functionStack[i].node->ident(), false); 372 m_functions.add(functionStack[i].node->ident().impl()); 373 } 374 375 DeclarationStacks::VarStack& varStack = node->varStack(); 376 for (size_t i = 0; i < varStack.size(); ++i) { 377 if (node->captures(*varStack[i].name)) 378 continue; 379 varStack[i].reg = addVar(*varStack[i].name, varStack[i].attributes & DeclarationStacks::IsConstant); 380 } 381 } 382 383 void BytecodeGenerator::allocateActivationVar() 384 { 385 if (!m_codeBlock->needsFullScopeChain()) 386 return; 387 388 m_activationRegister = addVar(); 389 m_codeBlock->setActivationRegister(m_activationRegister->index()); 390 } 391 392 void BytecodeGenerator::allocateArgumentsVars() 393 { 394 FunctionBodyNode* node = static_cast<FunctionBodyNode*>(m_scopeNode); 395 396 // Both op_tear_off_activation and op_tear_off_arguments tear off the 'arguments' 397 // object, if created. 398 if (!m_codeBlock->needsFullScopeChain() && !node->usesArguments()) 399 return; 400 401 RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code. 402 RegisterID* argumentsRegister = addVar(propertyNames().arguments, false); // Can be changed by assigning to 'arguments'. 403 404 // We can save a little space by hard-coding the knowledge that the two 405 // 'arguments' values are stored in consecutive registers, and storing 406 // only the index of the assignable one. 407 m_codeBlock->setArgumentsRegister(argumentsRegister->index()); 408 ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->index() == JSC::unmodifiedArgumentsRegister(m_codeBlock->argumentsRegister())); 409 } 410 411 void BytecodeGenerator::allocateCalleeVarUndeclared() 412 { 413 FunctionBodyNode* node = static_cast<FunctionBodyNode*>(m_scopeNode); 414 415 if (node->ident().isNull() || !node->functionNameIsInScope()) 416 return; 417 418 // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name. 419 if ((m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks) 420 return; 421 422 if (!node->captures(node->ident())) { 423 m_calleeRegister.setIndex(RegisterFile::Callee); 424 return; 425 } 426 427 m_calleeRegister.setIndex(addVar()->index()); 428 } 429 430 void BytecodeGenerator::declareParameters() 431 { 432 FunctionBodyNode* node = static_cast<FunctionBodyNode*>(m_scopeNode); 433 FunctionParameters& parameters = *node->parameters(); 434 m_parameters.grow(parameters.size() + 1); // reserve space for "this" 435 436 // Add "this" as a parameter 437 int nextParameterIndex = CallFrame::thisArgumentOffset(); 438 m_thisRegister.setIndex(nextParameterIndex--); 439 m_codeBlock->addParameter(); 440 441 for (size_t i = 0; i < parameters.size(); ++i) 442 declareParameter(parameters[i], nextParameterIndex--); 443 } 444 445 void BytecodeGenerator::declareCallee() 446 { 447 FunctionBodyNode* node = static_cast<FunctionBodyNode*>(m_scopeNode); 448 449 if (node->ident().isNull() || !node->functionNameIsInScope()) 450 return; 451 452 // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name. 453 if ((m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks) 454 return; 455 456 symbolTable().add(node->ident().impl(), SymbolTableEntry(m_calleeRegister.index(), ReadOnly)); 457 } 458 459 void BytecodeGenerator::initCalleeVar() 460 { 461 FunctionBodyNode* node = static_cast<FunctionBodyNode*>(m_scopeNode); 462 463 if (node->ident().isNull() || !node->functionNameIsInScope()) 464 return; 465 466 // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name. 467 if ((m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks) { 468 emitOpcode(op_push_name_scope); 469 instructions().append(addConstant(node->ident())); 470 instructions().append(RegisterFile::Callee); 471 instructions().append(ReadOnly | DontDelete); 472 473 // Put a mirror object in compilation scope, so compile-time variable resolution sees the property name we'll see at runtime. 474 m_scope.set(*globalData(), 475 JSNameScope::create( 476 m_scope->globalObject()->globalExec(), 477 node->ident(), 478 jsUndefined(), 479 ReadOnly | DontDelete, 480 m_scope.get() 481 ) 482 ); 483 484 return; 485 } 486 487 if (!node->captures(node->ident())) 488 return; 489 490 // Move the callee into the captured section of the stack. 491 RegisterID callee(RegisterFile::Callee); 492 emitMove(&m_calleeRegister, &callee); 493 } 494 495 void BytecodeGenerator::initArgumentsVars() 496 { 497 if (!m_codeBlock->usesArguments()) 498 return; 499 500 int argumentsRegister = m_codeBlock->argumentsRegister(); 501 int unmodifiedArgumentsRegister = JSC::unmodifiedArgumentsRegister(argumentsRegister); 502 503 prependComment("unmodified arguments"); 504 emitInitLazyRegister(®isterFor(unmodifiedArgumentsRegister)); 505 prependComment("arguments"); 506 emitInitLazyRegister(®isterFor(argumentsRegister)); 507 508 if ((m_codeBlock->usesArguments() && m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks) { 509 emitOpcode(op_create_arguments); 510 instructions().append(m_codeBlock->argumentsRegister()); 511 } 512 } 513 514 void BytecodeGenerator::initActivationVar() 515 { 516 if (!m_codeBlock->needsFullScopeChain()) 517 return; 518 519 FunctionBodyNode* node = static_cast<FunctionBodyNode*>(m_scopeNode); 520 521 emitInitLazyRegister(m_activationRegister); 522 523 bool canLazilyCreateFunctions = !node->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks; 524 if (canLazilyCreateFunctions) 525 return; 526 527 emitOpcode(op_create_activation); 528 instructions().append(m_activationRegister->index()); 529 } 530 531 void BytecodeGenerator::initThisParameter() 532 { 533 FunctionBodyNode* node = static_cast<FunctionBodyNode*>(m_scopeNode); 534 535 if (isConstructor()) { 536 prependComment("'this' because we are a Constructor function"); 537 emitOpcode(op_create_this); 538 instructions().append(m_thisRegister.index()); 539 } else if (!m_codeBlock->isStrictMode() && (node->usesThis() || m_codeBlock->usesEval() || m_shouldEmitDebugHooks)) { 540 ValueProfile* profile = emitProfiledOpcode(op_convert_this); 541 instructions().append(m_thisRegister.index()); 542 instructions().append(profile); 543 } 544 } 545 546 void BytecodeGenerator::initFunctionDeclarations() 547 { 548 FunctionBodyNode* node = static_cast<FunctionBodyNode*>(m_scopeNode); 549 550 const DeclarationStacks::FunctionStack& functionStack = node->functionStack(); 551 bool canLazilyCreateFunctions = !node->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks; 552 for (size_t i = 0; i < functionStack.size(); ++i) { 553 FunctionBodyNode* function = functionStack[i].node; 554 const Identifier& ident = function->ident(); 555 RegisterID* reg = ®isterFor(symbolTable().get(ident.impl()).getIndex()); 556 if (node->captures(ident) || ident == propertyNames().arguments || !canLazilyCreateFunctions) 557 emitNewFunction(reg, function); 558 else { 559 emitInitLazyRegister(reg); 560 m_lazyFunctions.set(reg->index(), function); 561 } 341 562 } 342 563 } … … 360 581 , m_nextConstantOffset(0) 361 582 , m_globalConstantIndex(0) 362 , m_hasCreatedActivation(false)363 , m_firstLazyFunction(0)364 , m_lastLazyFunction(0)365 583 , m_globalData(scope->globalData()) 366 584 , m_lastOpcodeID(op_end) … … 377 595 378 596 codeBlock->setGlobalData(m_globalData); 379 380 prependComment("entering Function block"); 597 598 allocateArgumentsVars(); 599 allocateActivationVar(); 600 allocateCalleeVarUndeclared(); 601 allocateCapturedVars(); 602 codeBlock->m_numCapturedVars = codeBlock->m_numVars; 603 allocateUncapturedVars(); 604 if (m_shouldEmitDebugHooks) // FIXME: What about eval? 605 codeBlock->m_numCapturedVars = codeBlock->m_numVars; 606 preserveLastVar(); 607 608 declareParameters(); // Parameters lose to functions 609 declareCallee(); // Callee loses to everything 610 381 611 emitOpcode(op_enter); 382 if (m_codeBlock->needsFullScopeChain()) { 383 m_activationRegister = addVar(); 384 prependComment("activation for Full Scope Chain"); 385 emitInitLazyRegister(m_activationRegister); 386 m_codeBlock->setActivationRegister(m_activationRegister->index()); 387 } 388 389 // Both op_tear_off_activation and op_tear_off_arguments tear off the 'arguments' 390 // object, if created. 391 if (m_codeBlock->needsFullScopeChain() || functionBody->usesArguments()) { 392 RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code. 393 RegisterID* argumentsRegister = addVar(propertyNames().arguments, false); // Can be changed by assigning to 'arguments'. 394 395 // We can save a little space by hard-coding the knowledge that the two 396 // 'arguments' values are stored in consecutive registers, and storing 397 // only the index of the assignable one. 398 codeBlock->setArgumentsRegister(argumentsRegister->index()); 399 ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->index() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister())); 400 401 prependComment("arguments for Full Scope Chain"); 402 emitInitLazyRegister(argumentsRegister); 403 prependComment("unmodified arguments for Full Scope Chain"); 404 emitInitLazyRegister(unmodifiedArgumentsRegister); 405 406 if (m_codeBlock->isStrictMode()) { 407 prependComment("create arguments for strict mode"); 408 emitOpcode(op_create_arguments); 409 instructions().append(argumentsRegister->index()); 410 } 411 412 // The debugger currently retrieves the arguments object from an activation rather than pulling 413 // it from a call frame. In the long-term it should stop doing that (<rdar://problem/6911886>), 414 // but for now we force eager creation of the arguments object when debugging. 415 if (m_shouldEmitDebugHooks) { 416 prependComment("create arguments for debug hooks"); 417 emitOpcode(op_create_arguments); 418 instructions().append(argumentsRegister->index()); 419 } 420 } 421 422 RegisterID* calleeRegister = resolveCallee(functionBody); // May push to the scope chain and/or add a captured var. 423 424 const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack(); 425 const DeclarationStacks::VarStack& varStack = functionBody->varStack(); 426 427 // Captured variables and functions go first so that activations don't have 428 // to step over the non-captured locals to mark them. 429 m_hasCreatedActivation = false; 430 if (functionBody->hasCapturedVariables()) { 431 for (size_t i = 0; i < functionStack.size(); ++i) { 432 FunctionBodyNode* function = functionStack[i]; 433 const Identifier& ident = function->ident(); 434 if (functionBody->captures(ident)) { 435 if (!m_hasCreatedActivation) { 436 m_hasCreatedActivation = true; 437 prependComment("activation for captured vars"); 438 emitOpcode(op_create_activation); 439 instructions().append(m_activationRegister->index()); 440 } 441 m_functions.add(ident.impl()); 442 prependComment("captured function var"); 443 emitNewFunction(addVar(ident, false), function); 444 } 445 } 446 for (size_t i = 0; i < varStack.size(); ++i) { 447 const Identifier& ident = *varStack[i].first; 448 if (functionBody->captures(ident)) 449 addVar(ident, varStack[i].second & DeclarationStacks::IsConstant); 450 } 451 } 452 bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks; 453 if (!canLazilyCreateFunctions && !m_hasCreatedActivation) { 454 m_hasCreatedActivation = true; 455 prependComment("cannot lazily create functions"); 456 emitOpcode(op_create_activation); 457 instructions().append(m_activationRegister->index()); 458 } 459 460 codeBlock->m_numCapturedVars = codeBlock->m_numVars; 461 462 m_firstLazyFunction = codeBlock->m_numVars; 463 for (size_t i = 0; i < functionStack.size(); ++i) { 464 FunctionBodyNode* function = functionStack[i]; 465 const Identifier& ident = function->ident(); 466 if (!functionBody->captures(ident)) { 467 m_functions.add(ident.impl()); 468 RefPtr<RegisterID> reg = addVar(ident, false); 469 // Don't lazily create functions that override the name 'arguments' 470 // as this would complicate lazy instantiation of actual arguments. 471 prependComment("a function that override 'arguments'"); 472 if (!canLazilyCreateFunctions || ident == propertyNames().arguments) 473 emitNewFunction(reg.get(), function); 474 else { 475 emitInitLazyRegister(reg.get()); 476 m_lazyFunctions.set(reg->index(), function); 477 } 478 } 479 } 480 m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction; 481 for (size_t i = 0; i < varStack.size(); ++i) { 482 const Identifier& ident = *varStack[i].first; 483 if (!functionBody->captures(ident)) 484 addVar(ident, varStack[i].second & DeclarationStacks::IsConstant); 485 } 486 487 if (m_shouldEmitDebugHooks) 488 codeBlock->m_numCapturedVars = codeBlock->m_numVars; 489 490 FunctionParameters& parameters = *functionBody->parameters(); 491 m_parameters.grow(parameters.size() + 1); // reserve space for "this" 492 493 // Add "this" as a parameter 494 int nextParameterIndex = CallFrame::thisArgumentOffset(); 495 m_thisRegister.setIndex(nextParameterIndex--); 496 m_codeBlock->addParameter(); 497 498 for (size_t i = 0; i < parameters.size(); ++i) 499 addParameter(parameters[i], nextParameterIndex--); 500 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); 505 506 if (isConstructor()) { 507 prependComment("'this' because we are a Constructor function"); 508 emitOpcode(op_create_this); 509 instructions().append(m_thisRegister.index()); 510 } else if (!codeBlock->isStrictMode() && (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks)) { 511 ValueProfile* profile = emitProfiledOpcode(op_convert_this); 512 instructions().append(m_thisRegister.index()); 513 instructions().append(profile); 514 } 612 initArgumentsVars(); 613 initActivationVar(); 614 initCalleeVar(); 615 initThisParameter(); 616 initFunctionDeclarations(); 515 617 } 516 618 … … 533 635 , m_nextConstantOffset(0) 534 636 , m_globalConstantIndex(0) 535 , m_hasCreatedActivation(true)536 , m_firstLazyFunction(0)537 , m_lastLazyFunction(0)538 637 , m_globalData(scope->globalData()) 539 638 , m_lastOpcodeID(op_end) … … 556 655 const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack(); 557 656 for (size_t i = 0; i < functionStack.size(); ++i) 558 m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, functionStack[i] ));657 m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, functionStack[i].node)); 559 658 560 659 const DeclarationStacks::VarStack& varStack = evalNode->varStack(); … … 563 662 variables.reserveCapacity(numVariables); 564 663 for (size_t i = 0; i < numVariables; ++i) 565 variables.append(*varStack[i]. first);664 variables.append(*varStack[i].name); 566 665 codeBlock->adoptVariables(variables); 567 666 codeBlock->m_numCapturedVars = codeBlock->m_numVars; … … 581 680 } 582 681 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)); 628 } 629 630 void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex) 682 void BytecodeGenerator::declareParameter(const Identifier& ident, int parameterIndex) 631 683 { 632 684 // Parameters overwrite var declarations, but not function declarations. … … 672 724 RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg) 673 725 { 674 if (m_lastLazyFunction <= reg->index() || reg->index() < m_firstLazyFunction) 726 FunctionBodyNode* node = m_lazyFunctions.get(reg->index()); 727 if (!node) 675 728 return reg; 676 emitLazyNewFunction(reg, m_lazyFunctions.get(reg->index())); 729 730 emitLazyNewFunction(reg, node); 677 731 return reg; 678 732 } … … 1950 2004 void BytecodeGenerator::createActivationIfNecessary() 1951 2005 { 1952 if (m_hasCreatedActivation) 1953 return; 1954 if (!m_codeBlock->needsFullScopeChain()) 2006 if (!m_codeBlock->needsFullScopeChain() || m_codeType != FunctionCode) 1955 2007 return; 1956 2008 emitOpcode(op_create_activation); -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r127810 r127939 615 615 enum ConstantMode { IsConstant, IsVariable }; 616 616 enum FunctionMode { IsFunctionToSpecialize, NotFunctionOrNotSpecializable }; 617 enum VarType { Captured, NotCaptured }; 617 618 int addGlobalVar(const Identifier&, ConstantMode, FunctionMode); 618 619 void addParameter(const Identifier&, int parameterIndex); 620 RegisterID* resolveCallee(FunctionBodyNode*); 621 void addCallee(FunctionBodyNode*, RegisterID*); 619 void declareParameter(const Identifier&, int parameterIndex); 620 621 void allocateCapturedVars(); 622 void allocateUncapturedVars(); 623 void allocateActivationVar(); 624 void allocateArgumentsVars(); 625 void allocateCalleeVarUndeclared(); 626 void declareParameters(); 627 void declareCallee(); 628 void initCalleeVar(); 629 void initArgumentsVars(); 630 void initActivationVar(); 631 void initThisParameter(); 632 void initFunctionDeclarations(); 622 633 623 634 void preserveLastVar(); … … 739 750 int m_globalVarStorageOffset; 740 751 741 bool m_hasCreatedActivation;742 int m_firstLazyFunction;743 int m_lastLazyFunction;744 752 HashMap<unsigned int, FunctionBodyNode*, WTF::IntHash<unsigned int>, WTF::UnsignedWithZeroKeyHashTraits<unsigned int> > m_lazyFunctions; 745 753 typedef HashMap<FunctionBodyNode*, unsigned> FunctionOffsetMap; -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r127654 r127939 315 315 if (*name == m_globalData->propertyNames->arguments) 316 316 usesArguments(); 317 m_scope.m_funcDeclarations->data.append( decl->body());317 m_scope.m_funcDeclarations->data.append(DeclarationStacks::FunctionDeclaration(decl->body())); 318 318 body->setLoc(bodyStartLine, bodyEndLine, location.column); 319 319 return decl; … … 509 509 if (m_globalData->propertyNames->arguments == *ident) 510 510 usesArguments(); 511 m_scope.m_varDeclarations->data.append( std::make_pair(ident, attrs));511 m_scope.m_varDeclarations->data.append(DeclarationStacks::VarDeclaration(ident, attrs)); 512 512 } 513 513 -
trunk/Source/JavaScriptCore/parser/Nodes.h
r127810 r127939 86 86 87 87 namespace DeclarationStacks { 88 struct VarDeclaration { 89 VarDeclaration(const Identifier* name, unsigned attributes) 90 : name(name) 91 , attributes(attributes) 92 , reg(0) 93 { 94 } 95 const Identifier* name; 96 unsigned attributes; 97 RegisterID* reg; 98 }; 99 struct FunctionDeclaration { 100 explicit FunctionDeclaration(FunctionBodyNode* node) 101 : node(node) 102 , reg(0) 103 { 104 } 105 FunctionBodyNode* node; 106 RegisterID* reg; 107 }; 88 108 enum VarAttrs { IsConstant = 1, HasInitializer = 2 }; 89 typedef Vector< std::pair<const Identifier*, unsigned>> VarStack;90 typedef Vector<Function BodyNode*> FunctionStack;109 typedef Vector<VarDeclaration> VarStack; 110 typedef Vector<FunctionDeclaration> FunctionStack; 91 111 } 92 112
Note:
See TracChangeset
for help on using the changeset viewer.