- size_t count(type->data.signature.count);
- sig::Element *elements(type->data.signature.elements);
-
- char number[32];
-
- for (size_t index(0); index != count; ++index) {
- const char *name;
- name = elements[index].name;
-
- if (name == NULL) {
- sprintf(number, "%zu", index);
- name = number;
- }
-
- JSPropertyNameAccumulatorAddName(names, CYJSString(name));
- }
-}
-
-JSValueRef CYCallFunction(apr_pool_t *pool, JSContextRef context, size_t setups, void *setup[], size_t count, const JSValueRef arguments[], bool initialize, JSValueRef *exception, sig::Signature *signature, ffi_cif *cif, void (*function)()) { CYTry {
- if (setups + count != signature->count - 1)
- throw CYJSError(context, "incorrect number of arguments to ffi function");
-
- size_t size(setups + count);
- void *values[size];
- memcpy(values, setup, sizeof(void *) * setups);
-
- for (size_t index(setups); index != size; ++index) {
- sig::Element *element(&signature->elements[index + 1]);
- ffi_type *ffi(cif->arg_types[index]);
- // XXX: alignment?
- values[index] = new(pool) uint8_t[ffi->size];
- CYPoolFFI(pool, context, element->type, ffi, values[index], arguments[index - setups]);
- }
-
- uint8_t value[cif->rtype->size];
-
- if (hooks_ != NULL && hooks_->CallFunction != NULL)
- (*hooks_->CallFunction)(context, cif, function, value, values);
- else
- ffi_call(cif, function, value, values);
-
- return CYFromFFI(context, signature->elements[0].type, cif->rtype, value, initialize);
-} CYCatch }
-
-static JSValueRef Functor_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
- CYPool pool;
- cy::Functor *internal(reinterpret_cast<cy::Functor *>(JSObjectGetPrivate(object)));
- return CYCallFunction(pool, context, 0, NULL, count, arguments, false, exception, &internal->signature_, &internal->cif_, internal->GetValue());
-}
-
-static JSObjectRef CYMakeType(JSContextRef context, const char *type) {
- Type_privateData *internal(new Type_privateData(type));
- return JSObjectMake(context, Type_privateData::Class_, internal);
-}
-
-static JSObjectRef CYMakeType(JSContextRef context, sig::Type *type) {
- Type_privateData *internal(new Type_privateData(type));
- return JSObjectMake(context, Type_privateData::Class_, internal);
-}
-
-static void *CYCastSymbol(const char *name) {
- return dlsym(RTLD_DEFAULT, name);
-}
-
-static JSValueRef Runtime_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
- CYPool pool;
- CYUTF8String name(CYPoolUTF8String(pool, context, property));
-
- if (hooks_ != NULL && hooks_->RuntimeProperty != NULL)
- if (JSValueRef value = (*hooks_->RuntimeProperty)(context, name))
- return value;
-
- sqlite3_stmt *statement;
-
- _sqlcall(sqlite3_prepare(Bridge_,
- "select "
- "\"bridge\".\"mode\", "
- "\"bridge\".\"value\" "
- "from \"bridge\" "
- "where"
- " \"bridge\".\"name\" = ?"
- " limit 1"
- , -1, &statement, NULL));
-
- _sqlcall(sqlite3_bind_text(statement, 1, name.data, name.size, SQLITE_STATIC));
-
- int mode;
- const char *value;
-
- if (_sqlcall(sqlite3_step(statement)) == SQLITE_DONE) {
- mode = -1;
- value = NULL;
- } else {
- mode = sqlite3_column_int(statement, 0);
- value = sqlite3_column_pooled(pool, statement, 1);
- }
-
- _sqlcall(sqlite3_finalize(statement));
-
- switch (mode) {
- default:
- _assert(false);
- case -1:
- return NULL;
-
- case 0:
- return JSEvaluateScript(CYGetJSContext(context), CYJSString(value), NULL, NULL, 0, NULL);
-
- case 1:
- if (void (*symbol)() = reinterpret_cast<void (*)()>(CYCastSymbol(name.data)))
- return CYMakeFunctor(context, symbol, value);
- else return NULL;
-
- case 2:
- if (void *symbol = CYCastSymbol(name.data)) {
- // XXX: this is horrendously inefficient
- sig::Signature signature;
- sig::Parse(pool, &signature, value, &Structor_);
- ffi_cif cif;
- sig::sig_ffi_cif(pool, &sig::ObjectiveC, &signature, &cif);
- return CYFromFFI(context, signature.elements[0].type, cif.rtype, symbol);
- } else return NULL;
-
- // XXX: implement case 3
- case 4:
- return CYMakeType(context, value);
- }
-} CYCatch }
-
-static JSObjectRef Pointer_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
- if (count != 2)
- throw CYJSError(context, "incorrect number of arguments to Functor constructor");
-
- CYPool pool;
-
- void *value(CYCastPointer<void *>(context, arguments[0]));
- const char *type(CYPoolCString(pool, context, arguments[1]));
-
- sig::Signature signature;
- sig::Parse(pool, &signature, type, &Structor_);
-
- return CYMakePointer(context, value, _not(size_t), signature.elements[0].type, NULL, NULL);
-} CYCatch }
-
-static JSObjectRef Type_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
- if (count != 1)
- throw CYJSError(context, "incorrect number of arguments to Type constructor");
- CYPool pool;
- const char *type(CYPoolCString(pool, context, arguments[0]));
- return CYMakeType(context, type);
-} CYCatch }
-
-static JSValueRef Type_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
- Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
-
- sig::Type type;
-
- if (JSStringIsEqualToUTF8CString(property, "$cyi")) {
- type.primitive = sig::pointer_P;
- type.data.data.size = 0;
- } else {
- CYPool pool;
- size_t index(CYGetIndex(pool, context, property));
- if (index == _not(size_t))
- return NULL;
- type.primitive = sig::array_P;
- type.data.data.size = index;
- }
-
- type.name = NULL;
- type.flags = 0;
-
- type.data.data.type = internal->type_;
-
- return CYMakeType(context, &type);
-} CYCatch }
-
-static JSValueRef Type_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
- Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
-
- if (count != 1)
- throw CYJSError(context, "incorrect number of arguments to type cast function");
- sig::Type *type(internal->type_);
- ffi_type *ffi(internal->GetFFI());
- // XXX: alignment?
- uint8_t value[ffi->size];
- CYPool pool;
- CYPoolFFI(pool, context, type, ffi, value, arguments[0]);
- return CYFromFFI(context, type, ffi, value);
-} CYCatch }
-
-static JSObjectRef Type_callAsConstructor(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
- if (count != 0)
- throw CYJSError(context, "incorrect number of arguments to type cast function");
- Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
-
- sig::Type *type(internal->type_);
- size_t length;
-
- if (type->primitive != sig::array_P)
- length = _not(size_t);
- else {
- length = type->data.data.size;
- type = type->data.data.type;
- }
-
- void *value(malloc(internal->GetFFI()->size));
- return CYMakePointer(context, value, length, type, NULL, NULL);
-} CYCatch }
-
-static JSObjectRef Functor_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
- if (count != 2)
- throw CYJSError(context, "incorrect number of arguments to Functor constructor");
- CYPool pool;
- const char *type(CYPoolCString(pool, context, arguments[1]));
- return CYMakeFunctor(context, arguments[0], type);
-} CYCatch }
-
-static JSValueRef CYValue_callAsFunction_valueOf(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
- CYValue *internal(reinterpret_cast<CYValue *>(JSObjectGetPrivate(_this)));
- return CYCastJSValue(context, reinterpret_cast<uintptr_t>(internal->value_));
-} CYCatch }
-
-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);
-}
-
-static JSValueRef CYValue_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
- CYValue *internal(reinterpret_cast<CYValue *>(JSObjectGetPrivate(_this)));
- char string[32];
- sprintf(string, "%p", internal->value_);
- return CYCastJSValue(context, string);
-} CYCatch }
-
-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 {
- char string[32];
- sprintf(string, "%p", internal->value_);
- return CYCastJSValue(context, string);
- }
-} CYCatch }
-
-static JSValueRef Type_callAsFunction_toString(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
- Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(_this)));
- CYPool pool;
- const char *type(sig::Unparse(pool, internal->type_));
- return CYCastJSValue(context, CYJSString(type));
-} CYCatch }