├── Baton.hpp ├── Bridge.cpp ├── Bridge.def ├── Bridge.sh ├── COPYING ├── COPYING.LESSER ├── CYGWIN_NT-6.1.mk ├── Console.cpp ├── Cycript.l.in ├── Cycript.yy.in ├── Darwin-arm.mk ├── Darwin.mk ├── E4X └── Syntax.hpp ├── Error.hpp ├── Exception.hpp ├── Execute.cpp ├── Execute.hpp ├── Execute.mk ├── Filter.sh ├── FreeBSD.mk ├── GNUmakefile.in ├── GNUstep.mk ├── Handler.mm ├── Internal.hpp ├── JavaScript.hpp ├── JavaScriptCore.cpp ├── Library.cpp ├── Linux.mk ├── List.hpp ├── Local.hpp ├── Mach └── Inject.cpp ├── Makefile.in ├── Network.cpp ├── ObjectiveC.mk ├── ObjectiveC ├── Internal.hpp ├── Library.mm ├── Output.mm ├── Replace.cpp └── Syntax.hpp ├── Options.hpp ├── Output.cpp ├── Parser.cpp ├── Parser.dat ├── Parser.hpp ├── Pooling.hpp ├── Replace.cpp ├── Replace.hpp ├── Server.cpp ├── Standard.hpp ├── String.hpp ├── Trampoline.hpp ├── Trampoline.t.cpp ├── WebKit.mk ├── autogen.sh ├── com.saurik.Cyrver.plist ├── config.guess ├── config.rpath ├── config.sub ├── configure ├── configure.ac ├── control.in ├── cycript.hpp ├── cycript.xml ├── documents.txt ├── find_apr.m4 ├── framework.m4 ├── iPhone.mk ├── iPhone.sh ├── include ├── System │ └── machine │ │ └── cpu_capabilities.h ├── machine │ └── cpu_capabilities.h ├── posix_sched.h ├── pthread_internals.h ├── pthread_machdep.h └── pthread_spinlock.h ├── install-sh ├── ltmain.sh ├── makefile ├── missing ├── sig ├── copy.cpp ├── ffi_type.cpp ├── ffi_type.hpp ├── parse.cpp ├── parse.hpp └── types.hpp ├── todo.txt ├── trampoline.sh └── website └── index.html /Baton.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | struct Baton { 27 | void (*__pthread_set_self)(pthread_t); 28 | 29 | int (*pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *); 30 | int (*pthread_join)(pthread_t, void **); 31 | 32 | void *(*dlopen)(const char *, int); 33 | char *(*dlerror)(); 34 | void *(*dlsym)(void *, const char *); 35 | 36 | mach_port_t (*mach_thread_self)(); 37 | kern_return_t (*thread_terminate)(thread_act_t); 38 | 39 | pid_t pid; 40 | char library[]; 41 | }; 42 | -------------------------------------------------------------------------------- /Bridge.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include 23 | #include "Bridge.hpp" 24 | 25 | extern "C" struct CYBridgeEntry *CYBridgeHash(const char *data, size_t size) { 26 | return CYBridgeHash_(data, size); 27 | } 28 | -------------------------------------------------------------------------------- /Bridge.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cat << EOF 4 | %{ 5 | #include 6 | #include "Execute.hpp" 7 | %} 8 | 9 | %language=ANSI-C 10 | 11 | %define lookup-function-name CYBridgeHash_ 12 | %define slot-name name_ 13 | 14 | %struct-type 15 | %omit-struct-type 16 | 17 | %pic 18 | 19 | struct CYBridgeEntry { 20 | int name_; 21 | const char *value_; 22 | void *cache_; 23 | }; 24 | 25 | %% 26 | EOF 27 | 28 | grep '^[CFV]' "$1" | sed -e 's/^C/0/;s/^F/1/;s/^V/2/' | sed -e 's/"/\\"/g;s/^\([^ ]*\) \([^ ]*\) \(.*\)$/\1\2, "\3", NULL/'; 29 | grep '^[EST]' "$1" | sed -e 's/^S/3/;s/^T/4/;s/^E/5/' | sed -e 's/^5\(.*\)$/4\1 i/;s/"/\\"/g' | sed -e 's/^\([^ ]*\) \([^ ]*\) \(.*\)$/\1\2, "\3", NULL/'; 30 | grep '^:' "$1" | sed -e 's/^: \([^ ]*\) \(.*\)/6\1, "\2", NULL/'; 31 | -------------------------------------------------------------------------------- /COPYING.LESSER: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /CYGWIN_NT-6.1.mk: -------------------------------------------------------------------------------- 1 | lib := 2 | dll := dll 3 | library += -liconv 4 | -------------------------------------------------------------------------------- /Darwin-arm.mk: -------------------------------------------------------------------------------- 1 | flags += -F${PKG_ROOT}/System/Library/PrivateFrameworks 2 | 3 | all += #cyrver 4 | 5 | arch := iphoneos-arm 6 | console += -framework UIKit 7 | depends += apr-lib readline libffi mobilesubstrate 8 | #library += -framework CFNetwork 9 | library += -framework WebCore 10 | # XXX: all Darwin, maybe all device, should have this 11 | library += -lsubstrate 12 | 13 | ldid := ldid -S 14 | entitle := ldid -Scycript.xml 15 | 16 | cyrver: Server.o 17 | $(target)g++ $(flags) -o $@ $(filter %.o,$^) \ 18 | -lapr-1 -lsubstrate -framework CFNetwork 19 | $(ldid) $@ 20 | 21 | extra:: 22 | sed -i -e '/^Depends: / s/\/mobilesubstrate (>= 0.9.3072)/g' package/DEBIAN/control 23 | #mkdir -p package/System/Library/LaunchDaemons 24 | #cp -pR com.saurik.Cyrver.plist package/System/Library/LaunchDaemons 25 | -------------------------------------------------------------------------------- /Darwin.mk: -------------------------------------------------------------------------------- 1 | prefix := /sw 2 | 3 | dll := dylib 4 | link += -lobjc -framework CoreFoundation 5 | console += -framework Foundation 6 | library += -install_name $(prefix)/lib/libcycript.$(dll) 7 | library += -framework Foundation 8 | console += -framework JavaScriptCore 9 | # XXX: do I just need WebCore? 10 | console += -framework WebKit 11 | library += -undefined dynamic_lookup 12 | library += -liconv 13 | flags += -I/usr/include/ffi 14 | apr_config := /usr/bin/apr-1-config 15 | flags += -arch i386 -arch x86_64 #-arch armv6 16 | 17 | flags += -mmacosx-version-min=10.5 18 | 19 | flags += -DCY_ATTACH -DCY_LIBRARY='"$(prefix)/lib/libcycript.dylib"' 20 | code += Handler.o 21 | inject += Mach/Inject.o 22 | Mach/Inject.o: Trampoline.t.hpp Baton.hpp 23 | 24 | %.t.hpp: %.t.cpp trampoline.sh Baton.hpp Trampoline.hpp Darwin.mk 25 | ./trampoline.sh $@ $*.t.dylib $* sed $(target){otool,lipo,nm,gcc} $(flags) -dynamiclib -g0 -fno-stack-protector -fno-exceptions -Iinclude $< -o $*.t.dylib 26 | 27 | clean:: 28 | rm -f Trampoline.t.hpp 29 | 30 | include Execute.mk 31 | include ObjectiveC.mk 32 | -------------------------------------------------------------------------------- /E4X/Syntax.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_E4X_SYNTAX_HPP 23 | #define CYCRIPT_E4X_SYNTAX_HPP 24 | 25 | #include "Parser.hpp" 26 | 27 | struct CYDefaultXMLNamespace : 28 | CYStatement 29 | { 30 | CYExpression *expression_; 31 | 32 | CYDefaultXMLNamespace(CYExpression *expression) : 33 | expression_(expression) 34 | { 35 | } 36 | 37 | virtual CYStatement *Replace(CYContext &context); 38 | virtual void Output(CYOutput &out, CYFlags flags) const; 39 | }; 40 | 41 | struct CYPropertyIdentifier { 42 | }; 43 | 44 | struct CYSelector 45 | { 46 | }; 47 | 48 | struct CYWildcard : 49 | CYPropertyIdentifier, 50 | CYSelector 51 | { 52 | virtual CYExpression *Replace(CYContext &context); 53 | virtual void Output(CYOutput &out, CYFlags flags) const; 54 | }; 55 | 56 | struct CYQualified : 57 | CYPropertyIdentifier 58 | { 59 | CYSelector *namespace_; 60 | CYSelector *name_; 61 | 62 | CYQualified(CYSelector *_namespace, CYSelector *name) : 63 | namespace_(_namespace), 64 | name_(name) 65 | { 66 | } 67 | }; 68 | 69 | struct CYPropertyVariable : 70 | CYExpression 71 | { 72 | CYPropertyIdentifier *identifier_; 73 | 74 | CYPropertyVariable(CYPropertyIdentifier *identifier) : 75 | identifier_(identifier) 76 | { 77 | } 78 | 79 | CYPrecedence(0) 80 | 81 | virtual CYExpression *Replace(CYContext &context); 82 | virtual void Output(CYOutput &out, CYFlags flags) const; 83 | }; 84 | 85 | struct CYAttribute : 86 | CYPropertyIdentifier 87 | { 88 | CYQualified *identifier_; 89 | 90 | CYAttribute(CYQualified *identifier) : 91 | identifier_(identifier) 92 | { 93 | } 94 | }; 95 | 96 | #endif/*CYCRIPT_E4X_SYNTAX_HPP*/ 97 | -------------------------------------------------------------------------------- /Error.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_ERROR_HPP 23 | #define CYCRIPT_ERROR_HPP 24 | 25 | #include "Pooling.hpp" 26 | #include "Exception.hpp" 27 | 28 | #ifdef CY_EXECUTE 29 | struct CYJSError : 30 | CYException 31 | { 32 | JSContextRef context_; 33 | JSValueRef value_; 34 | 35 | CYJSError(JSContextRef context, JSValueRef value) : 36 | context_(context), 37 | value_(value) 38 | { 39 | } 40 | 41 | CYJSError(JSContextRef context, const char *format, ...); 42 | 43 | virtual const char *PoolCString(apr_pool_t *pool) const; 44 | virtual JSValueRef CastJSValue(JSContextRef context) const; 45 | }; 46 | #endif 47 | 48 | struct CYPoolError : 49 | CYException 50 | { 51 | CYPool pool_; 52 | const char *message_; 53 | 54 | CYPoolError(const char *format, ...); 55 | CYPoolError(const char *format, va_list args); 56 | 57 | virtual const char *PoolCString(apr_pool_t *pool) const; 58 | #ifdef CY_EXECUTE 59 | virtual JSValueRef CastJSValue(JSContextRef context) const; 60 | #endif 61 | }; 62 | 63 | #endif/*CYCRIPT_ERROR_HPP*/ 64 | -------------------------------------------------------------------------------- /Exception.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_EXCEPTION_HPP 23 | #define CYCRIPT_EXCEPTION_HPP 24 | 25 | #ifdef CY_EXECUTE 26 | #include 27 | #endif 28 | 29 | #include 30 | #include "Standard.hpp" 31 | 32 | struct CYException { 33 | virtual ~CYException() { 34 | } 35 | 36 | virtual const char *PoolCString(apr_pool_t *pool) const = 0; 37 | #ifdef CY_EXECUTE 38 | virtual JSValueRef CastJSValue(JSContextRef context) const = 0; 39 | #endif 40 | }; 41 | 42 | void CYThrow(const char *format, ...) _noreturn; 43 | 44 | #ifdef CY_EXECUTE 45 | void CYThrow(JSContextRef context, JSValueRef value); 46 | #endif 47 | 48 | #define CYTry \ 49 | try 50 | #define CYCatch \ 51 | catch (const CYException &error) { \ 52 | *exception = error.CastJSValue(context); \ 53 | return NULL; \ 54 | } catch (...) { \ 55 | *exception = CYCastJSValue(context, "catch(...)"); \ 56 | return NULL; \ 57 | } 58 | 59 | // XXX: fix this: _ is not safe; this is /not/ Menes ;P 60 | #undef _assert 61 | #define _assert(test, args...) do { \ 62 | if (!(test)) \ 63 | CYThrow("*** _assert(%s):%s(%u):%s [errno=%d]", #test, __FILE__, __LINE__, __FUNCTION__, errno); \ 64 | } while (false) 65 | 66 | #define _trace() do { \ 67 | fprintf(stderr, "_trace():%u\n", __LINE__); \ 68 | } while (false) 69 | 70 | #define _syscall(expr) ({ \ 71 | __typeof__(expr) _value; \ 72 | do if ((long) (_value = (expr)) != -1) \ 73 | break; \ 74 | else switch (errno) { \ 75 | case EINTR: \ 76 | continue; \ 77 | default: \ 78 | _assert(false); \ 79 | } while (true); \ 80 | _value; \ 81 | }) 82 | 83 | #define _aprcall(expr) \ 84 | do { \ 85 | apr_status_t _aprstatus((expr)); \ 86 | _assert(_aprstatus == APR_SUCCESS); \ 87 | } while (false) 88 | 89 | #define _krncall(expr) \ 90 | do { \ 91 | kern_return_t _krnstatus((expr)); \ 92 | _assert(_krnstatus == KERN_SUCCESS); \ 93 | } while (false) 94 | 95 | #define _sqlcall(expr) ({ \ 96 | __typeof__(expr) _value = (expr); \ 97 | if (_value != 0 && (_value < 100 || _value >= 200)) \ 98 | _assert(false, "_sqlcall(%u:%s): %s\n", _value, #expr, sqlite3_errmsg(database_)); \ 99 | _value; \ 100 | }) 101 | 102 | #endif/*CYCRIPT_ERROR_HPP*/ 103 | -------------------------------------------------------------------------------- /Execute.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_EXECUTE_HPP 23 | #define CYCRIPT_EXECUTE_HPP 24 | 25 | struct CYBridgeEntry { 26 | int name_; 27 | const char *value_; 28 | void *cache_; 29 | }; 30 | 31 | extern "C" struct CYBridgeEntry *CYBridgeHash(const char *data, size_t size); 32 | 33 | #endif/*CYCRIPT_EXECUTE_HPP*/ 34 | -------------------------------------------------------------------------------- /Execute.mk: -------------------------------------------------------------------------------- 1 | CY_EXECUTE := 1 2 | flags += -DCY_EXECUTE 3 | code += sig/ffi_type.o sig/parse.o sig/copy.o 4 | code += Execute.o Bridge.o 5 | library += -lffi 6 | filters += C 7 | header += JavaScript.hpp 8 | 9 | Bridge.gperf: Bridge.def Bridge.sh 10 | ./Bridge.sh Bridge.def >Bridge.gperf 11 | 12 | Bridge.hpp: Bridge.gperf 13 | gperf $< | sed -e 's/defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__/0/' >$@ 14 | 15 | Bridge.o: Bridge.hpp 16 | -------------------------------------------------------------------------------- /Filter.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | filters=("$@") 4 | 5 | while IFS= read -r line; do 6 | if [[ ${line} = @if* ]]; then 7 | line=${line#@if } 8 | for name in "${filters[@]}"; do 9 | if [[ ${line} = ${name}' '* ]]; then 10 | echo "${line#${name} }" 11 | fi 12 | done 13 | elif [[ ${line} = @begin* ]]; then 14 | set ${line}; shift 15 | filter= 16 | for name in "${filters[@]}"; do 17 | for side in "$@"; do 18 | if [[ ${name} == ${side} ]]; then 19 | unset filter 20 | fi 21 | done 22 | done 23 | elif [[ ${line} = @end ]]; then 24 | unset filter 25 | elif [[ -z ${filter+@} ]]; then 26 | echo "${line}" 27 | fi 28 | done 29 | -------------------------------------------------------------------------------- /FreeBSD.mk: -------------------------------------------------------------------------------- 1 | export PATH := /usr/local/bin:/usr/local/GNUstep/System/Tools:$(PATH) 2 | gcc := g++42 3 | flags += -fPIC 4 | include WebKit.mk 5 | -------------------------------------------------------------------------------- /GNUmakefile.in: -------------------------------------------------------------------------------- 1 | # @configure_input@ 2 | 3 | SHELL := @_BASH@ 4 | VPATH := @srcdir@ 5 | 6 | ifndef PKG_TARG 7 | target := 8 | else 9 | target := $(PKG_TARG)- 10 | endif 11 | 12 | srcdir := @srcdir@ 13 | top_builddir := @top_builddir@ 14 | flex := @FLEX@ 15 | libtool := @LIBTOOL@ 16 | cxx := @CXX@ 17 | objcxx := @OBJCXX@ 18 | cflags := @CPPFLAGS@ @CXXFLAGS@ -DYYDEBUG=1 $(filter -DHAVE_FFI% -DHAVE_READLINE% -DHAVE_HISTORY_H,@DEFS@) 19 | objcxxflags := @OBJCXXFLAGS@ 20 | ldflags := @LDFLAGS@ 21 | library := @LIBS@ @LTLIBAPR@ @LTLIBICONV@ 22 | sed := @SED@ 23 | bison := @BISON@ 24 | time := @TIME@ 25 | gperf := @GPERF@ 26 | otool := @_OTOOL@ 27 | lipo := @_LIPO@ 28 | nm := @_NM@ 29 | 30 | INSTALL := @INSTALL@ 31 | INSTALL_PROGRAM := @INSTALL_PROGRAM@ 32 | INSTALL_DATA := @INSTALL_DATA@ 33 | 34 | PACKAGE_TARNAME := @PACKAGE_TARNAME@ 35 | prefix := @prefix@ 36 | exec_prefix := @exec_prefix@ 37 | bindir := @bindir@ 38 | sbindir := @sbindir@ 39 | libexecdir := @libexecdir@ 40 | datarootdir := @datarootdir@ 41 | datadir := @datadir@ 42 | sysconfdir := @sysconfdir@ 43 | sharedstatedir := @sharedstatedir@ 44 | localstatedir := @localstatedir@ 45 | includedir := @includedir@ 46 | oldincludedir := @oldincludedir@ 47 | docdir := @docdir@ 48 | infodir := @infodir@ 49 | htmldir := @htmldir@ 50 | dvidir := @dvidir@ 51 | pdfdir := @pdfdir@ 52 | psdir := @psdir@ 53 | libdir := @libdir@ 54 | localedir := @localedir@ 55 | mandir := @mandir@ 56 | 57 | CY_EXECUTE := @CY_EXECUTE@ 58 | CY_OBJECTIVEC := @CY_OBJECTIVEC@ 59 | CY_OBJECTIVEC_MACH := @CY_OBJECTIVEC_MACH@ 60 | CY_ATTACH_GROUP := @CY_ATTACH_GROUP@ 61 | 62 | svn := @SVN@ 63 | svnversion := @SVNVERSION@ 64 | 65 | ifneq ($(svnversion),) 66 | release := $(shell svnversion $(srcdir)) 67 | 68 | ifneq ($(release),exported) 69 | gnutar := @GNUTAR@ 70 | version := @PACKAGE_VERSION@.$(release) 71 | tarname := @PACKAGE_TARNAME@-$(version) 72 | endif 73 | endif 74 | 75 | paths := $(foreach path,$(paths),$(wildcard $(path))) 76 | cflags += $(foreach path,$(paths),-I$(path) -L$(path)) 77 | 78 | #svn := $(shell svnversion $(srcdir)) 79 | 80 | all: 81 | all := cycript 82 | 83 | #dpkg_architecture := $(shell which dpkg-architecture 2>/dev/null) 84 | #ifneq ($(dpkg_architecture),) 85 | #arch := $(shell $(dpkg_architecture) -qDEB_HOST_ARCH 2>/dev/null) 86 | #endif 87 | 88 | header := Cycript.tab.hh Parser.hpp Pooling.hpp List.hpp Local.hpp cycript.hpp Internal.hpp Error.hpp String.hpp Exception.hpp Standard.hpp 89 | 90 | code := 91 | code += Replace.lo Output.lo 92 | code += Cycript.tab.lo lex.cy.lo 93 | code += Network.lo Parser.lo 94 | code += JavaScriptCore.lo Library.lo 95 | 96 | inject := 97 | 98 | filters := #E4X 99 | ldid := true 100 | entitle := $(ldid) 101 | lib := lib 102 | dll := @SO@ 103 | depends := 104 | 105 | restart ?= $(MAKE) 106 | uname_s ?= $(shell uname -s) 107 | uname_p ?= $(shell uname -p) 108 | 109 | ifeq ($(CY_EXECUTE),1) 110 | cflags += -DCY_EXECUTE 111 | code += sig/ffi_type.lo sig/parse.lo sig/copy.lo 112 | code += Execute.lo Bridge.lo 113 | filters += C 114 | header += JavaScript.hpp 115 | endif 116 | 117 | cflags += -Wall -Werror -Wno-parentheses #-Wno-unused 118 | cflags += -fno-common 119 | ifneq ($(srcdir),.) 120 | cflags += -I. 121 | endif 122 | cflags += -I$(srcdir) -I$(srcdir)/include 123 | 124 | all += libcycript.la 125 | 126 | filters += $(shell $(bison) <(echo '%code{}%%_:') -o/dev/null 2>/dev/null && echo Bison24 || echo Bison23) 127 | 128 | ifdef arch 129 | deb := $(shell grep ^Package: $(srcdir)/control.in | cut -d ' ' -f 2-)_$(shell grep ^Version: $(srcdir)/control.in | cut -d ' ' -f 2 | $(sed) -e 's/\#/$(svn)/')_$(arch).deb 130 | 131 | all: 132 | 133 | extra:: 134 | 135 | ifeq ($(depends)$(dll),dylib) 136 | control.tmp: control.in cycript $(lib)cycript.dylib 137 | $(sed) -e 's/&/'"$$(dpkg-query -S $$(otool -lah cycript *.dylib | grep dylib | grep -v ':$$' | $(sed) -e 's/^ *name //;s/ (offset [0-9]*)$$//' | sort -u) 2>/dev/null | $(sed) -e 's/:.*//; /^cycript$$/ d; s/$$/,/' | sort -u | tr '\n' ' ')"'/;s/, $$//;s/#/$(svn)/;s/%/$(arch)/' $< >$@ 138 | else 139 | ifeq ($(depends)$(dll),so) 140 | control.tmp: control.in cycript $(lib)cycript.so 141 | $(sed) -e 's/&/'"$$(dpkg-query -S $$(ldd cycript $(lib)cycript.so | $(sed) -e '/:$$/ d; s/^[ \t]*\([^ ]* => \)\?\([^ ]*\) .*/\2/' | sort -u) 2>/dev/null | $(sed) -e 's/:.*//; /^cycript$$/ d; s/$$/,/' | sort -u | tr '\n' ' ')"'/;s/, $$//;s/#/$(svn)/;s/%/$(arch)/' $< >$@ 142 | else 143 | control.tmp: control.in 144 | $(sed) -e 's/&/$(foreach depend,$(depends),$(depend),)/;s/,$$//;s/#/$(svn)/;s/%/$(arch)/' $< >$@ 145 | endif 146 | endif 147 | 148 | control: control.tmp 149 | [[ -e control ]] && diff control control.tmp &>/dev/null || cp -pRf control.tmp control 150 | 151 | $(deb): $(all) control 152 | rm -rf package 153 | mkdir -p package/DEBIAN 154 | cp -pR control package/DEBIAN 155 | mkdir -p package/usr/{bin,lib,sbin} 156 | $(restart) extra 157 | cp -pR $(lib)cycript.$(dll) package/usr/lib 158 | cp -pR cycript package/usr/bin 159 | #cp -pR cyrver package/usr/sbin 160 | dpkg-deb -b package $(deb) 161 | endif 162 | 163 | ifeq ($(CY_EXECUTE),1) 164 | Bridge.gperf: Bridge.def Bridge.sh 165 | $(srcdir)/Bridge.sh $< >$@ 166 | 167 | Bridge.hpp: Bridge.gperf 168 | $(gperf) $< | $(sed) -e 's/defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__/0/' >$@ 169 | 170 | Bridge.lo: Bridge.hpp 171 | endif 172 | 173 | ifeq ($(CY_OBJECTIVEC),1) 174 | filters += ObjectiveC 175 | header += Struct.hpp ObjectiveC/Internal.hpp ObjectiveC/Syntax.hpp 176 | code += ObjectiveC/Output.lo ObjectiveC/Replace.lo ObjectiveC/Library.lo 177 | 178 | Struct.hpp: 179 | $$($(objcxx) -print-prog-name=cc1obj) -print-objc-runtime-info $@ 180 | 181 | ifeq ($(CY_OBJECTIVEC_MACH),1) 182 | code += Handler.lo 183 | cflags += -DCY_ATTACH -DCY_LIBRARY='"$(libdir)/libcycript.$(dll)"' 184 | inject += Mach/Inject.lo 185 | 186 | Mach/Inject.lo: Trampoline.t.hpp Baton.hpp 187 | 188 | %.t.lo: %.t.cpp Baton.hpp Trampoline.hpp 189 | $(libtool) --mode=compile $(cxx) $(cflags) -c -o $@ $< -fno-stack-protector -fno-exceptions 190 | 191 | %.t.hpp: %.t.lo trampoline.sh 192 | $(srcdir)/trampoline.sh $@ .libs/lib$*.t.$(dll) $* $(sed) $(otool) $(lipo) $(nm) $(libtool) --mode=link $(cxx) $(ldflags) -o lib$*.t.la $< -rpath $(libdir) 193 | endif 194 | endif 195 | 196 | all: $(all) 197 | 198 | clean:: 199 | rm -rf *.lo *.o *.d *.t.hpp .libs */*.d */*.lo */.libs lib*.la $(all) Struct.hpp lex.cy.c Cycript.tab.cc Cycript.tab.hh location.hh position.hh stack.hh cyrver Cycript.yy Cycript.l control Bridge.gperf Bridge.hpp Cycript.output 200 | ifneq ($(srcdir),.) 201 | rm -rf Mach ObjectiveC sig 202 | endif 203 | 204 | distclean: clean 205 | rm -f GNUmakefile Makefile config.log config.status libtool 206 | 207 | %.yy: %.yy.in 208 | $(srcdir)/Filter.sh <$< >$@ $(filters) 209 | 210 | %.l: %.l.in 211 | $(srcdir)/Filter.sh <$< >$@ $(filters) 212 | 213 | Cycript.tab.cc Cycript.tab.hh location.hh position.hh: Cycript.yy 214 | $(bison) -v --report=state $< 215 | 216 | lex.cy.c: Cycript.l 217 | $(flex) -t $< | $(sed) -e 's/int yyl;/yy_size_t yyl;/;s/int yyleng_r;/yy_size_t yyleng_r;/' >$@ 218 | 219 | #Parser.hpp: Parser.py Parser.dat 220 | # ./Parser.py $@ 221 | 222 | Cycript.tab.lo: Cycript.tab.cc $(header) 223 | $(libtool) --mode=compile $(cxx) $(cflags) -c -o $@ $< 224 | 225 | lex.cy.lo: lex.cy.c $(header) 226 | $(libtool) --mode=compile $(cxx) $(cflags) -c -o $@ $< 227 | 228 | %.lo: %.cpp $(header) 229 | $(libtool) --mode=compile $(cxx) $(cflags) -c -o $@ $< 230 | 231 | %.lo: %.mm $(header) 232 | $(libtool) --mode=compile $(objcxx) $(objcxxflags) $(cflags) -c -o $@ $< 233 | 234 | libcycript.la: $(code) 235 | $(libtool) --mode=link $(cxx) $(ldflags) -o $@ $(filter %.lo,$^) $(library) $(link) -rpath $(libdir) 236 | $(ldid) $@ 237 | 238 | cycript: Console.lo libcycript.la $(inject) 239 | $(libtool) --mode=link $(cxx) $(ldflags) -o $@ $(filter %.lo,$^) libcycript.la $(link) -rpath $(libdir) 240 | $(entitle) cycript 241 | 242 | package: $(deb) 243 | 244 | test: cycript 245 | if [[ -e target.cy ]]; then ./cycript -c target.cy && echo; fi 246 | if [[ -e jquery.js ]]; then $(time) ./cycript -c jquery.js >jquery.cyc.js; gzip -9c jquery.cyc.js >jquery.cyc.js.gz; wc -c jquery.{mam,gcc,cyc,bak,yui}.js; wc -c jquery.{cyc,gcc,bak,mam,yui}.js.gz; fi 247 | if [[ -e test.cy ]]; then ./cycript test.cy; fi 248 | 249 | ifneq ($(gnutar),:) 250 | dist: 251 | echo -n >> $(tarname).tar.gz 252 | $(gnutar) -cC $(srcdir) -f $(tarname).tar.gz -vX <($(svn) propget svn:ignore $(srcdir)) -z --exclude-vcs --show-transformed-names --transform='s#^\.#$(tarname)#' . 253 | endif 254 | 255 | install: cycript libcycript.la 256 | $(INSTALL) -d $(DESTDIR)$(bindir) $(DESTDIR)$(libdir) 257 | $(libtool) --mode=install $(INSTALL_PROGRAM) libcycript.la $(DESTDIR)$(libdir)/libcycript.la 258 | $(libtool) --mode=install $(INSTALL_PROGRAM) cycript $(DESTDIR)$(bindir)/cycript 259 | ifneq ($(CY_ATTACH_GROUP),) 260 | chgrp $(CY_ATTACH_GROUP) $(DESTDIR)$(bindir)/cycript 261 | chmod g+s $(DESTDIR)$(bindir)/cycript 262 | endif 263 | 264 | uninstall: 265 | $(libtool) --mode=uninstall rm -f $(DESTDIR)$(bindir)/cycript 266 | $(libtool) --mode=uninstall rm -f $(DESTDIR)$(libdir)/libcycript.la 267 | 268 | .PHONY: all clean extra dist install uninstall package test control.tmp 269 | -------------------------------------------------------------------------------- /GNUstep.mk: -------------------------------------------------------------------------------- 1 | objc += $(shell gnustep-config --objc-flags) 2 | link += $(shell gnustep-config --base-libs) 3 | include ObjectiveC.mk 4 | -------------------------------------------------------------------------------- /Handler.mm: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include "cycript.hpp" 23 | #include "JavaScript.hpp" 24 | 25 | #include "Pooling.hpp" 26 | #include "Parser.hpp" 27 | 28 | #include "Cycript.tab.hh" 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | struct CYExecute_ { 41 | apr_pool_t *pool_; 42 | const char * volatile data_; 43 | }; 44 | 45 | // XXX: this is "tre lame" 46 | @interface CYClient_ : NSObject { 47 | } 48 | 49 | - (void) execute:(NSValue *)value; 50 | 51 | @end 52 | 53 | @implementation CYClient_ 54 | 55 | - (void) execute:(NSValue *)value { 56 | CYExecute_ *execute(reinterpret_cast([value pointerValue])); 57 | const char *data(execute->data_); 58 | execute->data_ = NULL; 59 | execute->data_ = CYExecute(execute->pool_, CYUTF8String(data)); 60 | } 61 | 62 | @end 63 | 64 | struct CYClient : 65 | CYData 66 | { 67 | int socket_; 68 | apr_thread_t *thread_; 69 | 70 | CYClient(int socket) : 71 | socket_(socket) 72 | { 73 | } 74 | 75 | ~CYClient() { 76 | _syscall(close(socket_)); 77 | } 78 | 79 | void Handle() { 80 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 81 | 82 | CYClient_ *client = [[[CYClient_ alloc] init] autorelease]; 83 | 84 | bool dispatch; 85 | if (CFStringRef mode = CFRunLoopCopyCurrentMode(CFRunLoopGetMain())) { 86 | dispatch = true; 87 | CFRelease(mode); 88 | } else 89 | dispatch = false; 90 | 91 | for (;;) { 92 | size_t size; 93 | if (!CYRecvAll(socket_, &size, sizeof(size))) 94 | return; 95 | 96 | CYLocalPool pool; 97 | char *data(new(pool) char[size + 1]); 98 | if (!CYRecvAll(socket_, data, size)) 99 | return; 100 | data[size] = '\0'; 101 | 102 | CYDriver driver; 103 | cy::parser parser(driver); 104 | 105 | driver.data_ = data; 106 | driver.size_ = size; 107 | 108 | const char *json; 109 | if (parser.parse() != 0 || !driver.errors_.empty()) { 110 | json = NULL; 111 | size = _not(size_t); 112 | } else { 113 | NSAutoreleasePool *ar = [[NSAutoreleasePool alloc] init]; 114 | 115 | CYOptions options; 116 | CYContext context(options); 117 | driver.program_->Replace(context); 118 | std::ostringstream str; 119 | CYOutput out(str, options); 120 | out << *driver.program_; 121 | std::string code(str.str()); 122 | CYExecute_ execute = {pool, code.c_str()}; 123 | NSValue *value([NSValue valueWithPointer:&execute]); 124 | if (dispatch) 125 | [client performSelectorOnMainThread:@selector(execute:) withObject:value waitUntilDone:YES]; 126 | else 127 | [client execute:value]; 128 | json = execute.data_; 129 | size = json == NULL ? _not(size_t) : strlen(json); 130 | 131 | [ar release]; 132 | } 133 | 134 | if (!CYSendAll(socket_, &size, sizeof(size))) 135 | return; 136 | if (json != NULL) 137 | if (!CYSendAll(socket_, json, size)) 138 | return; 139 | } 140 | 141 | [pool release]; 142 | } 143 | }; 144 | 145 | static void * APR_THREAD_FUNC OnClient(apr_thread_t *thread, void *data) { 146 | CYClient *client(reinterpret_cast(data)); 147 | client->Handle(); 148 | delete client; 149 | return NULL; 150 | } 151 | 152 | extern "C" void CYHandleClient(apr_pool_t *pool, int socket) { 153 | CYClient *client(new(pool) CYClient(socket)); 154 | apr_threadattr_t *attr; 155 | _aprcall(apr_threadattr_create(&attr, client->pool_)); 156 | _aprcall(apr_thread_create(&client->thread_, attr, &OnClient, client, client->pool_)); 157 | } 158 | 159 | extern "C" void CYHandleServer(pid_t pid) { 160 | CYInitializeDynamic(); 161 | 162 | int socket(_syscall(::socket(PF_UNIX, SOCK_STREAM, 0))); try { 163 | struct sockaddr_un address; 164 | memset(&address, 0, sizeof(address)); 165 | address.sun_family = AF_UNIX; 166 | sprintf(address.sun_path, "/tmp/.s.cy.%u", pid); 167 | 168 | _syscall(connect(socket, reinterpret_cast(&address), SUN_LEN(&address))); 169 | 170 | apr_pool_t *pool; 171 | apr_pool_create(&pool, NULL); 172 | 173 | CYHandleClient(pool, socket); 174 | } catch (const CYException &error) { 175 | CYPool pool; 176 | fprintf(stderr, "%s\n", error.PoolCString(pool)); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /Internal.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_INTERNAL_HPP 23 | #define CYCRIPT_INTERNAL_HPP 24 | 25 | #include "Pooling.hpp" 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | JSGlobalContextRef CYGetJSContext(JSContextRef context); 36 | void Structor_(apr_pool_t *pool, sig::Type *&type); 37 | 38 | struct Type_privateData : 39 | CYData 40 | { 41 | static JSClassRef Class_; 42 | 43 | ffi_type *ffi_; 44 | sig::Type *type_; 45 | 46 | void Set(sig::Type *type) { 47 | type_ = new(pool_) sig::Type; 48 | sig::Copy(pool_, *type_, *type); 49 | } 50 | 51 | Type_privateData(apr_pool_t *pool, const char *type) : 52 | ffi_(NULL) 53 | { 54 | _assert(pool != NULL); 55 | pool_ = pool; 56 | sig::Signature signature; 57 | sig::Parse(pool_, &signature, type, &Structor_); 58 | type_ = signature.elements[0].type; 59 | } 60 | 61 | Type_privateData(const char *type) : 62 | ffi_(NULL) 63 | { 64 | sig::Signature signature; 65 | sig::Parse(pool_, &signature, type, &Structor_); 66 | type_ = signature.elements[0].type; 67 | } 68 | 69 | Type_privateData(sig::Type *type) : 70 | ffi_(NULL) 71 | { 72 | if (type != NULL) 73 | Set(type); 74 | } 75 | 76 | Type_privateData(sig::Type *type, ffi_type *ffi) { 77 | ffi_ = new(pool_) ffi_type; 78 | sig::Copy(pool_, *ffi_, *ffi); 79 | Set(type); 80 | } 81 | 82 | ffi_type *GetFFI() { 83 | if (ffi_ == NULL) { 84 | ffi_ = new(pool_) ffi_type; 85 | 86 | sig::Element element; 87 | element.name = NULL; 88 | element.type = type_; 89 | element.offset = 0; 90 | 91 | sig::Signature signature; 92 | signature.elements = &element; 93 | signature.count = 1; 94 | 95 | ffi_cif cif; 96 | sig::sig_ffi_cif(pool_, &sig::ObjectiveC, &signature, &cif); 97 | *ffi_ = *cif.rtype; 98 | } 99 | 100 | return ffi_; 101 | } 102 | }; 103 | 104 | struct CYValue : 105 | CYData 106 | { 107 | void *value_; 108 | 109 | CYValue() { 110 | } 111 | 112 | CYValue(const void *value) : 113 | value_(const_cast(value)) 114 | { 115 | } 116 | 117 | CYValue(const CYValue &rhs) : 118 | value_(rhs.value_) 119 | { 120 | } 121 | 122 | virtual Type_privateData *GetType() const { 123 | return NULL; 124 | } 125 | }; 126 | 127 | struct CYOwned : 128 | CYValue 129 | { 130 | private: 131 | JSGlobalContextRef context_; 132 | JSObjectRef owner_; 133 | 134 | public: 135 | CYOwned(void *value, JSContextRef context, JSObjectRef owner) : 136 | CYValue(value), 137 | context_(CYGetJSContext(context)), 138 | owner_(owner) 139 | { 140 | //XXX:JSGlobalContextRetain(context_); 141 | if (owner_ != NULL) 142 | JSValueProtect(context_, owner_); 143 | } 144 | 145 | virtual ~CYOwned() { 146 | if (owner_ != NULL) 147 | JSValueUnprotect(context_, owner_); 148 | //XXX:JSGlobalContextRelease(context_); 149 | } 150 | 151 | JSObjectRef GetOwner() const { 152 | return owner_; 153 | } 154 | }; 155 | 156 | namespace cy { 157 | struct Functor : 158 | CYValue 159 | { 160 | sig::Signature signature_; 161 | ffi_cif cif_; 162 | 163 | Functor(const char *type, void (*value)()) : 164 | CYValue(reinterpret_cast(value)) 165 | { 166 | sig::Parse(pool_, &signature_, type, &Structor_); 167 | sig::sig_ffi_cif(pool_, &sig::ObjectiveC, &signature_, &cif_); 168 | } 169 | 170 | void (*GetValue())() const { 171 | return reinterpret_cast(value_); 172 | } 173 | 174 | static JSStaticFunction const * const StaticFunctions; 175 | }; } 176 | 177 | struct Closure_privateData : 178 | cy::Functor 179 | { 180 | JSGlobalContextRef context_; 181 | JSObjectRef function_; 182 | 183 | Closure_privateData(JSContextRef context, JSObjectRef function, const char *type) : 184 | cy::Functor(type, NULL), 185 | context_(CYGetJSContext(context)), 186 | function_(function) 187 | { 188 | //XXX:JSGlobalContextRetain(context_); 189 | JSValueProtect(context_, function_); 190 | } 191 | 192 | virtual ~Closure_privateData() { 193 | JSValueUnprotect(context_, function_); 194 | //XXX:JSGlobalContextRelease(context_); 195 | } 196 | }; 197 | 198 | Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, const char *type, void (*callback)(ffi_cif *, void *, void **, void *)); 199 | 200 | #endif/*CYCRIPT_INTERNAL_HPP*/ 201 | -------------------------------------------------------------------------------- /JavaScript.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_JAVASCRIPT_HPP 23 | #define CYCRIPT_JAVASCRIPT_HPP 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #ifdef HAVE_FFI_FFI_H 32 | #include 33 | #else 34 | #include 35 | #endif 36 | 37 | extern JSStringRef Array_s; 38 | extern JSStringRef cy_s; 39 | extern JSStringRef length_s; 40 | extern JSStringRef message_s; 41 | extern JSStringRef name_s; 42 | extern JSStringRef pop_s; 43 | extern JSStringRef prototype_s; 44 | extern JSStringRef push_s; 45 | extern JSStringRef splice_s; 46 | extern JSStringRef toCYON_s; 47 | extern JSStringRef toJSON_s; 48 | extern JSStringRef toPointer_s; 49 | extern JSStringRef toString_s; 50 | 51 | void CYInitializeDynamic(); 52 | JSGlobalContextRef CYGetJSContext(); 53 | JSObjectRef CYGetGlobalObject(JSContextRef context); 54 | 55 | extern "C" void CYSetupContext(JSGlobalContextRef context); 56 | const char *CYExecute(apr_pool_t *pool, CYUTF8String code); 57 | 58 | void CYSetArgs(int argc, const char *argv[]); 59 | 60 | bool CYCastBool(JSContextRef context, JSValueRef value); 61 | double CYCastDouble(JSContextRef context, JSValueRef value); 62 | 63 | CYUTF8String CYPoolUTF8String(apr_pool_t *pool, JSContextRef context, JSStringRef value); 64 | const char *CYPoolCString(apr_pool_t *pool, JSContextRef context, JSStringRef value); 65 | 66 | JSValueRef CYGetProperty(JSContextRef context, JSObjectRef object, size_t index); 67 | JSValueRef CYGetProperty(JSContextRef context, JSObjectRef object, JSStringRef name); 68 | 69 | void CYSetProperty(JSContextRef context, JSObjectRef object, size_t index, JSValueRef value); 70 | void CYSetProperty(JSContextRef context, JSObjectRef object, JSStringRef name, JSValueRef value, JSPropertyAttributes attributes = kJSPropertyAttributeNone); 71 | void CYSetProperty(JSContextRef context, JSObjectRef object, JSStringRef name, JSValueRef (*callback)(JSContextRef, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef *), JSPropertyAttributes attributes = kJSPropertyAttributeNone); 72 | 73 | JSObjectRef CYGetCachedObject(JSContextRef context, JSStringRef name); 74 | 75 | JSValueRef CYCastJSValue(JSContextRef context, bool value); 76 | JSValueRef CYCastJSValue(JSContextRef context, double value); 77 | JSValueRef CYCastJSValue(JSContextRef context, int value); 78 | JSValueRef CYCastJSValue(JSContextRef context, unsigned int value); 79 | JSValueRef CYCastJSValue(JSContextRef context, long int value); 80 | JSValueRef CYCastJSValue(JSContextRef context, long unsigned int value); 81 | JSValueRef CYCastJSValue(JSContextRef context, long long int value); 82 | JSValueRef CYCastJSValue(JSContextRef context, long long unsigned int value); 83 | 84 | JSValueRef CYCastJSValue(JSContextRef context, JSStringRef value); 85 | JSValueRef CYCastJSValue(JSContextRef context, const char *value); 86 | 87 | JSObjectRef CYCastJSObject(JSContextRef context, JSValueRef value); 88 | JSValueRef CYJSUndefined(JSContextRef context); 89 | JSValueRef CYJSNull(JSContextRef context); 90 | 91 | void *CYCastPointer_(JSContextRef context, JSValueRef value); 92 | 93 | template 94 | _finline Type_ CYCastPointer(JSContextRef context, JSValueRef value) { 95 | return reinterpret_cast(CYCastPointer_(context, value)); 96 | } 97 | 98 | void CYPoolFFI(apr_pool_t *pool, JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, JSValueRef value); 99 | JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void *data, bool initialize = false, JSObjectRef owner = NULL); 100 | 101 | JSValueRef CYCallFunction(apr_pool_t *pool, JSContextRef context, size_t setups, void *setup[], size_t count, const JSValueRef arguments[], bool initialize, JSValueRef *exception, sig::Signature *signature, ffi_cif *cif, void (*function)()); 102 | 103 | bool CYIsCallable(JSContextRef context, JSValueRef value); 104 | JSValueRef CYCallAsFunction(JSContextRef context, JSObjectRef function, JSObjectRef _this, size_t count, const JSValueRef arguments[]); 105 | 106 | const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSObjectRef object); 107 | 108 | struct CYHooks { 109 | void *(*ExecuteStart)(JSContextRef); 110 | void (*ExecuteEnd)(JSContextRef, void *); 111 | 112 | JSValueRef (*RuntimeProperty)(JSContextRef, CYUTF8String); 113 | void (*CallFunction)(JSContextRef, ffi_cif *, void (*)(), uint8_t *, void **); 114 | 115 | void (*Initialize)(); 116 | void (*SetupContext)(JSContextRef); 117 | 118 | bool (*PoolFFI)(apr_pool_t *, JSContextRef, sig::Type *, ffi_type *, void *, JSValueRef); 119 | JSValueRef (*FromFFI)(JSContextRef, sig::Type *, ffi_type *, void *, bool, JSObjectRef); 120 | }; 121 | 122 | extern struct CYHooks *hooks_; 123 | 124 | JSObjectRef CYMakePointer(JSContextRef context, void *pointer, size_t length, sig::Type *type, ffi_type *ffi, JSObjectRef owner); 125 | 126 | void CYFinalize(JSObjectRef object); 127 | 128 | const char *CYPoolCString(apr_pool_t *pool, JSContextRef context, JSValueRef value); 129 | 130 | JSStringRef CYCopyJSString(const char *value); 131 | JSStringRef CYCopyJSString(JSStringRef value); 132 | JSStringRef CYCopyJSString(CYUTF8String value); 133 | JSStringRef CYCopyJSString(JSContextRef context, JSValueRef value); 134 | 135 | class CYJSString { 136 | private: 137 | JSStringRef string_; 138 | 139 | void Clear_() { 140 | if (string_ != NULL) 141 | JSStringRelease(string_); 142 | } 143 | 144 | public: 145 | CYJSString(const CYJSString &rhs) : 146 | string_(CYCopyJSString(rhs.string_)) 147 | { 148 | } 149 | 150 | template 151 | CYJSString(Arg0_ arg0) : 152 | string_(CYCopyJSString(arg0)) 153 | { 154 | } 155 | 156 | template 157 | CYJSString(Arg0_ arg0, Arg1_ arg1) : 158 | string_(CYCopyJSString(arg0, arg1)) 159 | { 160 | } 161 | 162 | CYJSString &operator =(const CYJSString &rhs) { 163 | Clear_(); 164 | string_ = CYCopyJSString(rhs.string_); 165 | return *this; 166 | } 167 | 168 | ~CYJSString() { 169 | Clear_(); 170 | } 171 | 172 | void Clear() { 173 | Clear_(); 174 | string_ = NULL; 175 | } 176 | 177 | operator JSStringRef() const { 178 | return string_; 179 | } 180 | }; 181 | 182 | #endif/*CYCRIPT_JAVASCRIPT_HPP*/ 183 | -------------------------------------------------------------------------------- /JavaScriptCore.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include "cycript.hpp" 23 | -------------------------------------------------------------------------------- /Library.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include 23 | #include 24 | 25 | #include "cycript.hpp" 26 | 27 | #include "Pooling.hpp" 28 | 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include "Parser.hpp" 40 | #include "Cycript.tab.hh" 41 | 42 | #include "Error.hpp" 43 | #include "String.hpp" 44 | #include "Execute.hpp" 45 | 46 | /* C Strings {{{ */ 47 | template 48 | _finline size_t iconv_(size_t (*iconv)(iconv_t, Type_, size_t *, char **, size_t *), iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { 49 | return iconv(cd, const_cast(inbuf), inbytesleft, outbuf, outbytesleft); 50 | } 51 | 52 | #ifdef __GLIBC__ 53 | #define UCS_2_INTERNAL "UCS-2" 54 | #else 55 | #define UCS_2_INTERNAL "UCS-2-INTERNAL" 56 | #endif 57 | 58 | CYUTF8String CYPoolUTF8String(apr_pool_t *pool, CYUTF16String utf16) { 59 | _assert(pool != NULL); 60 | 61 | const char *in(reinterpret_cast(utf16.data)); 62 | 63 | iconv_t conversion(_syscall(iconv_open("UTF-8", UCS_2_INTERNAL))); 64 | 65 | // XXX: this is wrong 66 | size_t size(utf16.size * 5); 67 | char *out(new(pool) char[size]); 68 | CYUTF8String utf8(out, size); 69 | 70 | size = utf16.size * 2; 71 | _syscall(iconv_(&iconv, conversion, const_cast(&in), &size, &out, &utf8.size)); 72 | 73 | *out = '\0'; 74 | utf8.size = out - utf8.data; 75 | 76 | _syscall(iconv_close(conversion)); 77 | 78 | return utf8; 79 | } 80 | 81 | CYUTF16String CYPoolUTF16String(apr_pool_t *pool, CYUTF8String utf8) { 82 | _assert(pool != NULL); 83 | 84 | const char *in(utf8.data); 85 | 86 | iconv_t conversion(_syscall(iconv_open(UCS_2_INTERNAL, "UTF-8"))); 87 | 88 | // XXX: this is wrong 89 | size_t size(utf8.size * 5); 90 | uint16_t *temp(new (pool) uint16_t[size]); 91 | CYUTF16String utf16(temp, size * 2); 92 | char *out(reinterpret_cast(temp)); 93 | 94 | size = utf8.size; 95 | _syscall(iconv_(&iconv, conversion, const_cast(&in), &size, &out, &utf16.size)); 96 | 97 | utf16.size = reinterpret_cast(out) - utf16.data; 98 | temp[utf16.size] = 0; 99 | 100 | _syscall(iconv_close(conversion)); 101 | 102 | return utf16; 103 | } 104 | /* }}} */ 105 | /* Index Offsets {{{ */ 106 | size_t CYGetIndex(const CYUTF8String &value) { 107 | if (value.data[0] != '0') { 108 | size_t index(0); 109 | for (size_t i(0); i != value.size; ++i) { 110 | if (!DigitRange_[value.data[i]]) 111 | return _not(size_t); 112 | index *= 10; 113 | index += value.data[i] - '0'; 114 | } 115 | return index; 116 | } else if (value.size == 1) 117 | return 0; 118 | else 119 | return _not(size_t); 120 | } 121 | 122 | // XXX: this isn't actually right 123 | bool CYGetOffset(const char *value, ssize_t &index) { 124 | if (value[0] != '0') { 125 | char *end; 126 | index = strtol(value, &end, 10); 127 | if (value + strlen(value) == end) 128 | return true; 129 | } else if (value[1] == '\0') { 130 | index = 0; 131 | return true; 132 | } 133 | 134 | return false; 135 | } 136 | /* }}} */ 137 | /* JavaScript *ify {{{ */ 138 | void CYStringify(std::ostringstream &str, const char *data, size_t size) { 139 | unsigned quot(0), apos(0); 140 | for (const char *value(data), *end(data + size); value != end; ++value) 141 | if (*value == '"') 142 | ++quot; 143 | else if (*value == '\'') 144 | ++apos; 145 | 146 | bool single(quot > apos); 147 | 148 | str << (single ? '\'' : '"'); 149 | 150 | for (const char *value(data), *end(data + size); value != end; ++value) 151 | switch (*value) { 152 | case '\\': str << "\\\\"; break; 153 | case '\b': str << "\\b"; break; 154 | case '\f': str << "\\f"; break; 155 | case '\n': str << "\\n"; break; 156 | case '\r': str << "\\r"; break; 157 | case '\t': str << "\\t"; break; 158 | case '\v': str << "\\v"; break; 159 | 160 | case '"': 161 | if (!single) 162 | str << "\\\""; 163 | else goto simple; 164 | break; 165 | 166 | case '\'': 167 | if (single) 168 | str << "\\'"; 169 | else goto simple; 170 | break; 171 | 172 | default: 173 | // this test is designed to be "awesome", generating neither warnings nor incorrect results 174 | if (*value < 0x20 || *value >= 0x7f) 175 | str << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(uint8_t(*value)); 176 | else simple: 177 | str << *value; 178 | } 179 | 180 | str << (single ? '\'' : '"'); 181 | } 182 | 183 | void CYNumerify(std::ostringstream &str, double value) { 184 | char string[32]; 185 | // XXX: I want this to print 1e3 rather than 1000 186 | sprintf(string, "%.17g", value); 187 | str << string; 188 | } 189 | 190 | bool CYIsKey(CYUTF8String value) { 191 | const char *data(value.data); 192 | size_t size(value.size); 193 | 194 | if (size == 0) 195 | return false; 196 | 197 | if (DigitRange_[data[0]]) { 198 | size_t index(CYGetIndex(value)); 199 | if (index == _not(size_t)) 200 | return false; 201 | } else { 202 | if (!WordStartRange_[data[0]]) 203 | return false; 204 | for (size_t i(1); i != size; ++i) 205 | if (!WordEndRange_[data[i]]) 206 | return false; 207 | } 208 | 209 | return true; 210 | } 211 | /* }}} */ 212 | 213 | double CYCastDouble(const char *value, size_t size) { 214 | char *end; 215 | double number(strtod(value, &end)); 216 | if (end != value + size) 217 | return NAN; 218 | return number; 219 | } 220 | 221 | double CYCastDouble(const char *value) { 222 | return CYCastDouble(value, strlen(value)); 223 | } 224 | 225 | extern "C" void CydgetPoolParse(apr_pool_t *remote, const uint16_t **data, size_t *size) { 226 | CYLocalPool local; 227 | 228 | CYDriver driver; 229 | cy::parser parser(driver); 230 | 231 | CYUTF8String utf8(CYPoolUTF8String(local, CYUTF16String(*data, *size))); 232 | 233 | driver.data_ = utf8.data; 234 | driver.size_ = utf8.size; 235 | 236 | if (parser.parse() != 0 || !driver.errors_.empty()) 237 | return; 238 | 239 | CYOptions options; 240 | CYContext context(options); 241 | driver.program_->Replace(context); 242 | std::ostringstream str; 243 | CYOutput out(str, options); 244 | out << *driver.program_; 245 | std::string code(str.str()); 246 | 247 | CYUTF16String utf16(CYPoolUTF16String(remote, CYUTF8String(code.c_str(), code.size()))); 248 | 249 | *data = utf16.data; 250 | *size = utf16.size; 251 | } 252 | 253 | static apr_pool_t *Pool_; 254 | 255 | static bool initialized_; 256 | 257 | void CYInitializeStatic() { 258 | if (!initialized_) 259 | initialized_ = true; 260 | else return; 261 | 262 | _aprcall(apr_initialize()); 263 | _aprcall(apr_pool_create(&Pool_, NULL)); 264 | } 265 | 266 | apr_pool_t *CYGetGlobalPool() { 267 | CYInitializeStatic(); 268 | return Pool_; 269 | } 270 | 271 | void CYThrow(const char *format, ...) { 272 | va_list args; 273 | va_start(args, format); 274 | throw CYPoolError(format, args); 275 | // XXX: does this matter? :( 276 | va_end(args); 277 | } 278 | 279 | const char *CYPoolError::PoolCString(apr_pool_t *pool) const { 280 | return apr_pstrdup(pool, message_); 281 | } 282 | 283 | CYPoolError::CYPoolError(const char *format, ...) { 284 | va_list args; 285 | va_start(args, format); 286 | message_ = apr_pvsprintf(pool_, format, args); 287 | va_end(args); 288 | } 289 | 290 | CYPoolError::CYPoolError(const char *format, va_list args) { 291 | message_ = apr_pvsprintf(pool_, format, args); 292 | } 293 | -------------------------------------------------------------------------------- /Linux.mk: -------------------------------------------------------------------------------- 1 | flags += -fPIC 2 | include WebKit.mk 3 | -------------------------------------------------------------------------------- /List.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_LIST_HPP 23 | #define CYCRIPT_LIST_HPP 24 | 25 | template 26 | struct CYNext { 27 | Type_ *next_; 28 | 29 | CYNext() : 30 | next_(NULL) 31 | { 32 | } 33 | 34 | CYNext(Type_ *next) : 35 | next_(next) 36 | { 37 | } 38 | 39 | void SetNext(Type_ *next) { 40 | next_ = next; 41 | } 42 | }; 43 | 44 | template 45 | void CYSetLast(Type_ *&list, Type_ *item) { 46 | if (list == NULL) 47 | list = item; 48 | else { 49 | Type_ *next(list); 50 | while (next->next_ != NULL) 51 | next = next->next_; 52 | next->next_ = item; 53 | } 54 | } 55 | 56 | #define CYForEach(value, list) \ 57 | for (__typeof__(*list) *value(list); value != NULL; value = value->next_) 58 | 59 | #endif/*CYCRIPT_LIST_HPP*/ 60 | -------------------------------------------------------------------------------- /Local.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_LOCAL_HPP 23 | #define CYCRIPT_LOCAL_HPP 24 | 25 | #include 26 | 27 | template 28 | class CYLocal { 29 | private: 30 | static ::pthread_key_t key_; 31 | 32 | Type_ *last_; 33 | 34 | protected: 35 | static _finline void Set(Type_ *value) { 36 | _assert(::pthread_setspecific(key_, value) == 0); 37 | } 38 | 39 | static ::pthread_key_t Key_() { 40 | ::pthread_key_t key; 41 | ::pthread_key_create(&key, NULL); 42 | return key; 43 | } 44 | 45 | public: 46 | CYLocal(Type_ *next) { 47 | last_ = Get(); 48 | Set(next); 49 | } 50 | 51 | _finline ~CYLocal() { 52 | Set(last_); 53 | } 54 | 55 | static _finline Type_ *Get() { 56 | return reinterpret_cast(::pthread_getspecific(key_)); 57 | } 58 | }; 59 | 60 | template 61 | ::pthread_key_t CYLocal::key_ = Key_(); 62 | 63 | #endif/*CYCRIPT_LOCAL_HPP*/ 64 | -------------------------------------------------------------------------------- /Mach/Inject.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "Baton.hpp" 32 | #include "Exception.hpp" 33 | #include "Pooling.hpp" 34 | #include "Trampoline.t.hpp" 35 | 36 | extern "C" void __pthread_set_self(pthread_t); 37 | 38 | void InjectLibrary(pid_t pid) { 39 | const char *library(CY_LIBRARY); 40 | 41 | static const size_t Stack_(8 * 1024); 42 | size_t length(strlen(library) + 1), depth(sizeof(Baton) + length); 43 | depth = (depth + sizeof(uintptr_t) + 1) / sizeof(uintptr_t) * sizeof(uintptr_t); 44 | 45 | CYPool pool; 46 | uint8_t *local(reinterpret_cast(apr_palloc(pool, depth))); 47 | Baton *baton(reinterpret_cast(local)); 48 | 49 | baton->__pthread_set_self = &__pthread_set_self; 50 | 51 | baton->pthread_create = &pthread_create; 52 | baton->pthread_join = &pthread_join; 53 | 54 | baton->dlopen = &dlopen; 55 | baton->dlerror = &dlerror; 56 | baton->dlsym = &dlsym; 57 | 58 | baton->mach_thread_self = &mach_thread_self; 59 | baton->thread_terminate = &thread_terminate; 60 | 61 | baton->pid = getpid(); 62 | memcpy(baton->library, library, length); 63 | 64 | vm_size_t size(depth + Stack_); 65 | 66 | mach_port_t self(mach_task_self()), task; 67 | _krncall(task_for_pid(self, pid, &task)); 68 | 69 | vm_address_t stack; 70 | _krncall(vm_allocate(task, &stack, size, true)); 71 | vm_address_t data(stack + Stack_); 72 | 73 | vm_write(task, data, reinterpret_cast(baton), depth); 74 | 75 | thread_act_t thread; 76 | _krncall(thread_create(task, &thread)); 77 | 78 | thread_state_flavor_t flavor; 79 | mach_msg_type_number_t count; 80 | size_t push; 81 | 82 | Trampoline *trampoline; 83 | 84 | #if defined(__arm__) 85 | trampoline = &Trampoline_arm_; 86 | arm_thread_state_t state; 87 | flavor = ARM_THREAD_STATE; 88 | count = ARM_THREAD_STATE_COUNT; 89 | push = 0; 90 | #elif defined(__i386__) 91 | trampoline = &Trampoline_i386_; 92 | i386_thread_state_t state; 93 | flavor = i386_THREAD_STATE; 94 | count = i386_THREAD_STATE_COUNT; 95 | push = 5; 96 | #elif defined(__x86_64__) 97 | trampoline = &Trampoline_x86_64_; 98 | x86_thread_state64_t state; 99 | flavor = x86_THREAD_STATE64; 100 | count = x86_THREAD_STATE64_COUNT; 101 | push = 2; 102 | #else 103 | #error XXX: implement 104 | #endif 105 | 106 | vm_address_t code; 107 | _krncall(vm_allocate(task, &code, trampoline->size_, true)); 108 | vm_write(task, code, reinterpret_cast(trampoline->data_), trampoline->size_); 109 | _krncall(vm_protect(task, code, trampoline->size_, false, VM_PROT_READ | VM_PROT_EXECUTE)); 110 | 111 | /* 112 | printf("_ptss:%p\n", baton->__pthread_set_self); 113 | printf("dlsym:%p\n", baton->dlsym); 114 | printf("code:%zx\n", (size_t) code); 115 | */ 116 | 117 | uint32_t frame[push]; 118 | if (sizeof(frame) != 0) 119 | memset(frame, 0, sizeof(frame)); 120 | memset(&state, 0, sizeof(state)); 121 | 122 | mach_msg_type_number_t read(count); 123 | _krncall(thread_get_state(thread, flavor, reinterpret_cast(&state), &read)); 124 | _assert(count == count); 125 | 126 | #if defined(__arm__) 127 | state.r[0] = data; 128 | state.sp = stack + Stack_; 129 | state.pc = code + trampoline->entry_; 130 | 131 | if ((state.pc & 0x1) != 0) { 132 | state.pc &= ~0x1; 133 | state.cpsr |= 0x20; 134 | } 135 | #elif defined(__i386__) 136 | frame[1] = data; 137 | 138 | state.__eip = code + trampoline->entry_; 139 | state.__esp = stack + Stack_ - sizeof(frame); 140 | #elif defined(__x86_64__) 141 | frame[0] = 0xdeadbeef; 142 | state.__rdi = data; 143 | state.__rip = code + trampoline->entry_; 144 | state.__rsp = stack + Stack_ - sizeof(frame); 145 | #else 146 | #error XXX: implement 147 | #endif 148 | 149 | if (sizeof(frame) != 0) 150 | vm_write(task, stack + Stack_ - sizeof(frame), reinterpret_cast(frame), sizeof(frame)); 151 | 152 | _krncall(thread_set_state(thread, flavor, reinterpret_cast(&state), count)); 153 | _krncall(thread_resume(thread)); 154 | 155 | _krncall(mach_port_deallocate(self, task)); 156 | } 157 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | # @configure_input@ 2 | # The real makefile is GNUmakefile 3 | 4 | gmake=@GMAKE@ 5 | 6 | all: 7 | $(gmake) $@ 8 | 9 | .DEFAULT: 10 | $(gmake) $@ 11 | -------------------------------------------------------------------------------- /Network.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include "cycript.hpp" 23 | 24 | #include 25 | #include 26 | 27 | #include "Error.hpp" 28 | 29 | bool CYRecvAll_(int socket, uint8_t *data, size_t size) { 30 | while (size != 0) if (size_t writ = _syscall(recv(socket, data, size, 0))) { 31 | data += writ; 32 | size -= writ; 33 | } else 34 | return false; 35 | return true; 36 | } 37 | 38 | bool CYSendAll_(int socket, const uint8_t *data, size_t size) { 39 | while (size != 0) if (size_t writ = _syscall(send(socket, data, size, 0))) { 40 | data += writ; 41 | size -= writ; 42 | } else 43 | return false; 44 | return true; 45 | } 46 | -------------------------------------------------------------------------------- /ObjectiveC.mk: -------------------------------------------------------------------------------- 1 | filters += ObjectiveC 2 | header += Struct.hpp ObjectiveC/Internal.hpp ObjectiveC/Syntax.hpp 3 | code += ObjectiveC/Output.o ObjectiveC/Replace.o ObjectiveC/Library.o 4 | 5 | Struct.hpp: 6 | $$($(target)gcc -print-prog-name=cc1obj) -print-objc-runtime-info $@ 7 | -------------------------------------------------------------------------------- /ObjectiveC/Internal.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_OBJECTIVEC_INTERNAL_HPP 23 | #define CYCRIPT_OBJECTIVEC_INTERNAL_HPP 24 | 25 | #include 26 | #include 27 | 28 | struct Selector_privateData : 29 | CYValue 30 | { 31 | _finline Selector_privateData(SEL value) : 32 | CYValue(value) 33 | { 34 | } 35 | 36 | _finline SEL GetValue() const { 37 | return reinterpret_cast(value_); 38 | } 39 | 40 | virtual Type_privateData *GetType() const; 41 | }; 42 | 43 | struct Instance : 44 | CYValue 45 | { 46 | enum Flags { 47 | None = 0, 48 | Transient = (1 << 0), 49 | Uninitialized = (1 << 1), 50 | }; 51 | 52 | Flags flags_; 53 | 54 | _finline Instance(id value, Flags flags) : 55 | CYValue(value), 56 | flags_(flags) 57 | { 58 | } 59 | 60 | virtual ~Instance(); 61 | 62 | static JSObjectRef Make(JSContextRef context, id object, Flags flags = None); 63 | 64 | _finline id GetValue() const { 65 | return reinterpret_cast(value_); 66 | } 67 | 68 | _finline bool IsUninitialized() const { 69 | return (flags_ & Uninitialized) != 0; 70 | } 71 | 72 | virtual Type_privateData *GetType() const; 73 | }; 74 | 75 | namespace cy { 76 | struct Super : 77 | Instance 78 | { 79 | Class class_; 80 | 81 | _finline Super(id value, Class _class) : 82 | Instance(value, Instance::Transient), 83 | class_(_class) 84 | { 85 | } 86 | 87 | static JSObjectRef Make(JSContextRef context, id object, Class _class); 88 | }; } 89 | 90 | struct Messages : 91 | CYValue 92 | { 93 | _finline Messages(Class value) : 94 | CYValue(value) 95 | { 96 | } 97 | 98 | static JSObjectRef Make(JSContextRef context, Class _class, bool array = false); 99 | 100 | _finline Class GetValue() const { 101 | return reinterpret_cast(value_); 102 | } 103 | }; 104 | 105 | struct Internal : 106 | CYOwned 107 | { 108 | _finline Internal(id value, JSContextRef context, JSObjectRef owner) : 109 | CYOwned(value, context, owner) 110 | { 111 | } 112 | 113 | static JSObjectRef Make(JSContextRef context, id object, JSObjectRef owner); 114 | 115 | _finline id GetValue() const { 116 | return reinterpret_cast(value_); 117 | } 118 | }; 119 | 120 | #endif/*CYCRIPT_OBJECTIVEC_INTERNAL_HPP*/ 121 | -------------------------------------------------------------------------------- /ObjectiveC/Output.mm: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include "Replace.hpp" 23 | #include "ObjectiveC/Syntax.hpp" 24 | 25 | #include 26 | #include 27 | 28 | void CYCategory::Output(CYOutput &out, CYFlags flags) const { 29 | out << "(function($cys,$cyp,$cyc,$cyn,$cyt){"; 30 | out << "$cyp=object_getClass($cys);"; 31 | out << "$cyc=$cys;"; 32 | if (messages_ != NULL) 33 | messages_->Output(out, true); 34 | out << "})("; 35 | name_->ClassName(out, true); 36 | out << ')'; 37 | out << ';'; 38 | } 39 | 40 | void CYClass::Output(CYOutput &out, CYFlags flags) const { 41 | // XXX: I don't necc. need the ()s 42 | out << "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){"; 43 | out << "$cyp=object_getClass($cys);"; 44 | out << "$cyc=objc_allocateClassPair($cys,"; 45 | if (name_ != NULL) 46 | name_->ClassName(out, false); 47 | else 48 | out << "$cyq(\"CY$\")"; 49 | out << ",0);"; 50 | out << "$cym=object_getClass($cyc);"; 51 | if (fields_ != NULL) 52 | fields_->Output(out); 53 | if (messages_ != NULL) 54 | messages_->Output(out, false); 55 | if (protocols_ != NULL) { 56 | out << '<'; 57 | out << *protocols_; 58 | out << '>'; 59 | } 60 | out << "objc_registerClassPair($cyc);"; 61 | out << "return $cyc;"; 62 | out << "}("; 63 | if (super_ != NULL) 64 | super_->Output(out, CYAssign::Precedence_, CYNoFlags); 65 | else 66 | out << "null"; 67 | out << "))"; 68 | } 69 | 70 | void CYClassExpression::Output(CYOutput &out, CYFlags flags) const { 71 | CYClass::Output(out, flags); 72 | } 73 | 74 | void CYClassStatement::Output(CYOutput &out, CYFlags flags) const { 75 | CYClass::Output(out, flags); 76 | } 77 | 78 | void CYField::Output(CYOutput &out) const { 79 | } 80 | 81 | void CYImport::Output(CYOutput &out, CYFlags flags) const { 82 | out << "@import"; 83 | } 84 | 85 | void CYMessage::Output(CYOutput &out, bool replace) const { 86 | out << (instance_ ? '-' : '+'); 87 | 88 | CYForEach (parameter, parameters_) 89 | if (parameter->tag_ != NULL) { 90 | out << ' ' << *parameter->tag_; 91 | if (parameter->name_ != NULL) 92 | out << ':' << *parameter->name_; 93 | } 94 | 95 | out << code_; 96 | } 97 | 98 | void CYProtocol::Output(CYOutput &out) const { 99 | name_->Output(out, CYAssign::Precedence_, CYNoFlags); 100 | if (next_ != NULL) 101 | out << ',' << ' ' << *next_; 102 | } 103 | 104 | void CYSelector::Output(CYOutput &out, CYFlags flags) const { 105 | out << "@selector" << '(' << name_ << ')'; 106 | } 107 | 108 | void CYSelectorPart::Output(CYOutput &out) const { 109 | out << name_; 110 | if (value_) 111 | out << ':'; 112 | out << next_; 113 | } 114 | 115 | void CYSend::Output(CYOutput &out, CYFlags flags) const { 116 | CYForEach (argument, arguments_) 117 | if (argument->name_ != NULL) { 118 | out << ' ' << *argument->name_; 119 | if (argument->value_ != NULL) 120 | out << ':' << *argument->value_; 121 | } 122 | } 123 | 124 | void CYSendDirect::Output(CYOutput &out, CYFlags flags) const { 125 | out << '['; 126 | self_->Output(out, CYAssign::Precedence_, CYNoFlags); 127 | CYSend::Output(out, flags); 128 | out << ']'; 129 | } 130 | 131 | void CYSendSuper::Output(CYOutput &out, CYFlags flags) const { 132 | out << '[' << "super"; 133 | CYSend::Output(out, flags); 134 | out << ']'; 135 | } 136 | -------------------------------------------------------------------------------- /ObjectiveC/Replace.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include "Replace.hpp" 23 | #include "ObjectiveC/Syntax.hpp" 24 | 25 | #include 26 | 27 | CYStatement *CYCategory::Replace(CYContext &context) { 28 | CYVariable *cyc($V("$cyc")), *cys($V("$cys")); 29 | 30 | return $E($C1($F(NULL, $P5("$cys", "$cyp", "$cyc", "$cyn", "$cyt"), $$->* 31 | $E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->* 32 | $E($ CYAssign(cyc, cys))->* 33 | $E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->* 34 | messages_->Replace(context, true) 35 | ), name_->ClassName(context, true))); 36 | } 37 | 38 | CYExpression *CYClass::Replace_(CYContext &context) { 39 | CYVariable *cyc($V("$cyc")), *cys($V("$cys")); 40 | 41 | CYExpression *name(name_ != NULL ? name_->ClassName(context, false) : $C1($V("$cyq"), $S("CY$"))); 42 | 43 | return $C1($F(NULL, $P6("$cys", "$cyp", "$cyc", "$cyn", "$cyt", "$cym"), $$->* 44 | $E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->* 45 | $E($ CYAssign(cyc, $C3($V("objc_allocateClassPair"), cys, name, $D(0))))->* 46 | $E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->* 47 | protocols_->Replace(context)->* 48 | fields_->Replace(context)->* 49 | messages_->Replace(context, false)->* 50 | $E($C1($V("objc_registerClassPair"), cyc))->* 51 | $ CYReturn(cyc) 52 | ), super_ == NULL ? $ CYNull() : super_); 53 | } 54 | 55 | CYExpression *CYClassExpression::Replace(CYContext &context) { 56 | return Replace_(context); 57 | } 58 | 59 | CYStatement *CYClassStatement::Replace(CYContext &context) { 60 | return $E(Replace_(context)); 61 | } 62 | 63 | CYStatement *CYField::Replace(CYContext &context) const { 64 | return NULL; 65 | } 66 | 67 | CYStatement *CYImport::Replace(CYContext &context) { 68 | return this; 69 | } 70 | 71 | CYStatement *CYMessage::Replace(CYContext &context, bool replace) const { $T(NULL) 72 | CYVariable *cyn($V("$cyn")); 73 | CYVariable *cyt($V("$cyt")); 74 | CYVariable *self($V("self")); 75 | CYVariable *_class($V(instance_ ? "$cys" : "$cyp")); 76 | 77 | return $ CYBlock($$->* 78 | next_->Replace(context, replace)->* 79 | $E($ CYAssign(cyn, parameters_->Selector(context)))->* 80 | $E($ CYAssign(cyt, $C1($M(cyn, $S("type")), _class)))->* 81 | $E($C4($V(replace ? "class_replaceMethod" : "class_addMethod"), 82 | $V(instance_ ? "$cyc" : "$cym"), 83 | cyn, 84 | $N2($V("Functor"), $F(NULL, $P2("self", "_cmd", parameters_->Parameters(context)), $$->* 85 | $ CYVar($L1($L($I("$cyr"), $N2($V("Super"), self, _class))))->* 86 | $ CYReturn($C1($M($F(NULL, NULL, code_), $S("call")), self)) 87 | ), cyt), 88 | cyt 89 | )) 90 | ); 91 | } 92 | 93 | CYFunctionParameter *CYMessageParameter::Parameters(CYContext &context) const { $T(NULL) 94 | CYFunctionParameter *next(next_->Parameters(context)); 95 | return name_ == NULL ? next : $ CYFunctionParameter(name_, next); 96 | } 97 | 98 | CYSelector *CYMessageParameter::Selector(CYContext &context) const { 99 | return $ CYSelector(SelectorPart(context)); 100 | } 101 | 102 | CYSelectorPart *CYMessageParameter::SelectorPart(CYContext &context) const { $T(NULL) 103 | CYSelectorPart *next(next_->SelectorPart(context)); 104 | return tag_ == NULL ? next : $ CYSelectorPart(tag_, name_ != NULL, next); 105 | } 106 | 107 | CYStatement *CYProtocol::Replace(CYContext &context) const { $T(NULL) 108 | return $ CYBlock($$->* 109 | next_->Replace(context)->* 110 | $E($C2($V("class_addProtocol"), 111 | $V("$cyc"), name_ 112 | )) 113 | ); 114 | } 115 | 116 | CYExpression *CYSelector::Replace(CYContext &context) { 117 | return $N1($V("Selector"), name_->Replace(context)); 118 | } 119 | 120 | CYString *CYSelectorPart::Replace(CYContext &context) { 121 | std::ostringstream str; 122 | CYForEach (part, this) { 123 | if (part->name_ != NULL) 124 | str << part->name_->Word(); 125 | if (part->value_) 126 | str << ':'; 127 | } 128 | return $S(apr_pstrdup($pool, str.str().c_str())); 129 | } 130 | 131 | CYExpression *CYSendDirect::Replace(CYContext &context) { 132 | std::ostringstream name; 133 | CYArgument **argument(&arguments_); 134 | CYSelectorPart *selector(NULL), *current(NULL); 135 | 136 | while (*argument != NULL) { 137 | if ((*argument)->name_ != NULL) { 138 | CYSelectorPart *part($ CYSelectorPart((*argument)->name_, (*argument)->value_ != NULL)); 139 | if (selector == NULL) 140 | selector = part; 141 | if (current != NULL) 142 | current->SetNext(part); 143 | current = part; 144 | (*argument)->name_ = NULL; 145 | } 146 | 147 | if ((*argument)->value_ == NULL) 148 | *argument = (*argument)->next_; 149 | else 150 | argument = &(*argument)->next_; 151 | } 152 | 153 | return $C2($V("objc_msgSend"), self_, ($ CYSelector(selector))->Replace(context), arguments_); 154 | } 155 | 156 | CYExpression *CYSendSuper::Replace(CYContext &context) { 157 | return $ CYSendDirect($V("$cyr"), arguments_); 158 | } 159 | -------------------------------------------------------------------------------- /ObjectiveC/Syntax.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_OBJECTIVEC_SYNTAX_HPP 23 | #define CYCRIPT_OBJECTIVEC_SYNTAX_HPP 24 | 25 | #include "Parser.hpp" 26 | 27 | struct CYSelectorPart : 28 | CYNext, 29 | CYThing 30 | { 31 | CYWord *name_; 32 | bool value_; 33 | 34 | CYSelectorPart(CYWord *name, bool value, CYSelectorPart *next = NULL) : 35 | CYNext(next), 36 | name_(name), 37 | value_(value) 38 | { 39 | } 40 | 41 | CYString *Replace(CYContext &context); 42 | virtual void Output(CYOutput &out) const; 43 | }; 44 | 45 | struct CYSelector : 46 | CYLiteral 47 | { 48 | CYSelectorPart *name_; 49 | 50 | CYSelector(CYSelectorPart *name) : 51 | name_(name) 52 | { 53 | } 54 | 55 | CYPrecedence(1) 56 | 57 | virtual CYExpression *Replace(CYContext &context); 58 | virtual void Output(CYOutput &out, CYFlags flags) const; 59 | }; 60 | 61 | struct CYField : 62 | CYNext 63 | { 64 | CYStatement *Replace(CYContext &context) const; 65 | void Output(CYOutput &out) const; 66 | }; 67 | 68 | struct CYMessageParameter : 69 | CYNext 70 | { 71 | CYWord *tag_; 72 | CYExpression *type_; 73 | CYIdentifier *name_; 74 | 75 | CYMessageParameter(CYWord *tag, CYExpression *type, CYIdentifier *name) : 76 | tag_(tag), 77 | type_(type), 78 | name_(name) 79 | { 80 | } 81 | 82 | CYFunctionParameter *Parameters(CYContext &context) const; 83 | CYSelector *Selector(CYContext &context) const; 84 | CYSelectorPart *SelectorPart(CYContext &context) const; 85 | }; 86 | 87 | struct CYMessage : 88 | CYNext 89 | { 90 | bool instance_; 91 | CYExpression *type_; 92 | CYMessageParameter *parameters_; 93 | CYBlock code_; 94 | 95 | CYMessage(bool instance, CYExpression *type, CYMessageParameter *parameter, CYStatement *statements) : 96 | instance_(instance), 97 | type_(type), 98 | parameters_(parameter), 99 | code_(statements) 100 | { 101 | } 102 | 103 | CYStatement *Replace(CYContext &context, bool replace) const; 104 | void Output(CYOutput &out, bool replace) const; 105 | }; 106 | 107 | struct CYProtocol : 108 | CYNext, 109 | CYThing 110 | { 111 | CYExpression *name_; 112 | 113 | CYProtocol(CYExpression *name, CYProtocol *next = NULL) : 114 | CYNext(next), 115 | name_(name) 116 | { 117 | } 118 | 119 | CYStatement *Replace(CYContext &context) const; 120 | void Output(CYOutput &out) const; 121 | }; 122 | 123 | struct CYImport : 124 | CYStatement 125 | { 126 | virtual CYStatement *Replace(CYContext &context); 127 | virtual void Output(CYOutput &out, CYFlags flags) const; 128 | }; 129 | 130 | struct CYClass { 131 | CYClassName *name_; 132 | CYExpression *super_; 133 | CYProtocol *protocols_; 134 | CYField *fields_; 135 | CYMessage *messages_; 136 | 137 | CYClass(CYClassName *name, CYExpression *super, CYProtocol *protocols, CYField *fields, CYMessage *messages) : 138 | name_(name), 139 | super_(super), 140 | protocols_(protocols), 141 | fields_(fields), 142 | messages_(messages) 143 | { 144 | } 145 | 146 | virtual ~CYClass() { 147 | } 148 | 149 | CYExpression *Replace_(CYContext &context); 150 | virtual void Output(CYOutput &out, CYFlags flags) const; 151 | }; 152 | 153 | struct CYClassExpression : 154 | CYClass, 155 | CYExpression 156 | { 157 | CYClassExpression(CYClassName *name, CYExpression *super, CYProtocol *protocols, CYField *fields, CYMessage *messages) : 158 | CYClass(name, super, protocols, fields, messages) 159 | { 160 | } 161 | 162 | CYPrecedence(0) 163 | 164 | virtual CYExpression *Replace(CYContext &context); 165 | virtual void Output(CYOutput &out, CYFlags flags) const; 166 | }; 167 | 168 | struct CYClassStatement : 169 | CYClass, 170 | CYStatement 171 | { 172 | CYClassStatement(CYClassName *name, CYExpression *super, CYProtocol *protocols, CYField *fields, CYMessage *messages) : 173 | CYClass(name, super, protocols, fields, messages) 174 | { 175 | } 176 | 177 | virtual CYStatement *Replace(CYContext &context); 178 | virtual void Output(CYOutput &out, CYFlags flags) const; 179 | }; 180 | 181 | struct CYCategory : 182 | CYStatement 183 | { 184 | CYClassName *name_; 185 | CYMessage *messages_; 186 | 187 | CYCategory(CYClassName *name, CYMessage *messages) : 188 | name_(name), 189 | messages_(messages) 190 | { 191 | } 192 | 193 | virtual CYStatement *Replace(CYContext &context); 194 | virtual void Output(CYOutput &out, CYFlags flags) const; 195 | }; 196 | 197 | struct CYSend : 198 | CYExpression 199 | { 200 | CYArgument *arguments_; 201 | 202 | CYSend(CYArgument *arguments) : 203 | arguments_(arguments) 204 | { 205 | } 206 | 207 | CYPrecedence(0) 208 | 209 | virtual void Output(CYOutput &out, CYFlags flags) const; 210 | }; 211 | 212 | struct CYSendDirect : 213 | CYSend 214 | { 215 | CYExpression *self_; 216 | 217 | CYSendDirect(CYExpression *self, CYArgument *arguments) : 218 | CYSend(arguments), 219 | self_(self) 220 | { 221 | } 222 | 223 | virtual CYExpression *Replace(CYContext &context); 224 | virtual void Output(CYOutput &out, CYFlags flags) const; 225 | }; 226 | 227 | struct CYSendSuper : 228 | CYSend 229 | { 230 | CYSendSuper(CYArgument *arguments) : 231 | CYSend(arguments) 232 | { 233 | } 234 | 235 | virtual CYExpression *Replace(CYContext &context); 236 | virtual void Output(CYOutput &out, CYFlags flags) const; 237 | }; 238 | 239 | #endif/*CYCRIPT_OBJECTIVEC_SYNTAX_HPP*/ 240 | -------------------------------------------------------------------------------- /Options.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_OPTIONS_HPP 23 | #define CYCRIPT_OPTIONS_HPP 24 | 25 | struct CYOptions { 26 | bool verbose_; 27 | 28 | CYOptions() : 29 | verbose_(false) 30 | { 31 | } 32 | }; 33 | 34 | #endif/*CYCRIPT_OPTIONS_HPP*/ 35 | -------------------------------------------------------------------------------- /Parser.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include "Parser.hpp" 23 | #include "Cycript.tab.hh" 24 | 25 | CYRange DigitRange_ (0x3ff000000000000LLU, 0x000000000000000LLU); // 0-9 26 | CYRange WordStartRange_(0x000001000000000LLU, 0x7fffffe87fffffeLLU); // A-Za-z_$ 27 | CYRange WordEndRange_ (0x3ff001000000000LLU, 0x7fffffe87fffffeLLU); // A-Za-z_$0-9 28 | 29 | CYDriver::CYDriver(const std::string &filename) : 30 | state_(CYClear), 31 | data_(NULL), 32 | size_(0), 33 | file_(NULL), 34 | strict_(false), 35 | filename_(filename), 36 | program_(NULL), 37 | auto_(false), 38 | context_(NULL), 39 | mode_(AutoNone) 40 | { 41 | ScannerInit(); 42 | } 43 | 44 | CYDriver::~CYDriver() { 45 | ScannerDestroy(); 46 | } 47 | 48 | void CYDriver::Warning(const cy::location &location, const char *message) { 49 | if (!strict_) 50 | return; 51 | 52 | CYDriver::Error error; 53 | error.warning_ = true; 54 | error.location_ = location; 55 | error.message_ = message; 56 | errors_.push_back(error); 57 | } 58 | 59 | void cy::parser::error(const cy::parser::location_type &location, const std::string &message) { 60 | CYDriver::Error error; 61 | error.warning_ = false; 62 | error.location_ = location; 63 | error.message_ = message; 64 | driver.errors_.push_back(error); 65 | } 66 | -------------------------------------------------------------------------------- /Parser.dat: -------------------------------------------------------------------------------- 1 | & AddressOf R BitwiseAnd 5 2 | && - R LogicalAnd 8 3 | &= - A BitwiseAnd 4 | ^ - R BitwiseXor 6 5 | ^= - A BitwiseXor 6 | = - A 7 | == - R Equal 4 8 | === - R Identical 4 9 | ! LogicalNot 10 | != - R NotEqual 4 11 | !== - R NotIdentical 4 12 | - Negate R Subtract 1 13 | -= - A Subtract 14 | -- PreDecrement R PostDecrement 15 | -> - U Indirect 16 | < - R LessThan 3 17 | <= - R LessThanOrEqual 3 18 | << - R LeftShift 2 19 | <<= - A LeftShift 20 | % - R Modulus 0 21 | %= - A Modulus 22 | . - U Direct 23 | | - R BitwiseOr 7 24 | |= - A BitwiseOr 25 | || - R LogicalOr 9 26 | + Affirm R Add 1 27 | += - A Add 28 | ++ PreIncrement R PostIncrement 29 | > - R GreaterThan 3 30 | >= - R GreaterThanOrEqual 3 31 | >> - R SignedRightShift 2 32 | >>= - A SignedRightShift 33 | >>> - R UnsignedRightShift 2 34 | >>>= - A UnsignedRightShift 35 | / - R Divide 0 36 | /= - A Divide 37 | * Indirect R Multiply 0 38 | *= - A Multiply 39 | ~ BitwiseNot 40 | Break - 41 | Case - 42 | Catch - 43 | Continue - 44 | Default - 45 | Delete Delete 46 | Do - 47 | Else - 48 | False - L 49 | Finally - 50 | For - 51 | Function - 52 | If - 53 | In - R In 3 54 | InstanceOf - R InstanceOf 3 55 | New - 56 | Null - L 57 | Return - 58 | Switch - 59 | This - V 60 | Throw - 61 | True - L 62 | Try - 63 | TypeOf TypeOf 64 | Var - 65 | Void Void 66 | While - 67 | With - 68 | -------------------------------------------------------------------------------- /Pooling.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_POOLING_HPP 23 | #define CYCRIPT_POOLING_HPP 24 | 25 | #include 26 | #include 27 | 28 | #include "Exception.hpp" 29 | #include "Local.hpp" 30 | #include "Standard.hpp" 31 | 32 | #include 33 | 34 | _finline void *operator new(size_t size, apr_pool_t *pool) { 35 | return apr_palloc(pool, size); 36 | } 37 | 38 | _finline void *operator new [](size_t size, apr_pool_t *pool) { 39 | return apr_palloc(pool, size); 40 | } 41 | 42 | class CYPool { 43 | private: 44 | apr_pool_t *pool_; 45 | 46 | public: 47 | CYPool(apr_pool_t *pool = NULL) { 48 | _aprcall(apr_pool_create(&pool_, pool)); 49 | } 50 | 51 | ~CYPool() { 52 | apr_pool_destroy(pool_); 53 | } 54 | 55 | void Clear() { 56 | apr_pool_clear(pool_); 57 | } 58 | 59 | operator apr_pool_t *() const { 60 | return pool_; 61 | } 62 | 63 | char *operator ()(const char *data) const { 64 | return apr_pstrdup(pool_, data); 65 | } 66 | 67 | char *operator ()(const char *data, size_t size) const { 68 | return apr_pstrndup(pool_, data, size); 69 | } 70 | }; 71 | 72 | struct CYData { 73 | apr_pool_t *pool_; 74 | unsigned count_; 75 | 76 | CYData() : 77 | count_(1) 78 | { 79 | } 80 | 81 | virtual ~CYData() { 82 | } 83 | 84 | static void *operator new(size_t size, apr_pool_t *pool) { 85 | void *data(apr_palloc(pool, size)); 86 | reinterpret_cast(data)->pool_ = pool; 87 | return data; 88 | } 89 | 90 | static void *operator new(size_t size) { 91 | apr_pool_t *pool; 92 | _aprcall(apr_pool_create(&pool, NULL)); 93 | return operator new(size, pool); 94 | } 95 | 96 | static void operator delete(void *data) { 97 | apr_pool_destroy(reinterpret_cast(data)->pool_); 98 | } 99 | }; 100 | 101 | template 102 | struct CYPoolAllocator { 103 | apr_pool_t *pool_; 104 | 105 | typedef Type_ value_type; 106 | typedef value_type *pointer; 107 | typedef const value_type *const_pointer; 108 | typedef value_type &reference; 109 | typedef const value_type &const_reference; 110 | typedef std::size_t size_type; 111 | typedef std::ptrdiff_t difference_type; 112 | 113 | CYPoolAllocator() : 114 | pool_(NULL) 115 | { 116 | } 117 | 118 | template 119 | CYPoolAllocator(const CYPoolAllocator &rhs) : 120 | pool_(rhs.pool_) 121 | { 122 | } 123 | 124 | pointer allocate(size_type size, const void *hint = 0) { 125 | return reinterpret_cast(apr_palloc(pool_, size)); 126 | } 127 | 128 | void deallocate(pointer data, size_type size) { 129 | } 130 | 131 | void construct(pointer address, const Type_ &rhs) { 132 | new(address) Type_(rhs); 133 | } 134 | 135 | void destroy(pointer address) { 136 | address->~Type_(); 137 | } 138 | 139 | template 140 | inline bool operator==(const CYPoolAllocator &rhs) { 141 | return pool_ == rhs.pool_; 142 | } 143 | 144 | template 145 | inline bool operator!=(const CYPoolAllocator &rhs) { 146 | return !operator==(rhs); 147 | } 148 | 149 | template 150 | struct rebind { 151 | typedef CYPoolAllocator other; 152 | }; 153 | }; 154 | 155 | class CYLocalPool : 156 | public CYPool 157 | { 158 | private: 159 | CYLocal local_; 160 | 161 | public: 162 | CYLocalPool() : 163 | CYPool(), 164 | local_(operator apr_pool_t *()) 165 | { 166 | } 167 | }; 168 | 169 | #define $pool \ 170 | CYLocal::Get() 171 | 172 | #endif/*CYCRIPT_POOLING_HPP*/ 173 | -------------------------------------------------------------------------------- /Replace.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_REPLACE_HPP 23 | #define CYCRIPT_REPLACE_HPP 24 | 25 | #include "Parser.hpp" 26 | 27 | #define $ new($pool) 28 | 29 | #define $D(args...) \ 30 | ($ CYNumber(args)) 31 | #define $E(args...) \ 32 | ($ CYExpress(args)) 33 | #define $F(args...) \ 34 | ($ CYFunctionExpression(args)) 35 | #define $I(args...) \ 36 | ($ CYIdentifier(args)) 37 | #define $M(args...) \ 38 | ($ CYDirectMember(args)) 39 | #define $P(args...) \ 40 | ($ CYFunctionParameter(args)) 41 | #define $S(args...) \ 42 | ($ CYString(args)) 43 | #define $U \ 44 | $V($I("undefined")) 45 | #define $V(name) \ 46 | ($ CYVariable(name)) 47 | 48 | #define $T(value) \ 49 | if (this == NULL) \ 50 | return value; 51 | #define $$ \ 52 | CYStatements() 53 | 54 | #define $P1(arg0, args...) \ 55 | $P($I(arg0), ##args) 56 | #define $P2(arg0, arg1, args...) \ 57 | $P($I(arg0), $P1(arg1, ##args)) 58 | #define $P3(arg0, arg1, arg2, args...) \ 59 | $P($I(arg0), $P2(arg1, arg2, ##args)) 60 | #define $P4(arg0, arg1, arg2, arg3, args...) \ 61 | $P($I(arg0), $P3(arg1, arg2, arg3, ##args)) 62 | #define $P5(arg0, arg1, arg2, arg3, arg4, args...) \ 63 | $P($I(arg0), $P4(arg1, arg2, arg3, arg4, ##args)) 64 | #define $P6(arg0, arg1, arg2, arg3, arg4, arg5, args...) \ 65 | $P($I(arg0), $P5(arg1, arg2, arg3, arg4, arg5, ##args)) 66 | 67 | #define $C(args...) \ 68 | ($ CYCall(args)) 69 | #define $C_(args...) \ 70 | ($ CYArgument(args)) 71 | #define $N(args...) \ 72 | ($ cy::Syntax::New(args)) 73 | 74 | #define $C1_(arg0, args...) \ 75 | $C_(arg0, ##args) 76 | #define $C2_(arg0, arg1, args...) \ 77 | $C_(arg0, $C1_(arg1, ##args)) 78 | #define $C3_(arg0, arg1, arg2, args...) \ 79 | $C_(arg0, $C2_(arg1, arg2, ##args)) 80 | #define $C4_(arg0, arg1, arg2, arg3, args...) \ 81 | $C_(arg0, $C3_(arg1, arg2, arg3, ##args)) 82 | #define $C5_(arg0, arg1, arg2, arg3, arg4, args...) \ 83 | $C_(arg0, $C4_(arg1, arg2, arg3, arg4, ##args)) 84 | #define $C6_(arg0, arg1, arg2, arg3, arg4, arg5, args...) \ 85 | $C_(arg0, $C5_(arg1, arg2, arg3, arg4, arg5, ##args)) 86 | 87 | #define $C0(func, args...) \ 88 | $C(func, ##args) 89 | #define $C1(func, args...) \ 90 | $C(func, $C1_(args)) 91 | #define $C2(func, args...) \ 92 | $C(func, $C2_(args)) 93 | #define $C3(func, args...) \ 94 | $C(func, $C3_(args)) 95 | #define $C4(func, args...) \ 96 | $C(func, $C4_(args)) 97 | #define $C5(func, args...) \ 98 | $C(func, $C5_(args)) 99 | 100 | #define $N0(func, args...) \ 101 | $N(func, ##args) 102 | #define $N1(func, args...) \ 103 | $N(func, $C1_(args)) 104 | #define $N2(func, args...) \ 105 | $N(func, $C2_(args)) 106 | #define $N3(func, args...) \ 107 | $N(func, $C3_(args)) 108 | #define $N4(func, args...) \ 109 | $N(func, $C4_(args)) 110 | #define $N5(func, args...) \ 111 | $N(func, $C5_(args)) 112 | 113 | #define $L(args...) \ 114 | $ CYDeclaration(args) 115 | #define $L1(arg0) \ 116 | $ CYDeclarations(arg0) 117 | #define $L2(arg0, args...) \ 118 | $ CYDeclarations(arg0, $L1(args)) 119 | #define $L3(arg0, args...) \ 120 | $ CYDeclarations(arg0, $L2(args)) 121 | #define $L4(arg0, args...) \ 122 | $ CYDeclarations(arg0, $L3(args)) 123 | #define $L5(arg0, args...) \ 124 | $ CYDeclarations(arg0, $L4(args)) 125 | 126 | #endif/*CYCRIPT_REPLACE_HPP*/ 127 | -------------------------------------------------------------------------------- /Server.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | struct Client { 35 | CFHTTPMessageRef message_; 36 | CFSocketRef socket_; 37 | }; 38 | 39 | static void OnData(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) { 40 | switch (type) { 41 | case kCFSocketDataCallBack: 42 | CFDataRef data(reinterpret_cast(value)); 43 | Client *client(reinterpret_cast(info)); 44 | 45 | if (client->message_ == NULL) 46 | client->message_ = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE); 47 | 48 | if (!CFHTTPMessageAppendBytes(client->message_, CFDataGetBytePtr(data), CFDataGetLength(data))) 49 | CFLog(kCFLogLevelError, CFSTR("CFHTTPMessageAppendBytes()")); 50 | else if (CFHTTPMessageIsHeaderComplete(client->message_)) { 51 | CFURLRef url(CFHTTPMessageCopyRequestURL(client->message_)); 52 | Boolean absolute; 53 | CFStringRef path(CFURLCopyStrictPath(url, &absolute)); 54 | CFRelease(client->message_); 55 | 56 | CFStringRef code(CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, path, CFSTR(""))); 57 | CFRelease(path); 58 | 59 | JSStringRef script(JSStringCreateWithCFString(code)); 60 | CFRelease(code); 61 | 62 | JSValueRef result(JSEvaluateScript(CYGetJSContext(), script, NULL, NULL, 0, NULL)); 63 | JSStringRelease(script); 64 | 65 | CFHTTPMessageRef response(CFHTTPMessageCreateResponse(kCFAllocatorDefault, 200, NULL, kCFHTTPVersion1_1)); 66 | CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Type"), CFSTR("application/json; charset=utf-8")); 67 | 68 | CFStringRef json(CYCopyJSONString(CYGetJSContext(), result, NULL)); 69 | CFDataRef body(CFStringCreateExternalRepresentation(kCFAllocatorDefault, json, kCFStringEncodingUTF8, NULL)); 70 | CFRelease(json); 71 | 72 | CFStringRef length(CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"), CFDataGetLength(body))); 73 | CFHTTPMessageSetHeaderFieldValue(response, CFSTR("Content-Length"), length); 74 | CFRelease(length); 75 | 76 | CFHTTPMessageSetBody(response, body); 77 | CFRelease(body); 78 | 79 | CFDataRef serialized(CFHTTPMessageCopySerializedMessage(response)); 80 | CFRelease(response); 81 | 82 | CFSocketSendData(socket, NULL, serialized, 0); 83 | CFRelease(serialized); 84 | 85 | CFRelease(url); 86 | } 87 | break; 88 | } 89 | } 90 | 91 | static void OnAccept(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) { 92 | switch (type) { 93 | case kCFSocketAcceptCallBack: 94 | Client *client(new Client()); 95 | 96 | client->message_ = NULL; 97 | 98 | CFSocketContext context; 99 | context.version = 0; 100 | context.info = client; 101 | context.retain = NULL; 102 | context.release = NULL; 103 | context.copyDescription = NULL; 104 | 105 | client->socket_ = CFSocketCreateWithNative(kCFAllocatorDefault, *reinterpret_cast(value), kCFSocketDataCallBack, &OnData, &context); 106 | 107 | CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, client->socket_, 0), kCFRunLoopDefaultMode); 108 | break; 109 | } 110 | } 111 | 112 | int main(int argc, char *argv[]) { 113 | { 114 | struct sockaddr_in address; 115 | address.sin_len = sizeof(address); 116 | address.sin_family = AF_INET; 117 | address.sin_addr.s_addr = INADDR_ANY; 118 | address.sin_port = htons(787); 119 | 120 | CFDataRef data(CFDataCreate(kCFAllocatorDefault, reinterpret_cast(&address), sizeof(address))); 121 | 122 | CFSocketSignature signature; 123 | signature.protocolFamily = AF_INET; 124 | signature.socketType = SOCK_STREAM; 125 | signature.protocol = IPPROTO_TCP; 126 | signature.address = data; 127 | 128 | CFSocketRef socket(CFSocketCreateWithSocketSignature(kCFAllocatorDefault, &signature, kCFSocketAcceptCallBack, &OnAccept, NULL)); 129 | CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0), kCFRunLoopDefaultMode); 130 | } 131 | 132 | { 133 | CYServer *server(new CYServer()); 134 | server->socket_ = _syscall(socket(PF_UNIX, SOCK_STREAM, 0)); 135 | 136 | struct sockaddr_un address; 137 | memset(&address, 0, sizeof(address)); 138 | address.sun_family = AF_UNIX; 139 | 140 | sprintf(address.sun_path, "/tmp/.s.cy"); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Standard.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_STANDARD_HPP 23 | #define CYCRIPT_STANDARD_HPP 24 | 25 | #define _not(type) \ 26 | ((type) ~ (type) 0) 27 | 28 | #define _finline \ 29 | inline __attribute__((__always_inline__)) 30 | #define _disused \ 31 | __attribute__((__unused__)) 32 | 33 | #define _label__(x) _label ## x 34 | #define _label_(y) _label__(y) 35 | #define _label _label_(__LINE__) 36 | 37 | #define _packed \ 38 | __attribute__((__packed__)) 39 | #define _noreturn \ 40 | __attribute__((__noreturn__)) 41 | 42 | #endif/*CYCRIPT_STANDARD_HPP*/ 43 | -------------------------------------------------------------------------------- /String.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_STRING_HPP 23 | #define CYCRIPT_STRING_HPP 24 | 25 | #include "cycript.hpp" 26 | #include "Pooling.hpp" 27 | 28 | #include 29 | 30 | struct CYUTF8String { 31 | const char *data; 32 | size_t size; 33 | 34 | CYUTF8String(const char *data) : 35 | data(data), 36 | size(strlen(data)) 37 | { 38 | } 39 | 40 | CYUTF8String(const char *data, size_t size) : 41 | data(data), 42 | size(size) 43 | { 44 | } 45 | 46 | bool operator ==(const char *value) const { 47 | size_t length(strlen(data)); 48 | return length == size && memcmp(value, data, length) == 0; 49 | } 50 | }; 51 | 52 | static inline std::ostream &operator <<(std::ostream &lhs, CYUTF8String &rhs) { 53 | lhs.write(rhs.data, rhs.size); 54 | return lhs; 55 | } 56 | 57 | struct CYUTF16String { 58 | const uint16_t *data; 59 | size_t size; 60 | 61 | CYUTF16String(const uint16_t *data, size_t size) : 62 | data(data), 63 | size(size) 64 | { 65 | } 66 | }; 67 | 68 | size_t CYGetIndex(const CYUTF8String &value); 69 | bool CYIsKey(CYUTF8String value); 70 | bool CYGetOffset(const char *value, ssize_t &index); 71 | 72 | CYUTF8String CYPoolUTF8String(apr_pool_t *pool, CYUTF16String utf16); 73 | CYUTF16String CYPoolUTF16String(apr_pool_t *pool, CYUTF8String utf8); 74 | 75 | #endif/*CYCRIPT_STRING_HPP*/ 76 | -------------------------------------------------------------------------------- /Trampoline.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | struct Trampoline { 23 | const char *data_; 24 | size_t size_; 25 | size_t entry_; 26 | }; 27 | -------------------------------------------------------------------------------- /Trampoline.t.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #define _PTHREAD_ATTR_T 23 | #include 24 | 25 | #include "Standard.hpp" 26 | #include "Baton.hpp" 27 | 28 | template 29 | static _finline void dlset(Baton *baton, Type_ &function, const char *name, void *handle = RTLD_DEFAULT) { 30 | function = reinterpret_cast(baton->dlsym(handle, name)); 31 | if (function == NULL) 32 | baton->dlerror(); 33 | } 34 | 35 | #define Framework(framework) \ 36 | "/System/Library/Frameworks/" #framework ".framework/" #framework 37 | 38 | void *Routine(void *arg) { 39 | Baton *baton(reinterpret_cast(arg)); 40 | 41 | void *(*dlopen)(const char *, int); 42 | dlset(baton, dlopen, "dlopen"); 43 | 44 | if (baton->dlsym(RTLD_DEFAULT, "JSEvaluateScript") == NULL) 45 | dlopen(Framework(JavaScriptCore), RTLD_GLOBAL | RTLD_LAZY); 46 | 47 | void *(*objc_getClass)(const char *); 48 | dlset(baton, objc_getClass, "objc_getClass"); 49 | 50 | if (objc_getClass("WebUndefined") == NULL) 51 | dlopen(Framework(WebKit), RTLD_GLOBAL | RTLD_LAZY); 52 | 53 | void *handle(dlopen(baton->library, RTLD_LAZY | RTLD_LOCAL)); 54 | if (handle == NULL) { 55 | baton->dlerror(); 56 | return NULL; 57 | } 58 | 59 | void (*CYHandleServer)(pid_t); 60 | dlset(baton, CYHandleServer, "CYHandleServer", handle); 61 | 62 | CYHandleServer(baton->pid); 63 | 64 | return NULL; 65 | } 66 | 67 | static void $bzero(void *data, size_t size) { 68 | char *bytes(reinterpret_cast(data)); 69 | for (size_t i(0); i != size; ++i) 70 | bytes[i] = 0; 71 | } 72 | 73 | extern "C" void Start(Baton *baton) { 74 | struct _pthread self; 75 | $bzero(&self, sizeof(self)); 76 | 77 | // this code comes from _pthread_set_self 78 | self.tsd[0] = &self; 79 | baton->__pthread_set_self(&self); 80 | 81 | int (*pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *); 82 | dlset(baton, pthread_create, "pthread_create"); 83 | 84 | pthread_t thread; 85 | baton->pthread_create(&thread, NULL, &Routine, baton); 86 | 87 | int (*pthread_join)(pthread_t, void **); 88 | dlset(baton, pthread_join, "pthread_join"); 89 | 90 | void *result; 91 | baton->pthread_join(thread, &result); 92 | 93 | mach_port_t (*mach_thread_self)(); 94 | dlset(baton, mach_thread_self, "mach_thread_self"); 95 | 96 | kern_return_t (*thread_terminate)(thread_act_t); 97 | dlset(baton, thread_terminate, "thread_terminate"); 98 | 99 | baton->thread_terminate(baton->mach_thread_self()); 100 | } 101 | -------------------------------------------------------------------------------- /WebKit.mk: -------------------------------------------------------------------------------- 1 | ifneq ($(shell pkg-config webkit-1.0 --modversion 2>/dev/null),) 2 | flags += $(shell pkg-config --cflags webkit-1.0) 3 | library += $(shell pkg-config --libs webkit-1.0) 4 | include Execute.mk 5 | else 6 | ifneq ($(shell pkg-config WebKitGtk --modversion 2>/dev/null),) 7 | flags += $(shell pkg-config --cflags WebKitGtk) 8 | library += $(shell pkg-config --libs WebKitGtk) 9 | include Execute.mk 10 | endif 11 | endif 12 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | shopt -s expand_aliases extglob 4 | unalias -a 5 | libdirs=() 6 | case `uname` in 7 | (Linux) 8 | libdirs=('/usr/share/gettext') 9 | ;; 10 | (FreeBSD) 11 | alias sed=gsed 12 | ;; 13 | (Darwin) 14 | alias sed=gsed libtoolize=glibtoolize 15 | ;; 16 | esac 17 | aclocal 18 | sed -e 's/AC_PROG_AWK/dnl &/' -i aclocal.m4 19 | cat `aclocal --print-ac-dir`/check_gnu_make.m4 !(aclocal).m4 >> aclocal.m4 20 | function filter() 21 | { 22 | sed -e '/no proper invocation of AM_INIT_AUTOMAKE was found\./d' \ 23 | -e '/You should verify that configure\.ac invokes AM_INIT_AUTOMAKE,/d' \ 24 | -e '/that aclocal\.m4 is present in the top-level directory,/d' \ 25 | -e '/and that aclocal\.m4 was recently regenerated (using aclocal)\./d' \ 26 | -e "/no \`Makefile\.am' found for any configure output/d" \ 27 | -e "/Consider adding \`AC_CONFIG_MACRO_DIR(\[m4\])' to configure\.ac and/d" \ 28 | -e '/rerunning g\?libtoolize, to keep the correct libtool macros in-tree\./d' \ 29 | -e "/Consider adding \`-I m4' to ACLOCAL_AMFLAGS in Makefile\.am\./d" 30 | } 31 | automake -acf 2>&1 | filter 32 | for libdir in ${libdirs[*]}; do 33 | automake -acf --libdir $libdir 2>&1 | filter 34 | done 35 | libtoolize -ci | filter 36 | autoconf 37 | -------------------------------------------------------------------------------- /com.saurik.Cyrver.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.saurik.Cyrver 7 | 8 | ProgramArguments 9 | 10 | /usr/sbin/cyrver 11 | 12 | 13 | OnDemand 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ([2.65]) 2 | AC_INIT([Cycript], [0.9], [saurik@saurik.com], [cycript], [http://www.cycript.org/]) 3 | AC_CONFIG_SRCDIR([Console.cpp]) 4 | AC_CONFIG_AUX_DIR([.]) 5 | LT_INIT([disable-static]) 6 | PKG_PROG_PKG_CONFIG([0.22]) 7 | CHECK_GNU_MAKE 8 | AC_SUBST([GMAKE], [$_cv_gnu_make_command]) 9 | AS_IF([test "x$GMAKE" = x], [AC_MSG_ERROR([You need GNU make])]) 10 | AC_PATH_PROGS([_BASH], [bash]) 11 | AS_IF([test "x$_BASH" = x], [AC_MSG_ERROR([You need GNU bash])]) 12 | AC_PATH_PROGS([TIME], [time]) 13 | AC_DEFUN([CY_CHECK_PROGS_VERSION], [ 14 | AC_MSG_CHECKING(for ]$2[ >= ]$5[) 15 | AC_PATH_PROGS_FEATURE_CHECK(]$1[, ]$3[, 16 | AS_VERSION_COMPARE(`$ac_path_]$1[ ]$4[`, ]$5[, , 17 | ac_cv_path_]$1[=$ac_path_]$1[ 18 | , 19 | ac_cv_path_]$1[=$ac_path_]$1[ 20 | ) 21 | , 22 | AC_MSG_RESULT(no) 23 | AC_MSG_ERROR(You need ]$2[ ]$5[ or greater) 24 | ) 25 | AC_SUBST(]$1[, $ac_cv_path_]$1[) 26 | AC_MSG_RESULT($]$1[) 27 | ]) 28 | AC_ARG_VAR([BISON], [GNU Project parser generator (yacc replacement)]) 29 | CY_CHECK_PROGS_VERSION([BISON], [bison], [bison], 30 | [-V | $SED -e '1 s/^bison (GNU Bison) \(.*\)$/\1/p;d'], [2.3]) 31 | AC_ARG_VAR([FLEX], [the fast lexical analyser generator]) 32 | CY_CHECK_PROGS_VERSION([FLEX], [flex], [flex], 33 | [--version | $SED -e '1 s/^.* \(@<:@0-9.@:>@*\)$/\1/p;d'], [2.5.33]) 34 | AC_ARG_VAR([GPERF], [perfect hash function generator]) 35 | CY_CHECK_PROGS_VERSION([GPERF], [gperf], [gperf], 36 | [--version | $SED -e '1 s/^.* \(@<:@0-9.@:>@*\)$/\1/p;d'], [3.0.3]) 37 | AC_PROG_INSTALL 38 | AC_MSG_CHECKING([for GNU tar >=1.19]) 39 | AC_PATH_PROGS_FEATURE_CHECK([GNUTAR], [tar gtar gnutar], [ 40 | AS_IF([test "x`$ac_path_GNUTAR --version | $SED -e '1 s/^tar (GNU tar)/&/p;d'`" != x], [ 41 | AS_VERSION_COMPARE([`$ac_path_GNUTAR --version | $SED -e '1 s/^tar (GNU tar) \(.*\)$/\1/p;d'`], [1.19], , [ 42 | ac_cv_path_GNUTAR=$ac_path_GNUTAR 43 | ], [ 44 | ac_cv_path_GNUTAR=$ac_path_GNUTAR 45 | ]) 46 | ]) 47 | ]) 48 | AS_IF([test "x$ac_cv_path_GNUTAR" != x], [ 49 | AC_SUBST([GNUTAR], [$ac_cv_path_GNUTAR]) 50 | AC_MSG_RESULT([$GNUTAR]) 51 | ], [ 52 | AC_SUBST([GNUTAR], [:]) 53 | AC_MSG_RESULT([no]) 54 | ]) 55 | AC_CHECK_PROGS([SVN], [svn]) 56 | AC_CHECK_PROGS([SVNVERSION], [svnversion]) 57 | AC_PROG_CXX 58 | AC_PROG_OBJCXX 59 | AC_DEFUN([CY_CHECK_UNIVERSAL], [ 60 | AC_MSG_CHECKING([for universal binary support]) 61 | AS_CASE([$host_vendor], [apple], [ 62 | AS_CASE([$host_cpu], [i386|x86_64], [ 63 | for cy_arch in i386 x86_64; do 64 | cy_save_CXXFLAGS=$CXXFLAGS 65 | AC_LIB_APPENDTOVAR([CXXFLAGS], ["-arch $cy_arch"]) 66 | AC_TRY_LINK([], [], [ 67 | AC_LIB_APPENDTOVAR([cy_arches], [$cy_arch]) 68 | AC_LIB_APPENDTOVAR([CFLAGS], ["-arch $cy_arch"]) 69 | AC_LIB_APPENDTOVAR([LDFLAGS], ["-arch $cy_arch"]) 70 | AC_LIB_APPENDTOVAR([OBJCXXFLAGS], ["-arch $cy_arch"]) 71 | ], [ 72 | CXXFLAGS=$cy_save_CXXFLAGS 73 | ]) 74 | done 75 | ]) 76 | ]) 77 | AC_MSG_RESULT([${cy_arches-no}]) 78 | ]) 79 | AC_ARG_ENABLE([universal-binary], [AS_HELP_STRING( 80 | [--disable-universal-binary], 81 | [do not build with universal binary support on Darwin] 82 | )], [ 83 | AS_CASE([$enableval], [no], [], [CY_CHECK_UNIVERSAL]) 84 | ], [CY_CHECK_UNIVERSAL]) 85 | AC_ARG_WITH([frameworks], [AS_HELP_STRING( 86 | [--with-frameworks=DIRS], 87 | [add to DIRS (space separated) to the Darwin include path for frameworks with -F] 88 | )], [ 89 | for cy_framework in $withval; do 90 | AC_LIB_APPENDTOVAR([CFLAGS], [-F$cy_framework]) 91 | AC_LIB_APPENDTOVAR([CXXFLAGS], [-F$cy_framework]) 92 | AC_LIB_APPENDTOVAR([OBJCCXXFLAGS], [-F$cy_framework]) 93 | done 94 | ]) 95 | AC_LANG([C++]) 96 | APR_FIND_APR([], [], [1], [1]) 97 | AS_CASE([$apr_found], [yes], [ 98 | AC_LIB_APPENDTOVAR([CPPFLAGS], [`$apr_config --includes`]) 99 | AC_SUBST([LTLIBAPR], [`$apr_config --link-libtool`]) 100 | ], [AC_MSG_ERROR([You need apr])]) 101 | AC_DEFUN([CY_CHECK_JAVASCRIPTCORE], [ 102 | PKG_CHECK_MODULES([WEBKIT], [webkit-1.0], [ 103 | CY_EXECUTE=1 104 | AC_LIB_APPENDTOVAR([CXXFLAGS], [`$PKG_CONFIG --cflags webkit-1.0`]) 105 | AC_LIB_APPENDTOVAR([LIBS], [`$PKG_CONFIG --libs webkit-1.0`]) 106 | ], [ 107 | PKG_CHECK_MODULES([WEBKIT], [WebKitGtk], [ 108 | CY_EXECUTE=1 109 | AC_LIB_APPENDTOVAR([CXXFLAGS], [`$PKG_CONFIG --cflags WebKitGtk`]) 110 | AC_LIB_APPENDTOVAR([LIBS], [`$PKG_CONFIG --libs WebKitGtk`]) 111 | ], [ 112 | AC_CHECK_FRAMEWORK([JavaScriptCore], [ 113 | #include 114 | ], [JSEvaluateScript(0, 0, 0, 0, 0, 0);], [CY_EXECUTE=1]) 115 | ]) 116 | ]) 117 | ]) 118 | AC_DEFUN([CY_CHECK_JAVASCRIPT], [ 119 | CY_CHECK_JAVASCRIPTCORE 120 | ]) 121 | AC_ARG_ENABLE([javascript], [AS_HELP_STRING( 122 | [--enable-javascript@<:@=ENGINE@:>@], 123 | [use a JavaScript runtime (currently the only available option for ENGINE is JavaScriptCore) @<:@default=yes@:>@] 124 | )], [ 125 | AS_CASE([$enableval], [yes], [CY_CHECK_JAVASCRIPT], [no], [ 126 | AC_SUBST([CY_EXECUTE], [0]) 127 | ], [JavaScriptCore], [ 128 | CY_CHECK_JAVASCRIPTCORE 129 | ], [AC_MSG_ERROR([Unknown JavaScript engine: $enableval])]) 130 | ], [CY_CHECK_JAVASCRIPT]) 131 | AC_DEFUN([CY_CHECK_PKG_CONFIG_LIBFFI], [ 132 | PKG_CHECK_MODULES([LIBFFI], [libffi], [ 133 | AC_LIB_APPENDTOVAR([CXXFLAGS], [`$PKG_CONFIG --cflags libffi`]) 134 | AC_LIB_APPENDTOVAR([LIBS], [`$PKG_CONFIG --libs libffi`]) 135 | ], [ 136 | AC_MSG_ERROR([You need libffi]) 137 | ]) 138 | ]) 139 | AS_CASE([$CY_EXECUTE], [1], [ 140 | AC_SUBST([CY_EXECUTE]) 141 | AC_CHECK_HEADERS([ffi.h ffi/ffi.h], [break]) 142 | AS_IF([test "x$ac_cv_header_ffi_h" = xno && test "x$ac_cv_header_ffi_ffi_h" = xno], [ 143 | CY_CHECK_PKG_CONFIG_LIBFFI 144 | ], [ 145 | AC_SEARCH_LIBS([ffi_call], [ffi]) 146 | AS_CASE([$ac_cv_search_ffi_call], [no], [CY_CHECK_PKG_CONFIG_LIBFFI]) 147 | ]) 148 | AC_LANG_PUSH([Objective C++]) 149 | AC_MSG_CHECKING([if we really have Objective C++]) 150 | AC_COMPILE_IFELSE([ 151 | // This space intentionally left blank 152 | ], [ 153 | CY_OBJECTIVEC=1 154 | AC_MSG_RESULT([yes]) 155 | ], [AC_MSG_RESULT([no])]) 156 | AS_IF([test "x$CY_OBJECTIVEC" = x1], [ 157 | AC_CHECK_FRAMEWORK([CoreFoundation], [ 158 | #include 159 | ], [CFAllocatorGetDefault();], [ 160 | AC_SUBST([CY_OBJECTIVEC]) 161 | AC_CHECK_FRAMEWORK([Foundation], [ 162 | #include 163 | ], [[[[NSObject alloc] init];]]) 164 | AC_CHECK_FRAMEWORK([WebKit], [ 165 | #include 166 | ], [[[[WebScriptObject alloc] init];]]) 167 | ], [ 168 | AC_ARG_VAR([GNUSTEP_CONFIG], [prints information about the current gnustep installation]) 169 | AC_CHECK_PROGS([GNUSTEP_CONFIG], [gnustep-config]) 170 | AS_IF([test "x$GNUSTEP_CONFIG" != x], [ 171 | AC_SUBST([CY_OBJECTIVEC]) 172 | AC_LIB_APPENDTOVAR([OBJCXXFLAGS], [`$GNUSTEP_CONFIG --objc-flags`]) 173 | AC_LIB_APPENDTOVAR([LIBS], [`$GNUSTEP_CONFIG --base-libs`]) 174 | ], [AC_SUBST([CY_OBJECTIVEC], [0])]) 175 | ]) 176 | ]) 177 | AC_LANG_POP([Objective C++]) 178 | ]) 179 | VL_LIB_READLINE 180 | AS_CASE([$vl_cv_lib_readline], [no], [AC_MSG_ERROR([You need readline])]) 181 | AC_LANG_PUSH([C]) 182 | AM_ICONV 183 | AS_CASE([$am_cv_func_iconv], [yes], [], [ 184 | for cy_iconv_prefix_arg in $CFLAGS $CXXFLAGS $OBJCXXFLAGS $LDFLAGS $LIBS; do 185 | AS_CASE([$cy_iconv_prefix_arg], [-I*], [ 186 | AC_LIB_APPENDTOVAR([cy_iconv_prefixes], [`echo $cy_iconv_prefix_arg | sed -e 's/^-I//;s|/include$||'`]) 187 | ], [-L*], [ 188 | AC_LIB_APPENDTOVAR([cy_iconv_prefixes], [`echo $cy_iconv_prefix_arg | sed -e 's/^-L//;s|/lib$||'`]) 189 | ]) 190 | done 191 | for with_libiconv_prefix in $cy_iconv_prefixes; do 192 | AS_UNSET([am_cv_func_iconv]) 193 | AM_ICONV_LINKFLAGS_BODY 194 | AM_ICONV 195 | done 196 | ]) 197 | AS_CASE([$am_cv_func_iconv], [yes], [], [AC_MSG_ERROR([You need iconv])]) 198 | AC_LANG_POP([C]) 199 | AS_IF([test "x$CY_OBJECTIVEC" = x1], [ 200 | AC_CHECK_HEADER([mach/mach.h], [ 201 | AC_CHECK_TOOLS([_OTOOL], [otool]) 202 | AS_IF([test "x$_OTOOL" = x], [AC_MSG_ERROR([You need otool])]) 203 | AC_CHECK_TOOLS([_LIPO], [lipo]) 204 | AS_IF([test "x$_LIPO" = x], [AC_MSG_ERROR([You need lipo])]) 205 | AC_CHECK_TOOLS([_NM], [nm]) 206 | AS_IF([test "x$_NM" = x], [AC_MSG_ERROR([You need nm])]) 207 | AC_SUBST([SO], [$acl_shlibext]) 208 | AC_SUBST([CY_OBJECTIVEC_MACH], [1]) 209 | AC_SUBST([CY_ATTACH_GROUP], [procmod]) 210 | ]) 211 | ]) 212 | AS_IF([test "x$GMAKE" != xmake], [ 213 | AC_CONFIG_FILES([Makefile]) 214 | ]) 215 | AC_CONFIG_FILES([GNUmakefile]) 216 | AC_OUTPUT 217 | -------------------------------------------------------------------------------- /control.in: -------------------------------------------------------------------------------- 1 | Package: cycript 2 | Priority: optional 3 | Section: Development 4 | Maintainer: Jay Freeman (saurik) 5 | Architecture: % 6 | Version: 0.9.#-1 7 | Description: runtime execution server and disassembler 8 | Name: Cycript 9 | Depends: & 10 | Author: Jay Freeman (saurik) 11 | Depiction: http://cydia.saurik.com/info/cycript/ 12 | Tag: purpose::daemon, role::developer 13 | -------------------------------------------------------------------------------- /cycript.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_HPP 23 | #define CYCRIPT_HPP 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "String.hpp" 30 | 31 | void CYInitializeStatic(); 32 | 33 | bool CYRecvAll_(int socket, uint8_t *data, size_t size); 34 | bool CYSendAll_(int socket, const uint8_t *data, size_t size); 35 | 36 | void CYNumerify(std::ostringstream &str, double value); 37 | void CYStringify(std::ostringstream &str, const char *data, size_t size); 38 | 39 | double CYCastDouble(const char *value, size_t size); 40 | double CYCastDouble(const char *value); 41 | 42 | extern "C" void CYHandleClient(apr_pool_t *pool, int socket); 43 | 44 | template 45 | bool CYRecvAll(int socket, Type_ *data, size_t size) { 46 | return CYRecvAll_(socket, reinterpret_cast(data), size); 47 | } 48 | 49 | template 50 | bool CYSendAll(int socket, const Type_ *data, size_t size) { 51 | return CYSendAll_(socket, reinterpret_cast(data), size); 52 | } 53 | 54 | apr_pool_t *CYGetGlobalPool(); 55 | 56 | #endif/*CYCRIPT_HPP*/ 57 | -------------------------------------------------------------------------------- /cycript.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | com.apple.springboard.debugapplications 5 | 6 | get-task-allow 7 | 8 | task_for_pid-allow 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /documents.txt: -------------------------------------------------------------------------------- 1 | http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html 2 | http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html 3 | http://www.webweavertech.com/ovidiu/Objective-C/objc-features_3.html 4 | 5 | http://www.mail-archive.com/es-discuss@mozilla.org/msg00999.html 6 | http://www.mail-archive.com/es-discuss@mozilla.org/msg01025.html 7 | -------------------------------------------------------------------------------- /find_apr.m4: -------------------------------------------------------------------------------- 1 | dnl -------------------------------------------------------- -*- autoconf -*- 2 | dnl Licensed to the Apache Software Foundation (ASF) under one or more 3 | dnl contributor license agreements. See the NOTICE file distributed with 4 | dnl this work for additional information regarding copyright ownership. 5 | dnl The ASF licenses this file to You under the Apache License, Version 2.0 6 | dnl (the "License"); you may not use this file except in compliance with 7 | dnl the License. You may obtain a copy of the License at 8 | dnl 9 | dnl http://www.apache.org/licenses/LICENSE-2.0 10 | dnl 11 | dnl Unless required by applicable law or agreed to in writing, software 12 | dnl distributed under the License is distributed on an "AS IS" BASIS, 13 | dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | dnl See the License for the specific language governing permissions and 15 | dnl limitations under the License. 16 | 17 | dnl 18 | dnl find_apr.m4 : locate the APR include files and libraries 19 | dnl 20 | dnl This macro file can be used by applications to find and use the APR 21 | dnl library. It provides a standardized mechanism for using APR. It supports 22 | dnl embedding APR into the application source, or locating an installed 23 | dnl copy of APR. 24 | dnl 25 | dnl APR_FIND_APR(srcdir, builddir, implicit-install-check, acceptable-majors, 26 | dnl detailed-check) 27 | dnl 28 | dnl where srcdir is the location of the bundled APR source directory, or 29 | dnl empty if source is not bundled. 30 | dnl 31 | dnl where builddir is the location where the bundled APR will will be built, 32 | dnl or empty if the build will occur in the srcdir. 33 | dnl 34 | dnl where implicit-install-check set to 1 indicates if there is no 35 | dnl --with-apr option specified, we will look for installed copies. 36 | dnl 37 | dnl where acceptable-majors is a space separated list of acceptable major 38 | dnl version numbers. Often only a single major version will be acceptable. 39 | dnl If multiple versions are specified, and --with-apr=PREFIX or the 40 | dnl implicit installed search are used, then the first (leftmost) version 41 | dnl in the list that is found will be used. Currently defaults to [0 1]. 42 | dnl 43 | dnl where detailed-check is an M4 macro which sets the apr_acceptable to 44 | dnl either "yes" or "no". The macro will be invoked for each installed 45 | dnl copy of APR found, with the apr_config variable set appropriately. 46 | dnl Only installed copies of APR which are considered acceptable by 47 | dnl this macro will be considered found. If no installed copies are 48 | dnl considered acceptable by this macro, apr_found will be set to either 49 | dnl either "no" or "reconfig". 50 | dnl 51 | dnl Sets the following variables on exit: 52 | dnl 53 | dnl apr_found : "yes", "no", "reconfig" 54 | dnl 55 | dnl apr_config : If the apr-config tool exists, this refers to it. If 56 | dnl apr_found is "reconfig", then the bundled directory 57 | dnl should be reconfigured *before* using apr_config. 58 | dnl 59 | dnl Note: this macro file assumes that apr-config has been installed; it 60 | dnl is normally considered a required part of an APR installation. 61 | dnl 62 | dnl If a bundled source directory is available and needs to be (re)configured, 63 | dnl then apr_found is set to "reconfig". The caller should reconfigure the 64 | dnl (passed-in) source directory, placing the result in the build directory, 65 | dnl as appropriate. 66 | dnl 67 | dnl If apr_found is "yes" or "reconfig", then the caller should use the 68 | dnl value of apr_config to fetch any necessary build/link information. 69 | dnl 70 | 71 | AC_DEFUN([APR_FIND_APR], [ 72 | apr_found="no" 73 | 74 | if test "$target_os" = "os2-emx"; then 75 | # Scripts don't pass test -x on OS/2 76 | TEST_X="test -f" 77 | else 78 | TEST_X="test -x" 79 | fi 80 | 81 | ifelse([$4], [], [ 82 | ifdef(AC_WARNING,AC_WARNING([$0: missing argument 4 (acceptable-majors): Defaulting to APR 0.x then APR 1.x])) 83 | acceptable_majors="0 1"], 84 | [acceptable_majors="$4"]) 85 | 86 | apr_temp_acceptable_apr_config="" 87 | for apr_temp_major in $acceptable_majors 88 | do 89 | case $apr_temp_major in 90 | 0) 91 | apr_temp_acceptable_apr_config="$apr_temp_acceptable_apr_config apr-config" 92 | ;; 93 | *) 94 | apr_temp_acceptable_apr_config="$apr_temp_acceptable_apr_config apr-$apr_temp_major-config" 95 | ;; 96 | esac 97 | done 98 | 99 | AC_MSG_CHECKING(for APR) 100 | AC_ARG_WITH(apr, 101 | [ --with-apr=PATH prefix for installed APR or the full path to 102 | apr-config], 103 | [ 104 | if test "$withval" = "no" || test "$withval" = "yes"; then 105 | AC_MSG_ERROR([--with-apr requires a directory or file to be provided]) 106 | fi 107 | 108 | for apr_temp_apr_config_file in $apr_temp_acceptable_apr_config 109 | do 110 | for lookdir in "$withval/bin" "$withval" 111 | do 112 | if $TEST_X "$lookdir/$apr_temp_apr_config_file"; then 113 | apr_config="$lookdir/$apr_temp_apr_config_file" 114 | ifelse([$5], [], [], [ 115 | apr_acceptable="yes" 116 | $5 117 | if test "$apr_acceptable" != "yes"; then 118 | AC_MSG_WARN([Found APR in $apr_config, but we think it is considered unacceptable]) 119 | continue 120 | fi]) 121 | apr_found="yes" 122 | break 2 123 | fi 124 | done 125 | done 126 | 127 | if test "$apr_found" != "yes" && $TEST_X "$withval" && $withval --help > /dev/null 2>&1 ; then 128 | apr_config="$withval" 129 | ifelse([$5], [], [apr_found="yes"], [ 130 | apr_acceptable="yes" 131 | $5 132 | if test "$apr_acceptable" = "yes"; then 133 | apr_found="yes" 134 | fi]) 135 | fi 136 | 137 | dnl if --with-apr is used, it is a fatal error for its argument 138 | dnl to be invalid 139 | if test "$apr_found" != "yes"; then 140 | AC_MSG_ERROR([the --with-apr parameter is incorrect. It must specify an install prefix, a build directory, or an apr-config file.]) 141 | fi 142 | ],[ 143 | dnl If we allow installed copies, check those before using bundled copy. 144 | if test -n "$3" && test "$3" = "1"; then 145 | for apr_temp_apr_config_file in $apr_temp_acceptable_apr_config 146 | do 147 | if $apr_temp_apr_config_file --help > /dev/null 2>&1 ; then 148 | apr_config="$apr_temp_apr_config_file" 149 | ifelse([$5], [], [], [ 150 | apr_acceptable="yes" 151 | $5 152 | if test "$apr_acceptable" != "yes"; then 153 | AC_MSG_WARN([skipped APR at $apr_config, version not acceptable]) 154 | continue 155 | fi]) 156 | apr_found="yes" 157 | break 158 | else 159 | dnl look in some standard places 160 | for lookdir in /usr /usr/local /usr/local/apr /opt/apr; do 161 | if $TEST_X "$lookdir/bin/$apr_temp_apr_config_file"; then 162 | apr_config="$lookdir/bin/$apr_temp_apr_config_file" 163 | ifelse([$5], [], [], [ 164 | apr_acceptable="yes" 165 | $5 166 | if test "$apr_acceptable" != "yes"; then 167 | AC_MSG_WARN([skipped APR at $apr_config, version not acceptable]) 168 | continue 169 | fi]) 170 | apr_found="yes" 171 | break 2 172 | fi 173 | done 174 | fi 175 | done 176 | fi 177 | dnl if we have not found anything yet and have bundled source, use that 178 | if test "$apr_found" = "no" && test -d "$1"; then 179 | apr_temp_abs_srcdir="`cd $1 && pwd`" 180 | apr_found="reconfig" 181 | apr_bundled_major="`sed -n '/#define.*APR_MAJOR_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p' \"$1/include/apr_version.h\"`" 182 | case $apr_bundled_major in 183 | "") 184 | AC_MSG_ERROR([failed to find major version of bundled APR]) 185 | ;; 186 | 0) 187 | apr_temp_apr_config_file="apr-config" 188 | ;; 189 | *) 190 | apr_temp_apr_config_file="apr-$apr_bundled_major-config" 191 | ;; 192 | esac 193 | if test -n "$2"; then 194 | apr_config="$2/$apr_temp_apr_config_file" 195 | else 196 | apr_config="$1/$apr_temp_apr_config_file" 197 | fi 198 | fi 199 | ]) 200 | 201 | AC_MSG_RESULT($apr_found) 202 | ]) 203 | -------------------------------------------------------------------------------- /framework.m4: -------------------------------------------------------------------------------- 1 | # AC_CHECK_FRAMEWORK(FRAMEWORK, PROLOGUE, BODY, 2 | # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], 3 | # [OTHER-LIBRARIES]) 4 | # ------------------------------------------------------ 5 | # 6 | # Use a cache variable name containing both the framework and function name, 7 | # because the test really is for framework $1 defining function $2, not 8 | # just for framework $1. Separate tests with the same $1 and different $2s 9 | # may have different results. 10 | # 11 | # Note that using directly AS_VAR_PUSHDEF([ac_Framework], [ac_cv_framework_$1]) 12 | # is asking for troubles, since AC_CHECK_FRAMEWORK($framework, fun) would give 13 | # ac_cv_framework_$framework_fun, which is definitely not what was meant. Hence 14 | # the AS_LITERAL_IF indirection. 15 | # 16 | # FIXME: This macro is extremely suspicious. It DEFINEs unconditionally, 17 | # whatever the FUNCTION, in addition to not being a *S macro. Note 18 | # that the cache does depend upon the function we are looking for. 19 | # 20 | # It is on purpose we used `ac_check_framework_save_LIBS' and not just 21 | # `ac_save_LIBS': there are many macros which don't want to see `LIBS' 22 | # changed but still want to use AC_CHECK_FRAMEWORK, so they save `LIBS'. 23 | # And ``ac_save_LIBS' is too tempting a name, so let's leave them some 24 | # freedom. 25 | AC_DEFUN([AC_CHECK_FRAMEWORK], [ 26 | m4_ifval([$4], , [AH_CHECK_FRAMEWORK([$1])])dnl 27 | AS_LITERAL_IF([$1], [AS_VAR_PUSHDEF([ac_Framework], [ac_cv_framework_$1])], 28 | [AS_VAR_PUSHDEF([ac_Framework], [ac_cv_framework_$1''])] 29 | )dnl 30 | AC_CACHE_CHECK([for framework $1], ac_Framework, [ 31 | ac_check_framework_save_LIBS=$LIBS 32 | LIBS="-framework $1 $6 $LIBS" 33 | AC_LINK_IFELSE([AC_LANG_PROGRAM([$2], [$3])],[ 34 | AS_VAR_SET(ac_Framework, yes) 35 | ], [AS_VAR_SET(ac_Framework, no)]) 36 | LIBS=$ac_check_framework_save_LIBS] 37 | ) 38 | AS_IF([test AS_VAR_GET(ac_Framework) = yes], [ 39 | AC_LIB_APPENDTOVAR([LIBS], ["-framework $1 $LIBS"]) 40 | m4_default([$4], [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FRAMEWORK_$1))]) 41 | ], [$5])dnl 42 | AS_VAR_POPDEF([ac_Framework])dnl 43 | ])# AC_CHECK_FRAMEWORK 44 | 45 | # AH_CHECK_FRAMEWORK(FRAMEWORK) 46 | # --------------------- 47 | m4_define([AH_CHECK_FRAMEWORK], [ 48 | AH_TEMPLATE(AS_TR_CPP(HAVE_FRAMEWORK_$1), 49 | [Define to 1 if you have the `]$1[' framework (-framework ]$1[).] 50 | )]) 51 | -------------------------------------------------------------------------------- /iPhone.mk: -------------------------------------------------------------------------------- 1 | uname_s := Darwin 2 | uname_p := arm 3 | paths := ~/menes/mobilesubstrate 4 | restart := ./iPhone.sh 5 | flags += -g0 -O3 6 | include makefile 7 | -------------------------------------------------------------------------------- /iPhone.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | PKG_ARCH=iphoneos-arm /apl/tel/exec.sh :apr-lib:libffi:readline make -f iPhone.mk "$@" 3 | -------------------------------------------------------------------------------- /include/System/machine/cpu_capabilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2007 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | #ifdef PRIVATE 29 | 30 | #ifndef _MACHINE_CPU_CAPABILITIES_H 31 | #define _MACHINE_CPU_CAPABILITIES_H 32 | 33 | #ifdef KERNEL_PRIVATE 34 | #if defined (__ppc__) 35 | #include "ppc/cpu_capabilities.h" 36 | #elif defined (__i386__) 37 | #include "i386/cpu_capabilities.h" 38 | #else 39 | #error architecture not supported 40 | #endif 41 | 42 | #else /* !KERNEL_PRIVATE -- System Framework header */ 43 | #if defined (__ppc__) || defined(__ppc64__) 44 | #include 45 | #elif defined (__i386__) || defined(__x86_64__) 46 | #include 47 | #else 48 | #error architecture not supported 49 | #endif 50 | #endif /* KERNEL_PRIVATE */ 51 | 52 | #endif /* _MACHINE_CPU_CAPABILITIES_H */ 53 | #endif /* PRIVATE */ 54 | -------------------------------------------------------------------------------- /include/machine/cpu_capabilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2007 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | #ifdef PRIVATE 29 | 30 | #ifndef _MACHINE_CPU_CAPABILITIES_H 31 | #define _MACHINE_CPU_CAPABILITIES_H 32 | 33 | #ifdef KERNEL_PRIVATE 34 | #if defined (__ppc__) 35 | #include "ppc/cpu_capabilities.h" 36 | #elif defined (__i386__) 37 | #include "i386/cpu_capabilities.h" 38 | #else 39 | #error architecture not supported 40 | #endif 41 | 42 | #else /* !KERNEL_PRIVATE -- System Framework header */ 43 | #if defined (__ppc__) || defined(__ppc64__) 44 | #include 45 | #elif defined (__i386__) || defined(__x86_64__) 46 | #include 47 | #else 48 | #error architecture not supported 49 | #endif 50 | #endif /* KERNEL_PRIVATE */ 51 | 52 | #endif /* _MACHINE_CPU_CAPABILITIES_H */ 53 | #endif /* PRIVATE */ 54 | -------------------------------------------------------------------------------- /include/posix_sched.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 25 | * All Rights Reserved 26 | * 27 | * Permission to use, copy, modify, and distribute this software and 28 | * its documentation for any purpose and without fee is hereby granted, 29 | * provided that the above copyright notice appears in all copies and 30 | * that both the copyright notice and this permission notice appear in 31 | * supporting documentation. 32 | * 33 | * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 34 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 35 | * FOR A PARTICULAR PURPOSE. 36 | * 37 | * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 38 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 39 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 40 | * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 41 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 42 | * 43 | */ 44 | /* 45 | * MkLinux 46 | */ 47 | 48 | /* 49 | * POSIX Realtime Scheduling Framework - IEEE 1003.1b 50 | */ 51 | 52 | #ifndef _POSIX_SCHED_H 53 | #define _POSIX_SCHED_H 54 | 55 | struct sched_param 56 | { 57 | int sched_priority; 58 | int quantum; 59 | }; 60 | 61 | /* 62 | * POSIX scheduling policies 63 | */ 64 | 65 | #define SCHED_OTHER POLICY_TIMESHARE 66 | #define SCHED_FIFO POLICY_FIFO 67 | #define SCHED_RR POLICY_RR 68 | 69 | #endif /* _POSIX_SCHED_H */ 70 | -------------------------------------------------------------------------------- /include/pthread_machdep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003-2004, 2008 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 25 | * All Rights Reserved 26 | * 27 | * Permission to use, copy, modify, and distribute this software and 28 | * its documentation for any purpose and without fee is hereby granted, 29 | * provided that the above copyright notice appears in all copies and 30 | * that both the copyright notice and this permission notice appear in 31 | * supporting documentation. 32 | * 33 | * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 34 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 35 | * FOR A PARTICULAR PURPOSE. 36 | * 37 | * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 38 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 39 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 40 | * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 41 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 42 | */ 43 | /* 44 | * MkLinux 45 | */ 46 | 47 | /* Machine-dependent definitions for pthread internals. */ 48 | 49 | #ifndef _POSIX_PTHREAD_MACHDEP_H 50 | #define _POSIX_PTHREAD_MACHDEP_H 51 | 52 | #ifdef __LP64__ 53 | #define _PTHREAD_TSD_OFFSET 0x60 54 | #else 55 | #define _PTHREAD_TSD_OFFSET 0x48 56 | #endif /* __LP64__ */ 57 | 58 | #ifndef __ASSEMBLER__ 59 | 60 | #include 61 | #ifdef __arm__ 62 | #include 63 | #endif 64 | 65 | /* 66 | ** Define macros for inline pthread_getspecific() usage. 67 | ** We reserve a number of slots for Apple internal use. 68 | ** This number can grow dynamically, no need to fix it. 69 | */ 70 | 71 | /* This header contains pre defined thread specific keys */ 72 | /* 0 is used for pthread_self */ 73 | #define _PTHREAD_TSD_SLOT_PTHREAD_SELF 0 74 | /* Keys 1- 9 for use by dyld, directly or indirectly */ 75 | #define _PTHREAD_TSD_SLOT_DYLD_1 1 76 | #define _PTHREAD_TSD_SLOT_DYLD_2 2 77 | #define _PTHREAD_TSD_SLOT_DYLD_3 3 78 | #define _PTHREAD_TSD_RESERVED_SLOT_COUNT 4 79 | 80 | /* Keys 10 - 29 are for Libc/Libsystem internal ussage */ 81 | /* used as __pthread_tsd_first + Num */ 82 | #define __PTK_LIBC_LOCALE_KEY 10 83 | #define __PTK_LIBC_TTYNAME_KEY 11 84 | #define __PTK_LIBC_LOCALTIME_KEY 12 85 | #define __PTK_LIBC_GMTIME_KEY 13 86 | #define __PTK_LIBC_GDTOA_BIGINT_KEY 14 87 | #define __PTK_LIBC_PARSEFLOAT_KEY 15 88 | 89 | /* Keys 20-25 for libdispactch usage */ 90 | #define __PTK_LIBDISPATCH_KEY0 20 91 | #define __PTK_LIBDISPATCH_KEY1 21 92 | #define __PTK_LIBDISPATCH_KEY2 22 93 | #define __PTK_LIBDISPATCH_KEY3 23 94 | #define __PTK_LIBDISPATCH_KEY4 24 95 | #define __PTK_LIBDISPATCH_KEY5 25 96 | 97 | /* Keys 30-255 for Non Libsystem usage */ 98 | 99 | /* Keys 30-39 for Graphic frameworks usage */ 100 | #define _PTHREAD_TSD_SLOT_OPENGL 30 /* backwards compat sake */ 101 | #define __PTK_FRAMEWORK_OPENGL_KEY 30 102 | #define __PTK_FRAMEWORK_GRAPHICS_KEY1 31 103 | #define __PTK_FRAMEWORK_GRAPHICS_KEY2 32 104 | #define __PTK_FRAMEWORK_GRAPHICS_KEY3 33 105 | #define __PTK_FRAMEWORK_GRAPHICS_KEY4 34 106 | #define __PTK_FRAMEWORK_GRAPHICS_KEY5 35 107 | #define __PTK_FRAMEWORK_GRAPHICS_KEY6 36 108 | #define __PTK_FRAMEWORK_GRAPHICS_KEY7 37 109 | #define __PTK_FRAMEWORK_GRAPHICS_KEY8 38 110 | #define __PTK_FRAMEWORK_GRAPHICS_KEY9 39 111 | 112 | /* Keys 40-49 for Objective-C runtime usage */ 113 | #define __PTK_FRAMEWORK_OBJC_KEY0 40 114 | #define __PTK_FRAMEWORK_OBJC_KEY1 41 115 | #define __PTK_FRAMEWORK_OBJC_KEY2 42 116 | #define __PTK_FRAMEWORK_OBJC_KEY3 43 117 | #define __PTK_FRAMEWORK_OBJC_KEY4 44 118 | #define __PTK_FRAMEWORK_OBJC_KEY5 45 119 | #define __PTK_FRAMEWORK_OBJC_KEY6 46 120 | #define __PTK_FRAMEWORK_OBJC_KEY7 47 121 | #define __PTK_FRAMEWORK_OBJC_KEY8 48 122 | #define __PTK_FRAMEWORK_OBJC_KEY9 49 123 | 124 | /* Keys 50-59 for Core Foundation usage */ 125 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY0 50 126 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY1 51 127 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY2 52 128 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY3 53 129 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY4 54 130 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY5 55 131 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY6 56 132 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY7 57 133 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY8 58 134 | #define __PTK_FRAMEWORK_COREFOUNDATION_KEY9 59 135 | 136 | /* Keys 60-69 for Foundation usage */ 137 | #define __PTK_FRAMEWORK_FOUNDATION_KEY0 60 138 | #define __PTK_FRAMEWORK_FOUNDATION_KEY1 61 139 | #define __PTK_FRAMEWORK_FOUNDATION_KEY2 62 140 | #define __PTK_FRAMEWORK_FOUNDATION_KEY3 63 141 | #define __PTK_FRAMEWORK_FOUNDATION_KEY4 64 142 | #define __PTK_FRAMEWORK_FOUNDATION_KEY5 65 143 | #define __PTK_FRAMEWORK_FOUNDATION_KEY6 66 144 | #define __PTK_FRAMEWORK_FOUNDATION_KEY7 67 145 | #define __PTK_FRAMEWORK_FOUNDATION_KEY8 68 146 | #define __PTK_FRAMEWORK_FOUNDATION_KEY9 69 147 | 148 | /* Keys 70-79 for Core Animation/QuartzCore usage */ 149 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY0 70 150 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY1 71 151 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY2 72 152 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY3 73 153 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY4 74 154 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY5 75 155 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY6 76 156 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY7 77 157 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY8 78 158 | #define __PTK_FRAMEWORK_QUARTZCORE_KEY9 79 159 | 160 | 161 | /* Keys 80-89 for Garbage Collection */ 162 | #define __PTK_FRAMEWORK_GC_KEY0 80 163 | #define __PTK_FRAMEWORK_GC_KEY1 81 164 | #define __PTK_FRAMEWORK_GC_KEY2 82 165 | #define __PTK_FRAMEWORK_GC_KEY3 83 166 | #define __PTK_FRAMEWORK_GC_KEY4 84 167 | #define __PTK_FRAMEWORK_GC_KEY5 85 168 | #define __PTK_FRAMEWORK_GC_KEY6 86 169 | #define __PTK_FRAMEWORK_GC_KEY7 87 170 | #define __PTK_FRAMEWORK_GC_KEY8 88 171 | #define __PTK_FRAMEWORK_GC_KEY9 89 172 | 173 | 174 | /* 175 | ** Define macros for inline pthread_getspecific() usage. 176 | ** We reserve a number of slots for Apple internal use. 177 | ** This number can grow dynamically, no need to fix it. 178 | */ 179 | 180 | 181 | #if defined(__cplusplus) 182 | extern "C" { 183 | #endif 184 | 185 | extern void *pthread_getspecific(unsigned long); 186 | /* setup destructor function for static key as it is not created with pthread_key_create() */ 187 | int pthread_key_init_np(int, void (*)(void *)); 188 | 189 | #if defined(__cplusplus) 190 | } 191 | #endif 192 | 193 | typedef int pthread_lock_t; 194 | 195 | inline static int 196 | _pthread_has_direct_tsd(void) 197 | { 198 | #if defined(__ppc__) 199 | int *caps = (int *)_COMM_PAGE_CPU_CAPABILITIES; 200 | if (*caps & kFastThreadLocalStorage) { 201 | return 1; 202 | } else { 203 | return 0; 204 | } 205 | #elif defined(__arm__) && defined(__thumb__) && defined(_ARM_ARCH_6) && !defined(_ARM_ARCH_7) 206 | return 0; 207 | #else 208 | return 1; 209 | #endif 210 | } 211 | 212 | /* To be used with static constant keys only */ 213 | inline static void * 214 | _pthread_getspecific_direct(unsigned long slot) 215 | { 216 | void *ret; 217 | #if defined(__i386__) || defined(__x86_64__) 218 | #if defined(__OPTIMIZE__) 219 | asm volatile("mov %%gs:%P1, %0" : "=r" (ret) : "i" (slot * sizeof(void *) + _PTHREAD_TSD_OFFSET)); 220 | #else 221 | asm("mov %%gs:%P2(,%1,%P3), %0" : "=r" (ret) : "r" (slot), "i" (_PTHREAD_TSD_OFFSET), "i" (sizeof (void *))); 222 | #endif 223 | #elif defined(__ppc__) 224 | void **__pthread_tsd; 225 | asm volatile("mfspr %0, 259" : "=r" (__pthread_tsd)); 226 | ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; 227 | #elif defined(__ppc64__) 228 | register void **__pthread_tsd asm ("r13"); 229 | ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; 230 | #elif defined(__arm__) && defined(_ARM_ARCH_6) 231 | void **__pthread_tsd; 232 | __asm__ ("mrc p15, 0, %0, c13, c0, 3" : "=r"(__pthread_tsd)); 233 | ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; 234 | #elif defined(__arm__) && !defined(_ARM_ARCH_6) 235 | register void **__pthread_tsd asm ("r9"); 236 | ret = __pthread_tsd[slot + (_PTHREAD_TSD_OFFSET / sizeof(void *))]; 237 | #else 238 | #error no pthread_getspecific_direct implementation for this arch 239 | #endif 240 | return ret; 241 | } 242 | 243 | /* To be used with static constant keys only */ 244 | #define _pthread_setspecific_direct(key, val) pthread_setspecific(key, val) 245 | 246 | #define LOCK_INIT(l) ((l) = 0) 247 | #define LOCK_INITIALIZER 0 248 | 249 | #endif /* ! __ASSEMBLER__ */ 250 | #endif /* _POSIX_PTHREAD_MACHDEP_H */ 251 | -------------------------------------------------------------------------------- /include/pthread_spinlock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 25 | * All Rights Reserved 26 | * 27 | * Permission to use, copy, modify, and distribute this software and 28 | * its documentation for any purpose and without fee is hereby granted, 29 | * provided that the above copyright notice appears in all copies and 30 | * that both the copyright notice and this permission notice appear in 31 | * supporting documentation. 32 | * 33 | * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 34 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 35 | * FOR A PARTICULAR PURPOSE. 36 | * 37 | * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 38 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 39 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 40 | * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 41 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 42 | * 43 | */ 44 | /* 45 | * MkLinux 46 | */ 47 | 48 | /* 49 | * POSIX Threads - IEEE 1003.1c 50 | */ 51 | 52 | #ifndef _POSIX_PTHREAD_SPINLOCK_H 53 | #define _POSIX_PTHREAD_SPINLOCK_H 54 | 55 | #include 56 | #define __APPLE_API_PRIVATE 57 | #include 58 | 59 | #ifndef __POSIX_LIB__ 60 | #define __POSIX_LIB__ 61 | #endif 62 | 63 | #include "pthread_machdep.h" /* Machine-dependent definitions. */ 64 | 65 | /* Number of times to spin when the lock is unavailable and we are on a 66 | multiprocessor. On a uniprocessor we yield the processor immediately. */ 67 | #define MP_SPIN_TRIES 1000 68 | extern int _spin_tries; 69 | extern int __is_threaded; 70 | 71 | /* Internal mutex locks for data structures */ 72 | #define TRY_LOCK(v) (!__is_threaded || _spin_lock_try((pthread_lock_t *)&(v))) 73 | 74 | /* _DO_SPINLOCK_LOCK() takes a (pthread_lock_t *) */ 75 | #define _DO_SPINLOCK_LOCK(v) _spin_lock(v) 76 | 77 | /* _DO_SPINLOCK_UNLOCK() takes a (pthread_lock_t *) */ 78 | #define _DO_SPINLOCK_UNLOCK(v) _spin_unlock(v) 79 | 80 | /* LOCK() takes a (pthread_lock_t) */ 81 | #define LOCK(v) \ 82 | do { \ 83 | if (__is_threaded) { \ 84 | _DO_SPINLOCK_LOCK((pthread_lock_t *)&(v)); \ 85 | } \ 86 | } while (0) 87 | 88 | /* UNLOCK() takes a (pthread_lock_t) */ 89 | #define UNLOCK(v) \ 90 | do { \ 91 | if (__is_threaded) { \ 92 | _DO_SPINLOCK_UNLOCK((pthread_lock_t *)&(v)); \ 93 | } \ 94 | } while (0) 95 | 96 | /* Prototypes. */ 97 | 98 | /* Functions defined in machine-dependent files. */ 99 | extern void _spin_lock(pthread_lock_t *lockp); 100 | extern int _spin_lock_try(pthread_lock_t *lockp); 101 | extern void _spin_unlock(pthread_lock_t *lockp); 102 | 103 | #endif /* _POSIX_PTHREAD_SPINLOCK_H */ 104 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | SHELL := $(shell which bash 2>/dev/null) 2 | 3 | ifndef PKG_TARG 4 | target := 5 | else 6 | target := $(PKG_TARG)- 7 | endif 8 | 9 | prefix := /usr 10 | 11 | gcc := g++ 12 | flags ?= -g3 -O0 -DYYDEBUG=1 13 | 14 | paths := $(foreach path,$(paths),$(wildcard $(path))) 15 | flags += $(foreach path,$(paths),-I$(path) -L$(path)) 16 | objc := 17 | 18 | svn := $(shell svnversion) 19 | 20 | all: 21 | all := cycript 22 | 23 | dpkg_architecture := $(shell which dpkg-architecture 2>/dev/null) 24 | ifneq ($(dpkg_architecture),) 25 | arch := $(shell $(dpkg_architecture) -qDEB_HOST_ARCH 2>/dev/null) 26 | endif 27 | 28 | header := Cycript.tab.hh Parser.hpp Pooling.hpp List.hpp Local.hpp cycript.hpp Internal.hpp Error.hpp String.hpp Exception.hpp Standard.hpp 29 | 30 | code := 31 | code += Replace.o Output.o 32 | code += Cycript.tab.o lex.cy.o 33 | code += Network.o Parser.o 34 | code += JavaScriptCore.o Library.o 35 | 36 | inject := 37 | 38 | filters := #E4X 39 | ldid := true 40 | entitle := $(ldid) 41 | lib := lib 42 | dll := so 43 | apr_config := apr-1-config 44 | library := 45 | console := -lreadline 46 | depends := 47 | 48 | restart ?= $(MAKE) 49 | uname_s ?= $(shell uname -s) 50 | uname_p ?= $(shell uname -p) 51 | 52 | -include $(uname_s).mk 53 | -include $(uname_s)-$(uname_p).mk 54 | 55 | ifneq ($(shell pkg-config libffi --modversion 2>/dev/null),) 56 | flags += $(shell pkg-config --cflags libffi) 57 | endif 58 | 59 | ifdef CY_EXECUTE 60 | ifeq ($(filter ObjectiveC,$(filters)),) 61 | ifneq ($(shell which gnustep-config 2>/dev/null),) 62 | include GNUstep.mk 63 | endif 64 | endif 65 | endif 66 | 67 | apr := $(shell $(apr_config) --link-ld) 68 | library += $(apr) 69 | console += $(apr) 70 | 71 | flags += -Wall -Werror -Wno-parentheses #-Wno-unused 72 | flags += -fno-common 73 | flags += -I. -Iinclude -I$(shell $(apr_config) --includedir) 74 | 75 | all += $(lib)cycript.$(dll) 76 | 77 | filters += $(shell bison <(echo '%code{}%%_:') -o/dev/null 2>/dev/null && echo Bison24 || echo Bison23) 78 | 79 | ifdef arch 80 | deb := $(shell grep ^Package: control.in | cut -d ' ' -f 2-)_$(shell grep ^Version: control.in | cut -d ' ' -f 2 | sed -e 's/\#/$(svn)/')_$(arch).deb 81 | 82 | all: 83 | 84 | extra:: 85 | 86 | ifeq ($(depends)$(dll),dylib) 87 | control.tmp: control.in cycript $(lib)cycript.dylib 88 | sed -e 's/&/'"$$(dpkg-query -S $$(otool -lah cycript *.dylib | grep dylib | grep -v ':$$' | sed -e 's/^ *name //;s/ (offset [0-9]*)$$//' | sort -u) 2>/dev/null | sed -e 's/:.*//; /^cycript$$/ d; s/$$/,/' | sort -u | tr '\n' ' ')"'/;s/, $$//;s/#/$(svn)/;s/%/$(arch)/' $< >$@ 89 | else 90 | ifeq ($(depends)$(dll),so) 91 | control.tmp: control.in cycript $(lib)cycript.so 92 | sed -e 's/&/'"$$(dpkg-query -S $$(ldd cycript $(lib)cycript.so | sed -e '/:$$/ d; s/^[ \t]*\([^ ]* => \)\?\([^ ]*\) .*/\2/' | sort -u) 2>/dev/null | sed -e 's/:.*//; /^cycript$$/ d; s/$$/,/' | sort -u | tr '\n' ' ')"'/;s/, $$//;s/#/$(svn)/;s/%/$(arch)/' $< >$@ 93 | else 94 | control.tmp: control.in 95 | sed -e 's/&/$(foreach depend,$(depends),$(depend),)/;s/,$$//;s/#/$(svn)/;s/%/$(arch)/' $< >$@ 96 | endif 97 | endif 98 | 99 | control: control.tmp 100 | [[ -e control ]] && diff control control.tmp &>/dev/null || cp -pRf control.tmp control 101 | 102 | $(deb): $(all) control 103 | rm -rf package 104 | mkdir -p package/DEBIAN 105 | cp -pR control package/DEBIAN 106 | mkdir -p package$(prefix)/{bin,lib,sbin} 107 | $(restart) extra 108 | cp -pR $(lib)cycript.$(dll) package$(prefix)/lib 109 | cp -pR cycript package$(prefix)/bin 110 | #cp -pR cyrver package$(prefix)/sbin 111 | dpkg-deb -b package $(deb) 112 | endif 113 | 114 | all: $(all) 115 | 116 | clean:: 117 | rm -f *.o $(lib)cycript.$(dll) $(all) Struct.hpp lex.cy.c Cycript.tab.cc Cycript.tab.hh location.hh position.hh stack.hh cyrver Cycript.yy Cycript.l control Bridge.hpp Cycript.output 118 | 119 | %.yy: %.yy.in 120 | ./Filter.sh <$< >$@ $(filters) 121 | 122 | %.l: %.l.in 123 | ./Filter.sh <$< >$@ $(filters) 124 | 125 | Cycript.tab.cc Cycript.tab.hh location.hh position.hh: Cycript.yy 126 | bison -v --report=state $< 127 | 128 | lex.cy.c: Cycript.l 129 | flex -t $< | sed -e 's/int yyl;/yy_size_t yyl;/;s/int yyleng_r;/yy_size_t yyleng_r;/' >$@ 130 | 131 | #Parser.hpp: Parser.py Parser.dat 132 | # ./Parser.py $@ 133 | 134 | Cycript.tab.o: Cycript.tab.cc $(header) 135 | $(target)$(gcc) $(flags) -c -o $@ $< 136 | 137 | lex.cy.o: lex.cy.c $(header) 138 | $(target)$(gcc) $(flags) -c -o $@ $< 139 | 140 | %.o: %.cpp $(header) 141 | $(target)$(gcc) $(flags) -c -o $@ $< 142 | 143 | #objc := -x c++ 144 | %.o: %.mm $(header) 145 | $(target)$(gcc) $(objc) $(flags) -c -o $@ $< 146 | 147 | $(lib)cycript.$(dll): $(code) 148 | $(target)$(gcc) $(flags) -shared -dynamiclib -o $@ $(filter %.o,$^) $(library) $(link) 149 | $(ldid) $@ 150 | 151 | cycript: Console.o $(lib)cycript.$(dll) $(inject) 152 | $(target)$(gcc) $(flags) -o $@ $(filter %.o,$^) -L. -lcycript $(console) $(link) 153 | $(entitle) cycript 154 | 155 | package: $(deb) 156 | 157 | test: $(deb) 158 | dpkg -i $(deb) 159 | if [[ -e target.cy ]]; then cycript -c target.cy && echo; fi 160 | if [[ -e jquery.js ]]; then /usr/bin/time cycript -c jquery.js >jquery.cyc.js; gzip -9c jquery.cyc.js >jquery.cyc.js.gz; wc -c jquery.{mam,gcc,cyc,bak,yui}.js; wc -c jquery.{cyc,gcc,bak,mam,yui}.js.gz; fi 161 | if [[ -e test.cy ]]; then cycript test.cy; fi 162 | 163 | install: cycript $(lib)cycript.$(dll) 164 | sudo cp -p cycript /usr/bin 165 | sudo cp -p $(lib)cycript.$(dll) /usr/lib 166 | sudo chgrp procmod /usr/bin/cycript 167 | sudo chmod g+s /usr/bin/cycript 168 | 169 | uninstall: 170 | sudo rm -f /usr/bin/cycript /usr/lib/libcycript.dylib 171 | 172 | .PHONY: all clean extra package control.tmp 173 | -------------------------------------------------------------------------------- /sig/copy.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef _GNU_SOURCE 23 | #define _GNU_SOURCE 24 | #endif 25 | 26 | #include 27 | #include "Pooling.hpp" 28 | #include "sig/parse.hpp" 29 | 30 | #ifdef HAVE_FFI_FFI_H 31 | #include 32 | #else 33 | #include 34 | #endif 35 | 36 | namespace sig { 37 | 38 | void Copy(apr_pool_t *pool, Element &lhs, Element &rhs) { 39 | lhs.name = apr_pstrdup(pool, rhs.name); 40 | if (rhs.type == NULL) 41 | lhs.type = NULL; 42 | else { 43 | lhs.type = new(pool) Type; 44 | Copy(pool, *lhs.type, *rhs.type); 45 | } 46 | lhs.offset = rhs.offset; 47 | } 48 | 49 | void Copy(apr_pool_t *pool, Signature &lhs, Signature &rhs) { 50 | size_t count(rhs.count); 51 | lhs.count = count; 52 | lhs.elements = new(pool) Element[count]; 53 | for (size_t index(0); index != count; ++index) 54 | Copy(pool, lhs.elements[index], rhs.elements[index]); 55 | } 56 | 57 | void Copy(apr_pool_t *pool, Type &lhs, Type &rhs) { 58 | lhs.primitive = rhs.primitive; 59 | lhs.name = apr_pstrdup(pool, rhs.name); 60 | lhs.flags = rhs.flags; 61 | 62 | if (sig::IsAggregate(rhs.primitive)) 63 | Copy(pool, lhs.data.signature, rhs.data.signature); 64 | else { 65 | sig::Type *&lht(lhs.data.data.type); 66 | sig::Type *&rht(rhs.data.data.type); 67 | 68 | if (rht == NULL) 69 | lht = NULL; 70 | else { 71 | lht = new(pool) Type; 72 | Copy(pool, *lht, *rht); 73 | } 74 | 75 | lhs.data.data.size = rhs.data.data.size; 76 | } 77 | } 78 | 79 | void Copy(apr_pool_t *pool, ffi_type &lhs, ffi_type &rhs) { 80 | lhs.size = rhs.size; 81 | lhs.alignment = rhs.alignment; 82 | lhs.type = rhs.type; 83 | if (rhs.elements == NULL) 84 | lhs.elements = NULL; 85 | else { 86 | size_t count(0); 87 | while (rhs.elements[count] != NULL) 88 | ++count; 89 | 90 | lhs.elements = new(pool) ffi_type *[count + 1]; 91 | lhs.elements[count] = NULL; 92 | 93 | for (size_t index(0); index != count; ++index) { 94 | // XXX: if these are libffi native then you can just take them 95 | ffi_type *ffi(new(pool) ffi_type); 96 | lhs.elements[index] = ffi; 97 | sig::Copy(pool, *ffi, *rhs.elements[index]); 98 | } 99 | } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /sig/ffi_type.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include "Error.hpp" 23 | 24 | #include "sig/ffi_type.hpp" 25 | #include "sig/types.hpp" 26 | 27 | #define ffi_type_slonglong ffi_type_sint64 28 | #define ffi_type_ulonglong ffi_type_uint64 29 | 30 | namespace sig { 31 | 32 | void sig_ffi_types( 33 | apr_pool_t *pool, 34 | ffi_type *(*sig_ffi_type)(apr_pool_t *, struct Type *), 35 | struct Signature *signature, 36 | ffi_type **types, 37 | size_t skip = 0, 38 | size_t offset = 0 39 | ) { 40 | _assert(signature->count >= skip); 41 | for (size_t index = skip; index != signature->count; ++index) 42 | types[index - skip + offset] = (*sig_ffi_type)(pool, signature->elements[index].type); 43 | } 44 | 45 | ffi_type *ObjectiveC(apr_pool_t *pool, struct Type *type) { 46 | switch (type->primitive) { 47 | case typename_P: return &ffi_type_pointer; 48 | 49 | case union_P: 50 | /* XXX: we can totally make this work */ 51 | _assert(false); 52 | break; 53 | 54 | case string_P: return &ffi_type_pointer; 55 | case selector_P: return &ffi_type_pointer; 56 | case block_P: return &ffi_type_pointer; 57 | case object_P: return &ffi_type_pointer; 58 | case boolean_P: return &ffi_type_uchar; 59 | case uchar_P: return &ffi_type_uchar; 60 | case uint_P: return &ffi_type_uint; 61 | case ulong_P: return &ffi_type_ulong; 62 | case ulonglong_P: return &ffi_type_ulonglong; 63 | case ushort_P: return &ffi_type_ushort; 64 | 65 | case array_P: { 66 | // XXX: this is really lame 67 | ffi_type *aggregate(reinterpret_cast(apr_palloc(pool, sizeof(ffi_type)))); 68 | aggregate->size = 0; 69 | aggregate->alignment = 0; 70 | aggregate->type = FFI_TYPE_STRUCT; 71 | 72 | ffi_type *element(ObjectiveC(pool, type->data.data.type)); 73 | size_t size(type->data.data.size); 74 | 75 | aggregate->elements = reinterpret_cast(apr_palloc(pool, (size + 1) * sizeof(ffi_type *))); 76 | for (size_t i(0); i != size; ++i) 77 | aggregate->elements[i] = element; 78 | aggregate->elements[size] = NULL; 79 | 80 | return aggregate; 81 | } break; 82 | 83 | case pointer_P: return &ffi_type_pointer; 84 | 85 | case bit_P: 86 | /* XXX: we can totally make this work */ 87 | _assert(false); 88 | break; 89 | 90 | case char_P: return &ffi_type_schar; 91 | case double_P: return &ffi_type_double; 92 | case float_P: return &ffi_type_float; 93 | case int_P: return &ffi_type_sint; 94 | case long_P: return &ffi_type_slong; 95 | case longlong_P: return &ffi_type_slonglong; 96 | case short_P: return &ffi_type_sshort; 97 | 98 | case void_P: return &ffi_type_void; 99 | 100 | case struct_P: { 101 | ffi_type *aggregate(reinterpret_cast(apr_palloc(pool, sizeof(ffi_type)))); 102 | aggregate->size = 0; 103 | aggregate->alignment = 0; 104 | aggregate->type = FFI_TYPE_STRUCT; 105 | 106 | aggregate->elements = reinterpret_cast(apr_palloc(pool, (type->data.signature.count + 1) * sizeof(ffi_type *))); 107 | sig_ffi_types(pool, &ObjectiveC, &type->data.signature, aggregate->elements); 108 | aggregate->elements[type->data.signature.count] = NULL; 109 | 110 | return aggregate; 111 | } break; 112 | 113 | default: 114 | _assert(false); 115 | break; 116 | } 117 | } 118 | 119 | ffi_type *Java(apr_pool_t *pool, struct Type *type) { 120 | switch (type->primitive) { 121 | case typename_P: return &ffi_type_pointer; 122 | case union_P: return &ffi_type_pointer; 123 | case string_P: return &ffi_type_pointer; 124 | case selector_P: return &ffi_type_pointer; 125 | case block_P: return &ffi_type_pointer; 126 | case object_P: return &ffi_type_pointer; 127 | case boolean_P: return &ffi_type_uchar; 128 | case uchar_P: return &ffi_type_uchar; 129 | case uint_P: return &ffi_type_uint; 130 | case ulong_P: return &ffi_type_ulong; 131 | case ulonglong_P: return &ffi_type_ulonglong; 132 | case ushort_P: return &ffi_type_ushort; 133 | case array_P: return &ffi_type_pointer; 134 | case pointer_P: return &ffi_type_pointer; 135 | 136 | /* XXX: bit type */ 137 | case bit_P: return &ffi_type_uint; 138 | 139 | case char_P: return &ffi_type_schar; 140 | case double_P: return &ffi_type_double; 141 | case float_P: return &ffi_type_double; 142 | case int_P: return &ffi_type_sint; 143 | case long_P: return &ffi_type_slong; 144 | case longlong_P: return &ffi_type_slonglong; 145 | case short_P: return &ffi_type_sshort; 146 | case void_P: return &ffi_type_void; 147 | case struct_P: return &ffi_type_pointer; 148 | 149 | default: 150 | _assert(false); 151 | break; 152 | } 153 | } 154 | 155 | void sig_ffi_cif( 156 | apr_pool_t *pool, 157 | ffi_type *(*sig_ffi_type)(apr_pool_t *, struct Type *), 158 | struct Signature *signature, 159 | ffi_cif *cif, 160 | size_t skip, 161 | ffi_type **types, 162 | size_t offset 163 | ) { 164 | if (types == NULL) 165 | types = reinterpret_cast(apr_palloc(pool, (signature->count - 1) * sizeof(ffi_type *))); 166 | ffi_type *type = (*sig_ffi_type)(pool, signature->elements[0].type); 167 | sig_ffi_types(pool, sig_ffi_type, signature, types, 1 + skip, offset); 168 | ffi_status status = ffi_prep_cif(cif, FFI_DEFAULT_ABI, signature->count - 1 - skip + offset, type, types); 169 | _assert(status == FFI_OK); 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /sig/ffi_type.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef SIG_FFI_TYPE_H 23 | #define SIG_FFI_TYPE_H 24 | 25 | #include 26 | 27 | #ifdef HAVE_FFI_FFI_H 28 | #include 29 | #else 30 | #include 31 | #endif 32 | 33 | #include "sig/types.hpp" 34 | 35 | namespace sig { 36 | 37 | ffi_type *ObjectiveC(apr_pool_t *pool, struct Type *type); 38 | ffi_type *Java(apr_pool_t *pool, struct Type *type); 39 | 40 | void sig_ffi_cif( 41 | apr_pool_t *pool, 42 | ffi_type *(*sig_ffi_type)(apr_pool_t *, struct Type *), 43 | struct Signature *signature, 44 | ffi_cif *cif, 45 | size_t skip = 0, 46 | ffi_type **types = NULL, 47 | size_t offset = 0 48 | ); 49 | 50 | void Copy(apr_pool_t *pool, ffi_type &lhs, ffi_type &rhs); 51 | 52 | } 53 | 54 | #endif/*SIG_FFI_TYPE_H*/ 55 | -------------------------------------------------------------------------------- /sig/parse.cpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #include 23 | #include "sig/parse.hpp" 24 | #include "Error.hpp" 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace sig { 31 | 32 | void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, char eos, Callback callback); 33 | struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named, Callback callback); 34 | 35 | 36 | /* XXX: I really screwed up this time */ 37 | void *prealloc_(apr_pool_t *pool, void *odata, size_t osize, size_t nsize) { 38 | void *ndata = apr_palloc(pool, nsize); 39 | memcpy(ndata, odata, osize); 40 | return ndata; 41 | } 42 | 43 | void Parse_(apr_pool_t *pool, struct Signature *signature, const char **name, char eos, Callback callback) { 44 | _assert(*name != NULL); 45 | 46 | // XXX: this is just a stupid check :( 47 | bool named(**name == '"'); 48 | 49 | signature->elements = NULL; 50 | signature->count = 0; 51 | 52 | for (;;) { 53 | if (**name == eos) { 54 | ++*name; 55 | return; 56 | } 57 | 58 | signature->elements = (struct Element *) prealloc_(pool, signature->elements, signature->count * sizeof(struct Element), (signature->count + 1) * sizeof(struct Element)); 59 | _assert(signature->elements != NULL); 60 | 61 | struct Element *element = &signature->elements[signature->count++]; 62 | 63 | if (**name != '"') 64 | element->name = NULL; 65 | else { 66 | const char *quote = strchr(++*name, '"'); 67 | element->name = apr_pstrmemdup(pool, *name, quote - *name); 68 | *name = quote + 1; 69 | } 70 | 71 | element->type = Parse_(pool, name, eos, named, callback); 72 | 73 | if (**name < '0' || **name > '9') 74 | element->offset = _not(size_t); 75 | else { 76 | element->offset = 0; 77 | 78 | do 79 | element->offset = element->offset * 10 + (*(*name)++ - '0'); 80 | while (**name >= '0' && **name <= '9'); 81 | } 82 | } 83 | } 84 | 85 | struct Type *Parse_(apr_pool_t *pool, const char **name, char eos, bool named, Callback callback) { 86 | char next = *(*name)++; 87 | if (next == '?') 88 | return NULL; 89 | 90 | struct Type *type = (struct Type *) apr_palloc(pool, sizeof(struct Type)); 91 | _assert(type != NULL); 92 | memset(type, 0, sizeof(struct Type)); 93 | 94 | parse: 95 | switch (next) { 96 | case '#': type->primitive = typename_P; break; 97 | 98 | case '(': 99 | if (type->data.signature.count < 2) 100 | type->primitive = struct_P; 101 | else 102 | type->primitive = union_P; 103 | next = ')'; 104 | goto aggregate; 105 | 106 | case '*': type->primitive = string_P; break; 107 | case ':': type->primitive = selector_P; break; 108 | 109 | case '@': { 110 | char next(**name); 111 | 112 | if (next == '?') { 113 | type->primitive = block_P; 114 | ++*name; 115 | } else { 116 | type->primitive = object_P; 117 | 118 | if (next == '"') { 119 | const char *quote = strchr(*name + 1, '"'); 120 | if (!named || quote[1] == eos || quote[1] == '"') { 121 | type->name = apr_pstrmemdup(pool, *name + 1, quote - *name - 1); 122 | *name = quote + 1; 123 | } 124 | } 125 | } 126 | 127 | } break; 128 | 129 | case 'B': type->primitive = boolean_P; break; 130 | case 'C': type->primitive = uchar_P; break; 131 | case 'I': type->primitive = uint_P; break; 132 | case 'L': type->primitive = ulong_P; break; 133 | case 'Q': type->primitive = ulonglong_P; break; 134 | case 'S': type->primitive = ushort_P; break; 135 | 136 | case '[': 137 | type->primitive = array_P; 138 | type->data.data.size = strtoul(*name, (char **) name, 10); 139 | type->data.data.type = Parse_(pool, name, eos, false, callback); 140 | if (**name != ']') { 141 | printf("']' != \"%s\"\n", *name); 142 | _assert(false); 143 | } 144 | ++*name; 145 | break; 146 | 147 | case '^': 148 | type->primitive = pointer_P; 149 | if (**name == '"') { 150 | type->data.data.type = NULL; 151 | } else { 152 | type->data.data.type = Parse_(pool, name, eos, named, callback); 153 | sig::Type *&target(type->data.data.type); 154 | if (target != NULL && target->primitive == void_P) 155 | target = NULL; 156 | } 157 | break; 158 | 159 | case 'b': 160 | type->primitive = bit_P; 161 | type->data.data.size = strtoul(*name, (char **) name, 10); 162 | break; 163 | 164 | case 'c': type->primitive = char_P; break; 165 | case 'd': type->primitive = double_P; break; 166 | case 'f': type->primitive = float_P; break; 167 | case 'i': type->primitive = int_P; break; 168 | case 'l': type->primitive = long_P; break; 169 | case 'q': type->primitive = longlong_P; break; 170 | case 's': type->primitive = short_P; break; 171 | case 'v': type->primitive = void_P; break; 172 | 173 | case '{': 174 | type->primitive = struct_P; 175 | next = '}'; 176 | goto aggregate; 177 | 178 | aggregate: { 179 | char end = next; 180 | const char *begin = *name; 181 | do next = *(*name)++; 182 | while ( 183 | next != '=' && 184 | next != '}' 185 | ); 186 | size_t length = *name - begin - 1; 187 | if (strncmp(begin, "?", length) != 0) 188 | type->name = (char *) apr_pstrmemdup(pool, begin, length); 189 | else 190 | type->name = NULL; 191 | 192 | // XXX: this types thing is a throwback to JocStrap 193 | 194 | if (next == '=') 195 | Parse_(pool, &type->data.signature, name, end, callback); 196 | } break; 197 | 198 | case 'N': type->flags |= JOC_TYPE_INOUT; goto next; 199 | case 'n': type->flags |= JOC_TYPE_IN; goto next; 200 | case 'O': type->flags |= JOC_TYPE_BYCOPY; goto next; 201 | case 'o': type->flags |= JOC_TYPE_OUT; goto next; 202 | case 'R': type->flags |= JOC_TYPE_BYREF; goto next; 203 | case 'r': type->flags |= JOC_TYPE_CONST; goto next; 204 | case 'V': type->flags |= JOC_TYPE_ONEWAY; goto next; 205 | 206 | next: 207 | next = *(*name)++; 208 | goto parse; 209 | break; 210 | 211 | default: 212 | printf("invalid type character: '%c' {%s}\n", next, *name - 10); 213 | _assert(false); 214 | } 215 | 216 | if (callback != NULL) 217 | (*callback)(pool, type); 218 | 219 | return type; 220 | } 221 | 222 | void Parse(apr_pool_t *pool, struct Signature *signature, const char *name, Callback callback) { 223 | const char *temp = name; 224 | Parse_(pool, signature, &temp, '\0', callback); 225 | _assert(temp[-1] == '\0'); 226 | } 227 | 228 | const char *Unparse(apr_pool_t *pool, struct Signature *signature) { 229 | const char *value = ""; 230 | size_t offset; 231 | 232 | for (offset = 0; offset != signature->count; ++offset) { 233 | const char *type = Unparse(pool, signature->elements[offset].type); 234 | value = apr_pstrcat(pool, value, type, NULL); 235 | } 236 | 237 | return value; 238 | } 239 | 240 | const char *Unparse(apr_pool_t *pool, struct Type *type) { 241 | if (type == NULL) 242 | return "?"; 243 | else switch (type->primitive) { 244 | case typename_P: return "#"; 245 | case union_P: return apr_psprintf(pool, "(%s)", Unparse(pool, &type->data.signature)); 246 | case string_P: return "*"; 247 | case selector_P: return ":"; 248 | case block_P: return "@?"; 249 | case object_P: return type->name == NULL ? "@" : apr_psprintf(pool, "@\"%s\"", type->name); 250 | case boolean_P: return "B"; 251 | case uchar_P: return "C"; 252 | case uint_P: return "I"; 253 | case ulong_P: return "L"; 254 | case ulonglong_P: return "Q"; 255 | case ushort_P: return "S"; 256 | 257 | case array_P: { 258 | const char *value = Unparse(pool, type->data.data.type); 259 | return apr_psprintf(pool, "[%"APR_SIZE_T_FMT"%s]", type->data.data.size, value); 260 | } break; 261 | 262 | case pointer_P: return apr_psprintf(pool, "^%s", type->data.data.type == NULL ? "v" : Unparse(pool, type->data.data.type)); 263 | case bit_P: return apr_psprintf(pool, "b%"APR_SIZE_T_FMT"", type->data.data.size); 264 | case char_P: return "c"; 265 | case double_P: return "d"; 266 | case float_P: return "f"; 267 | case int_P: return "i"; 268 | case long_P: return "l"; 269 | case longlong_P: return "q"; 270 | case short_P: return "s"; 271 | case void_P: return "v"; 272 | case struct_P: return apr_psprintf(pool, "{%s=%s}", type->name == NULL ? "?" : type->name, Unparse(pool, &type->data.signature)); 273 | } 274 | 275 | _assert(false); 276 | return NULL; 277 | } 278 | 279 | } 280 | -------------------------------------------------------------------------------- /sig/parse.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef SIG_PARSE_H 23 | #define SIG_PARSE_H 24 | 25 | #include "sig/types.hpp" 26 | 27 | #include 28 | 29 | namespace sig { 30 | 31 | typedef void (*Callback)(apr_pool_t *pool, Type *&type); 32 | void Parse(apr_pool_t *pool, struct Signature *signature, const char *name, Callback callback); 33 | 34 | const char *Unparse(apr_pool_t *pool, struct Signature *signature); 35 | const char *Unparse(apr_pool_t *pool, struct Type *type); 36 | 37 | void Copy(apr_pool_t *pool, Type &lhs, Type &rhs); 38 | void Copy(apr_pool_t *pool, Signature &lhs, Signature &rhs); 39 | void Copy(apr_pool_t *pool, Type &lhs, Type &rhs); 40 | 41 | } 42 | 43 | #endif/*SIG_PARSE_H*/ 44 | -------------------------------------------------------------------------------- /sig/types.hpp: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2010 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU Lesser General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 | * License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef SIG_TYPES_H 23 | #define SIG_TYPES_H 24 | 25 | #include "Standard.hpp" 26 | 27 | namespace sig { 28 | 29 | enum Primitive { 30 | typename_P = '#', 31 | union_P = '(', 32 | string_P = '*', 33 | selector_P = ':', 34 | block_P = '?', 35 | object_P = 'W', 36 | boolean_P = 'B', 37 | uchar_P = 'C', 38 | uint_P = 'I', 39 | ulong_P = 'L', 40 | ulonglong_P = 'Q', 41 | ushort_P = 'S', 42 | array_P = '[', 43 | pointer_P = '^', 44 | bit_P = 'b', 45 | char_P = 'c', 46 | double_P = 'd', 47 | float_P = 'f', 48 | int_P = 'i', 49 | long_P = 'l', 50 | longlong_P = 'q', 51 | short_P = 's', 52 | void_P = 'v', 53 | struct_P = '{' 54 | }; 55 | 56 | struct Element { 57 | char *name; 58 | struct Type *type; 59 | size_t offset; 60 | }; 61 | 62 | struct Signature { 63 | struct Element *elements; 64 | size_t count; 65 | }; 66 | 67 | #define JOC_TYPE_INOUT (1 << 0) 68 | #define JOC_TYPE_IN (1 << 1) 69 | #define JOC_TYPE_BYCOPY (1 << 2) 70 | #define JOC_TYPE_OUT (1 << 3) 71 | #define JOC_TYPE_BYREF (1 << 4) 72 | #define JOC_TYPE_CONST (1 << 5) 73 | #define JOC_TYPE_ONEWAY (1 << 6) 74 | 75 | struct Type { 76 | enum Primitive primitive; 77 | char *name; 78 | uint8_t flags; 79 | 80 | union { 81 | struct { 82 | struct Type *type; 83 | size_t size; 84 | } data; 85 | 86 | struct Signature signature; 87 | } data; 88 | }; 89 | 90 | struct Type *joc_parse_type(char **name, char eos, bool variable, bool signature); 91 | void joc_parse_signature(struct Signature *signature, char **name, char eos, bool variable); 92 | 93 | _finline bool IsAggregate(Primitive primitive) { 94 | return primitive == struct_P || primitive == union_P; 95 | } 96 | 97 | } 98 | 99 | #endif/*SIG_TYPES_H*/ 100 | -------------------------------------------------------------------------------- /todo.txt: -------------------------------------------------------------------------------- 1 | lol 2 | unicode identifier support (native and \u) 3 | support unions (right now 0-1 fields parsed as struct) 4 | look into what String is, and whether to bridge it 5 | think about bridging NSNumber with Number prototype 6 | some JS callbacks don't use exception pointers at all... 7 | a newline needs to not be allowed after a unary * 8 | finish implementing default xml namespace statement 9 | encode newlines in history for later replay (psql uses ^A) 10 | 11 | consider replacing regex literals with constructors 12 | https://bugzilla.mozilla.org/show_bug.cgi?id=98409 13 | numerification needs to use specific precision values 14 | https://bugzilla.mozilla.org/show_bug.cgi?id=5856 15 | consider a mode where unicode string content is saved 16 | https://bugzilla.mozilla.org/show_bug.cgi?id=274152 17 | 18 | NSDictionaries that have NSNumber keys don't getProperty 19 | errors in another process aren't displayed; to fix this, parse errors should get converted to exceptions and thrown 20 | CYPoolTry/Catch now carefully save the exception after it /no longer needs the exception/... uhh... wtf? 21 | throw CYJSError should probably be replaced with CYThrow() across the board 22 | figure out what to do about global context refs: I really really want to retain the bastards 23 | the concept of NULL pooling is entirely incorrect and sad... bad... evil... need to work on this... really 24 | NSArray's .toString() and .toLocaleString() fail hard, as Array.prototype.to*String are Array-specific 25 | applyOnMainThread, when done at console, loops the cyonifier 26 | special work needs to be done to correctly handle the "arguments" symbol: Declare("arguments", ...Special) 27 | at the Program level I seem to be eating away all of the var statements 28 | function pointers are ?; note that blocks are currently block_P = '?' 29 | I should probably attempt to use the auto_ flag somehow to not do contexts_ push when compiling 30 | Object_callAsFunction_toCYON should be implemented 31 | 32 | [NSString stringWithString:""] crashes, on linux, not on mac 33 | GS #defines should be _finline 34 | 35 | replace procmod g+s with gdb's macosx_get_task_for_pid_rights 36 | non-local return prologue is not being Replace()d: multipass compiler! 37 | interpretation of documentation comments should be compiler-only and off by default 38 | don't ever generate $ CYWith, in particular for CYLet... use CYFunctionExpression 39 | -------------------------------------------------------------------------------- /trampoline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | shopt -s extglob 4 | 5 | hpp=$1 6 | object=$2 7 | name=$3 8 | sed=$4 9 | otool=$5 10 | lipo=$6 11 | nm=$7 12 | shift 7 13 | 14 | #shift 1 15 | #set /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -I/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.3.sdk/usr/include "$@" 16 | 17 | "$@" 18 | 19 | detailed=$(lipo -detailed_info "${object}") 20 | 21 | { 22 | 23 | echo '#include "Trampoline.hpp"' 24 | 25 | for arch in $(echo "${detailed}" | "${sed}" -e '/^architecture / { s/^architecture //; p; }; d;'); do 26 | offset=$(echo "${detailed}" | "${sed}" -e ' 27 | /^architecture / { x; s/.*/0/; x; }; 28 | /^architecture '${arch}'$/ { x; s/.*/1/; x; }; 29 | x; /^1$/ { x; /^ *offset / { s/^ *offset //; p; }; x; }; x; 30 | d; 31 | ') 32 | 33 | file=($("${otool}" -arch "${arch}" -l "${object}" | "${sed}" -e ' 34 | x; /^1$/ { x; 35 | /^ *fileoff / { s/^.* //; p; }; 36 | /^ *filesize / { s/^.* //; p; }; 37 | x; }; x; 38 | 39 | /^ *cmd LC_SEGMENT/ { x; s/.*/1/; x; }; 40 | 41 | d; 42 | ')) 43 | 44 | fileoff=${file[0]} 45 | filesize=${file[1]} 46 | 47 | echo 48 | echo "static const char ${name}_${arch}_data_[] = {" 49 | 50 | od -v -t x1 -t c -j "$((offset + fileoff))" -N "${filesize}" "${object}" | "${sed}" -e ' 51 | /^[0-7]/ ! { 52 | s@^ @// @; 53 | s/\(....\)/ \1/g; 54 | s@^ // @//@; 55 | s/ *$/,/; 56 | }; 57 | 58 | /^[0-7]/ { 59 | s/^[^ ]*//; 60 | s/ */ /g; 61 | s/^ *//; 62 | s/ $//; 63 | s/ /,/g; 64 | s/\([^,][^,]\)/0x\1/g; 65 | s/$/,/; 66 | /^,$/ ! { s/^/ /g; p; }; d; 67 | }; 68 | ' 69 | 70 | echo "};" 71 | 72 | echo 73 | entry=$("${nm}" -arch "${arch}" "${object}" | "${sed}" -e '/ _Start$/ { s/ .*//; p; }; d;') 74 | entry=${entry##*(0)} 75 | echo "static size_t ${name}_${arch}_entry_ = 0x${entry:=0};" 76 | 77 | echo 78 | echo "/*" 79 | "${otool}" -vVt -arch "${arch}" "${object}" 80 | echo "*/" 81 | 82 | echo 83 | echo "static Trampoline ${name}_${arch}_ = {" 84 | echo " ${name}_${arch}_data_," 85 | echo " sizeof(${name}_${arch}_data_)," 86 | echo " ${name}_${arch}_entry_," 87 | echo "};" 88 | done 89 | 90 | } >"${hpp}" 91 | 92 | #rm -f "${object}" 93 | -------------------------------------------------------------------------------- /website/index.html: -------------------------------------------------------------------------------- 1 | Cycript 2 | 3 | 4 |

