X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/53ba31e9e6b378d1fbe7bc8eba0e02b7fc358a52..d2742118d583fb2438e68bc85ca6639e239e8a6b:/Library.cpp diff --git a/Library.cpp b/Library.cpp index 029797d..5517565 100644 --- a/Library.cpp +++ b/Library.cpp @@ -112,6 +112,10 @@ void CYSetProperty(JSContextRef context, JSObjectRef object, JSStringRef name, J JSObjectSetProperty(context, object, name, value, attributes, &exception); CYThrow(context, exception); } + +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); +} /* }}} */ /* JavaScript Strings {{{ */ JSStringRef CYCopyJSString(const char *value) { @@ -123,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); } @@ -256,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: @@ -296,35 +300,26 @@ bool CYIsKey(CYUTF8String value) { } /* }}} */ -static JSGlobalContextRef Context_; -static JSObjectRef System_; - +static JSClassRef All_; +static JSClassRef Context_; static JSClassRef Functor_; +static JSClassRef Global_; static JSClassRef Pointer_; -static JSClassRef Runtime_; static JSClassRef Struct_; -static JSStringRef Result_; - -JSObjectRef Array_; -JSObjectRef Error_; -JSObjectRef Function_; -JSObjectRef String_; +JSStringRef Array_s; +JSStringRef cy_s; +JSStringRef length_s; +JSStringRef message_s; +JSStringRef name_s; +JSStringRef pop_s; +JSStringRef prototype_s; +JSStringRef push_s; +JSStringRef splice_s; +JSStringRef toCYON_s; +JSStringRef toJSON_s; -JSStringRef length_; -JSStringRef message_; -JSStringRef name_; -JSStringRef prototype_; -JSStringRef toCYON_; -JSStringRef toJSON_; - -JSObjectRef Object_prototype_; -JSObjectRef Function_prototype_; - -JSObjectRef Array_prototype_; -JSObjectRef Array_pop_; -JSObjectRef Array_push_; -JSObjectRef Array_splice_; +static JSStringRef Result_; sqlite3 *Bridge_; @@ -403,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 { @@ -515,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); @@ -589,13 +595,14 @@ const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSValueRef value } const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSObjectRef object) { - JSValueRef toCYON(CYGetProperty(context, object, toCYON_)); + 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); } - JSValueRef toJSON(CYGetProperty(context, object, toJSON_)); + JSValueRef toJSON(CYGetProperty(context, object, toJSON_s)); if (CYIsCallable(context, toJSON)) { JSValueRef arguments[1] = {CYCastJSValue(context, CYJSString(""))}; JSValueRef exception(NULL); @@ -645,7 +652,7 @@ static JSValueRef Array_callAsFunction_toCYON(JSContextRef context, JSObjectRef str << '['; - JSValueRef length(CYGetProperty(context, _this, length_)); + JSValueRef length(CYGetProperty(context, _this, length_s)); bool comma(false); for (size_t index(0), count(CYCastDouble(context, length)); index != count; ++index) { @@ -865,7 +872,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), @@ -885,12 +892,21 @@ 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) { + return CYCastJSObject(context, CYGetProperty(context, CYCastJSObject(context, CYGetProperty(context, CYGetGlobalObject(context), cy_s)), name)); } static JSObjectRef CYMakeFunctor(JSContextRef context, JSValueRef value, const char *type) { + JSObjectRef Function(CYGetCachedObject(context, CYJSString("Function"))); + JSValueRef exception(NULL); - bool function(JSValueIsInstanceOfConstructor(context, value, Function_, &exception)); + bool function(JSValueIsInstanceOfConstructor(context, value, Function, &exception)); CYThrow(context, exception); if (function) { @@ -949,7 +965,7 @@ static JSValueRef Pointer_getProperty(JSContextRef context, JSObjectRef object, CYPool pool; Pointer *internal(reinterpret_cast(JSObjectGetPrivate(object))); - if (JSStringIsEqual(property, length_)) + if (JSStringIsEqual(property, length_s)) return internal->length_ == _not(size_t) ? CYJSUndefined(context) : CYCastJSValue(context, internal->length_); Type_privateData *typical(internal->type_); @@ -1104,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)); @@ -1146,7 +1168,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))) @@ -1276,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); @@ -1355,11 +1378,13 @@ void CYSetArgs(int argc, const char *argv[]) { array = (*JSObjectMakeArray$)(context, argc, args, &exception); CYThrow(context, exception); } else { - JSValueRef value(CYCallAsFunction(context, Array_, NULL, argc, args)); + JSObjectRef Array(CYGetCachedObject(context, CYJSString("Array"))); + JSValueRef value(CYCallAsFunction(context, Array, NULL, argc, args)); array = CYCastJSObject(context, value); } - CYSetProperty(context, System_, CYJSString("args"), array); + JSObjectRef System(CYGetCachedObject(context, CYJSString("System"))); + CYSetProperty(context, System, CYJSString("args"), array); } JSObjectRef CYGetGlobalObject(JSContextRef context) { @@ -1422,6 +1447,72 @@ void CYInitialize() { _sqlcall(sqlite3_open("/usr/lib/libcycript.db", &Bridge_)); JSObjectMakeArray$ = reinterpret_cast(dlsym(RTLD_DEFAULT, "JSObjectMakeArray")); + + 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; + 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.getProperty = &Global_getProperty; + Global_ = JSClassCreate(&definition); + + Array_s = JSStringCreateWithUTF8CString("Array"); + cy_s = JSStringCreateWithUTF8CString("$cy"); + length_s = JSStringCreateWithUTF8CString("length"); + message_s = JSStringCreateWithUTF8CString("message"); + name_s = JSStringCreateWithUTF8CString("name"); + pop_s = JSStringCreateWithUTF8CString("pop"); + prototype_s = JSStringCreateWithUTF8CString("prototype"); + push_s = JSStringCreateWithUTF8CString("push"); + splice_s = JSStringCreateWithUTF8CString("splice"); + toCYON_s = JSStringCreateWithUTF8CString("toCYON"); + toJSON_s = JSStringCreateWithUTF8CString("toJSON"); + + Result_ = JSStringCreateWithUTF8CString("_"); + + if (hooks_ != NULL && hooks_->Initialize != NULL) + (*hooks_->Initialize)(); } apr_pool_t *CYGetGlobalPool() { @@ -1435,7 +1526,8 @@ void CYThrow(JSContextRef context, JSValueRef value) { } const char *CYJSError::PoolCString(apr_pool_t *pool) const { - return CYPoolCString(pool, context_, value_); + // XXX: this used to be CYPoolCString + return CYPoolCCYON(pool, context_, value_); } JSValueRef CYJSError::CastJSValue(JSContextRef context) const { @@ -1445,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 { @@ -1457,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) { @@ -1467,10 +1559,12 @@ CYPoolError::CYPoolError(const char *format, va_list args) { } JSValueRef CYCastJSError(JSContextRef context, const char *message) { + JSObjectRef Error(CYGetCachedObject(context, CYJSString("Error"))); + JSValueRef arguments[1] = {CYCastJSValue(context, message)}; JSValueRef exception(NULL); - JSValueRef value(JSObjectCallAsConstructor(context, Error_, 1, arguments, &exception)); + JSValueRef value(JSObjectCallAsConstructor(context, Error, 1, arguments, &exception)); CYThrow(context, exception); return value; @@ -1481,139 +1575,96 @@ JSValueRef CYPoolError::CastJSValue(JSContextRef context) const { } CYJSError::CYJSError(JSContextRef context, const char *format, ...) { - if (context == NULL) - context = CYGetJSContext(); + _assert(context != NULL); 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() { - 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); +JSGlobalContextRef CYGetJSContext(JSContextRef context) { + return reinterpret_cast(JSObjectGetPrivate(CYCastJSObject(context, CYGetProperty(context, CYGetGlobalObject(context), cy_s))))->context_; +} - definition = kJSClassDefinitionEmpty; - definition.className = "Runtime"; - definition.getProperty = &Runtime_getProperty; - Runtime_ = JSClassCreate(&definition); +extern "C" void CYSetupContext(JSGlobalContextRef context) { + CYInitialize(); - definition = kJSClassDefinitionEmpty; - //definition.getProperty = &Global_getProperty; - JSClassRef Global(JSClassCreate(&definition)); + JSObjectRef global(CYGetGlobalObject(context)); - JSGlobalContextRef context(JSGlobalContextCreate(Global)); - Context_ = context; - JSObjectRef global(CYGetGlobalObject(context)); + JSObjectRef cy(JSObjectMake(context, Context_, new Context(context))); + CYSetProperty(context, global, cy_s, cy, kJSPropertyAttributeDontEnum); - JSObjectSetPrototype(context, global, JSObjectMake(context, Runtime_, NULL)); +/* Cache Globals {{{ */ + JSObjectRef Array(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array")))); + CYSetProperty(context, cy, CYJSString("Array"), Array); - Array_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array"))); - JSValueProtect(context, Array_); + JSObjectRef Array_prototype(CYCastJSObject(context, CYGetProperty(context, Array, prototype_s))); + CYSetProperty(context, cy, CYJSString("Array_prototype"), Array_prototype); - Error_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Error"))); - JSValueProtect(context, Error_); + JSObjectRef Error(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Error")))); + CYSetProperty(context, cy, CYJSString("Error"), Error); - Function_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function"))); - JSValueProtect(context, Function_); + JSObjectRef Function(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function")))); + CYSetProperty(context, cy, CYJSString("Function"), Function); - String_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("String"))); - JSValueProtect(context, String_); + JSObjectRef Function_prototype(CYCastJSObject(context, CYGetProperty(context, Function, prototype_s))); + CYSetProperty(context, cy, CYJSString("Function_prototype"), Function_prototype); - length_ = JSStringCreateWithUTF8CString("length"); - message_ = JSStringCreateWithUTF8CString("message"); - name_ = JSStringCreateWithUTF8CString("name"); - prototype_ = JSStringCreateWithUTF8CString("prototype"); - toCYON_ = JSStringCreateWithUTF8CString("toCYON"); - toJSON_ = JSStringCreateWithUTF8CString("toJSON"); + JSObjectRef Object(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Object")))); + CYSetProperty(context, cy, CYJSString("Object"), Object); - JSObjectRef Object(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Object")))); - Object_prototype_ = CYCastJSObject(context, CYGetProperty(context, Object, prototype_)); - JSValueProtect(context, Object_prototype_); + JSObjectRef Object_prototype(CYCastJSObject(context, CYGetProperty(context, Object, prototype_s))); + CYSetProperty(context, cy, CYJSString("Object_prototype"), Object_prototype); - 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"))); + JSObjectRef String(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("String")))); + CYSetProperty(context, cy, CYJSString("String"), String); +/* }}} */ - CYSetProperty(context, Array_prototype_, toCYON_, JSObjectMakeFunctionWithCallback(context, toCYON_, &Array_callAsFunction_toCYON), kJSPropertyAttributeDontEnum); + CYSetProperty(context, Array_prototype, toCYON_s, &Array_callAsFunction_toCYON, kJSPropertyAttributeDontEnum); - JSValueProtect(context, Array_prototype_); - JSValueProtect(context, Array_pop_); - JSValueProtect(context, Array_push_); - JSValueProtect(context, Array_splice_); + 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)); + JSObjectRef Functor(JSObjectMakeConstructor(context, Functor_, &Functor_new)); + JSObjectSetPrototype(context, CYCastJSObject(context, CYGetProperty(context, Functor, prototype_s)), Function_prototype); + CYSetProperty(context, cycript, CYJSString("Functor"), Functor); - Function_prototype_ = (JSObjectRef) CYGetProperty(context, Function_, prototype_); - JSValueProtect(context, Function_prototype_); + CYSetProperty(context, cycript, CYJSString("Pointer"), JSObjectMakeConstructor(context, Pointer_, &Pointer_new)); + CYSetProperty(context, cycript, CYJSString("Type"), JSObjectMakeConstructor(context, Type_privateData::Class_, &Type_new)); - JSObjectSetPrototype(context, (JSObjectRef) CYGetProperty(context, Functor, prototype_), Function_prototype_); + JSObjectRef all(JSObjectMake(context, All_, NULL)); + CYSetProperty(context, cycript, CYJSString("all"), all); - 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("$cyq"), &$cyq); - 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, global, CYJSString("$cyq"), JSObjectMakeFunctionWithCallback(context, CYJSString("$cyq"), &$cyq)); + JSObjectRef System(JSObjectMake(context, NULL, NULL)); + CYSetProperty(context, cy, CYJSString("System"), Function); - 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"), &System_print); - CYSetProperty(context, global, CYJSString("system"), System_); - CYSetProperty(context, System_, CYJSString("args"), CYJSNull(context)); - //CYSetProperty(context, System_, CYJSString("global"), global); + if (hooks_ != NULL && hooks_->SetupContext != NULL) + (*hooks_->SetupContext)(context); +} - CYSetProperty(context, System_, CYJSString("print"), JSObjectMakeFunctionWithCallback(context, CYJSString("print"), &System_print)); +JSGlobalContextRef CYGetJSContext() { + CYInitialize(); - Result_ = JSStringCreateWithUTF8CString("_"); + static JSGlobalContextRef context_; - if (hooks_ != NULL && hooks_->SetupContext != NULL) - (*hooks_->SetupContext)(context); + if (context_ == NULL) { + context_ = JSGlobalContextCreate(Global_); + CYSetupContext(context_); + JSObjectSetPrototype(context_, CYGetGlobalObject(context_), JSObjectMake(context_, All_, NULL)); } - return Context_; + return context_; }