X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/498c3570ae00dea1f54fb067e1d2c27435863e90..d2742118d583fb2438e68bc85ca6639e239e8a6b:/Library.cpp diff --git a/Library.cpp b/Library.cpp index bc16967..5517565 100644 --- a/Library.cpp +++ b/Library.cpp @@ -113,7 +113,7 @@ void CYSetProperty(JSContextRef context, JSObjectRef object, JSStringRef name, J CYThrow(context, exception); } -void CYSetProperty(JSContextRef context, JSObjectRef object, JSStringRef name, JSValueRef (*callback)(JSContextRef, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef *), JSPropertyAttributes attributes = kJSPropertyAttributeNone) { +void CYSetProperty(JSContextRef context, JSObjectRef object, JSStringRef name, JSValueRef (*callback)(JSContextRef, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef *), JSPropertyAttributes attributes) { CYSetProperty(context, object, name, JSObjectMakeFunctionWithCallback(context, name, callback), attributes); } /* }}} */ @@ -127,7 +127,7 @@ JSStringRef CYCopyJSString(JSStringRef value) { } JSStringRef CYCopyJSString(CYUTF8String value) { - // XXX: this is very wrong + // XXX: this is very wrong; it needs to convert to UTF16 and then create from there return CYCopyJSString(value.data); } @@ -260,7 +260,7 @@ void CYStringify(std::ostringstream &str, const char *data, size_t size) { break; default: - // this test is designed to be "awewsome", generating neither warnings nor incorrect results + // this test is designed to be "awesome", generating neither warnings nor incorrect results if (*value < 0x20 || *value >= 0x7f) str << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(uint8_t(*value)); else simple: @@ -300,12 +300,11 @@ bool CYIsKey(CYUTF8String value) { } /* }}} */ -static JSGlobalContextRef Context_; - +static JSClassRef All_; +static JSClassRef Context_; static JSClassRef Functor_; static JSClassRef Global_; static JSClassRef Pointer_; -static JSClassRef Runtime_; static JSClassRef Struct_; JSStringRef Array_s; @@ -399,6 +398,17 @@ void Structor_(apr_pool_t *pool, sig::Type *&type) { JSClassRef Type_privateData::Class_; +struct Context : + CYData +{ + JSGlobalContextRef context_; + + Context(JSGlobalContextRef context) : + context_(context) + { + } +}; + struct Pointer : CYOwned { @@ -511,7 +521,7 @@ JSObjectRef CYCastJSObject(JSContextRef context, JSValueRef value) { return object; } -JSValueRef CYCallAsFunction(JSContextRef context, JSObjectRef function, JSObjectRef _this, size_t count, JSValueRef arguments[]) { +JSValueRef CYCallAsFunction(JSContextRef context, JSObjectRef function, JSObjectRef _this, size_t count, const JSValueRef arguments[]) { JSValueRef exception(NULL); JSValueRef value(JSObjectCallAsFunction(context, function, _this, count, arguments, &exception)); CYThrow(context, exception); @@ -588,6 +598,7 @@ const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSObjectRef obje JSValueRef toCYON(CYGetProperty(context, object, toCYON_s)); if (CYIsCallable(context, toCYON)) { JSValueRef value(CYCallAsFunction(context, (JSObjectRef) toCYON, object, 0, NULL)); + _assert(value != NULL); return CYPoolCString(pool, context, value); } @@ -881,7 +892,10 @@ Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, static JSObjectRef CYMakeFunctor(JSContextRef context, JSObjectRef function, const char *type) { Closure_privateData *internal(CYMakeFunctor_(context, function, type, &FunctionClosure_)); - return JSObjectMake(context, Functor_, internal); + JSObjectRef object(JSObjectMake(context, Functor_, internal)); + // XXX: see above notes about needing to leak + JSValueProtect(CYGetJSContext(context), object); + return object; } JSObjectRef CYGetCachedObject(JSContextRef context, JSStringRef name) { @@ -1106,7 +1120,13 @@ static void *CYCastSymbol(const char *name) { return dlsym(RTLD_DEFAULT, name); } -static JSValueRef Runtime_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { +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")))); + if (JSValueRef value = CYGetProperty(context, cycript, property)) + if (!JSValueIsUndefined(context, value)) + return value; + CYPool pool; CYUTF8String name(CYPoolUTF8String(pool, context, property)); @@ -1278,10 +1298,11 @@ static JSValueRef CYValue_callAsFunction_toCYON(JSContextRef context, JSObjectRe 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)) - // XXX: maybe dynamically look up Array.toCYON? - return Array_callAsFunction_toCYON(context, object, _this, count, arguments, exception); - else { + if (internal->length_ != _not(size_t)) { + JSObjectRef Array(CYGetCachedObject(context, Array_s)); + JSObjectRef toCYON(CYCastJSObject(context, CYGetProperty(context, Array, toCYON_s))); + return CYCallAsFunction(context, toCYON, _this, count, arguments); + } else { char string[32]; sprintf(string, "%p", internal->value_); return CYCastJSValue(context, string); @@ -1429,6 +1450,16 @@ void CYInitialize() { JSClassDefinition definition; + definition = kJSClassDefinitionEmpty; + definition.className = "All"; + definition.getProperty = &All_getProperty; + All_ = JSClassCreate(&definition); + + definition = kJSClassDefinitionEmpty; + definition.className = "Context"; + definition.finalize = &CYFinalize; + Context_ = JSClassCreate(&definition); + definition = kJSClassDefinitionEmpty; definition.className = "Functor"; definition.staticFunctions = cy::Functor::StaticFunctions; @@ -1462,11 +1493,6 @@ void CYInitialize() { 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); @@ -1511,10 +1537,10 @@ JSValueRef CYJSError::CastJSValue(JSContextRef context) const { void CYThrow(const char *format, ...) { va_list args; - va_start (args, format); + va_start(args, format); throw CYPoolError(format, args); // XXX: does this matter? :( - va_end (args); + va_end(args); } const char *CYPoolError::PoolCString(apr_pool_t *pool) const { @@ -1523,9 +1549,9 @@ const char *CYPoolError::PoolCString(apr_pool_t *pool) const { CYPoolError::CYPoolError(const char *format, ...) { va_list args; - va_start (args, format); + va_start(args, format); message_ = apr_pvsprintf(pool_, format, args); - va_end (args); + va_end(args); } CYPoolError::CYPoolError(const char *format, va_list args) { @@ -1554,24 +1580,26 @@ CYJSError::CYJSError(JSContextRef context, const char *format, ...) { CYPool pool; va_list args; - va_start (args, format); + va_start(args, format); const char *message(apr_pvsprintf(pool, format, args)); - va_end (args); + va_end(args); value_ = CYCastJSError(context, message); } JSGlobalContextRef CYGetJSContext(JSContextRef context) { - // XXX: do something better - return Context_; + return reinterpret_cast(JSObjectGetPrivate(CYCastJSObject(context, CYGetProperty(context, CYGetGlobalObject(context), cy_s))))->context_; } -void CYSetupContext(JSGlobalContextRef context) { +extern "C" void CYSetupContext(JSGlobalContextRef context) { + CYInitialize(); + JSObjectRef global(CYGetGlobalObject(context)); - JSObjectRef cy(JSObjectMake(context, NULL, NULL)); - CYSetProperty(context, global, cy_s, cy); + JSObjectRef cy(JSObjectMake(context, Context_, new Context(context))); + CYSetProperty(context, global, cy_s, cy, kJSPropertyAttributeDontEnum); +/* Cache Globals {{{ */ JSObjectRef Array(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array")))); CYSetProperty(context, cy, CYJSString("Array"), Array); @@ -1595,21 +1623,23 @@ void CYSetupContext(JSGlobalContextRef context) { JSObjectRef String(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("String")))); CYSetProperty(context, cy, CYJSString("String"), String); - - JSObjectSetPrototype(context, global, JSObjectMake(context, Runtime_, NULL)); +/* }}} */ CYSetProperty(context, Array_prototype, toCYON_s, &Array_callAsFunction_toCYON, kJSPropertyAttributeDontEnum); + JSObjectRef cycript(JSObjectMake(context, NULL, NULL)); + CYSetProperty(context, global, CYJSString("Cycript"), cycript); + CYSetProperty(context, cycript, CYJSString("gc"), &Cycript_gc_callAsFunction); + JSObjectRef Functor(JSObjectMakeConstructor(context, Functor_, &Functor_new)); JSObjectSetPrototype(context, CYCastJSObject(context, CYGetProperty(context, Functor, prototype_s)), Function_prototype); - CYSetProperty(context, global, CYJSString("Functor"), Functor); + CYSetProperty(context, cycript, 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, cycript, CYJSString("Pointer"), JSObjectMakeConstructor(context, Pointer_, &Pointer_new)); + CYSetProperty(context, cycript, CYJSString("Type"), JSObjectMakeConstructor(context, Type_privateData::Class_, &Type_new)); - JSObjectRef cycript(JSObjectMake(context, NULL, NULL)); - CYSetProperty(context, global, CYJSString("Cycript"), cycript); - CYSetProperty(context, cycript, CYJSString("gc"), &Cycript_gc_callAsFunction); + JSObjectRef all(JSObjectMake(context, All_, NULL)); + CYSetProperty(context, cycript, CYJSString("all"), all); CYSetProperty(context, global, CYJSString("$cyq"), &$cyq); @@ -1628,10 +1658,13 @@ void CYSetupContext(JSGlobalContextRef context) { JSGlobalContextRef CYGetJSContext() { CYInitialize(); - if (Context_ == NULL) { - Context_ = JSGlobalContextCreate(Global_); - CYSetupContext(Context_); + static JSGlobalContextRef context_; + + if (context_ == NULL) { + context_ = JSGlobalContextCreate(Global_); + CYSetupContext(context_); + JSObjectSetPrototype(context_, CYGetGlobalObject(context_), JSObjectMake(context_, All_, NULL)); } - return Context_; + return context_; }