]>
git.saurik.com Git - cycript.git/blob - Replace.cpp
5a2ed376d8da5a54a2ec217c51e6a69e8f0e3875
1 /* Cycript - Remove Execution Server and Disassembler
2 * Copyright (C) 2009 Jay Freeman (saurik)
5 /* Modified BSD License {{{ */
7 * Redistribution and use in source and binary
8 * forms, with or without modification, are permitted
9 * provided that the following conditions are met:
11 * 1. Redistributions of source code must retain the
12 * above copyright notice, this list of conditions
13 * and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the
15 * above copyright notice, this list of conditions
16 * and the following disclaimer in the documentation
17 * and/or other materials provided with the
19 * 3. The name of the author may not be used to endorse
20 * or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
25 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 #include "Replace.hpp"
46 CYExpression
*CYAdd::Replace(CYContext
&context
) {
47 CYInfix::Replace(context
);
49 CYExpression
*lhp(lhs_
->Primitive(context
));
50 CYExpression
*rhp(rhs_
->Primitive(context
));
52 CYString
*lhs(dynamic_cast<CYString
*>(lhp
));
53 CYString
*rhs(dynamic_cast<CYString
*>(rhp
));
55 if (lhs
!= NULL
|| rhs
!= NULL
) {
57 lhs
= lhp
->String(context
);
60 } else if (rhs
== NULL
) {
61 rhs
= rhp
->String(context
);
66 return lhs
->Concat(context
, rhs
);
69 if (CYNumber
*lhn
= lhp
->Number(context
))
70 if (CYNumber
*rhn
= rhp
->Number(context
))
71 return $
D(lhn
->Value() + rhn
->Value());
76 CYExpression
*CYAddressOf::Replace(CYContext
&context
) {
77 CYPrefix::Replace(context
);
78 return $
C0($
M(rhs_
, $
S("$cya")));
81 void CYArgument::Replace(CYContext
&context
) { $
T()
82 context
.Replace(value_
);
83 next_
->Replace(context
);
86 CYExpression
*CYArray::Replace(CYContext
&context
) {
87 elements_
->Replace(context
);
91 CYExpression
*CYArrayComprehension::Replace(CYContext
&context
) {
92 CYVariable
*cyv($
V("$cyv"));
94 return $
C0($
F(NULL
, $
P1("$cyv", comprehensions_
->Parameters(context
)), $$
->*
95 $
E($
CYAssign(cyv
, $
CYArray()))->*
96 comprehensions_
->Replace(context
, $
E($
C1($
M(cyv
, $
S("push")), expression_
)))->*
101 CYExpression
*CYAssignment::Replace(CYContext
&context
) {
102 context
.Replace(lhs_
);
103 context
.Replace(rhs_
);
107 CYStatement
*CYBlock::Replace(CYContext
&context
) {
108 statements_
= statements_
->ReplaceAll(context
);
112 CYStatement
*CYBreak::Replace(CYContext
&context
) {
116 CYExpression
*CYCall::Replace(CYContext
&context
) {
117 context
.Replace(function_
);
118 arguments_
->Replace(context
);
125 void Catch::Replace(CYContext
&context
) { $
T()
126 code_
.Replace(context
);
131 void CYClause::Replace(CYContext
&context
) { $
T()
132 context
.Replace(case_
);
133 statements_
= statements_
->ReplaceAll(context
);
134 next_
->Replace(context
);
137 CYExpression
*CYCompound::Replace(CYContext
&context
) {
138 expressions_
= expressions_
->ReplaceAll(context
);
142 CYFunctionParameter
*CYComprehension::Parameters(CYContext
&context
) const { $
T(NULL
)
143 CYFunctionParameter
*next(next_
->Parameters(context
));
144 if (CYFunctionParameter
*parameter
= Parameter(context
)) {
145 parameter
->SetNext(next
);
151 CYStatement
*CYComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
152 return next_
== NULL
? statement
: next_
->Replace(context
, statement
);
155 CYExpression
*CYCondition::Replace(CYContext
&context
) {
156 context
.Replace(test_
);
157 context
.Replace(true_
);
158 context
.Replace(false_
);
162 CYStatement
*CYContinue::Replace(CYContext
&context
) {
166 CYExpression
*CYDeclaration::ForEachIn(CYContext
&context
) {
167 return $
CYVariable(identifier_
);
170 void CYDeclaration::Replace(CYContext
&context
) {
171 context
.Replace(initialiser_
);
174 void CYDeclarations::Replace(CYContext
&context
) { $
T()
175 declaration_
->Replace(context
);
176 next_
->Replace(context
);
179 CYExpression
*CYDirectMember::Replace(CYContext
&context
) {
184 CYStatement
*CYDoWhile::Replace(CYContext
&context
) {
185 context
.Replace(test_
);
186 context
.Replace(code_
);
190 void CYElement::Replace(CYContext
&context
) { $
T()
191 context
.Replace(value_
);
192 next_
->Replace(context
);
195 CYStatement
*CYEmpty::Replace(CYContext
&context
) {
199 CYStatement
*CYExpress::Replace(CYContext
&context
) {
200 context
.Replace(expression_
);
204 CYExpression
*CYExpression::ClassName(CYContext
&context
, bool object
) {
208 CYExpression
*CYExpression::ForEachIn(CYContext
&context
) {
212 CYExpression
*CYExpression::ReplaceAll(CYContext
&context
) { $
T(NULL
)
213 CYExpression
*replace(this);
214 context
.Replace(replace
);
216 if (CYExpression
*next
= next_
->ReplaceAll(context
))
217 replace
->SetNext(next
);
219 replace
->SetNext(next_
);
224 CYNumber
*CYFalse::Number(CYContext
&context
) {
228 CYString
*CYFalse::String(CYContext
&context
) {
232 void CYFinally::Replace(CYContext
&context
) { $
T()
233 code_
.Replace(context
);
236 CYStatement
*CYFor::Replace(CYContext
&context
) {
238 context
.Replace(test_
);
239 context
.Replace(increment_
);
240 context
.Replace(code_
);
244 CYStatement
*CYForIn::Replace(CYContext
&context
) {
246 context
.Replace(set_
);
247 context
.Replace(code_
);
251 CYFunctionParameter
*CYForInComprehension::Parameter(CYContext
&context
) const {
252 return $
CYFunctionParameter(name_
);
255 CYStatement
*CYForInComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
256 return $
CYForIn($
CYVariable(name_
), set_
, CYComprehension::Replace(context
, statement
));
259 CYStatement
*CYForEachIn::Replace(CYContext
&context
) {
260 CYVariable
*cys($
V("$cys")), *cyt($
V("$cyt"));
262 return $
CYWith($
CYObject($
CYProperty($
S("$cys"), $
D(0), $
CYProperty($
S("$cyt"), $
D(0)))), $
CYBlock($$
->*
263 $
E($
CYAssign(cys
, set_
))->*
264 $
CYForIn(cyt
, cys
, $
CYBlock($$
->*
265 $
E($
CYAssign(initialiser_
->ForEachIn(context
), $
M(cys
, cyt
)))->*
271 CYFunctionParameter
*CYForEachInComprehension::Parameter(CYContext
&context
) const {
272 return $
CYFunctionParameter(name_
);
275 CYStatement
*CYForEachInComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
276 CYVariable
*cys($
V("$cys")), *name($
CYVariable(name_
));
278 return $
E($
C0($
F(NULL
, $
P1("$cys"), $$
->*
279 $
E($
CYAssign(cys
, set_
))->*
280 $
CYForIn(name
, cys
, $
CYBlock($$
->*
281 $
E($
CYAssign(name
, $
M(cys
, name
)))->*
282 CYComprehension::Replace(context
, statement
)
287 void CYFunction::Replace_(CYContext
&context
) {
288 code_
.Replace(context
);
291 CYExpression
*CYFunctionExpression::Replace(CYContext
&context
) {
296 CYStatement
*CYFunctionStatement::Replace(CYContext
&context
) {
301 CYStatement
*CYIf::Replace(CYContext
&context
) {
302 context
.Replace(test_
);
303 context
.Replace(true_
);
304 context
.Replace(false_
);
308 CYFunctionParameter
*CYIfComprehension::Parameter(CYContext
&context
) const {
312 CYStatement
*CYIfComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
313 return $
CYIf(test_
, CYComprehension::Replace(context
, statement
));
316 CYExpression
*CYIndirect::Replace(CYContext
&context
) {
317 CYPrefix::Replace(context
);
318 return $
M(rhs_
, $
S("$cyi"));
321 CYExpression
*CYIndirectMember::Replace(CYContext
&context
) {
323 return $
M($
CYIndirect(object_
), property_
);
326 CYExpression
*CYInfix::Replace(CYContext
&context
) {
327 context
.Replace(lhs_
);
328 context
.Replace(rhs_
);
332 CYStatement
*CYLabel::Replace(CYContext
&context
) {
333 context
.Replace(statement_
);
337 void CYMember::Replace_(CYContext
&context
) {
338 context
.Replace(object_
);
339 context
.Replace(property_
);
342 CYExpression
*CYNew::Replace(CYContext
&context
) {
343 context
.Replace(constructor_
);
344 arguments_
->Replace(context
);
348 CYNumber
*CYNull::Number(CYContext
&context
) {
352 CYString
*CYNull::String(CYContext
&context
) {
356 CYNumber
*CYNumber::Number(CYContext
&context
) {
360 CYString
*CYNumber::String(CYContext
&context
) {
361 // XXX: there is a precise algorithm for this
362 return $
S(apr_psprintf(context
.pool_
, "%.17g", Value()));
365 CYExpression
*CYObject::Replace(CYContext
&context
) {
366 properties_
->Replace(context
);
370 CYExpression
*CYPostfix::Replace(CYContext
&context
) {
371 context
.Replace(lhs_
);
375 CYExpression
*CYPrefix::Replace(CYContext
&context
) {
376 context
.Replace(rhs_
);
380 void CYProgram::Replace(CYContext
&context
) {
381 statements_
= statements_
->ReplaceAll(context
);
384 void CYProperty::Replace(CYContext
&context
) { $
T()
385 context
.Replace(value_
);
386 next_
->Replace(context
);
389 CYStatement
*CYReturn::Replace(CYContext
&context
) {
390 context
.Replace(value_
);
394 CYStatement
*CYStatement::ReplaceAll(CYContext
&context
) { $
T(NULL
)
395 CYStatement
*replace(this);
396 context
.Replace(replace
);
398 if (CYStatement
*next
= next_
->ReplaceAll(context
))
399 replace
->SetNext(next
);
401 replace
->SetNext(next_
);
406 CYString
*CYString::Concat(CYContext
&context
, CYString
*rhs
) const {
407 size_t size(size_
+ rhs
->size_
);
408 char *value(new(context
.pool_
) char[size
+ 1]);
409 memcpy(value
, value_
, size_
);
410 memcpy(value
+ size_
, rhs
->value_
, rhs
->size_
);
415 CYNumber
*CYString::Number(CYContext
&context
) {
416 // XXX: there is a precise algorithm for this
420 CYString
*CYString::String(CYContext
&context
) {
424 CYStatement
*CYSwitch::Replace(CYContext
&context
) {
425 context
.Replace(value_
);
426 clauses_
->Replace(context
);
430 CYExpression
*CYThis::Replace(CYContext
&context
) {
437 CYStatement
*Throw::Replace(CYContext
&context
) {
438 context
.Replace(value_
);
444 CYExpression
*CYTrivial::Replace(CYContext
&context
) {
448 CYNumber
*CYTrue::Number(CYContext
&context
) {
452 CYString
*CYTrue::String(CYContext
&context
) {
459 CYStatement
*Try::Replace(CYContext
&context
) {
460 code_
.Replace(context
);
461 catch_
->Replace(context
);
462 finally_
->Replace(context
);
468 CYStatement
*CYVar::Replace(CYContext
&context
) {
469 declarations_
->Replace(context
);
473 CYExpression
*CYVariable::Replace(CYContext
&context
) {
477 CYStatement
*CYWhile::Replace(CYContext
&context
) {
478 context
.Replace(test_
);
479 context
.Replace(code_
);
483 CYStatement
*CYWith::Replace(CYContext
&context
) {
484 context
.Replace(scope_
);
485 context
.Replace(code_
);
489 CYExpression
*CYWord::ClassName(CYContext
&context
, bool object
) {
490 CYString
*name($
S(this));
492 return $
C1($
V("objc_getClass"), name
);