/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2014 Jay Freeman (saurik)
+ * Copyright (C) 2009-2015 Jay Freeman (saurik)
*/
/* GNU Affero General Public License, Version 3 {{{ */
}
static void *CYCastSymbol(const char *name) {
+ for (CYHook *hook : GetHooks())
+ if (hook->CastSymbol != NULL)
+ if (void *value = (*hook->CastSymbol)(name))
+ return value;
return dlsym(RTLD_DEFAULT, name);
}
}
}
-void CYExecuteClosure(ffi_cif *cif, void *result, void **arguments, void *arg, JSValueRef (*adapter)(JSContextRef, size_t, JSValueRef[], JSObjectRef)) {
+void CYExecuteClosure(ffi_cif *cif, void *result, void **arguments, void *arg) {
Closure_privateData *internal(reinterpret_cast<Closure_privateData *>(arg));
JSContextRef context(internal->context_);
for (size_t index(0); index != count; ++index)
values[index] = CYFromFFI(context, internal->signature_.elements[1 + index].type, internal->cif_.arg_types[index], arguments[index]);
- JSValueRef value(adapter(context, count, values, internal->function_));
+ JSValueRef value(internal->adapter_(context, count, values, internal->function_));
CYPoolFFI(NULL, context, internal->signature_.elements[0].type, internal->cif_.rtype, result, value);
}
return CYCallAsFunction(context, function, NULL, count, values);
}
-static void FunctionClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
- CYExecuteClosure(cif, result, arguments, arg, &FunctionAdapter_);
-}
-
-Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, const sig::Signature &signature, void (*callback)(ffi_cif *, void *, void **, void *)) {
+Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, const sig::Signature &signature, JSValueRef (*adapter)(JSContextRef, size_t, JSValueRef[], JSObjectRef)) {
// XXX: in case of exceptions this will leak
// XXX: in point of fact, this may /need/ to leak :(
- Closure_privateData *internal(new Closure_privateData(context, function, signature));
+ Closure_privateData *internal(new Closure_privateData(context, function, adapter, signature));
#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
void *executable;
ffi_closure *writable(reinterpret_cast<ffi_closure *>(ffi_closure_alloc(sizeof(ffi_closure), &executable)));
- ffi_status status(ffi_prep_closure_loc(writable, &internal->cif_, callback, internal, executable));
+ ffi_status status(ffi_prep_closure_loc(writable, &internal->cif_, &CYExecuteClosure, internal, executable));
_assert(status == FFI_OK);
internal->value_ = executable;
-1, 0
)));
- ffi_status status(ffi_prep_closure(closure, &internal->cif_, callback, internal));
+ ffi_status status(ffi_prep_closure(closure, &internal->cif_, &CYExecuteClosure, internal));
_assert(status == FFI_OK);
_syscall(mprotect(closure, sizeof(*closure), PROT_READ | PROT_EXEC));
}
static JSObjectRef CYMakeFunctor(JSContextRef context, JSObjectRef function, const sig::Signature &signature) {
- Closure_privateData *internal(CYMakeFunctor_(context, function, signature, &FunctionClosure_));
+ Closure_privateData *internal(CYMakeFunctor_(context, function, signature, &FunctionAdapter_));
JSObjectRef object(JSObjectMake(context, Functor_, internal));
// XXX: see above notes about needing to leak
JSValueProtect(CYGetJSContext(context), object);
}
}
+void CYCallFunction(CYPool &pool, JSContextRef context, ffi_cif *cif, void (*function)(), void *value, void **values) {
+ ffi_call(cif, function, value, values);
+}
+
JSValueRef CYCallFunction(CYPool &pool, JSContextRef context, size_t setups, void *setup[], size_t count, const JSValueRef arguments[], bool initialize, sig::Signature *signature, ffi_cif *cif, void (*function)()) {
if (setups + count != signature->count - 1)
throw CYJSError(context, "incorrect number of arguments to ffi function");
uint8_t value[cif->rtype->size];
+ void (*call)(CYPool &, JSContextRef, ffi_cif *, void (*)(), void *, void **) = &CYCallFunction;
+ // XXX: this only supports one hook, but it is a bad idea anyway
for (CYHook *hook : GetHooks())
- if (hook->CallFunction != NULL) {
- // XXX: this only supports one hook, but it is a bad idea anyway
- (*hook->CallFunction)(context, cif, function, value, values);
- goto from;
- }
- ffi_call(cif, function, value, values);
+ if (hook->CallFunction != NULL)
+ call = hook->CallFunction;
- from:
+ call(pool, context, cif, function, value, values);
return CYFromFFI(context, signature->elements[0].type, cif->rtype, value, initialize);
}
extern "C" bool CydgetMemoryParse(const uint16_t **data, size_t *size);
void *CYMapFile(const char *path, size_t *psize) {
- int fd(_syscall_(open(path, O_RDONLY), 1, {ENOENT}));
+ int fd(_syscall_(open(path, O_RDONLY), 1, ENOENT));
if (fd == -1)
return NULL;
//CYSetProperty(context, System, CYJSString("global"), global);
CYSetProperty(context, System, CYJSString("print"), &System_print);
+#ifdef __APPLE__
if (&JSWeakObjectMapCreate != NULL) {
JSWeakObjectMapRef weak(JSWeakObjectMapCreate(context, NULL, NULL));
CYSetProperty(context, cy, weak_s, CYCastJSValue(context, reinterpret_cast<uintptr_t>(weak)));
}
+#endif
if (CYBridgeEntry *entry = CYBridgeHash("1dlerror", 8))
entry->cache_ = new cy::Functor(entry->value_, reinterpret_cast<void (*)()>(&dlerror));