]> git.saurik.com Git - cycript.git/blame - Internal.hpp
Wedge way to link against Python 2.7 to configure.
[cycript.git] / Internal.hpp
CommitLineData
b3378a02 1/* Cycript - Optimizing JavaScript Compiler/Runtime
c1d3e52e 2 * Copyright (C) 2009-2015 Jay Freeman (saurik)
d15b59f5
JF
3*/
4
f95d2598 5/* GNU Affero General Public License, Version 3 {{{ */
d15b59f5 6/*
f95d2598
JF
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
c15969fd 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f95d2598
JF
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/>.
b3378a02 19**/
d15b59f5
JF
20/* }}} */
21
3c1c3635
JF
22#ifndef CYCRIPT_INTERNAL_HPP
23#define CYCRIPT_INTERNAL_HPP
24
b799113b
JF
25#include <sig/parse.hpp>
26#include <sig/ffi_type.hpp>
3c1c3635
JF
27
28#include <JavaScriptCore/JSBase.h>
bc60fb46 29#include <JavaScriptCore/JSContextRef.h>
37954781 30#include <JavaScriptCore/JSObjectRef.h>
3c1c3635
JF
31#include <JavaScriptCore/JSValueRef.h>
32
d6848e73 33#include "JavaScript.hpp"
b799113b 34#include "Pooling.hpp"
d6848e73 35#include "Utility.hpp"
3c1c3635 36
bc60fb46 37JSGlobalContextRef CYGetJSContext(JSContextRef context);
0559abf8 38sig::Type *Structor_(CYPool &pool, sig::Aggregate *aggregate);
8a23fb2e 39
3f9ae37c
JF
40extern JSClassRef Functor_;
41
3c1c3635
JF
42struct Type_privateData :
43 CYData
44{
45 static JSClassRef Class_;
46
47 ffi_type *ffi_;
48 sig::Type *type_;
49
807a88be
JF
50 Type_privateData(const char *type) :
51 ffi_(NULL)
52 {
3c1c3635 53 sig::Signature signature;
b799113b 54 sig::Parse(*pool_, &signature, type, &Structor_);
3c1c3635
JF
55 type_ = signature.elements[0].type;
56 }
57
0559abf8
JF
58 Type_privateData(const sig::Type &type, ffi_type *ffi = NULL) :
59 type_(type.Copy(*pool_))
baea6375 60 {
baea6375 61
0559abf8
JF
62 if (ffi == NULL)
63 ffi_ = NULL;
64 else {
65 ffi_ = new(*pool_) ffi_type;
66 sig::Copy(*pool_, *ffi_, *ffi);
67 }
3c1c3635
JF
68 }
69
70 ffi_type *GetFFI() {
71 if (ffi_ == NULL) {
3c1c3635
JF
72 sig::Element element;
73 element.name = NULL;
74 element.type = type_;
75 element.offset = 0;
76
77 sig::Signature signature;
78 signature.elements = &element;
79 signature.count = 1;
80
81 ffi_cif cif;
574d4720 82 sig::sig_ffi_cif(*pool_, false, signature, &cif);
446d46d2
JF
83
84 ffi_ = new(*pool_) ffi_type;
3c1c3635
JF
85 *ffi_ = *cif.rtype;
86 }
87
88 return ffi_;
89 }
90};
91
92struct CYValue :
93 CYData
94{
95 void *value_;
96
97 CYValue() {
98 }
99
100 CYValue(const void *value) :
101 value_(const_cast<void *>(value))
102 {
103 }
104
105 CYValue(const CYValue &rhs) :
106 value_(rhs.value_)
107 {
108 }
3c1c3635
JF
109};
110
d6848e73
JF
111template <typename Internal_, typename Value_>
112struct CYValue_ :
3c1c3635
JF
113 CYValue
114{
d6848e73 115 static JSClassRef Class_;
d6848e73
JF
116
117 using CYValue::CYValue;
118
119 _finline Value_ GetValue() const {
120 return reinterpret_cast<Value_>(value_);
121 }
122
d6848e73
JF
123 _finline JSValueRef GetPrototype(JSContextRef context) const {
124 return NULL;
125 }
126
127 template <typename... Args_>
128 _finline static JSClassRef GetClass(Args_ &&... args) {
129 return Class_;
130 }
131
132 template <typename... Args_>
133 static JSObjectRef Make(JSContextRef context, Args_ &&... args) {
134 Internal_ *internal(new Internal_(cy::Forward<Args_>(args)...));
135 JSObjectRef object(JSObjectMake(context, Internal_::GetClass(cy::Forward<Args_>(args)...), internal));
136 if (JSValueRef prototype = internal->GetPrototype(context))
137 CYSetPrototype(context, object, prototype);
138 return object;
139 }
140};
141
142template <typename Internal_, typename Value_>
143JSClassRef CYValue_<Internal_, Value_>::Class_;
144
d6848e73 145struct CYProtect {
3c1c3635 146 private:
bc60fb46 147 JSGlobalContextRef context_;
d6848e73 148 JSObjectRef object_;
3c1c3635
JF
149
150 public:
d6848e73 151 CYProtect(JSContextRef context, JSObjectRef object) :
bc60fb46 152 context_(CYGetJSContext(context)),
d6848e73 153 object_(object)
3c1c3635 154 {
bc60fb46 155 //XXX:JSGlobalContextRetain(context_);
d6848e73
JF
156 if (object_ != NULL)
157 JSValueProtect(context_, object_);
3c1c3635
JF
158 }
159
d6848e73
JF
160 ~CYProtect() {
161 if (object_ != NULL)
162 JSValueUnprotect(context_, object_);
bc60fb46 163 //XXX:JSGlobalContextRelease(context_);
3c1c3635
JF
164 }
165
5f7a1d38
JF
166 operator bool() const {
167 return object_ != NULL;
168 }
169
170 operator JSContextRef() const {
171 return context_;
172 }
173
d6848e73
JF
174 operator JSObjectRef() const {
175 return object_;
3c1c3635
JF
176 }
177};
178
37954781
JF
179namespace cy {
180struct Functor :
181 CYValue
182{
077756a4
JF
183 private:
184 void set() {
574d4720 185 sig::sig_ffi_cif(*pool_, variadic_ ? signature_.count : 0, signature_, &cif_);
077756a4
JF
186 }
187
188 public:
574d4720 189 bool variadic_;
37954781
JF
190 sig::Signature signature_;
191 ffi_cif cif_;
192
574d4720
JF
193 Functor(void (*value)(), bool variadic, const sig::Signature &signature) :
194 CYValue(reinterpret_cast<void *>(value)),
195 variadic_(variadic)
37954781 196 {
077756a4
JF
197 sig::Copy(*pool_, signature_, signature);
198 set();
199 }
200
574d4720
JF
201 Functor(void (*value)(), const char *encoding) :
202 CYValue(reinterpret_cast<void *>(value)),
203 variadic_(false)
077756a4
JF
204 {
205 sig::Parse(*pool_, &signature_, encoding, &Structor_);
206 set();
37954781
JF
207 }
208
01d0f64d 209 void (*GetValue() const)() {
37954781
JF
210 return reinterpret_cast<void (*)()>(value_);
211 }
212
213 static JSStaticFunction const * const StaticFunctions;
8493347d 214 static JSStaticValue const * const StaticValues;
37954781
JF
215}; }
216
217struct Closure_privateData :
218 cy::Functor
219{
5f7a1d38 220 CYProtect function_;
24e7b1a6 221 JSValueRef (*adapter_)(JSContextRef, size_t, JSValueRef[], JSObjectRef);
37954781 222
24e7b1a6 223 Closure_privateData(JSContextRef context, JSObjectRef function, JSValueRef (*adapter)(JSContextRef, size_t, JSValueRef[], JSObjectRef), const sig::Signature &signature) :
574d4720 224 cy::Functor(NULL, false, signature),
5f7a1d38 225 function_(context, function),
24e7b1a6 226 adapter_(adapter)
37954781 227 {
37954781
JF
228 }
229};
230
24e7b1a6 231Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, const sig::Signature &signature, JSValueRef (*adapter)(JSContextRef, size_t, JSValueRef[], JSObjectRef));
9ec7dd18 232void CYExecuteClosure(ffi_cif *cif, void *result, void **arguments, void *arg, JSValueRef (*adapter)(JSContextRef, size_t, JSValueRef[], JSObjectRef));
37954781 233
3c1c3635 234#endif/*CYCRIPT_INTERNAL_HPP*/