X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/14ec9e00ac4903521e92002604eb56ed7cde036d..6a9812501258df26b7c487e50744b91abe8ebe39:/Replace.cpp diff --git a/Replace.cpp b/Replace.cpp index e376922..45be919 100644 --- a/Replace.cpp +++ b/Replace.cpp @@ -38,12 +38,10 @@ /* }}} */ #include "Parser.hpp" -#include "Context.hpp" +#include "Replace.hpp" #include <iomanip> -#include "Replace.hpp" - CYExpression *CYAdd::Replace(CYContext &context) { CYInfix::Replace(context); @@ -180,9 +178,9 @@ CYExpression *CYDeclaration::ForEachIn(CYContext &context) { } CYExpression *CYDeclaration::Replace(CYContext &context) { - CYIdentifier *identifier(identifier_->Replace(context)); - context.scope_->internal_.insert(CYIdentifierAddressFlagsMap::value_type(identifier, CYIdentifierVariable)); - return $ CYVariable(identifier); + context.Replace(identifier_); + context.scope_->Declare(context, identifier_, CYIdentifierVariable); + return $ CYVariable(identifier_); } CYProperty *CYDeclarations::Property(CYContext &context) { $T(NULL) @@ -332,8 +330,8 @@ CYStatement *CYForEachInComprehension::Replace(CYContext &context, CYStatement * } void CYFunction::Inject(CYContext &context) { - name_ = name_->Replace(context); - context.scope_->internal_.insert(CYIdentifierAddressFlagsMap::value_type(name_, CYIdentifierOther)); + context.Replace(name_); + context.scope_->Declare(context, name_, CYIdentifierOther); } void CYFunction::Replace_(CYContext &context, bool outer) { @@ -360,7 +358,7 @@ CYExpression *CYFunctionExpression::Replace(CYContext &context) { void CYFunctionParameter::Replace(CYContext &context) { $T() name_ = name_->Replace(context); - context.scope_->internal_.insert(CYIdentifierAddressFlagsMap::value_type(name_, CYIdentifierArgument)); + context.scope_->Declare(context, name_, CYIdentifierArgument); next_->Replace(context); } @@ -370,16 +368,9 @@ CYStatement *CYFunctionStatement::Replace(CYContext &context) { } CYIdentifier *CYIdentifier::Replace(CYContext &context) { - if (replace_ != NULL) - return replace_; - - CYIdentifierValueSet &identifiers(context.scope_->identifiers_); - std::pair<CYIdentifierValueSet::iterator, bool> insert(identifiers.insert(this)); - if (!insert.second) - return *insert.first; - - replace_ = this; - return this; + if (replace_ == NULL) + replace_ = context.scope_->Lookup(context, this); + return replace_; } CYStatement *CYIf::Replace(CYContext &context) { @@ -475,11 +466,15 @@ void CYProgram::Replace(CYContext &context) { statements_ = statements_->ReplaceAll(context); context.scope_ = parent_; - Scope(context, statements_); context.program_ = program; + Scope(context, statements_); size_t offset(0); + CYCStringSet external; + for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i) + external.insert((*i)->Word()); + // XXX: totalling the probable occurrences and sorting by them would improve the result for (CYIdentifierAddressVector::const_iterator i(rename_.begin()); i != rename_.end(); ++i, ++offset) { const char *name; @@ -499,7 +494,7 @@ void CYProgram::Replace(CYContext &context) { id[--position] = index == 0 ? '0' : index < 27 ? index - 1 + 'a' : index - 27 + 'A'; } while (local != 0); - if (external_.find(id + position) != external_.end()) { + if (external.find(id + position) != external.end()) { ++offset; goto id; } @@ -523,34 +518,35 @@ CYStatement *CYReturn::Replace(CYContext &context) { return this; } -void CYScope::Add(CYContext &context, CYIdentifierAddressVector &external) { - for (CYIdentifierAddressVector::const_iterator i(external.begin()); i != external.end(); ++i) { - std::pair<CYIdentifierAddressSet::iterator, bool> insert(identifiers_.insert(*i)); - if (!insert.second) - (*i)->replace_ = *insert.first; - } +void CYScope::Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags) { + internal_.insert(CYIdentifierAddressFlagsMap::value_type(identifier, flags)); } -void CYScope::Scope(CYContext &context, CYStatement *&statements) { - CYIdentifierAddressVector external; +CYIdentifier *CYScope::Lookup(CYContext &context, CYIdentifier *identifier) { + std::pair<CYIdentifierValueSet::iterator, bool> insert(identifiers_.insert(identifier)); + return *insert.first; +} - for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i) - if (internal_.find(*i) == internal_.end()) - external.push_back(*i); +void CYScope::Merge(CYContext &context, CYIdentifier *identifier) { + std::pair<CYIdentifierAddressSet::iterator, bool> insert(identifiers_.insert(identifier)); + if (!insert.second) { + if ((*insert.first)->offset_ < identifier->offset_) + (*insert.first)->offset_ = identifier->offset_; + identifier->replace_ = *insert.first; + } +} +void CYScope::Scope(CYContext &context, CYStatement *&statements) { CYDeclarations *last(NULL), *curr(NULL); CYProgram *program(context.program_); + typedef std::multimap<size_t, CYIdentifier *> IdentifierOffsetMap; + IdentifierOffsetMap offsetted; + // XXX: we don't want to do this in order, we want to sort it by probable occurrence for (CYIdentifierAddressFlagsMap::const_iterator i(internal_.begin()); i != internal_.end(); ++i) { - if (program != NULL && i->second != CYIdentifierMagic) { - if (program->rename_.size() <= offset_) - program->rename_.resize(offset_ + 1); - CYIdentifier *&identifier(program->rename_[offset_++]); - i->first->SetNext(identifier); - identifier = i->first; - } - + if (program != NULL && i->second != CYIdentifierMagic) + offsetted.insert(IdentifierOffsetMap::value_type(i->first->offset_, i->first)); if (i->second == CYIdentifierVariable) { CYDeclarations *next($ CYDeclarations($ CYDeclaration(i->first))); if (last == NULL) @@ -561,19 +557,30 @@ void CYScope::Scope(CYContext &context, CYStatement *&statements) { } } + size_t offset(0); + + for (IdentifierOffsetMap::const_iterator i(offsetted.begin()); i != offsetted.end(); ++i) { + if (offset < i->first) + offset = i->first; + if (program->rename_.size() <= offset) + program->rename_.resize(offset + 1); + CYIdentifier *&identifier(program->rename_[offset++]); + i->second->SetNext(identifier); + identifier = i->second; + } + if (last != NULL) { CYVar *var($ CYVar(last)); var->SetNext(statements); statements = var; } - if (parent_ != NULL) { - if (parent_->offset_ < offset_) - parent_->offset_ = offset_; - parent_->Add(context, external); - } else if (program != NULL) - for (CYIdentifierAddressVector::const_iterator i(external.begin()); i != external.end(); ++i) - program->external_.insert((*i)->Word()); + for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i) + if (internal_.find(*i) == internal_.end()) { + if ((*i)->offset_ < offset) + (*i)->offset_ = offset; + parent_->Merge(context, *i); + } } CYStatement *CYStatement::Collapse(CYContext &context) {