Changeset 127987 in webkit
- Timestamp:
- Sep 9, 2012 10:10:21 AM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r127970 r127987 1 2012-09-09 Geoffrey Garen <ggaren@apple.com> 2 3 Rolled out <http://trac.webkit.org/changeset/127939> because it broke 4 fast/js/named-function-expression.html. 5 6 Refactored bytecode generator initialization to support moving captured vars around 7 https://bugs.webkit.org/show_bug.cgi?id=96159 8 9 Reviewed by Gavin Barraclough. 10 1 11 2012-09-08 Csaba Osztrogonác <ossy@webkit.org> 2 12 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r127958 r127987 279 279 , m_nextConstantOffset(0) 280 280 , m_globalConstantIndex(0) 281 , m_hasCreatedActivation(true) 282 , m_firstLazyFunction(0) 283 , m_lastLazyFunction(0) 281 284 , m_globalData(scope->globalData()) 282 285 , m_lastOpcodeID(op_end) … … 318 321 319 322 for (size_t i = 0; i < functionStack.size(); ++i) { 320 FunctionBodyNode* function = functionStack[i] .node;323 FunctionBodyNode* function = functionStack[i]; 321 324 bool propertyDidExist = 322 325 globalObject->removeDirect(*m_globalData, function->ident()); // Newly declared functions overwrite existing properties. … … 330 333 331 334 for (size_t i = 0; i < varStack.size(); ++i) { 332 if (globalObject->hasProperty(exec, *varStack[i]. name))335 if (globalObject->hasProperty(exec, *varStack[i].first)) 333 336 continue; 334 337 addGlobalVar( 335 *varStack[i]. name,336 (varStack[i]. attributes& DeclarationStacks::IsConstant) ? IsConstant : IsVariable,338 *varStack[i].first, 339 (varStack[i].second & DeclarationStacks::IsConstant) ? IsConstant : IsVariable, 337 340 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 two405 // 'arguments' values are stored in consecutive registers, and storing406 // 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 parameter437 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 }562 341 } 563 342 } … … 581 360 , m_nextConstantOffset(0) 582 361 , m_globalConstantIndex(0) 362 , m_hasCreatedActivation(false) 363 , m_firstLazyFunction(0) 364 , m_lastLazyFunction(0) 583 365 , m_globalData(scope->globalData()) 584 366 , m_lastOpcodeID(op_end) … … 595 377 596 378 codeBlock->setGlobalData(m_globalData); 597 598 allocateArgumentsVars(); 599 allocateActivationVar(); 600 allocateCalleeVarUndeclared(); 601 allocateCapturedVars(); 379 380 prependComment("entering Function block"); 381 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 602 460 codeBlock->m_numCapturedVars = codeBlock->m_numVars; 603 allocateUncapturedVars(); 604 if (m_shouldEmitDebugHooks) // FIXME: What about eval? 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) 605 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 606 501 preserveLastVar(); 607 502 608 declareParameters(); // Parameters lose to functions 609 declareCallee(); // Callee loses to everything 610 611 emitOpcode(op_enter); 612 initArgumentsVars(); 613 initActivationVar(); 614 initCalleeVar(); 615 initThisParameter(); 616 initFunctionDeclarations(); 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 } 617 515 } 618 516 … … 635 533 , m_nextConstantOffset(0) 636 534 , m_globalConstantIndex(0) 535 , m_hasCreatedActivation(true) 536 , m_firstLazyFunction(0) 537 , m_lastLazyFunction(0) 637 538 , m_globalData(scope->globalData()) 638 539 , m_lastOpcodeID(op_end) … … 655 556 const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack(); 656 557 for (size_t i = 0; i < functionStack.size(); ++i) 657 m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, functionStack[i] .node));558 m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, functionStack[i])); 658 559 659 560 const DeclarationStacks::VarStack& varStack = evalNode->varStack(); … … 662 563 variables.reserveCapacity(numVariables); 663 564 for (size_t i = 0; i < numVariables; ++i) 664 variables.append(*varStack[i]. name);565 variables.append(*varStack[i].first); 665 566 codeBlock->adoptVariables(variables); 666 567 codeBlock->m_numCapturedVars = codeBlock->m_numVars; … … 680 581 } 681 582 682 void BytecodeGenerator::declareParameter(const Identifier& ident, int parameterIndex) 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) 683 631 { 684 632 // Parameters overwrite var declarations, but not function declarations. … … 724 672 RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg) 725 673 { 726 FunctionBodyNode* node = m_lazyFunctions.get(reg->index()); 727 if (!node) 674 if (m_lastLazyFunction <= reg->index() || reg->index() < m_firstLazyFunction) 728 675 return reg; 729 730 emitLazyNewFunction(reg, node); 676 emitLazyNewFunction(reg, m_lazyFunctions.get(reg->index())); 731 677 return reg; 732 678 } … … 2004 1950 void BytecodeGenerator::createActivationIfNecessary() 2005 1951 { 2006 if (!m_codeBlock->needsFullScopeChain() || m_codeType != FunctionCode) 1952 if (m_hasCreatedActivation) 1953 return; 1954 if (!m_codeBlock->needsFullScopeChain()) 2007 1955 return; 2008 1956 emitOpcode(op_create_activation); -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r127939 r127987 615 615 enum ConstantMode { IsConstant, IsVariable }; 616 616 enum FunctionMode { IsFunctionToSpecialize, NotFunctionOrNotSpecializable }; 617 enum VarType { Captured, NotCaptured };618 617 int addGlobalVar(const Identifier&, ConstantMode, FunctionMode); 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(); 618 619 void addParameter(const Identifier&, int parameterIndex); 620 RegisterID* resolveCallee(FunctionBodyNode*); 621 void addCallee(FunctionBodyNode*, RegisterID*); 633 622 634 623 void preserveLastVar(); … … 750 739 int m_globalVarStorageOffset; 751 740 741 bool m_hasCreatedActivation; 742 int m_firstLazyFunction; 743 int m_lastLazyFunction; 752 744 HashMap<unsigned int, FunctionBodyNode*, WTF::IntHash<unsigned int>, WTF::UnsignedWithZeroKeyHashTraits<unsigned int> > m_lazyFunctions; 753 745 typedef HashMap<FunctionBodyNode*, unsigned> FunctionOffsetMap; -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r127958 r127987 315 315 if (*name == m_globalData->propertyNames->arguments) 316 316 usesArguments(); 317 m_scope.m_funcDeclarations->data.append( DeclarationStacks::FunctionDeclaration(decl->body()));317 m_scope.m_funcDeclarations->data.append(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( DeclarationStacks::VarDeclaration(ident, attrs));511 m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs)); 512 512 } 513 513 -
trunk/Source/JavaScriptCore/parser/Nodes.h
r127939 r127987 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 };108 88 enum VarAttrs { IsConstant = 1, HasInitializer = 2 }; 109 typedef Vector< VarDeclaration> VarStack;110 typedef Vector<Function Declaration> FunctionStack;89 typedef Vector<std::pair<const Identifier*, unsigned> > VarStack; 90 typedef Vector<FunctionBodyNode*> FunctionStack; 111 91 } 112 92
Note: See TracChangeset
for help on using the changeset viewer.