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);
}
/* }}} */
}
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);
}
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:
}
/* }}} */
-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_;
-JSObjectRef Array_;
-JSObjectRef Error_;
-JSObjectRef Function_;
-JSObjectRef String_;
-
-JSObjectRef Array_prototype_;
-JSObjectRef Function_prototype_;
-JSObjectRef Object_prototype_;
-
+JSStringRef Array_s;
+JSStringRef cy_s;
JSStringRef length_s;
JSStringRef message_s;
JSStringRef name_s;
JSClassRef Type_privateData::Class_;
+struct Context :
+ CYData
+{
+ JSGlobalContextRef context_;
+
+ Context(JSGlobalContextRef context) :
+ context_(context)
+ {
+ }
+};
+
struct Pointer :
CYOwned
{
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);
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);
}
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) {
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));
static JSValueRef Pointer_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
Pointer *internal(reinterpret_cast<Pointer *>(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);
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) {
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.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);
+ Array_s = JSStringCreateWithUTF8CString("Array");
+ cy_s = JSStringCreateWithUTF8CString("$cy");
length_s = JSStringCreateWithUTF8CString("length");
message_s = JSStringCreateWithUTF8CString("message");
name_s = JSStringCreateWithUTF8CString("name");
}
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 {
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 {
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) {
}
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;
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<Context *>(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));
- Array_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array")));
- JSValueProtect(context, Array_);
- Array_prototype_ = CYCastJSObject(context, CYGetProperty(context, Array_, prototype_s));
- JSValueProtect(context, Array_prototype_);
+ JSObjectRef cy(JSObjectMake(context, Context_, new Context(context)));
+ CYSetProperty(context, global, cy_s, cy, kJSPropertyAttributeDontEnum);
- Error_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Error")));
- JSValueProtect(context, Error_);
+/* Cache Globals {{{ */
+ JSObjectRef Array(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Array"))));
+ CYSetProperty(context, cy, CYJSString("Array"), Array);
- Function_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function")));
- JSValueProtect(context, Function_);
- Function_prototype_ = (JSObjectRef) CYGetProperty(context, Function_, prototype_s);
- JSValueProtect(context, Function_prototype_);
+ JSObjectRef Array_prototype(CYCastJSObject(context, CYGetProperty(context, Array, prototype_s)));
+ CYSetProperty(context, cy, CYJSString("Array_prototype"), Array_prototype);
- JSObjectRef Object(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Object"))));
- Object_prototype_ = CYCastJSObject(context, CYGetProperty(context, Object, prototype_s));
- JSValueProtect(context, Object_prototype_);
+ JSObjectRef Error(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Error"))));
+ CYSetProperty(context, cy, CYJSString("Error"), Error);
- String_ = CYCastJSObject(context, CYGetProperty(context, global, CYJSString("String")));
- JSValueProtect(context, String_);
+ JSObjectRef Function(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Function"))));
+ CYSetProperty(context, cy, CYJSString("Function"), Function);
- JSObjectSetPrototype(context, global, JSObjectMake(context, Runtime_, NULL));
+ JSObjectRef Function_prototype(CYCastJSObject(context, CYGetProperty(context, Function, prototype_s)));
+ CYSetProperty(context, cy, CYJSString("Function_prototype"), Function_prototype);
- CYSetProperty(context, Array_prototype_, toCYON_s, &Array_callAsFunction_toCYON, kJSPropertyAttributeDontEnum);
+ JSObjectRef Object(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Object"))));
+ CYSetProperty(context, cy, CYJSString("Object"), Object);
- JSObjectRef Functor(JSObjectMakeConstructor(context, Functor_, &Functor_new));
+ JSObjectRef Object_prototype(CYCastJSObject(context, CYGetProperty(context, Object, prototype_s)));
+ CYSetProperty(context, cy, CYJSString("Object_prototype"), Object_prototype);
- JSObjectSetPrototype(context, (JSObjectRef) CYGetProperty(context, Functor, prototype_s), Function_prototype_);
+ JSObjectRef String(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("String"))));
+ CYSetProperty(context, cy, CYJSString("String"), String);
+/* }}} */
- 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, 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, cycript, CYJSString("Functor"), Functor);
+
+ CYSetProperty(context, cycript, CYJSString("Pointer"), JSObjectMakeConstructor(context, Pointer_, &Pointer_new));
+ CYSetProperty(context, cycript, CYJSString("Type"), JSObjectMakeConstructor(context, Type_privateData::Class_, &Type_new));
+
+ JSObjectRef all(JSObjectMake(context, All_, NULL));
+ CYSetProperty(context, cycript, CYJSString("all"), all);
+
CYSetProperty(context, global, CYJSString("$cyq"), &$cyq);
- System_ = JSObjectMake(context, NULL, NULL);
- JSValueProtect(context, System_);
+ JSObjectRef System(JSObjectMake(context, NULL, NULL));
+ CYSetProperty(context, cy, CYJSString("System"), Function);
- 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);
+ CYSetProperty(context, System, CYJSString("print"), &System_print);
if (hooks_ != NULL && hooks_->SetupContext != NULL)
(*hooks_->SetupContext)(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_;
}