]> git.saurik.com Git - cycript.git/blob - Internal.hpp
Remove duplicated manually-pooled Type constructor.
[cycript.git] / Internal.hpp
1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2014 Jay Freeman (saurik)
3 */
4
5 /* GNU Affero General Public License, Version 3 {{{ */
6 /*
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20 /* }}} */
21
22 #ifndef CYCRIPT_INTERNAL_HPP
23 #define CYCRIPT_INTERNAL_HPP
24
25 #include <sig/parse.hpp>
26 #include <sig/ffi_type.hpp>
27
28 #include <JavaScriptCore/JSBase.h>
29 #include <JavaScriptCore/JSContextRef.h>
30 #include <JavaScriptCore/JSObjectRef.h>
31 #include <JavaScriptCore/JSValueRef.h>
32
33 #include "Pooling.hpp"
34
35 JSGlobalContextRef CYGetJSContext(JSContextRef context);
36 void Structor_(CYPool &pool, sig::Type *&type);
37
38 JSObjectRef CYMakeType(JSContextRef context, const char *type);
39 JSObjectRef CYMakeType(JSContextRef context, sig::Type *type);
40
41 extern JSClassRef Functor_;
42
43 struct Type_privateData :
44 CYData
45 {
46 static JSClassRef Class_;
47
48 ffi_type *ffi_;
49 sig::Type *type_;
50
51 void Set(sig::Type *type) {
52 type_ = new(*pool_) sig::Type;
53 sig::Copy(*pool_, *type_, *type);
54 }
55
56 Type_privateData(const char *type) :
57 ffi_(NULL)
58 {
59 sig::Signature signature;
60 sig::Parse(*pool_, &signature, type, &Structor_);
61 type_ = signature.elements[0].type;
62 }
63
64 Type_privateData(sig::Type *type) :
65 ffi_(NULL)
66 {
67 // XXX: just in case I messed up migrating
68 _assert(type != NULL);
69 Set(type);
70 }
71
72 Type_privateData(sig::Type *type, ffi_type *ffi) {
73 ffi_ = new(*pool_) ffi_type;
74 sig::Copy(*pool_, *ffi_, *ffi);
75 Set(type);
76 }
77
78 ffi_type *GetFFI() {
79 if (ffi_ == NULL) {
80 sig::Element element;
81 element.name = NULL;
82 element.type = type_;
83 element.offset = 0;
84
85 sig::Signature signature;
86 signature.elements = &element;
87 signature.count = 1;
88
89 ffi_cif cif;
90 sig::sig_ffi_cif(*pool_, &sig::ObjectiveC, &signature, &cif);
91
92 ffi_ = new(*pool_) ffi_type;
93 *ffi_ = *cif.rtype;
94 }
95
96 return ffi_;
97 }
98 };
99
100 struct CYValue :
101 CYData
102 {
103 void *value_;
104
105 CYValue() {
106 }
107
108 CYValue(const void *value) :
109 value_(const_cast<void *>(value))
110 {
111 }
112
113 CYValue(const CYValue &rhs) :
114 value_(rhs.value_)
115 {
116 }
117
118 virtual Type_privateData *GetType() const {
119 return NULL;
120 }
121 };
122
123 struct CYOwned :
124 CYValue
125 {
126 private:
127 JSGlobalContextRef context_;
128 JSObjectRef owner_;
129
130 public:
131 CYOwned(void *value, JSContextRef context, JSObjectRef owner) :
132 CYValue(value),
133 context_(CYGetJSContext(context)),
134 owner_(owner)
135 {
136 //XXX:JSGlobalContextRetain(context_);
137 if (owner_ != NULL)
138 JSValueProtect(context_, owner_);
139 }
140
141 virtual ~CYOwned() {
142 if (owner_ != NULL)
143 JSValueUnprotect(context_, owner_);
144 //XXX:JSGlobalContextRelease(context_);
145 }
146
147 JSObjectRef GetOwner() const {
148 return owner_;
149 }
150 };
151
152 namespace cy {
153 struct Functor :
154 CYValue
155 {
156 private:
157 void set() {
158 sig::sig_ffi_cif(*pool_, &sig::ObjectiveC, &signature_, &cif_);
159 }
160
161 public:
162 sig::Signature signature_;
163 ffi_cif cif_;
164
165 Functor(const sig::Signature &signature, void (*value)()) :
166 CYValue(reinterpret_cast<void *>(value))
167 {
168 sig::Copy(*pool_, signature_, signature);
169 set();
170 }
171
172 Functor(const char *encoding, void (*value)()) :
173 CYValue(reinterpret_cast<void *>(value))
174 {
175 sig::Parse(*pool_, &signature_, encoding, &Structor_);
176 set();
177 }
178
179 void (*GetValue() const)() {
180 return reinterpret_cast<void (*)()>(value_);
181 }
182
183 static JSStaticFunction const * const StaticFunctions;
184 static JSStaticValue const * const StaticValues;
185 }; }
186
187 struct Closure_privateData :
188 cy::Functor
189 {
190 JSGlobalContextRef context_;
191 JSObjectRef function_;
192
193 Closure_privateData(JSContextRef context, JSObjectRef function, const sig::Signature &signature) :
194 cy::Functor(signature, NULL),
195 context_(CYGetJSContext(context)),
196 function_(function)
197 {
198 //XXX:JSGlobalContextRetain(context_);
199 JSValueProtect(context_, function_);
200 }
201
202 virtual ~Closure_privateData() {
203 JSValueUnprotect(context_, function_);
204 //XXX:JSGlobalContextRelease(context_);
205 }
206 };
207
208 Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, const sig::Signature &signature, void (*callback)(ffi_cif *, void *, void **, void *));
209 void CYExecuteClosure(ffi_cif *cif, void *result, void **arguments, void *arg, JSValueRef (*adapter)(JSContextRef, size_t, JSValueRef[], JSObjectRef));
210
211 #endif/*CYCRIPT_INTERNAL_HPP*/