Cycript: Objective-JavaScript

5 | 6 |

What is Cycript?

7 | 8 |

A programming language designed to blend the barrier between Objective-C and JavaScript. This project has similar goals to JSCocoa, but a very different set of starting technologies and a different guiding philosophy. In particular, Cycript has started life with a full-blown JavaScript parser/serializer, allowing it to have interesting hybrid syntax without constraints (such as those imposed on JSCocoa by JSLint).

9 | 10 |

Is it done?

11 | 12 |

Well, it works ;P. It is still "in flux": core language features are changing every few hours. However, it has already changed the workflow of the "elite" iPhone developers that write most of the extensions you see in Cydia: having a language that changes doesn't matter when you are mostly using it at the immediate console. I'm hoping, however, that I manage tolock it into something that feels "correct" in the very near future.

13 | 14 |

How do you pronounce "Cycript"?

15 | 16 |

I pronounce it "sscript" (with a geminate, aka long, 's'). I doubt anyone else will pronounce it like this, but I have my hopes.

17 | 18 |

Where do I get it?

19 | 20 |

Right now you can find releases of it at: http://www.cycript.org/debs/. This package depends on MobileSubstrate and libffi (both of which are in Cydia).

21 | 22 |

So, how do I use it?!

23 | 24 |

Although you can write full applications in Cycript, the fastest way to get playing with it is via the immediate console: just type "cycript".

