static ExpressionPtr cloneForInline(InlineCloneInfo &info, ExpressionPtr exp, const std::string &prefix, AnalysisResultConstPtr ar, FunctionScopePtr scope) { return cloneForInlineRecur(info, exp->clone(), prefix, ar, scope); }
ExpressionPtr AssignmentExpression::preOptimize(AnalysisResultConstPtr ar) { if (m_variable->getContainedEffects() & ~(CreateEffect|AccessorEffect)) { return ExpressionPtr(); } ExpressionPtr val = m_value; while (val) { if (val->is(KindOfExpressionList)) { val = static_pointer_cast<ExpressionList>(val)->listValue(); continue; } if (val->is(KindOfAssignmentExpression)) { val = static_pointer_cast<AssignmentExpression>(val)->m_value; continue; } break; } if (val && val->isScalar()) { if (val != m_value) { ExpressionListPtr rep(new ExpressionList( getScope(), getRange(), ExpressionList::ListKindWrapped)); rep->addElement(m_value); m_value = val->clone(); rep->addElement(static_pointer_cast<Expression>(shared_from_this())); return replaceValue(rep); } } return ExpressionPtr(); }
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); } }
ExpressionPtr AssignmentExpression::preOptimize(AnalysisResultConstPtr ar) { if (Option::EliminateDeadCode && ar->getPhase() >= AnalysisResult::FirstPreOptimize) { // otherwise used & needed flags may not be up to date yet ExpressionPtr rep = optimize(ar); if (rep) return rep; } if (m_variable->getContainedEffects() & ~(CreateEffect|AccessorEffect)) { return ExpressionPtr(); } ExpressionPtr val = m_value; while (val) { if (val->is(KindOfExpressionList)) { ExpressionListPtr el(static_pointer_cast<ExpressionList>(val)); val = el->listValue(); continue; } if (val->is(KindOfAssignmentExpression)) { val = static_pointer_cast<AssignmentExpression>(val)->m_value; continue; } break; } if (val && val->isScalar()) { if (val != m_value) { ExpressionListPtr rep(new ExpressionList( getScope(), getLocation(), KindOfExpressionList, ExpressionList::ListKindWrapped)); rep->addElement(m_value); m_value = val->clone(); rep->addElement(static_pointer_cast<Expression>(shared_from_this())); return replaceValue(rep); } if (!m_ref && m_variable->is(KindOfArrayElementExpression)) { ArrayElementExpressionPtr ae( static_pointer_cast<ArrayElementExpression>(m_variable)); ExpressionPtr avar(ae->getVariable()); ExpressionPtr aoff(ae->getOffset()); if (!aoff || aoff->isScalar()) { avar = avar->getCanonLVal(); while (avar) { if (avar->isScalar()) { Variant v,o,r; if (!avar->getScalarValue(v)) break; if (!val->getScalarValue(r)) break; try { g_context->setThrowAllErrors(true); if (aoff) { if (!aoff->getScalarValue(o)) break; v.set(o, r); } else { v.append(r); } g_context->setThrowAllErrors(false); } catch (...) { break; } ExpressionPtr rep( new AssignmentExpression( getScope(), getLocation(), KindOfAssignmentExpression, m_variable->replaceValue(Clone(ae->getVariable())), makeScalarExpression(ar, v), false)); if (!isUnused()) { ExpressionListPtr el( new ExpressionList( getScope(), getLocation(), KindOfExpressionList, ExpressionList::ListKindWrapped)); el->addElement(rep); el->addElement(val); rep = el; } return replaceValue(rep); } avar = avar->getCanonPtr(); } g_context->setThrowAllErrors(false); } } } return ExpressionPtr(); }
ExpressionPtr AliasManager::canonicalizeNode(ExpressionPtr e) { e->setCanonPtr(ExpressionPtr()); e->setCanonID(0); switch (e->getKindOf()) { case Expression::KindOfObjectMethodExpression: case Expression::KindOfDynamicFunctionCall: case Expression::KindOfSimpleFunctionCall: case Expression::KindOfNewObjectExpression: add(m_bucketMap[0], e); break; case Expression::KindOfListAssignment: add(m_bucketMap[0], e); break; case Expression::KindOfAssignmentExpression: { AssignmentExpressionPtr ae = spc(AssignmentExpression,e); if (e->getContext() & Expression::DeadStore) { Construct::recomputeEffects(); return ae->getValue(); } ExpressionPtr rep; int interf = findInterf(ae->getVariable(), false, rep); if (interf == SameAccess) { switch (rep->getKindOf()) { default: break; case Expression::KindOfAssignmentExpression: { AssignmentExpressionPtr a = spc(AssignmentExpression, rep); ExpressionPtr value = a->getValue(); if (a->getValue()->getContext() & Expression::RefValue) { break; } } case Expression::KindOfUnaryOpExpression: case Expression::KindOfBinaryOpExpression: rep->setContext(Expression::DeadStore); break; } } add(m_bucketMap[0], e); break; } case Expression::KindOfConstantExpression: case Expression::KindOfSimpleVariable: case Expression::KindOfDynamicVariable: case Expression::KindOfArrayElementExpression: case Expression::KindOfObjectPropertyExpression: case Expression::KindOfStaticMemberExpression: if (!(e->getContext() & (Expression::AssignmentLHS| Expression::DeepAssignmentLHS| Expression::OprLValue))) { if (!(e->getContext() & (Expression::LValue| Expression::RefValue| Expression::RefParameter| Expression::UnsetContext))) { ExpressionPtr rep; int interf = findInterf(e, true, rep); if (interf == SameAccess) { if (rep->getKindOf() == e->getKindOf()) { e->setCanonID(rep->getCanonID()); e->setCanonPtr(rep); return ExpressionPtr(); } if (rep->getKindOf() == Expression::KindOfAssignmentExpression) { ExpressionPtr rhs = spc(AssignmentExpression,rep)->getValue(); if (rhs->is(Expression::KindOfScalarExpression)) { rhs = rhs->clone(); getCanonical(rhs); return rhs; } e->setCanonPtr(rhs); } } } add(m_bucketMap[0], e); } else { getCanonical(e); } break; case Expression::KindOfBinaryOpExpression: { BinaryOpExpressionPtr bop = spc(BinaryOpExpression, e); int rop = getOpForAssignmentOp(bop->getOp()); if (rop) { ExpressionPtr lhs = bop->getExp1(); ExpressionPtr rep; if (bop->getContext() & Expression::DeadStore) { Construct::recomputeEffects(); ExpressionPtr rhs = bop->getExp2()->clone(); lhs = lhs->clone(); lhs->clearContext(Expression::LValue); lhs->clearContext(Expression::NoLValueWrapper); lhs->clearContext(Expression::OprLValue); rep = ExpressionPtr (new BinaryOpExpression(e->getLocation(), Expression::KindOfBinaryOpExpression, lhs, rhs, rop)); } else { ExpressionPtr alt; int interf = findInterf(lhs, true, alt); if (interf == SameAccess && alt->is(Expression::KindOfAssignmentExpression)) { ExpressionPtr op0 = spc(AssignmentExpression,alt)->getValue(); if (op0->is(Expression::KindOfScalarExpression)) { ExpressionPtr op1 = bop->getExp2(); ExpressionPtr rhs (new BinaryOpExpression(e->getLocation(), Expression::KindOfBinaryOpExpression, op0->clone(), op1->clone(), rop)); lhs = lhs->clone(); lhs->clearContext(Expression::OprLValue); rep = ExpressionPtr (new AssignmentExpression(e->getLocation(), Expression::KindOfAssignmentExpression, lhs, rhs, false)); } } } if (rep) { ExpressionPtr c = canonicalizeRecur(rep); return c ? c : rep; } add(m_bucketMap[0], e); } else { getCanonical(e); } break; } case Expression::KindOfUnaryOpExpression: { UnaryOpExpressionPtr uop = spc(UnaryOpExpression, e); switch (uop->getOp()) { case T_INC: case T_DEC: if (uop->getContext() & Expression::DeadStore) { Construct::recomputeEffects(); ExpressionPtr val = uop->getExpression()->clone(); val->clearContext(Expression::LValue); val->clearContext(Expression::NoLValueWrapper); val->clearContext(Expression::OprLValue); if (uop->getFront()) { ExpressionPtr inc (new ScalarExpression(uop->getLocation(), Expression::KindOfScalarExpression, T_LNUMBER, string("1"))); val = ExpressionPtr (new BinaryOpExpression(uop->getLocation(), Expression::KindOfBinaryOpExpression, val, inc, uop->getOp() == T_INC ? '+' : '-')); } ExpressionPtr r = canonicalizeRecur(val); return r ? r : val; } add(m_bucketMap[0], e); break; default: getCanonical(e); break; } break; } default: getCanonical(e); break; } return ExpressionPtr(); }