]> git.saurik.com Git - cycript.git/blobdiff - Replace.cpp
Don't stack overflow on struct pointers in cycles.
[cycript.git] / Replace.cpp
index 719b3a57eeca3a67f7663d976cadf874d802fec0..29a78a04c21b5c18c96d932d0bcdb0a07102dcd6 100644 (file)
@@ -1,5 +1,5 @@
-/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2015  Jay Freeman (saurik)
+/* Cycript - The Truly Universal Scripting Language
+ * Copyright (C) 2009-2016  Jay Freeman (saurik)
 */
 
 /* GNU Affero General Public License, Version 3 {{{ */
@@ -117,6 +117,9 @@ CYTarget *CYArrayComprehension::Replace(CYContext &context) {
 }
 
 CYExpression *CYAssignment::Replace(CYContext &context) {
+    // XXX: this is a horrible hack but I'm a month over schedule :(
+    if (CYSubscriptMember *subscript = dynamic_cast<CYSubscriptMember *>(lhs_))
+        return $C2($M(subscript->object_, $S("$cys")), subscript->property_, rhs_);
     context.Replace(lhs_);
     context.Replace(rhs_);
     return this;
@@ -179,6 +182,7 @@ CYTarget *CYClassExpression::Replace(CYContext &context) {
 
     if (tail_->constructor_ == NULL)
         tail_->constructor_ = $ CYFunctionExpression(NULL, NULL, NULL);
+    tail_->constructor_->name_ = name_;
     tail_->constructor_ = CYSuperize(context, tail_->constructor_);
 
     context.super_ = old;
@@ -381,8 +385,16 @@ CYFunctionParameter *CYExpression::Parameter() const {
     return NULL;
 }
 
-CYStatement *CYExternal::Replace(CYContext &context) {
-    return $E($ CYAssign($V(typed_->identifier_), $C1(typed_->Replace(context), $C2($V("dlsym"), $V("RTLD_DEFAULT"), $S(typed_->identifier_->Word())))));
+CYTarget *CYExtend::Replace(CYContext &context) {
+    return object_.Replace(context, lhs_);
+}
+
+CYStatement *CYExternalDefinition::Replace(CYContext &context) {
+    return $E($ CYAssign($V(typed_->identifier_), $ CYExternalExpression(abi_, typed_)));
+}
+
+CYTarget *CYExternalExpression::Replace(CYContext &context) {
+    return $C1(typed_->Replace(context), $C2($V("dlsym"), $V("RTLD_DEFAULT"), $S(typed_->identifier_->Word())));
 }
 
 CYNumber *CYFalse::Number(CYContext &context) {
@@ -732,21 +744,25 @@ CYExpression *CYNumber::PropertyName(CYContext &context) {
     return String(context);
 }
 
-CYTarget *CYObject::Replace(CYContext &context) {
+CYTarget *CYObject::Replace(CYContext &context, CYTarget *seed) {
     CYBuilder builder;
     if (properties_ != NULL)
-        properties_ = properties_->ReplaceAll(context, builder, $ CYThis(), false);
+        properties_ = properties_->ReplaceAll(context, builder, $ CYThis(), seed != this);
 
     if (builder) {
         return $C1($M($ CYFunctionExpression(NULL, builder.bindings_->Parameter(context),
             builder.statements_
                 ->* $ CYReturn($ CYThis())
-        ), $S("call")), this, builder.bindings_->Argument(context));
+        ), $S("call")), seed, builder.bindings_->Argument(context));
     }
 
     CYForEach (property, properties_)
         property->Replace(context);
-    return this;
+    return seed;
+}
+
+CYTarget *CYObject::Replace(CYContext &context) {
+    return Replace(context, this);
 }
 
 CYTarget *CYParenthetical::Replace(CYContext &context) {
@@ -878,6 +894,10 @@ void CYScript::Replace(CYContext &context) {
     }
 }
 
+CYTarget *CYResolveMember::Replace(CYContext &context) {
+    return $M($M(object_, $S("$cyr")), property_);
+}
+
 CYStatement *CYReturn::Replace(CYContext &context) {
     if (context.nonlocal_ != NULL) {
         CYProperty *value(value_ == NULL ? NULL : $ CYPropertyValue($S("$cyv"), value_));
@@ -891,7 +911,7 @@ CYStatement *CYReturn::Replace(CYContext &context) {
 }
 
 CYTarget *CYRubyBlock::Replace(CYContext &context) {
-    return call_->AddArgument(context, proc_->Replace(context));
+    return lhs_->AddArgument(context, proc_->Replace(context));
 }
 
 CYTarget *CYRubyBlock::AddArgument(CYContext &context, CYExpression *value) {
@@ -1058,6 +1078,10 @@ void CYScope::Close(CYContext &context) {
     default:; } }
 }
 
+CYTarget *CYSubscriptMember::Replace(CYContext &context) {
+    return $C1($M(object_, $S("$cyg")), property_);
+}
+
 CYElementValue *CYSpan::Replace(CYContext &context) { $T(NULL)
     return $ CYElementValue(expression_, $ CYElementValue(string_, next_->Replace(context)));
 }
@@ -1122,6 +1146,10 @@ CYTarget *CYSuperCall::Replace(CYContext &context) {
     return $C($C1($M($V(context.super_), $S("bind")), $ CYThis()), arguments_);
 }
 
+CYTarget *CYSymbol::Replace(CYContext &context) {
+    return $C1($M($V("Symbol"), $S("for")), $S(name_));
+}
+
 CYStatement *CYSwitch::Replace(CYContext &context) {
     context.Replace(value_);
     clauses_->Replace(context);
@@ -1217,6 +1245,10 @@ CYTarget *CYTypeExpression::Replace(CYContext &context) {
     return typed_->Replace(context);
 }
 
+CYTarget *CYTypeInt128::Replace(CYContext &context) {
+    return $V(signing_ == CYTypeUnsigned ? "uint128" : "int128");
+}
+
 CYTarget *CYTypeIntegral::Replace(CYContext &context) {
     bool u(signing_ == CYTypeUnsigned);
     switch (length_) {