+bool Index_(apr_pool_t *pool, Struct_privateData *internal, JSStringRef property, ssize_t &index, uint8_t *&base) {
+ Type_privateData *typical(internal->type_);
+
+ size_t length;
+ const char *name(CYPoolCString(pool, property, &length));
+ double number(CYCastDouble(name, length));
+
+ size_t count(typical->type_.data.signature.count);
+
+ if (std::isnan(number)) {
+ if (property == NULL)
+ return false;
+
+ sig::Element *elements(typical->type_.data.signature.elements);
+
+ for (size_t local(0); local != count; ++local) {
+ sig::Element *element(&elements[local]);
+ if (element->name != NULL && strcmp(name, element->name) == 0) {
+ index = local;
+ goto base;
+ }
+ }
+
+ return false;
+ } else {
+ index = static_cast<ssize_t>(number);
+ if (index != number || index < 0 || static_cast<size_t>(index) >= count)
+ return false;
+ }
+
+ base:
+ base = reinterpret_cast<uint8_t *>(internal->value_);
+ for (ssize_t local(0); local != index; ++local)
+ base += typical->ffi_.elements[local]->size;
+
+ return true;
+}
+
+static JSValueRef Struct_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) {
+ CYPool pool;
+ Struct_privateData *internal(reinterpret_cast<Struct_privateData *>(JSObjectGetPrivate(object)));
+ Type_privateData *typical(internal->type_);
+
+ ssize_t index;
+ uint8_t *base;
+
+ if (!Index_(pool, internal, property, index, base))
+ return NULL;
+
+ CYTry {
+ return CYFromFFI(context, typical->type_.data.signature.elements[index].type, typical->ffi_.elements[index], base, false, object);
+ } CYCatch
+}
+
+static bool Struct_setProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) {
+ CYPool pool;
+ Struct_privateData *internal(reinterpret_cast<Struct_privateData *>(JSObjectGetPrivate(object)));
+ Type_privateData *typical(internal->type_);
+
+ ssize_t index;
+ uint8_t *base;
+
+ if (!Index_(pool, internal, property, index, base))
+ return false;
+
+ CYTry {
+ CYPoolFFI(NULL, context, typical->type_.data.signature.elements[index].type, typical->ffi_.elements[index], base, value);
+ return true;
+ } CYCatch
+}
+
+static void Struct_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) {
+ Struct_privateData *internal(reinterpret_cast<Struct_privateData *>(JSObjectGetPrivate(object)));
+ Type_privateData *typical(internal->type_);
+
+ size_t count(typical->type_.data.signature.count);
+ sig::Element *elements(typical->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, "%lu", 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)