25 | 26 |

iPhone:~$ cycript 27 | cy# 28 | 29 |

Code typed at this prompt will be executed as it is able to be parsed: the immediate console is trying to eagerly parse lines of code as they come in (and thereby is not subject to automatic-semicolon insertion, for those JavaScript experts). Parse errors will be noted to the output in a hopefully useful fashion.

30 | 31 | cy# function a() { 32 | cy> a + q r 33 | | .........^ 34 | | syntax error, unexpected Identifier, expecting ; or "\n" 35 | cy# 36 | 37 |

It should be noted that it is possible that you will manage to break my JavaScript serializer. In these cases, parse errors may be thrown by the underlying JavaScript engine rather than Cycript. To debug these issues you can use the special console command ?debug.

38 | 39 | cy# ?debug 40 | debug == true 41 | cy# var a = ((0 + (1)) * (2 * 3)) + m['a']('\'') 42 | var a=(0+1)*(2*3)+m.a("'"); 43 | ... 44 | 45 |

In addition to standard JavaScript, you an also access anything in the Objective-C runtime. Attempts have been made, sparingly, to bridge syntax when possible between the two environments. In particular, you may notice interesting properties of arrays, dictonaries, strings, and numbers. Care has been taken to minimize the damage to the object model.

46 | 47 | cy# var a = [NSMutableArray arrayWithCapacity:4] 48 | cy# a instanceof Array 49 | true 50 | cy# [a class] 51 | "NSCFArray" 52 | cy# [a addObject:"hello"]; a 53 | ["hello"] 54 | cy# a[1] = 4; a.push(10); a 55 | ["hello",4,10] 56 | cy# a.splice(1, 1, 6, 7); a 57 | ["hello",6,7,10] 58 | cy# b = [1, 2]; [b replaceObjectAtIndex:0 withObject:5]; b 59 | [5,2] 60 | 61 |

