+void Index_(Struct_privateData *internal, double number, ssize_t &index, uint8_t *&base) {
+ Type_privateData *typical(internal->type_);
+
+ index = static_cast<ssize_t>(number);
+ if (index != number)
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"struct index non-integral" userInfo:nil];
+ if (index < 0)
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"struct index negative" userInfo:nil];
+
+ base = reinterpret_cast<uint8_t *>(internal->value_);
+ for (ssize_t local(0); local != index; ++local)
+ if (ffi_type *element = typical->ffi_.elements[local])
+ base += element->size;
+ else
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"struct index out-of-range" userInfo:nil];
+}
+
+static JSValueRef Struct_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
+ CYTry {
+ CYPool pool;
+ Struct_privateData *internal(reinterpret_cast<Struct_privateData *>(JSObjectGetPrivate(object)));
+ Type_privateData *typical(internal->type_);
+
+ size_t length;
+ const char *name(CYPoolCString(pool, property, &length));
+ double number(CYCastDouble(name, length));
+
+ if (std::isnan(number)) {
+ // XXX: implement!
+ return NULL;
+ }
+
+ ssize_t index;
+ uint8_t *base;
+
+ Index_(internal, number, index, base);
+
+ return CYFromFFI(context, typical->type_.data.signature.elements[index].type, typical->ffi_.elements[index], base, object);
+ } CYCatch
+}
+
+static bool Struct_setProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) {
+ CYTry {
+ CYPool pool;
+ Struct_privateData *internal(reinterpret_cast<Struct_privateData *>(JSObjectGetPrivate(object)));
+ Type_privateData *typical(internal->type_);
+
+ size_t length;
+ const char *name(CYPoolCString(pool, property, &length));
+ double number(CYCastDouble(name, length));
+
+ if (std::isnan(number)) {
+ // XXX: implement!
+ return false;
+ }
+
+ ssize_t index;
+ uint8_t *base;
+
+ Index_(internal, number, index, base);
+
+ CYPoolFFI(NULL, context, typical->type_.data.signature.elements[index].type, typical->ffi_.elements[index], base, value);
+ return true;
+ } CYCatch
+}
+
+static JSValueRef CYCallFunction(JSContextRef context, size_t count, const JSValueRef *arguments, JSValueRef *exception, sig::Signature *signature, ffi_cif *cif, void (*function)()) {
+ CYTry {