Пример #1
0
  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);
    }
  }
Пример #2
0
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;
}