X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/37954781d9756ece500551055562183a1e28e943..fe123f47092fe716bf5111ca57b2670932c10d6d:/Parser.hpp diff --git a/Parser.hpp b/Parser.hpp index 30fa1ea..f48e81b 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -1,4 +1,4 @@ -/* Cycript - Remote Execution Server and Disassembler +/* Cycript - Inlining/Optimizing JavaScript Compiler * Copyright (C) 2009 Jay Freeman (saurik) */ @@ -47,11 +47,17 @@ #include #include +#include +#include +#include #include #include "location.hh" #include "Pooling.hpp" +#include "Options.hpp" + +class CYContext; template struct CYNext { @@ -73,13 +79,18 @@ struct CYNext { }; struct CYThing { + virtual ~CYThing() { + } + virtual void Output(struct CYOutput &out) const = 0; }; struct CYOutput { std::ostream &out_; + CYOptions &options_; bool pretty_; unsigned indent_; + bool right_; enum { NoMode, @@ -89,10 +100,12 @@ struct CYOutput { Terminated } mode_; - CYOutput(std::ostream &out) : + CYOutput(std::ostream &out, CYOptions &options) : out_(out), + options_(options), pretty_(false), indent_(0), + right_(false), mode_(NoMode) { } @@ -117,6 +130,9 @@ struct CYOutput { struct CYPropertyName { virtual void PropertyName(CYOutput &out) const = 0; + + virtual ~CYPropertyName() { + } }; struct CYExpression; @@ -135,32 +151,21 @@ enum CYFlags { CYNoCall = (1 << 3), CYNoRightHand = (1 << 4), CYNoDangle = (1 << 5), + CYNoInteger = (1 << 6), CYNoBF = (CYNoBrace | CYNoFunction), }; -struct CYContext { - apr_pool_t *pool_; - - CYContext(apr_pool_t *pool) : - pool_(pool) - { - } - - template - void Replace(Type_ *&value) { - if (value != NULL) - while (Type_ *replace = value->Replace(*this)) - value = replace; - } -}; - struct CYStatement : CYNext { + virtual ~CYStatement() { + } + void Single(CYOutput &out, CYFlags flags) const; void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const; CYStatement *ReplaceAll(CYContext &context); + virtual CYStatement *Collapse(CYContext &context); virtual CYStatement *Replace(CYContext &context) = 0; @@ -198,6 +203,9 @@ struct CYStatements { }; struct CYClassName { + virtual ~CYClassName() { + } + virtual CYExpression *ClassName(CYContext &context, bool object) = 0; virtual void ClassName(CYOutput &out, bool object) const = 0; }; @@ -214,10 +222,11 @@ struct CYWord : { } - const char *Value() const { - return word_; + void Set(const char *value) { + word_ = value; } + virtual const char *Word() const; virtual void Output(CYOutput &out) const; virtual CYExpression *ClassName(CYContext &context, bool object); @@ -226,16 +235,42 @@ struct CYWord : }; _finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) { - return lhs << rhs.Value(); + lhs << &rhs << '='; + return lhs << rhs.Word(); } struct CYIdentifier : + CYNext, CYWord { + CYIdentifier *replace_; + size_t offset_; + size_t usage_; + CYIdentifier(const char *word) : - CYWord(word) + CYWord(word), + replace_(NULL), + offset_(0), + usage_(0) + { + } + + virtual const char *Word() const; + CYIdentifier *Replace(CYContext &context); +}; + +struct CYComment : + CYStatement +{ + const char *value_; + + CYComment(const char *value) : + value_(value) { } + + virtual CYStatement *Replace(CYContext &context); + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYLabel : @@ -254,6 +289,60 @@ struct CYLabel : virtual void Output(CYOutput &out, CYFlags flags) const; }; +struct CYCStringLess : + std::binary_function +{ + _finline bool operator ()(const char *lhs, const char *rhs) const { + return strcmp(lhs, rhs) < 0; + } +}; + +struct CYIdentifierValueLess : + std::binary_function +{ + _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const { + return CYCStringLess()(lhs->Word(), rhs->Word()); + } +}; + +enum CYIdentifierFlags { + CYIdentifierArgument, + CYIdentifierVariable, + CYIdentifierOther, + CYIdentifierMagic, +}; + +typedef std::set CYCStringSet; +typedef std::set CYIdentifierValueSet; +typedef std::map CYIdentifierAddressFlagsMap; + +struct CYIdentifierUsage { + CYIdentifier *identifier_; + size_t usage_; +}; + +typedef std::vector CYIdentifierUsageVector; + +struct CYScope { + CYScope *parent_; + + CYIdentifierAddressFlagsMap internal_; + CYIdentifierValueSet identifiers_; + + CYScope() : + parent_(NULL) + { + } + + virtual ~CYScope() { + } + + void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags); + virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier); + void Merge(CYContext &context, CYIdentifier *identifier); + void Scope(CYContext &context, CYStatement *&statements); +}; + struct CYProgram : CYThing { @@ -265,10 +354,38 @@ struct CYProgram : } virtual void Replace(CYContext &context); - virtual void Output(CYOutput &out) const; }; +struct CYContext { + apr_pool_t *pool_; + CYOptions &options_; + CYScope *scope_; + CYIdentifierUsageVector rename_; + + CYContext(apr_pool_t *pool, CYOptions &options) : + pool_(pool), + options_(options), + scope_(NULL) + { + } + + virtual ~CYContext() { + } + + template + void Replace(Type_ *&value) { + for (;;) if (value == NULL) + break; + else { + Type_ *replace(value->Replace(*this)); + if (replace != value) + value = replace; + else break; + } + } +}; + struct CYBlock : CYStatement, CYThing @@ -284,6 +401,14 @@ struct CYBlock : return statements_; } + void AddPrev(CYStatement *statement) { + CYStatement *last(statement); + while (last->next_ != NULL) + last = last->next_; + last->SetNext(statements_); + statements_ = statement; + } + virtual CYStatement *Replace(CYContext &context); virtual void Output(CYOutput &out) const; @@ -346,13 +471,21 @@ class CYDriver { }; struct CYForInitialiser { + virtual ~CYForInitialiser() { + } + virtual void For(CYOutput &out) const = 0; + virtual CYExpression *Replace(CYContext &context) = 0; }; struct CYForInInitialiser { + virtual ~CYForInInitialiser() { + } + virtual void ForIn(CYOutput &out, CYFlags flags) const = 0; virtual const char *ForEachIn() const = 0; virtual CYExpression *ForEachIn(CYContext &out) = 0; + virtual CYExpression *Replace(CYContext &context) = 0; }; struct CYNumber; @@ -425,7 +558,7 @@ struct CYCompound : { CYExpression *expressions_; - CYCompound(CYExpression *expressions) : + CYCompound(CYExpression *expressions = NULL) : expressions_(expressions) { } @@ -456,6 +589,7 @@ struct CYFunctionParameter : { } + void Replace(CYContext &context); virtual void Output(CYOutput &out) const; }; @@ -484,7 +618,7 @@ struct CYForInComprehension : } virtual const char *Name() const { - return name_->Value(); + return name_->Word(); } virtual CYFunctionParameter *Parameter(CYContext &context) const; @@ -505,7 +639,7 @@ struct CYForEachInComprehension : } virtual const char *Name() const { - return name_->Value(); + return name_->Word(); } virtual CYFunctionParameter *Parameter(CYContext &context) const; @@ -620,7 +754,7 @@ struct CYString : } CYString(const CYWord *word) : - value_(word->Value()), + value_(word->Word()), size_(strlen(value_)) { } @@ -634,7 +768,7 @@ struct CYString : virtual CYNumber *Number(CYContext &context); virtual CYString *String(CYContext &context); - virtual CYString *Concat(CYContext &out, CYString *rhs) const; + CYString *Concat(CYContext &out, CYString *rhs) const; virtual void Output(CYOutput &out, CYFlags flags) const; virtual void PropertyName(CYOutput &out) const; }; @@ -929,13 +1063,31 @@ struct CYArray : virtual void Output(CYOutput &out, CYFlags flags) const; }; +struct CYProperty : + CYNext, + CYThing +{ + CYPropertyName *name_; + CYExpression *value_; + + CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) : + CYNext(next), + name_(name), + value_(value) + { + } + + void Replace(CYContext &context); + virtual void Output(CYOutput &out) const; +}; + struct CYDeclaration : CYForInInitialiser { CYIdentifier *identifier_; CYExpression *initialiser_; - CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser) : + CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) : identifier_(identifier), initialiser_(initialiser) { @@ -946,15 +1098,16 @@ struct CYDeclaration : virtual const char *ForEachIn() const; virtual CYExpression *ForEachIn(CYContext &out); - void Replace(CYContext &context); + virtual CYExpression *Replace(CYContext &context); + virtual CYAssignment *Assignment(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYDeclarations : CYNext, - CYForInitialiser, - CYThing + CYThing, + CYForInitialiser { CYDeclaration *declaration_; @@ -966,7 +1119,8 @@ struct CYDeclarations : virtual void For(CYOutput &out) const; - void Replace(CYContext &context); + virtual CYCompound *Replace(CYContext &context); + CYProperty *Property(CYContext &context); virtual void Output(CYOutput &out) const; virtual void Output(CYOutput &out, CYFlags flags) const; @@ -1058,24 +1212,6 @@ struct CYForEachIn : virtual void Output(CYOutput &out, CYFlags flags) const; }; -struct CYProperty : - CYNext, - CYThing -{ - CYPropertyName *name_; - CYExpression *value_; - - CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) : - CYNext(next), - name_(name), - value_(value) - { - } - - void Replace(CYContext &context); - virtual void Output(CYOutput &out) const; -}; - struct CYObject : CYLiteral { @@ -1242,7 +1378,11 @@ struct CYFunction { { } - virtual void Replace_(CYContext &context); + virtual ~CYFunction() { + } + + void Inject(CYContext &context); + virtual void Replace_(CYContext &context, bool outer); virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -1283,8 +1423,11 @@ struct CYExpress : CYExpress(CYExpression *expression) : expression_(expression) { + if (expression == NULL) + throw; } + virtual CYStatement *Collapse(CYContext &context); virtual CYStatement *Replace(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -1334,6 +1477,7 @@ struct CYReturn : struct CYEmpty : CYStatement { + virtual CYStatement *Collapse(CYContext &context); virtual CYStatement *Replace(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -1483,7 +1627,7 @@ struct CYIndirect : } virtual const char *Operator() const { - return "^"; + return "*"; } CYAlphabetic(false)