Memory management is mostly automatic, but instead of using the usual -[alloc] message you will need to use JavaScript's "new" operator, which returns a special "uninitialized" handle that can be used to send a single message (probably a form of init) before it "expires" and reverts to nil.

62 | 63 | cy# var a = new NSMutableDictionary 64 | cy# a 65 | "*** -[NSCFDictionary count]: method sent to an uninitialized mutable dictionary object" 66 | cy# var b = [a init]; b 67 | {} 68 | cy# a 69 | nil 70 | cy# var q = [new NSString init]; q 71 | "" 72 | 73 |

One note in particular is made about selectors. Not only do they act as in Objective-C, including being typed using @selector notation, but they also have Function.prototype in their prototype-chain, allowing you to use them in interesting functional ways ala JavaScript. You can also generate one from a string using new Selector().

74 | 75 | cy# var sel = @selector(initWithFrame:) 76 | cy# sel 77 | @selector(initWithFrame:) 78 | cy# sel.call(new UIView, [UIHardware fullScreenApplicationContentRect]) 79 | "<UIView: 0x22dae0; frame = (0 20; 320 460); layer = <CALayer: 0x209990>>" 80 | cy# new Selector("initWithFrame:") 81 | @selector(initWithFrame:) 82 | 83 |

As one would expect from JavaScript, objects have a property called constructor that references their class. You can also add methods along the prototype chain to instances. Eventually, all objects go through Instance, where you can put functions that should be available for all Objective-C classes.

