]>
git.saurik.com Git - cycript.git/blob - ObjectiveC/Replace.cpp
d90eecfd1a80b648b8548d2184dbb3809761a9e3
   1 /* Cycript - Optimizing JavaScript Compiler/Runtime 
   2  * Copyright (C) 2009-2014  Jay Freeman (saurik) 
   5 /* GNU Affero General Public License, Version 3 {{{ */ 
   7  * This program is free software: you can redistribute it and/or modify 
   8  * it under the terms of the GNU Affero General Public License as published by 
   9  * the Free Software Foundation, either version 3 of the License, or 
  10  * (at your option) any later version. 
  12  * This program is distributed in the hope that it will be useful, 
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15  * GNU Affero General Public License for more details. 
  17  * You should have received a copy of the GNU Affero General Public License 
  18  * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  22 #include "Replace.hpp" 
  23 #include "ObjectiveC/Syntax.hpp" 
  27 static CYExpression 
*MessageType(CYContext 
&context
, CYTypedIdentifier 
*type
, CYMessageParameter 
*next
, CYExpression 
*extra 
= NULL
) { 
  31     CYExpression 
*left($
C0($
M(type
->Replace(context
), $
S("toString")))); 
  33         left 
= $ 
CYAdd(left
, extra
); 
  35     if (next 
== NULL 
|| next
->name_ 
== NULL
) 
  38     CYExpression 
*right(next
->TypeSignature(context
)); 
  42     return $ 
CYAdd(left
, right
); 
  45 CYStatement 
*CYCategory::Replace(CYContext 
&context
) { 
  46     CYVariable 
*cyc($
V("$cyc")), *cys($
V("$cys")); 
  48     return $
E($
C1($
F(NULL
, $
P6($
L("$cys"), $
L("$cyp"), $
L("$cyc"), $
L("$cyn"), $
L("$cyt"), $
L("$cym")), $$
->* 
  49         $
E($ 
CYAssign($
V("$cyp"), $
C1($
V("object_getClass"), cys
)))->* 
  50         $
E($ 
CYAssign(cyc
, cys
))->* 
  51         $
E($ 
CYAssign($
V("$cym"), $
C1($
V("object_getClass"), cyc
)))->* 
  52         messages_
->Replace(context
, true) 
  53     ), name_
->ClassName(context
, true))); 
  56 CYExpression 
*CYClass::Replace_(CYContext 
&context
) { 
  57     CYVariable 
*cyc($
V("$cyc")), *cys($
V("$cys")); 
  59     CYExpression 
*name(name_ 
!= NULL 
? name_
->ClassName(context
, false) : $
C1($
V("$cyq"), $
S("CY$"))); 
  61     return $
C1($
F(NULL
, $
P6($
L("$cys"), $
L("$cyp"), $
L("$cyc"), $
L("$cyn"), $
L("$cyt"), $
L("$cym")), $$
->* 
  62         $
E($ 
CYAssign($
V("$cyp"), $
C1($
V("object_getClass"), cys
)))->* 
  63         $
E($ 
CYAssign(cyc
, $
C3($
V("objc_allocateClassPair"), cys
, name
, $
D(0))))->* 
  64         $
E($ 
CYAssign($
V("$cym"), $
C1($
V("object_getClass"), cyc
)))->* 
  65         protocols_
->Replace(context
)->* 
  66         fields_
->Replace(context
)->* 
  67         messages_
->Replace(context
, false)->* 
  68         $
E($
C1($
V("objc_registerClassPair"), cyc
))->* 
  70     ), super_ 
== NULL 
? $ 
CYNull() : super_
); 
  73 CYExpression 
*CYClassExpression::Replace(CYContext 
&context
) { 
  74     return Replace_(context
); 
  77 CYStatement 
*CYClassStatement::Replace(CYContext 
&context
) { 
  78     return $
E(Replace_(context
)); 
  81 CYStatement 
*CYField::Replace(CYContext 
&context
) const { $
T(NULL
) 
  82     CYVariable 
*cyn($
V("$cyn")); 
  83     CYVariable 
*cyt($
V("$cyt")); 
  85     CYExpression 
*type($
C0($
M(typed_
->Replace(context
), $
S("toString")))); 
  87     return $ 
CYBlock($$
->* 
  88         $
E($ 
CYAssign(cyt
, type
))->* 
  89         $
E($ 
CYAssign(cyn
, $
N1($
V("Type"), cyt
)))->* 
  90         $
E($
C5($
V("class_addIvar"), $
V("$cyc"), $
S(typed_
->identifier_
->Word()), $
M(cyn
, $
S("size")), $
M(cyn
, $
S("alignment")), cyt
))->* 
  91         next_
->Replace(context
) 
  95 CYExpression 
*CYInstanceLiteral::Replace(CYContext 
&context
) { 
  96     return $
N1($
V("Instance"), number_
); 
  99 CYStatement 
*CYMessage::Replace(CYContext 
&context
, bool replace
) const { $
T(NULL
) 
 100     CYVariable 
*cyn($
V("$cyn")); 
 101     CYVariable 
*cyt($
V("$cyt")); 
 102     CYVariable 
*self($
V("self")); 
 103     CYVariable 
*_class($
V(instance_ 
? "$cys" : "$cyp")); 
 105     CYExpression 
*type(TypeSignature(context
) ?: $
C1($
M(cyn
, $
S("type")), _class
)); 
 107     return $ 
CYBlock($$
->* 
 108         next_
->Replace(context
, replace
)->* 
 109         $
E($ 
CYAssign(cyn
, parameters_
->Selector(context
)))->* 
 110         $
E($ 
CYAssign(cyt
, type
))->* 
 111         $
E($
C4($
V(replace 
? "class_replaceMethod" : "class_addMethod"), 
 112             $
V(instance_ 
? "$cyc" : "$cym"), 
 114             $
N2($
V("Functor"), $
F(NULL
, $
P2($
L("self"), $
L("_cmd"), parameters_
->Parameters(context
)), $$
->* 
 115                 $ 
CYVar($
L1($
L("$cyr", $
N2($
V("objc_super"), self
, _class
))))->* 
 116                 $ 
CYReturn($
C1($
M($
F(NULL
, NULL
, code_
), $
S("call")), self
)) 
 123 CYExpression 
*CYMessage::TypeSignature(CYContext 
&context
) const { 
 124     return MessageType(context
, type_
, parameters_
, $
S("@:")); 
 127 CYFunctionParameter 
*CYMessageParameter::Parameters(CYContext 
&context
) const { $
T(NULL
) 
 128     CYFunctionParameter 
*next(next_
->Parameters(context
)); 
 129     return name_ 
== NULL 
? next 
: $ 
CYFunctionParameter($ 
CYDeclaration(name_
), next
); 
 132 CYSelector 
*CYMessageParameter::Selector(CYContext 
&context
) const { 
 133     return $ 
CYSelector(SelectorPart(context
)); 
 136 CYSelectorPart 
*CYMessageParameter::SelectorPart(CYContext 
&context
) const { $
T(NULL
) 
 137     CYSelectorPart 
*next(next_
->SelectorPart(context
)); 
 138     return tag_ 
== NULL 
? next 
: $ 
CYSelectorPart(tag_
, name_ 
!= NULL
, next
); 
 141 CYExpression 
*CYMessageParameter::TypeSignature(CYContext 
&context
) const { 
 142     return MessageType(context
, type_
, next_
); 
 145 CYExpression 
*CYBox::Replace(CYContext 
&context
) { 
 146     return $
C1($
M($
V("Instance"), $
S("box")), value_
); 
 149 CYExpression 
*CYObjCBlock::Replace(CYContext 
&context
) { 
 150     return $
C1($ 
CYEncodedType(($ 
CYTypedIdentifier(*typed_
))->Modify($ 
CYTypeBlockWith(parameters_
))), $ 
CYFunctionExpression(NULL
, parameters_
->Parameters(context
), statements_
)); 
 153 CYStatement 
*CYProtocol::Replace(CYContext 
&context
) const { $
T(NULL
) 
 154     return $ 
CYBlock($$
->* 
 155         next_
->Replace(context
)->* 
 156         $
E($
C2($
V("class_addProtocol"), 
 162 CYExpression 
*CYSelector::Replace(CYContext 
&context
) { 
 163     return $
C1($
V("sel_registerName"), name_
->Replace(context
)); 
 166 CYString 
*CYSelectorPart::Replace(CYContext 
&context
) { 
 167     std::ostringstream str
; 
 168     CYForEach (part
, this) { 
 169         if (part
->name_ 
!= NULL
) 
 170             str 
<< part
->name_
->Word(); 
 174     return $
S($pool
.strdup(str
.str().c_str())); 
 177 CYExpression 
*CYSendDirect::Replace(CYContext 
&context
) { 
 178     std::ostringstream name
; 
 179     CYArgument 
**argument(&arguments_
); 
 180     CYSelectorPart 
*selector(NULL
), *current(NULL
); 
 182     while (*argument 
!= NULL
) { 
 183         if ((*argument
)->name_ 
!= NULL
) { 
 184             CYSelectorPart 
*part($ 
CYSelectorPart((*argument
)->name_
, (*argument
)->value_ 
!= NULL
)); 
 185             if (selector 
== NULL
) 
 188                 current
->SetNext(part
); 
 190             (*argument
)->name_ 
= NULL
; 
 193         if ((*argument
)->value_ 
== NULL
) 
 194             *argument 
= (*argument
)->next_
; 
 196             argument 
= &(*argument
)->next_
; 
 199     return $
C2($
V("objc_msgSend"), self_
, selector
->Replace(context
), arguments_
); 
 202 CYExpression 
*CYSendSuper::Replace(CYContext 
&context
) { 
 203     return $ 
CYSendDirect($
V("$cyr"), arguments_
);