]> git.saurik.com Git - cycript.git/commitdiff
Support implicit return from block_lambda_revival.
authorJay Freeman (saurik) <saurik@saurik.com>
Tue, 24 Nov 2015 00:33:49 +0000 (16:33 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Tue, 24 Nov 2015 00:33:49 +0000 (16:33 -0800)
List.hpp
Parser.hpp
Replace.cpp

index f218f54fe510843406222d156f1380105eb50375..30390eb0786795a40f065eabc2088ac85398d8cf 100644 (file)
--- a/List.hpp
+++ b/List.hpp
@@ -53,14 +53,14 @@ Type_ *&CYSetLast(Type_ *&list) {
 }
 
 template <typename Type_>
 }
 
 template <typename Type_>
-Type_ *CYGetLast(Type_ *list) {
+Type_ *&CYGetLast(Type_ *&list) {
     if (list == NULL)
     if (list == NULL)
-        return NULL;
+        return list;
 
 
-    Type_ *next(list);
-    while (next->next_ != NULL)
-        next = next->next_;
-    return next;
+    Type_ **next(&list);
+    while ((*next)->next_ != NULL)
+        next = &(*next)->next_;
+    return *next;
 }
 
 #define CYForEach(value, list) \
 }
 
 #define CYForEach(value, list) \
index 8bd7cdc6f26fbae55e9c024b0d45ae30cee9247b..2c534cce50f150d70e6941625a4f8162b2275f29 100644 (file)
@@ -158,6 +158,8 @@ struct CYStatement :
 
     virtual CYStatement *Replace(CYContext &context) = 0;
 
 
     virtual CYStatement *Replace(CYContext &context) = 0;
 
+    virtual CYStatement *Return();
+
   private:
     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 };
   private:
     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
 };
@@ -447,6 +449,8 @@ struct CYBlock :
     virtual CYStatement *Replace(CYContext &context);
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
     virtual CYStatement *Replace(CYContext &context);
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
+
+    virtual CYStatement *Return();
 };
 
 struct CYForInitialiser {
 };
 
 struct CYForInitialiser {
@@ -1399,6 +1403,8 @@ struct CYIf :
 
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
+
+    virtual CYStatement *Return();
 };
 
 struct CYDoWhile :
 };
 
 struct CYDoWhile :
@@ -1440,13 +1446,15 @@ struct CYFunction {
     CYStatement *code_;
 
     CYNonLocal *nonlocal_;
     CYStatement *code_;
 
     CYNonLocal *nonlocal_;
+    bool implicit_;
     CYThisScope this_;
 
     CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
         name_(name),
         parameters_(parameters),
         code_(code),
     CYThisScope this_;
 
     CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
         name_(name),
         parameters_(parameters),
         code_(code),
-        nonlocal_(NULL)
+        nonlocal_(NULL),
+        implicit_(false)
     {
     }
 
     {
     }
 
@@ -1533,6 +1541,8 @@ struct CYExpress :
 
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
+
+    virtual CYStatement *Return();
 };
 
 struct CYContinue :
 };
 
 struct CYContinue :
index 74f04d9d489f7712d48366cd7837dc44ca35a32e..7b99022fd957473ffe52b8de2608284000483b5f 100644 (file)
@@ -29,6 +29,11 @@ CYFunctionExpression *CYNonLocalize(CYContext &context, CYFunctionExpression *fu
     return function;
 }
 
     return function;
 }
 