84 | 85 | cy# Instance.prototype.getMethod = function (sel) { return class_getInstanceMethod(this, sel); } 86 | {} 87 | cy# NSObject.getMethod(@selector(init)) 88 | 0x801354 89 | cy# NSObject.prototype.getMethod = function (sel) { return "ark"; } 90 | {} 91 | cy# NSObject.getMethod(@selector(init)) 92 | "ark" 93 | 94 |

Given that sending messages is actually a different namespace than function resolution, it is important to separate out the analog of a "prototype" in the world of Objective-C from that in JavaScript. Therefore, a field called "messages" (may change) is also added to Class objects. These messages can even be traded around and reassigned, with the results fully mapping back to the Objective-C runtime.

95 | 96 | cy# var view = [new UIView init] 97 | cy# view.constructor 98 | "UIView" 99 | cy# view.constructor.messages['description'] 100 | 0x309d84f5 101 | cy# [view description] 102 | "<UIView: 0x229bc0; frame = (0 0; 0 0); layer = <CALayer: 0x229d60>>" 103 | cy# view.constructor.messages['description'] = function () { return "not!"; } 104 | {} 105 | cy# [view description] 106 | "not!" 107 | 108 |

Structures are also supported (although unions are currently on the todo list and bitfields are still DOA): they are bridged back/forth as much as possible. You can specify them using either array syntax or in the form of dictionaries.

