From 3c9f7e221fac3b21092776dad59052fd79ec1897 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Wed, 4 Nov 2009 12:00:52 +0000 Subject: [PATCH] Broke SetupContext into an Initialize part. --- Library.cpp | 210 ++++++++++++++++++++++-------------------- ObjectiveC/Library.mm | 49 ++++++---- cycript.hpp | 2 + 3 files changed, 139 insertions(+), 122 deletions(-) diff --git a/Library.cpp b/Library.cpp index d9a7626..f44c8ec 100644 --- a/Library.cpp +++ b/Library.cpp @@ -300,6 +300,7 @@ static JSGlobalContextRef Context_; static JSObjectRef System_; static JSClassRef Functor_; +static JSClassRef Global_; static JSClassRef Pointer_; static JSClassRef Runtime_; static JSClassRef Struct_; @@ -865,7 +866,7 @@ static void FunctionClosure_(ffi_cif *cif, void *result, void **arguments, void 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 :( - Closure_privateData *internal(new Closure_privateData(CYGetJSContext(), function, type)); + Closure_privateData *internal(new Closure_privateData(context, function, type)); ffi_closure *closure((ffi_closure *) _syscall(mmap( NULL, sizeof(ffi_closure), @@ -1146,7 +1147,7 @@ static JSValueRef Runtime_getProperty(JSContextRef context, JSObjectRef object, return NULL; case 0: - return JSEvaluateScript(CYGetJSContext(), CYJSString(value), NULL, NULL, 0, NULL); + return JSEvaluateScript(CYGetJSContext(context), CYJSString(value), NULL, NULL, 0, NULL); case 1: if (void (*symbol)() = reinterpret_cast(CYCastSymbol(name.data))) @@ -1422,6 +1423,62 @@ void CYInitialize() { _sqlcall(sqlite3_open("/usr/lib/libcycript.db", &Bridge_)); JSObjectMakeArray$ = reinterpret_cast(dlsym(RTLD_DEFAULT, "JSObjectMakeArray")); + + JSClassDefinition definition; + + definition = kJSClassDefinitionEmpty; + definition.className = "Functor"; + definition.staticFunctions = cy::Functor::StaticFunctions; + definition.callAsFunction = &Functor_callAsFunction; + definition.finalize = &CYFinalize; + Functor_ = JSClassCreate(&definition); + + definition = kJSClassDefinitionEmpty; + definition.className = "Pointer"; + definition.staticFunctions = Pointer_staticFunctions; + definition.getProperty = &Pointer_getProperty; + definition.setProperty = &Pointer_setProperty; + definition.finalize = &CYFinalize; + Pointer_ = JSClassCreate(&definition); + + definition = kJSClassDefinitionEmpty; + definition.className = "Struct"; + definition.staticFunctions = Struct_staticFunctions; + definition.getProperty = &Struct_getProperty; + definition.setProperty = &Struct_setProperty; + definition.getPropertyNames = &Struct_getPropertyNames; + definition.finalize = &CYFinalize; + Struct_ = JSClassCreate(&definition); + + definition = kJSClassDefinitionEmpty; + definition.className = "Type"; + definition.staticFunctions = Type_staticFunctions; + definition.getProperty = &Type_getProperty; + definition.callAsFunction = &Type_callAsFunction; + definition.callAsConstructor = &Type_callAsConstructor; + definition.finalize = &CYFinalize; + Type_privateData::Class_ = JSClassCreate(&definition); + + definition = kJSClassDefinitionEmpty; + definition.className = "Runtime"; + definition.getProperty = &Runtime_getProperty; + Runtime_ = JSClassCreate(&definition); + + definition = kJSClassDefinitionEmpty; + //definition.getProperty = &Global_getProperty; + Global_ = JSClassCreate(&definition); + + length_ = JSStringCreateWithUTF8CString("length"); + message_ = JSStringCreateWithUTF8CString("message"); + name_ = JSStringCreateWithUTF8CString("name"); + prototype_ = JSStringCreateWithUTF8CString("prototype"); + toCYON_ = JSStringCreateWithUTF8CString("toCYON"); + toJSON_ = JSStringCreateWithUTF8CString("toJSON"); + + Result_ = JSStringCreateWithUTF8CString("_"); + + if (hooks_ != NULL && hooks_->Initialize != NULL) + (*hooks_->Initialize)(); } apr_pool_t *CYGetGlobalPool() { @@ -1481,8 +1538,7 @@ JSValueRef CYPoolError::CastJSValue(JSContextRef context) const { } CYJSError::CYJSError(JSContextRef context, const char *format, ...) { - if (context == NULL) - context = CYGetJSContext(); + _assert(context != NULL); CYPool pool; @@ -1499,125 +1555,75 @@ JSGlobalContextRef CYGetJSContext(JSContextRef context) { return Context_; } -JSGlobalContextRef CYGetJSContext() { - CYInitialize(); - - if (Context_ == NULL) { - JSClassDefinition definition; - - definition = kJSClassDefinitionEmpty; - definition.className = "Functor"; - definition.staticFunctions = cy::Functor::StaticFunctions; - definition.callAsFunction = &Functor_callAsFunction; - definition.finalize = &CYFinalize; - Functor_ = JSClassCreate(&definition); - - definition = kJSClassDefinitionEmpty; - definition.className = "Pointer"; - definition.staticFunctions = Pointer_staticFunctions; - definition.getProperty = &Pointer_getProperty; - definition.setProperty = &Pointer_setProperty; - definition.finalize = &CYFinalize; - Pointer_ = JSClassCreate(&definition); - - definition = kJSClassDefinitionEmpty; - definition.className = "Struct"; - definition.staticFunctions = Struct_staticFunctions; - definition.getProperty = &Struct_getProperty; - definition.setProperty = &Struct_setProperty; - definition.getPropertyNames = &Struct_getPropertyNames; - definition.finalize = &CYFinalize; - Struct_ = JSClassCreate(&definition); - - definition = kJSClassDefinitionEmpty; - definition.className = "Type"; - definition.staticFunctions = Type_staticFunctions; - definition.getProperty = &Type_getProperty; - definition.callAsFunction = &Type_callAsFunction; - definition.callAsConstructor = &Type_callAsConstructor; - definition.finalize = &CYFinalize; - Type_privateData::Class_ = JSClassCreate(&definition); +void CYSetupContext(JSGlobalContextRef context) { + JSObjectRef global(CYGetGlobalObject(context)); - definition = kJSClassDefinitionEmpty; - definition.className = "Runtime"; - definition.getProperty = &Runtime_getProperty; - Runtime_ = JSClassCreate(&definition); + JSObjectSetPrototype(context, global, JSObjectMake(context, Runtime_, NULL)); - definition = kJSClassDefinitionEmpty; - //definition.getProperty = &Global_getProperty; - JSClassRef Global(JSClassCreate(&definition)); + Array_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array"))); + JSValueProtect(context, Array_); - JSGlobalContextRef context(JSGlobalContextCreate(Global)); - Context_ = context; - JSObjectRef global(CYGetGlobalObject(context)); + Error_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Error"))); + JSValueProtect(context, Error_); - JSObjectSetPrototype(context, global, JSObjectMake(context, Runtime_, NULL)); + Function_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function"))); + JSValueProtect(context, Function_); - Array_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array"))); - JSValueProtect(context, Array_); + String_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("String"))); + JSValueProtect(context, String_); - Error_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Error"))); - JSValueProtect(context, Error_); + JSObjectRef Object(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Object")))); + Object_prototype_ = CYCastJSObject(context, CYGetProperty(context, Object, prototype_)); + JSValueProtect(context, Object_prototype_); - Function_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function"))); - JSValueProtect(context, Function_); + Array_prototype_ = CYCastJSObject(context, CYGetProperty(context, Array_, prototype_)); + Array_pop_ = CYCastJSObject(context, CYGetProperty(context, Array_prototype_, CYJSString("pop"))); + Array_push_ = CYCastJSObject(context, CYGetProperty(context, Array_prototype_, CYJSString("push"))); + Array_splice_ = CYCastJSObject(context, CYGetProperty(context, Array_prototype_, CYJSString("splice"))); - String_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("String"))); - JSValueProtect(context, String_); + CYSetProperty(context, Array_prototype_, toCYON_, JSObjectMakeFunctionWithCallback(context, toCYON_, &Array_callAsFunction_toCYON), kJSPropertyAttributeDontEnum); - length_ = JSStringCreateWithUTF8CString("length"); - message_ = JSStringCreateWithUTF8CString("message"); - name_ = JSStringCreateWithUTF8CString("name"); - prototype_ = JSStringCreateWithUTF8CString("prototype"); - toCYON_ = JSStringCreateWithUTF8CString("toCYON"); - toJSON_ = JSStringCreateWithUTF8CString("toJSON"); + JSValueProtect(context, Array_prototype_); + JSValueProtect(context, Array_pop_); + JSValueProtect(context, Array_push_); + JSValueProtect(context, Array_splice_); - JSObjectRef Object(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Object")))); - Object_prototype_ = CYCastJSObject(context, CYGetProperty(context, Object, prototype_)); - JSValueProtect(context, Object_prototype_); + JSObjectRef Functor(JSObjectMakeConstructor(context, Functor_, &Functor_new)); - Array_prototype_ = CYCastJSObject(context, CYGetProperty(context, Array_, prototype_)); - Array_pop_ = CYCastJSObject(context, CYGetProperty(context, Array_prototype_, CYJSString("pop"))); - Array_push_ = CYCastJSObject(context, CYGetProperty(context, Array_prototype_, CYJSString("push"))); - Array_splice_ = CYCastJSObject(context, CYGetProperty(context, Array_prototype_, CYJSString("splice"))); + Function_prototype_ = (JSObjectRef) CYGetProperty(context, Function_, prototype_); + JSValueProtect(context, Function_prototype_); - CYSetProperty(context, Array_prototype_, toCYON_, JSObjectMakeFunctionWithCallback(context, toCYON_, &Array_callAsFunction_toCYON), kJSPropertyAttributeDontEnum); + JSObjectSetPrototype(context, (JSObjectRef) CYGetProperty(context, Functor, prototype_), Function_prototype_); - JSValueProtect(context, Array_prototype_); - JSValueProtect(context, Array_pop_); - JSValueProtect(context, Array_push_); - JSValueProtect(context, Array_splice_); + CYSetProperty(context, global, CYJSString("Functor"), Functor); + CYSetProperty(context, global, CYJSString("Pointer"), JSObjectMakeConstructor(context, Pointer_, &Pointer_new)); + CYSetProperty(context, global, CYJSString("Type"), JSObjectMakeConstructor(context, Type_privateData::Class_, &Type_new)); - JSObjectRef Functor(JSObjectMakeConstructor(context, Functor_, &Functor_new)); + JSObjectRef cycript(JSObjectMake(context, NULL, NULL)); + CYSetProperty(context, global, CYJSString("Cycript"), cycript); + CYSetProperty(context, cycript, CYJSString("gc"), JSObjectMakeFunctionWithCallback(context, CYJSString("gc"), &Cycript_gc_callAsFunction)); - Function_prototype_ = (JSObjectRef) CYGetProperty(context, Function_, prototype_); - JSValueProtect(context, Function_prototype_); + CYSetProperty(context, global, CYJSString("$cyq"), JSObjectMakeFunctionWithCallback(context, CYJSString("$cyq"), &$cyq)); - JSObjectSetPrototype(context, (JSObjectRef) CYGetProperty(context, Functor, prototype_), Function_prototype_); + System_ = JSObjectMake(context, NULL, NULL); + JSValueProtect(context, System_); - CYSetProperty(context, global, CYJSString("Functor"), Functor); - CYSetProperty(context, global, CYJSString("Pointer"), JSObjectMakeConstructor(context, Pointer_, &Pointer_new)); - CYSetProperty(context, global, CYJSString("Type"), JSObjectMakeConstructor(context, Type_privateData::Class_, &Type_new)); + CYSetProperty(context, global, CYJSString("system"), System_); + CYSetProperty(context, System_, CYJSString("args"), CYJSNull(context)); + //CYSetProperty(context, System_, CYJSString("global"), global); - JSObjectRef cycript(JSObjectMake(context, NULL, NULL)); - CYSetProperty(context, global, CYJSString("Cycript"), cycript); - CYSetProperty(context, cycript, CYJSString("gc"), JSObjectMakeFunctionWithCallback(context, CYJSString("gc"), &Cycript_gc_callAsFunction)); + CYSetProperty(context, System_, CYJSString("print"), JSObjectMakeFunctionWithCallback(context, CYJSString("print"), &System_print)); - CYSetProperty(context, global, CYJSString("$cyq"), JSObjectMakeFunctionWithCallback(context, CYJSString("$cyq"), &$cyq)); - - System_ = JSObjectMake(context, NULL, NULL); - JSValueProtect(context, System_); - - CYSetProperty(context, global, CYJSString("system"), System_); - CYSetProperty(context, System_, CYJSString("args"), CYJSNull(context)); - //CYSetProperty(context, System_, CYJSString("global"), global); - - CYSetProperty(context, System_, CYJSString("print"), JSObjectMakeFunctionWithCallback(context, CYJSString("print"), &System_print)); + if (hooks_ != NULL && hooks_->SetupContext != NULL) + (*hooks_->SetupContext)(context); +} - Result_ = JSStringCreateWithUTF8CString("_"); +JSGlobalContextRef CYGetJSContext() { + CYInitialize(); - if (hooks_ != NULL && hooks_->SetupContext != NULL) - (*hooks_->SetupContext)(context); + if (Context_ == NULL) { + Context_ = JSGlobalContextCreate(Global_); + CYSetupContext(Context_); } return Context_; diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index 3cfb90e..8182375 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -2236,8 +2236,7 @@ static JSStaticFunction Selector_staticFunctions[5] = { {NULL, NULL, 0} }; -void CYObjectiveC_SetupContext(JSContextRef context) { - JSObjectRef global(CYGetGlobalObject(context)); +void CYObjectiveC_Initialize() { /*XXX*/ JSContextRef context(NULL); CYPoolTry { apr_pool_t *pool(CYGetGlobalPool()); Object_type = new(pool) Type_privateData("@"); @@ -2321,18 +2320,6 @@ void CYObjectiveC_SetupContext(JSContextRef context) { definition.getPropertyNames = &ObjectiveC_Classes_getPropertyNames; ObjectiveC_Classes_ = JSClassCreate(&definition); - definition = kJSClassDefinitionEmpty; - definition.className = "ObjectiveC::Protocols"; - definition.getProperty = &ObjectiveC_Protocols_getProperty; - definition.getPropertyNames = &ObjectiveC_Protocols_getPropertyNames; - ObjectiveC_Protocols_ = JSClassCreate(&definition); - - JSObjectRef ObjectiveC(JSObjectMake(context, NULL, NULL)); - CYSetProperty(context, global, CYJSString("ObjectiveC"), ObjectiveC); - - CYSetProperty(context, ObjectiveC, CYJSString("classes"), JSObjectMake(context, ObjectiveC_Classes_, NULL)); - CYSetProperty(context, ObjectiveC, CYJSString("protocols"), JSObjectMake(context, ObjectiveC_Protocols_, NULL)); - #if OBJC_API_VERSION >= 2 definition = kJSClassDefinitionEmpty; definition.className = "ObjectiveC::Images"; @@ -2345,7 +2332,33 @@ void CYObjectiveC_SetupContext(JSContextRef context) { definition.getProperty = &ObjectiveC_Image_Classes_getProperty; definition.getPropertyNames = &ObjectiveC_Image_Classes_getPropertyNames; ObjectiveC_Image_Classes_ = JSClassCreate(&definition); +#endif + definition = kJSClassDefinitionEmpty; + definition.className = "ObjectiveC::Protocols"; + definition.getProperty = &ObjectiveC_Protocols_getProperty; + definition.getPropertyNames = &ObjectiveC_Protocols_getPropertyNames; + ObjectiveC_Protocols_ = JSClassCreate(&definition); + +#if defined(__APPLE__) && defined(__arm__) + MSHookFunction(&objc_registerClassPair, MSHake(objc_registerClassPair)); +#endif + +#ifdef __APPLE__ + class_addMethod(NSCFType_, @selector(cy$toJSON:), reinterpret_cast(&NSCFType$cy$toJSON), "@12@0:4@8"); +#endif +} CYPoolCatch() } + +void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry { + JSObjectRef global(CYGetGlobalObject(context)); + + JSObjectRef ObjectiveC(JSObjectMake(context, NULL, NULL)); + CYSetProperty(context, global, CYJSString("ObjectiveC"), ObjectiveC); + + CYSetProperty(context, ObjectiveC, CYJSString("classes"), JSObjectMake(context, ObjectiveC_Classes_, NULL)); + CYSetProperty(context, ObjectiveC, CYJSString("protocols"), JSObjectMake(context, ObjectiveC_Protocols_, NULL)); + +#if OBJC_API_VERSION >= 2 CYSetProperty(context, ObjectiveC, CYJSString("images"), JSObjectMake(context, ObjectiveC_Images_, NULL)); #endif @@ -2363,24 +2376,20 @@ void CYObjectiveC_SetupContext(JSContextRef context) { #if defined(__APPLE__) && defined(__arm__) CYSetProperty(context, global, CYJSString("objc_registerClassPair"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_registerClassPair"), &objc_registerClassPair_)); - MSHookFunction(&objc_registerClassPair, MSHake(objc_registerClassPair)); #endif CYSetProperty(context, global, CYJSString("objc_msgSend"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_msgSend"), &$objc_msgSend)); JSObjectSetPrototype(context, (JSObjectRef) CYGetProperty(context, Message, prototype_), Function_prototype_); JSObjectSetPrototype(context, (JSObjectRef) CYGetProperty(context, Selector, prototype_), Function_prototype_); - -#ifdef __APPLE__ - class_addMethod(NSCFType_, @selector(cy$toJSON:), reinterpret_cast(&NSCFType$cy$toJSON), "@12@0:4@8"); -#endif -} +} CYPoolCatch() } static CYHooks CYObjectiveCHooks = { &CYObjectiveC_ExecuteStart, &CYObjectiveC_ExecuteEnd, &CYObjectiveC_RuntimeProperty, &CYObjectiveC_CallFunction, + &CYObjectiveC_Initialize, &CYObjectiveC_SetupContext, &CYObjectiveC_PoolFFI, &CYObjectiveC_FromFFI, diff --git a/cycript.hpp b/cycript.hpp index 05fc892..9b3c3cd 100644 --- a/cycript.hpp +++ b/cycript.hpp @@ -132,6 +132,8 @@ struct CYHooks { JSValueRef (*RuntimeProperty)(JSContextRef, CYUTF8String); void (*CallFunction)(JSContextRef, ffi_cif *, void (*)(), uint8_t *, void **); + + void (*Initialize)(); void (*SetupContext)(JSContextRef); bool (*PoolFFI)(apr_pool_t *, JSContextRef, sig::Type *, ffi_type *, void *, JSValueRef); -- 2.47.2