X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/21d5f610b933e87b7110d629daddeb8f333dcec9..e71ad0798f509366384257df77b925b33ab5ef66:/Execute.cpp?ds=sidebyside
diff --git a/Execute.cpp b/Execute.cpp
index 70cceae..b2fe08a 100644
--- a/Execute.cpp
+++ b/Execute.cpp
@@ -1,20 +1,20 @@
/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2012 Jay Freeman (saurik)
+ * Copyright (C) 2009-2013 Jay Freeman (saurik)
*/
-/* GNU Lesser General Public License, Version 3 {{{ */
+/* GNU General Public License, Version 3 {{{ */
/*
- * Cycript is free software: you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
+ * Cycript is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
*
- * Cycript is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
+ * Cycript is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public License
+ * You should have received a copy of the GNU General Public License
* along with Cycript. If not, see .
**/
/* }}} */
@@ -131,7 +131,7 @@ size_t CYGetIndex(apr_pool_t *pool, JSContextRef context, JSStringRef value) {
static JSClassRef All_;
static JSClassRef Context_;
-static JSClassRef Functor_;
+JSClassRef Functor_;
static JSClassRef Global_;
static JSClassRef Pointer_;
static JSClassRef Struct_;
@@ -257,6 +257,10 @@ JSObjectRef CYMakeStruct(JSContextRef context, void *data, sig::Type *type, ffi_
return JSObjectMake(context, Struct_, internal);
}
+static void *CYCastSymbol(const char *name) {
+ return dlsym(RTLD_DEFAULT, name);
+}
+
JSValueRef CYCastJSValue(JSContextRef context, bool value) {
return JSValueMakeBoolean(context, value);
}
@@ -331,7 +335,7 @@ static JSValueRef System_print(JSContextRef context, JSObjectRef object, JSObjec
}
return CYJSUndefined(context);
-} CYCatch }
+} CYCatch(NULL) }
static size_t Nonce_(0);
@@ -375,7 +379,7 @@ const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSValueRef value
default:
throw CYJSError(context, "JSValueGetType() == 0x%x", type);
}
-} CYCatch }
+} CYCatch(NULL) }
const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSValueRef value) {
JSValueRef exception(NULL);
@@ -475,7 +479,7 @@ static JSValueRef Array_callAsFunction_toCYON(JSContextRef context, JSObjectRef
std::string value(str.str());
return CYCastJSValue(context, CYJSString(CYUTF8String(value.c_str(), value.size())));
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef String_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
CYPool pool;
@@ -486,28 +490,31 @@ static JSValueRef String_callAsFunction_toCYON(JSContextRef context, JSObjectRef
std::string value(str.str());
return CYCastJSValue(context, CYJSString(CYUTF8String(value.c_str(), value.size())));
-} CYCatch }
+} CYCatch(NULL) }
JSObjectRef CYMakePointer(JSContextRef context, void *pointer, size_t length, sig::Type *type, ffi_type *ffi, JSObjectRef owner) {
Pointer *internal(new Pointer(pointer, context, owner, length, type));
return JSObjectMake(context, Pointer_, internal);
}
-static JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), const char *type, void **cache = NULL) {
- cy::Functor *internal;
+static JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), const char *type) {
+ return JSObjectMake(context, Functor_, new cy::Functor(type, function));
+}
- if (cache != NULL && *cache != NULL) {
+static JSObjectRef CYMakeFunctor(JSContextRef context, const char *symbol, const char *type, void **cache) {
+ cy::Functor *internal;
+ if (*cache != NULL)
internal = reinterpret_cast(*cache);
- ++internal->count_;
- } else {
- internal = new cy::Functor(type, function);
+ else {
+ void (*function)()(reinterpret_cast(CYCastSymbol(symbol)));
+ if (function == NULL)
+ return NULL;
- if (cache != NULL) {
- *cache = internal;
- ++internal->count_;
- }
+ internal = new cy::Functor(type, function);
+ *cache = internal;
}
+ ++internal->count_;
return JSObjectMake(context, Functor_, internal);
}
@@ -685,7 +692,7 @@ JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void
}
}
-static void FunctionClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
+void CYExecuteClosure(ffi_cif *cif, void *result, void **arguments, void *arg, JSValueRef (*adapter)(JSContextRef, size_t, JSValueRef[], JSObjectRef)) {
Closure_privateData *internal(reinterpret_cast(arg));
JSContextRef context(internal->context_);
@@ -696,10 +703,18 @@ static void FunctionClosure_(ffi_cif *cif, void *result, void **arguments, void
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(CYCallAsFunction(context, internal->function_, NULL, count, values));
+ JSValueRef value(adapter(context, count, values, internal->function_));
CYPoolFFI(NULL, context, internal->signature_.elements[0].type, internal->cif_.rtype, result, value);
}
+static JSValueRef FunctionAdapter_(JSContextRef context, size_t count, JSValueRef values[], JSObjectRef function) {
+ 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 char *type, void (*callback)(ffi_cif *, void *, void **, void *)) {
// XXX: in case of exceptions this will leak
// XXX: in point of fact, this may /need/ to leak :(
@@ -827,7 +842,7 @@ static JSValueRef Pointer_getProperty(JSContextRef context, JSObjectRef object,
JSObjectRef owner(internal->GetOwner() ?: object);
return CYFromFFI(context, typical->type_, ffi, base, false, owner);
-} CYCatch }
+} CYCatch(NULL) }
static bool Pointer_setProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) { CYTry {
CYPool pool;
@@ -835,13 +850,13 @@ static bool Pointer_setProperty(JSContextRef context, JSObjectRef object, JSStri
Type_privateData *typical(internal->type_);
if (typical->type_ == NULL)
- return NULL;
+ return false;
ssize_t offset;
if (JSStringIsEqualToUTF8CString(property, "$cyi"))
offset = 0;
else if (!CYGetOffset(pool, context, property, offset))
- return NULL;
+ return false;
ffi_type *ffi(typical->GetFFI());
@@ -850,7 +865,7 @@ static bool Pointer_setProperty(JSContextRef context, JSObjectRef object, JSStri
CYPoolFFI(NULL, context, typical->type_, ffi, base, value);
return true;
-} CYCatch }
+} CYCatch(false) }
static JSValueRef Struct_callAsFunction_$cya(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
Struct_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this)));
@@ -872,7 +887,7 @@ static JSValueRef Struct_getProperty(JSContextRef context, JSObjectRef object, J
JSObjectRef owner(internal->GetOwner() ?: object);
return CYFromFFI(context, typical->type_->data.signature.elements[index].type, typical->GetFFI()->elements[index], base, false, owner);
-} CYCatch }
+} CYCatch(NULL) }
static bool Struct_setProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) { CYTry {
CYPool pool;
@@ -887,7 +902,7 @@ static bool Struct_setProperty(JSContextRef context, JSObjectRef object, JSStrin
CYPoolFFI(NULL, context, typical->type_->data.signature.elements[index].type, typical->GetFFI()->elements[index], base, value);
return true;
-} CYCatch }
+} CYCatch(false) }
static void Struct_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) {
Struct_privateData *internal(reinterpret_cast(JSObjectGetPrivate(object)));
@@ -939,7 +954,7 @@ JSValueRef CYCallFunction(apr_pool_t *pool, JSContextRef context, size_t setups,
ffi_call(cif, function, value, values);
return CYFromFFI(context, signature->elements[0].type, cif->rtype, value, initialize);
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef Functor_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
CYPool pool;
@@ -957,10 +972,6 @@ JSObjectRef CYMakeType(JSContextRef context, sig::Type *type) {
return JSObjectMake(context, Type_privateData::Class_, internal);
}
-static void *CYCastSymbol(const char *name) {
- return dlsym(RTLD_DEFAULT, name);
-}
-
static JSValueRef All_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
JSObjectRef global(CYGetGlobalObject(context));
JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript"))));
@@ -990,9 +1001,7 @@ static JSValueRef All_getProperty(JSContextRef context, JSObjectRef object, JSSt
return JSEvaluateScript(CYGetJSContext(context), CYJSString(entry->value_), NULL, NULL, 0, NULL);
case '1':
- if (void (*symbol)() = reinterpret_cast(CYCastSymbol(name.data)))
- return CYMakeFunctor(context, symbol, entry->value_, &entry->cache_);
- else return NULL;
+ return CYMakeFunctor(context, name.data, entry->value_, &entry->cache_);
case '2':
if (void *symbol = CYCastSymbol(name.data)) {
@@ -1011,7 +1020,7 @@ static JSValueRef All_getProperty(JSContextRef context, JSObjectRef object, JSSt
}
return NULL;
-} CYCatch }
+} CYCatch(NULL) }
static void All_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) {
JSObjectRef global(CYGetGlobalObject(context));
@@ -1040,7 +1049,7 @@ static JSObjectRef Pointer_new(JSContextRef context, JSObjectRef object, size_t
sig::Parse(pool, &signature, type, &Structor_);
return CYMakePointer(context, value, _not(size_t), signature.elements[0].type, NULL, NULL);
-} CYCatch }
+} CYCatch(NULL) }
static JSObjectRef Type_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
if (count != 1)
@@ -1048,7 +1057,7 @@ static JSObjectRef Type_new(JSContextRef context, JSObjectRef object, size_t cou
CYPool pool;
const char *type(CYPoolCString(pool, context, arguments[0]));
return CYMakeType(context, type);
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef Type_callAsFunction_arrayOf(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
if (count != 1)
@@ -1069,7 +1078,7 @@ static JSValueRef Type_callAsFunction_arrayOf(JSContextRef context, JSObjectRef
type.data.data.size = index;
return CYMakeType(context, &type);
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef Type_callAsFunction_constant(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
if (count != 0)
@@ -1079,7 +1088,7 @@ static JSValueRef Type_callAsFunction_constant(JSContextRef context, JSObjectRef
sig::Type type(*internal->type_);
type.flags |= JOC_TYPE_CONST;
return CYMakeType(context, &type);
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef Type_callAsFunction_pointerTo(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
if (count != 0)
@@ -1095,7 +1104,7 @@ static JSValueRef Type_callAsFunction_pointerTo(JSContextRef context, JSObjectRe
type.data.data.size = 0;
return CYMakeType(context, &type);
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef Type_callAsFunction_withName(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
if (count != 1)
@@ -1108,7 +1117,7 @@ static JSValueRef Type_callAsFunction_withName(JSContextRef context, JSObjectRef
sig::Type type(*internal->type_);
type.name = name;
return CYMakeType(context, &type);
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef Type_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
if (count != 1)
@@ -1122,7 +1131,7 @@ static JSValueRef Type_callAsFunction(JSContextRef context, JSObjectRef object,
CYPool pool;
CYPoolFFI(pool, context, type, ffi, value, arguments[0]);
return CYFromFFI(context, type, ffi, value);
-} CYCatch }
+} CYCatch(NULL) }
static JSObjectRef Type_callAsConstructor(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
if (count != 0)
@@ -1141,7 +1150,7 @@ static JSObjectRef Type_callAsConstructor(JSContextRef context, JSObjectRef obje
void *value(malloc(internal->GetFFI()->size));
return CYMakePointer(context, value, length, type, NULL, NULL);
-} CYCatch }
+} CYCatch(NULL) }
static JSObjectRef Functor_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
if (count != 2)
@@ -1149,12 +1158,12 @@ static JSObjectRef Functor_new(JSContextRef context, JSObjectRef object, size_t
CYPool pool;
const char *type(CYPoolCString(pool, context, arguments[1]));
return CYMakeFunctor(context, arguments[0], type);
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef CYValue_callAsFunction_valueOf(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
CYValue *internal(reinterpret_cast(JSObjectGetPrivate(_this)));
return CYCastJSValue(context, reinterpret_cast(internal->value_));
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef CYValue_callAsFunction_toJSON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
return CYValue_callAsFunction_valueOf(context, object, _this, count, arguments, exception);
@@ -1165,12 +1174,12 @@ static JSValueRef CYValue_callAsFunction_toCYON(JSContextRef context, JSObjectRe
char string[32];
sprintf(string, "%p", internal->value_);
return CYCastJSValue(context, string);
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef Pointer_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
Pointer *internal(reinterpret_cast(JSObjectGetPrivate(_this)));
if (internal->length_ != _not(size_t)) {
- JSObjectRef Array(CYGetCachedObject(context, Array_s));
+ JSObjectRef Array(CYGetCachedObject(context, CYJSString("Array_prototype")));
JSObjectRef toCYON(CYCastJSObject(context, CYGetProperty(context, Array, toCYON_s)));
return CYCallAsFunction(context, toCYON, _this, count, arguments);
} else {
@@ -1178,7 +1187,7 @@ static JSValueRef Pointer_callAsFunction_toCYON(JSContextRef context, JSObjectRe
sprintf(string, "%p", internal->value_);
return CYCastJSValue(context, string);
}
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef Type_getProperty_alignment(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
Type_privateData *internal(reinterpret_cast(JSObjectGetPrivate(object)));
@@ -1200,21 +1209,17 @@ static JSValueRef Type_callAsFunction_toString(JSContextRef context, JSObjectRef
CYPool pool;
const char *type(sig::Unparse(pool, internal->type_));
return CYCastJSValue(context, CYJSString(type));
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef Type_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
Type_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this)));
CYPool pool;
const char *type(sig::Unparse(pool, internal->type_));
- size_t size(strlen(type));
- char *cyon(new(pool) char[12 + size + 1]);
- memcpy(cyon, "new Type(\"", 10);
- cyon[12 + size] = '\0';
- cyon[12 + size - 2] = '"';
- cyon[12 + size - 1] = ')';
- memcpy(cyon + 10, type, size);
+ std::ostringstream str;
+ CYStringify(str, type, strlen(type));
+ char *cyon(apr_pstrcat(pool, "new Type(", str.str().c_str(), ")", NULL));
return CYCastJSValue(context, CYJSString(cyon));
-} CYCatch }
+} CYCatch(NULL) }
static JSValueRef Type_callAsFunction_toJSON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
return Type_callAsFunction_toString(context, object, _this, count, arguments, exception);
@@ -1547,6 +1552,9 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) {
//CYSetProperty(context, System, CYJSString("global"), global);
CYSetProperty(context, System, CYJSString("print"), &System_print);
+ if (CYBridgeEntry *entry = CYBridgeHash("1dlerror", 8))
+ entry->cache_ = new cy::Functor(entry->value_, reinterpret_cast(&dlerror));
+
if (hooks_ != NULL && hooks_->SetupContext != NULL)
(*hooks_->SetupContext)(context);