109 | 110 | cy# var rect = [UIHardware fullScreenApplicationContentRect] 111 | cy# rect 112 | {origin:{x:0,y:20},size:{width:320,height:460}} 113 | cy# rect.origin = [2, 3] 114 | [2,3] 115 | cy# rect.size = {width: 0, height: 1} 116 | {width:0,height:1} 117 | cy# rect 118 | {origin:{x:2,y:3},size:{width:0,height:1}} 119 | 120 |

Access, allocation, and casting of pointers is possible through the usage of the Pointer and Type classes. Pointers can be indirected using the * and -> operators, as in C.

121 | 122 | cy# var count = new new Type("I") 123 | cy# var methods = class_copyMethodList(UIApplication, count) 124 | cy# *count 125 | 305 126 | cy# *new Pointer(count, "d") 127 | 7.304555902977629e-304 128 | cy# free(count) 129 | cy# methods 130 | 0x843800 131 | cy# methods[304] 132 | 0x825248 133 | cy# method_getName(methods[304]) 134 | @selector(init) 135 | 136 |

Objective-C @properties (some of which are auto-detected, as Apple doesn't always compile them into the resulting binaries) can be accessed using . notation. Currently, auto-detected @properties are usable, but aren't enumerable. This namespace is strictly separated from that of instance variables, which you can access by indirecting the object using * or ->.

137 | 138 | cy# var view = [new UIView init] 139 | cy# ps = []; for (var p in view) ps.push(p); ps 140 | ["skipsSubviewEnumeration","gestureRecognizers","gesturesEnabled","capturesDescendantTouches","deliversTouchesForGesturesToSuperview","userInteractionEnabled","layer","tag"] 141 | cy# vs = []; for (var v in *view) vs.push(v); vs 142 | ["isa","_layer","_tapInfo","_gestureInfo","_gestureRecognizers","_charge","_tag","_viewFlags"] 143 | cy# view.layer 144 | "<CALayer: 0x228f60>" 145 | cy# view->_layer 146 | "<CALayer: 0x228f60>" 147 | cy# (*view)._layer 148 | "<CALayer: 0x228f60>" 149 | 150 |

Fully-fledged Objective-C classes can also be declared using @class, which blurs the line between Objective-C's @interface and @implementation. Right now, declaring instance variables are not supported, but will be in a future version: for now you must provide an empty variable block.

151 | 152 | cy# @class TestClass : NSObject { 153 | cy> } 154 | cy> - description { 155 | cy> return "test"; 156 | cy> } 157 | cy> @end 158 | cy# [new TestClass init] 159 | "test" 160 | 161 |

The @class syntax can also be used to extend existing classes in a manner similar to categories. Note that type signatures, however, are not yet supported, so you end up heavily restricted in what you can add via this mechanism. In this case, one can also use a parenthesized expression as the class name.

162 | 163 | cy# @class NSObject 164 | cy> - description { return "replaced"; } 165 | cy> @end 166 | cy# var o = [new NSObject init] 167 | cy# o 168 | "replaced" 169 | cy# @class ([o class]) - description { return "again"; } @end 170 | cy# o 171 | "again" 172 | 173 |

Cycript is also capable of accessing normal C functions and variables. Knowledge of the type signatures of various functions are provided in the bridge definition file, which is currently a plist stored at /usr/lib/libcycript.plist.

174 | 175 | cy# malloc 176 | 0x31d48389 177 | cy# var p = malloc(4) 178 | cy# p 179 | 0x22e0a0 180 | cy# free(p) 181 | cy# 182 | 183 |

Cycript attempts to do its best to serialize information to the console about objects. In particular, CoreFoundaton objects bridged to Objective-C are detected and printed using CFCopyDescription.

184 | 185 | cy# UIGetScreenImage() 186 | "<CGImage 0x22f540>" 187 | cy# ABAddressBookCreate() 188 | "<ABCAddressBook 0x229cf0 [0x38208484]>" 189 | 190 |

How do I write an application with it?

191 | 192 |

This isn't quite "ready for primetime", but you can download the example HelloCycript.app from http://www.cycript.org/examples/ and put it in /Applicatons.

193 | 194 |

What else can it do?

195 | 196 |

Probably the awesomest thing you can do with Cycript is to hook into an existing process using the -p argument to the console interpreter. As an example, let's hook our way into SpringBoard and start spelunking.

197 | 198 | iPhone:~$ ps ax | grep Spring 199 | 18110 ?? Us 0:03.03 /System/Library/CoreServices/SpringBoard.app/SpringBoard 200 | 18115 s006 S+ 0:00.02 grep --color=auto --exclude=.svn Spring 201 | iPhone:~$ cycript -p 18110 202 | cy# UIApp 203 | "<SpringBoard: 0x266f00>" 204 | cy# UIApp->_uiController.window 205 | "<SBAppWindow: 0x27ac10; baseClass = UIWindow; frame = (0 0; 320 480); layer = <CALayer: 0x27aba0>>" 206 | cy# UIApp->_uiController.window.subviews 207 | ["<UIView: 0x4a6efa0; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x4a62d70>>","<SBAppContextHostView: 0x49a68f0; frame = (0 0; 320 480); clipsToBounds = YES; hidden = YES; layer = <CALayer: 0x2b4d10>> enabled: yes, context array: (\n)","<SBAppContextHostView: 0x4b5ccf0; frame = (0 0; 320 480); clipsToBounds = YES; hidden = YES; layer = <CALayer: 0x4b7f180>> enabled: yes, context array: (\n)"] 208 | cy# UIApp->_uiController.window.subviews[0].subviews 209 | ["<UIImageView: 0x4b3cea0; frame = (0 0; 320 480); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x4a75550>>","<UIView: 0x4b4ba80; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x4b4bbf0>>"] 210 | cy# UIApp->_uiController.window.subviews[0].subviews[0].image.size 211 | {width:320,height:480} 212 | cy# UIApp->_uiController.window.subviews[0].subviews[1].subviews 213 | ["<SBIconContentView: 0x4b4bc20; frame = (0 40; 320 349); autoresize = H; layer = <CALayer: 0x4a613c0>>","<UIView: 0x4a25250; frame = (0 389; 320 91); layer = <CALayer: 0x4a38630>>"] 214 | cy# UIApp->_uiController.window.subviews[0].subviews[1].subviews[0].subviews 215 | ["<SBIconListPageControl: 0x27aab0; baseClass = UIPageControl; frame = (0 330; 320 19); autoresize = TM; layer = <CALayer: 0x4b3c370>>","<SBIconScrollView: 0x4a62360; baseClass = UIScrollView; frame = (0 0; 320 330); autoresize = H; layer = <CALayer: 0x4a624e0>>"] 216 | cy# var pages = UIApp->_uiController.window.subviews[0].subviews[1].subviews[0].subviews[0] 217 | cy# pages.currentPage 218 | 1 219 | cy# pages.numberOfPages 220 | 15 221 | 222 | 223 | --------------------------------------------------------------------------------