void execute() { std::sort(m_rootEntries.begin(), m_rootEntries.end(), reCmp); for (int i = 0; i < m_size; i++) { RootEntry &re = m_rootEntries[i]; if (!re.second) break; const AstWalkerState &s = re.first[re.first.size() - 1]; StatementPtr sp(dynamic_pointer_cast<Statement>(s.cp)); assert(sp); StatementListPtr sl; int ix; if (sp->is(Statement::KindOfStatementList)) { sl = static_pointer_cast<StatementList>(sp); ix = (s.index - 1) / 2; } else { assert(sp->is(Statement::KindOfBlockStatement)); sl = static_pointer_cast<BlockStatement>(sp)->getStmts(); if (!sl) continue; ix = 0; } ExpressionPtr e = m_dict.get(re.second); assert(e && e->is(Expression::KindOfSimpleVariable)); SimpleVariablePtr sv(static_pointer_cast<SimpleVariable>(e)); Symbol *sym = sv->getSymbol(); bool inGen = sv->getFunctionScope()->isGenerator(); if (!sym || sym->isGlobal() || sym->isStatic() || sym->isParameter() || sym->isClosureVar() || sv->isThis() || inGen) { continue; } sym->setShrinkWrapped(); e = e->clone(); e->clearContext(); e->recomputeEffects(); e->setContext(Expression::Declaration); StatementPtr sub = (*sl)[ix]; e->setLocation(sub->getLocation()); e->setBlockScope(sub->getScope()); ExpStatementPtr exp( new ExpStatement(sub->getScope(), sub->getLocation(), e)); sl->insertElement(exp, ix); } }
static ExpressionPtr cloneForInlineRecur(InlineCloneInfo &info, ExpressionPtr exp, const std::string &prefix, AnalysisResultConstPtr ar, FunctionScopePtr scope) { exp->getOriginalScope(); // make sure to cache the original scope exp->setBlockScope(scope); for (int i = 0, n = exp->getKidCount(); i < n; i++) { if (ExpressionPtr k = exp->getNthExpr(i)) { exp->setNthKid(i, cloneForInlineRecur(info, k, prefix, ar, scope)); } } StaticClassName *scn = dynamic_cast<StaticClassName*>(exp.get()); if (scn && scn->isStatic() && !info.staticClass.empty()) { scn->resolveStatic(info.staticClass); } switch (exp->getKindOf()) { case Expression::KindOfSimpleVariable: { SimpleVariablePtr sv(dynamic_pointer_cast<SimpleVariable>(exp)); if (sv->isSuperGlobal()) break; string name; if (sv->isThis()) { if (!info.callWithThis) { if (!sv->hasContext(Expression::ObjectContext)) { exp = sv->makeConstant(ar, "null"); } else { // This will produce the wrong error // we really want a "throw_fatal" ast node. exp = sv->makeConstant(ar, "null"); } break; } if (info.localThis.empty()) break; name = info.localThis; } else { name = prefix + sv->getName(); } SimpleVariablePtr rep(new SimpleVariable( exp->getScope(), exp->getLocation(), name)); rep->copyContext(sv); rep->updateSymbol(SimpleVariablePtr()); rep->getSymbol()->setHidden(); // Conservatively set flags to prevent // the alias manager from getting confused. // On the next pass, it will correct the values, // and optimize appropriately. rep->getSymbol()->setUsed(); rep->getSymbol()->setReferenced(); if (exp->getContext() & (Expression::LValue| Expression::RefValue| Expression::RefParameter)) { info.sepm[name] = rep; } exp = rep; } break; case Expression::KindOfObjectMethodExpression: { FunctionCallPtr call( static_pointer_cast<FunctionCall>(exp)); if (call->getFuncScope() == info.func) { call->setNoInline(); } break; } case Expression::KindOfSimpleFunctionCall: { SimpleFunctionCallPtr call(static_pointer_cast<SimpleFunctionCall>(exp)); call->addLateDependencies(ar); call->setLocalThis(info.localThis); if (call->getFuncScope() == info.func) { call->setNoInline(); } } default: break; } return exp; }