]>
git.saurik.com Git - cycript.git/blob - Replace.cpp
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
);
122 void CYCatch::Replace(CYContext
&context
) { $
T()
123 code_
.Replace(context
);
126 void CYClause::Replace(CYContext
&context
) { $
T()
127 context
.Replace(case_
);
128 statements_
= statements_
->ReplaceAll(context
);
129 next_
->Replace(context
);
132 CYExpression
*CYCompound::Replace(CYContext
&context
) {
133 expressions_
= expressions_
->ReplaceAll(context
);
137 CYFunctionParameter
*CYComprehension::Parameters(CYContext
&context
) const { $
T(NULL
)
138 CYFunctionParameter
*next(next_
->Parameters(context
));
139 if (CYFunctionParameter
*parameter
= Parameter(context
)) {
140 parameter
->SetNext(next
);
146 CYStatement
*CYComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
147 return next_
== NULL
? statement
: next_
->Replace(context
, statement
);
150 CYExpression
*CYCondition::Replace(CYContext
&context
) {
151 context
.Replace(test_
);
152 context
.Replace(true_
);
153 context
.Replace(false_
);
157 CYStatement
*CYContinue::Replace(CYContext
&context
) {
161 CYExpression
*CYDeclaration::ForEachIn(CYContext
&context
) {
162 return $
CYVariable(identifier_
);
165 void CYDeclaration::Replace(CYContext
&context
) {
166 context
.Replace(initialiser_
);
169 void CYDeclarations::Replace(CYContext
&context
) { $
T()
170 declaration_
->Replace(context
);
171 next_
->Replace(context
);
174 CYExpression
*CYDirectMember::Replace(CYContext
&context
) {
179 CYStatement
*CYDoWhile::Replace(CYContext
&context
) {
180 context
.Replace(test_
);
181 context
.Replace(code_
);
185 void CYElement::Replace(CYContext
&context
) { $
T()
186 context
.Replace(value_
);
187 next_
->Replace(context
);
190 CYStatement
*CYEmpty::Replace(CYContext
&context
) {
194 CYStatement
*CYExpress::Replace(CYContext
&context
) {
195 context
.Replace(expression_
);
199 CYExpression
*CYExpression::ClassName(CYContext
&context
, bool object
) {
203 CYExpression
*CYExpression::ForEachIn(CYContext
&context
) {
207 CYExpression
*CYExpression::ReplaceAll(CYContext
&context
) { $
T(NULL
)
208 CYExpression
*replace(this);
209 context
.Replace(replace
);
211 if (CYExpression
*next
= next_
->ReplaceAll(context
))
212 replace
->SetNext(next
);
214 replace
->SetNext(next_
);
219 CYNumber
*CYFalse::Number(CYContext
&context
) {
223 CYString
*CYFalse::String(CYContext
&context
) {
227 void CYFinally::Replace(CYContext
&context
) { $
T()
228 code_
.Replace(context
);
231 CYStatement
*CYFor::Replace(CYContext
&context
) {
233 context
.Replace(test_
);
234 context
.Replace(increment_
);
235 context
.Replace(code_
);
239 CYStatement
*CYForIn::Replace(CYContext
&context
) {
241 context
.Replace(set_
);
242 context
.Replace(code_
);
246 CYFunctionParameter
*CYForInComprehension::Parameter(CYContext
&context
) const {
247 return $
CYFunctionParameter(name_
);
250 CYStatement
*CYForInComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
251 return $
CYForIn($
CYVariable(name_
), set_
, CYComprehension::Replace(context
, statement
));
254 CYStatement
*CYForEachIn::Replace(CYContext
&context
) {
255 CYVariable
*cys($
V("$cys")), *cyt($
V("$cyt"));
257 return $
CYWith($
CYObject($
CYProperty($
S("$cys"), $
D(0), $
CYProperty($
S("$cyt"), $
D(0)))), $
CYBlock($$
->*
258 $
E($
CYAssign(cys
, set_
))->*
259 $
CYForIn(cyt
, cys
, $
CYBlock($$
->*
260 $
E($
CYAssign(initialiser_
->ForEachIn(context
), $
M(cys
, cyt
)))->*
266 CYFunctionParameter
*CYForEachInComprehension::Parameter(CYContext
&context
) const {
267 return $
CYFunctionParameter(name_
);
270 CYStatement
*CYForEachInComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
271 CYVariable
*cys($
V("$cys")), *name($
CYVariable(name_
));
273 return $
E($
C0($
F(NULL
, $
P1("$cys"), $$
->*
274 $
E($
CYAssign(cys
, set_
))->*
275 $
CYForIn(name
, cys
, $
CYBlock($$
->*
276 $
E($
CYAssign(name
, $
M(cys
, name
)))->*
277 CYComprehension::Replace(context
, statement
)
282 void CYFunction::Replace_(CYContext
&context
) {
283 code_
.Replace(context
);
286 CYExpression
*CYFunctionExpression::Replace(CYContext
&context
) {
291 CYStatement
*CYFunctionStatement::Replace(CYContext
&context
) {
296 CYStatement
*CYIf::Replace(CYContext
&context
) {
297 context
.Replace(test_
);
298 context
.Replace(true_
);
299 context
.Replace(false_
);
303 CYFunctionParameter
*CYIfComprehension::Parameter(CYContext
&context
) const {
307 CYStatement
*CYIfComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
308 return $
CYIf(test_
, CYComprehension::Replace(context
, statement
));
311 CYExpression
*CYIndirect::Replace(CYContext
&context
) {
312 CYPrefix::Replace(context
);
313 return $
M(rhs_
, $
S("$cyi"));
316 CYExpression
*CYIndirectMember::Replace(CYContext
&context
) {
318 return $
M($
CYIndirect(object_
), property_
);
321 CYExpression
*CYInfix::Replace(CYContext
&context
) {
322 context
.Replace(lhs_
);
323 context
.Replace(rhs_
);
327 CYStatement
*CYLabel::Replace(CYContext
&context
) {
328 context
.Replace(statement_
);
332 void CYMember::Replace_(CYContext
&context
) {
333 context
.Replace(object_
);
334 context
.Replace(property_
);
337 CYExpression
*CYNew::Replace(CYContext
&context
) {
338 context
.Replace(constructor_
);
339 arguments_
->Replace(context
);
343 CYNumber
*CYNull::Number(CYContext
&context
) {
347 CYString
*CYNull::String(CYContext
&context
) {
351 CYNumber
*CYNumber::Number(CYContext
&context
) {
355 CYString
*CYNumber::String(CYContext
&context
) {
356 // XXX: there is a precise algorithm for this
357 return $
S(apr_psprintf(context
.pool_
, "%.17g", Value()));
360 CYExpression
*CYObject::Replace(CYContext
&context
) {
361 properties_
->Replace(context
);
365 CYExpression
*CYPostfix::Replace(CYContext
&context
) {
366 context
.Replace(lhs_
);
370 CYExpression
*CYPrefix::Replace(CYContext
&context
) {
371 context
.Replace(rhs_
);
375 void CYProgram::Replace(CYContext
&context
) {
376 statements_
= statements_
->ReplaceAll(context
);
379 void CYProperty::Replace(CYContext
&context
) { $
T()
380 context
.Replace(value_
);
381 next_
->Replace(context
);
384 CYStatement
*CYReturn::Replace(CYContext
&context
) {
385 context
.Replace(value_
);
389 CYStatement
*CYStatement::ReplaceAll(CYContext
&context
) { $
T(NULL
)
390 CYStatement
*replace(this);
391 context
.Replace(replace
);
393 if (CYStatement
*next
= next_
->ReplaceAll(context
))
394 replace
->SetNext(next
);
396 replace
->SetNext(next_
);
401 CYString
*CYString::Concat(CYContext
&context
, CYString
*rhs
) const {
402 size_t size(size_
+ rhs
->size_
);
403 char *value(new(context
.pool_
) char[size
+ 1]);
404 memcpy(value
, value_
, size_
);
405 memcpy(value
+ size_
, rhs
->value_
, rhs
->size_
);
410 CYNumber
*CYString::Number(CYContext
&context
) {
411 // XXX: there is a precise algorithm for this
415 CYString
*CYString::String(CYContext
&context
) {
419 CYStatement
*CYSwitch::Replace(CYContext
&context
) {
420 context
.Replace(value_
);
421 clauses_
->Replace(context
);
425 CYExpression
*CYThis::Replace(CYContext
&context
) {
429 CYStatement
*CYThrow::Replace(CYContext
&context
) {
430 context
.Replace(value_
);
434 CYExpression
*CYTrivial::Replace(CYContext
&context
) {
438 CYNumber
*CYTrue::Number(CYContext
&context
) {
442 CYString
*CYTrue::String(CYContext
&context
) {
446 CYStatement
*CYTry::Replace(CYContext
&context
) {
447 code_
.Replace(context
);
448 catch_
->Replace(context
);
449 finally_
->Replace(context
);
453 CYStatement
*CYVar::Replace(CYContext
&context
) {
454 declarations_
->Replace(context
);
458 CYExpression
*CYVariable::Replace(CYContext
&context
) {
462 CYStatement
*CYWhile::Replace(CYContext
&context
) {
463 context
.Replace(test_
);
464 context
.Replace(code_
);
468 CYStatement
*CYWith::Replace(CYContext
&context
) {
469 context
.Replace(scope_
);
470 context
.Replace(code_
);
474 CYExpression
*CYWord::ClassName(CYContext
&context
, bool object
) {
475 CYString
*name($
S(this));
477 return $
C1($
V("objc_getClass"), name
);