+static void CYImplicitReturn(CYStatement *&code) {
+    if (CYStatement *&last = CYGetLast(code))
+        last = last->Return();
+}
+
 CYExpression *CYAdd::Replace(CYContext &context) {
     CYInfix::Replace(context);
 
 CYExpression *CYAdd::Replace(CYContext &context) {
     CYInfix::Replace(context);
 
@@ -95,6 +100,11 @@ CYExpression *CYAssignment::Replace(CYContext &context) {
     return this;
 }
 
     return this;
 }
 
+CYStatement *CYBlock::Return() {
+    CYImplicitReturn(code_);
+    return this;
+}
+
 CYStatement *CYBlock::Replace(CYContext &context) {
     context.ReplaceAll(code_);
     if (code_ == NULL)
 CYStatement *CYBlock::Replace(CYContext &context) {
     context.ReplaceAll(code_);
     if (code_ == NULL)
@@ -305,6 +315,10 @@ CYExpression *CYEncodedType::Replace(CYContext &context) {
     return typed_->Replace(context);
 }
 
     return typed_->Replace(context);
 }
 
+CYStatement *CYExpress::Return() {
+    return $ CYReturn(expression_);
+}
+
 CYStatement *CYExpress::Replace(CYContext &context) {
     context.Replace(expression_);
     return this;
 CYStatement *CYExpress::Replace(CYContext &context) {
     context.Replace(expression_);
     return this;
@@ -430,7 +444,8 @@ void CYFunction::Replace_(CYContext &context, bool outer) {
         Inject(context);
 
     CYThisScope *_this(context.this_);
         Inject(context);
 
     CYThisScope *_this(context.this_);
-    context.this_ = CYGetLast(&this_);
+    context.this_ = &this_;
+    context.this_ = CYGetLast(context.this_);
 
     CYNonLocal *nonlocal(context.nonlocal_);
     CYNonLocal *nextlocal(context.nextlocal_);
 
     CYNonLocal *nonlocal(context.nonlocal_);
     CYNonLocal *nextlocal(context.nextlocal_);
@@ -453,6 +468,9 @@ void CYFunction::Replace_(CYContext &context, bool outer) {
     parameters_->Replace(context, code_);
     context.ReplaceAll(code_);
 
     parameters_->Replace(context, code_);
     context.ReplaceAll(code_);
 
+    if (implicit_)
+        CYImplicitReturn(code_);
+
     if (CYIdentifier *identifier = this_.identifier_)
         code_ = $$->*
             $ CYVar($L1($ CYDeclaration(identifier, $ CYThis())))->*
     if (CYIdentifier *identifier = this_.identifier_)
         code_ = $$->*
             $ CYVar($L1($ CYDeclaration(identifier, $ CYThis())))->*
@@ -501,6 +519,12 @@ CYIdentifier *CYIdentifier::Replace(CYContext &context) {
     return replace_;
 }
 
     return replace_;
 }
 
+CYStatement *CYIf::Return() {
+    CYImplicitReturn(true_);
+    CYImplicitReturn(false_);
+    return this;
+}
+
 CYStatement *CYIf::Replace(CYContext &context) {
     context.Replace(test_);
     context.ReplaceAll(true_);
 CYStatement *CYIf::Replace(CYContext &context) {
     context.Replace(test_);
     context.ReplaceAll(true_);
@@ -709,12 +733,14 @@ CYStatement *CYReturn::Replace(CYContext &context) {
 }
 
 CYExpression *CYRubyBlock::Replace(CYContext &context) {
 }
 
 CYExpression *CYRubyBlock::Replace(CYContext &context) {
-    // XXX: this needs to do something much more epic to handle return
     return call_->AddArgument(context, proc_->Replace(context));
 }
 
 CYExpression *CYRubyProc::Replace(CYContext &context) {
     return call_->AddArgument(context, proc_->Replace(context));
 }
 
 CYExpression *CYRubyProc::Replace(CYContext &context) {
-    return CYNonLocalize(context, $ CYFunctionExpression(NULL, parameters_, code_));
+    CYFunctionExpression *function($ CYFunctionExpression(NULL, parameters_, code_));
+    function = CYNonLocalize(context, function);
+    function->implicit_ = true;
+    return function;
 }
 
 CYScope::CYScope(bool transparent, CYContext &context) :
 }
 
 CYScope::CYScope(bool transparent, CYContext &context) :
@@ -831,6 +857,10 @@ void CYScope::Close(CYContext &context, CYStatement *&statements) {
         }
 }
 
         }
 }
 
+CYStatement *CYStatement::Return() {
+    return this;
+}
+
 CYString *CYString::Concat(CYContext &context, CYString *rhs) const {
     size_t size(size_ + rhs->size_);
     char *value($ char[size + 1]);
 CYString *CYString::Concat(CYContext &context, CYString *rhs) const {
     size_t size(size_ + rhs->size_);
     char *value($ char[size + 1]);