X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/b81e7fb6237425dcdc657869f7516ecdf2c93161..8628b7b54274e0d246ebbe99d19895faa1fdecf5:/Library.cpp diff --git a/Library.cpp b/Library.cpp index 383008a..01e3801 100644 --- a/Library.cpp +++ b/Library.cpp @@ -407,10 +407,12 @@ struct Pointer : CYOwned { Type_privateData *type_; + size_t length_; - Pointer(void *value, JSContextRef context, JSObjectRef owner, sig::Type *type) : + Pointer(void *value, JSContextRef context, JSObjectRef owner, sig::Type *type, size_t length = _not(size_t)) : CYOwned(value, context, owner), - type_(new(pool_) Type_privateData(type)) + type_(new(pool_) Type_privateData(type)), + length_(length) { } }; @@ -539,7 +541,7 @@ static size_t Nonce_(0); static JSValueRef $cyq(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYPool pool; - const char *name(apr_psprintf(pool, "%s%zu", CYPoolCString(pool, context, arguments[0]), Nonce_++)); + const char *name(apr_psprintf(pool, "%s%"APR_SIZE_T_FMT"", CYPoolCString(pool, context, arguments[0]), Nonce_++)); return CYCastJSValue(context, name); } @@ -668,7 +670,7 @@ static JSValueRef Array_callAsFunction_toCYON(JSContextRef context, JSObjectRef return CYCastJSValue(context, CYJSString(CYUTF8String(value.c_str(), value.size()))); } CYCatch } -JSObjectRef CYMakePointer(JSContextRef context, void *pointer, sig::Type *type, ffi_type *ffi, JSObjectRef owner) { +JSObjectRef CYMakePointer(JSContextRef context, void *pointer, size_t length, sig::Type *type, ffi_type *ffi, JSObjectRef owner) { Pointer *internal(new Pointer(pointer, context, owner, type)); return JSObjectMake(context, Pointer_, internal); } @@ -794,9 +796,14 @@ JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void CYFromFFI_(float, float) CYFromFFI_(double, double) + case sig::array_P: + if (void *pointer = data) + return CYMakePointer(context, pointer, type->data.data.size, type->data.data.type, NULL, owner); + else goto null; + case sig::pointer_P: if (void *pointer = *reinterpret_cast(data)) - return CYMakePointer(context, pointer, type->data.data.type, ffi, owner); + return CYMakePointer(context, pointer, _not(size_t), type->data.data.type, NULL, owner); else goto null; case sig::string_P: @@ -816,8 +823,7 @@ JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void if (JSValueRef value = (*hooks_->FromFFI)(context, type, ffi, data, initialize, owner)) return value; - fprintf(stderr, "CYFromFFI(%c)\n", type->primitive); - _assert(false); + CYThrow("failed conversion from FFI format: '%c'\n", type->primitive); } } @@ -919,52 +925,34 @@ static bool Index_(apr_pool_t *pool, JSContextRef context, Struct_privateData *i return true; } -static JSValueRef Pointer_getIndex(JSContextRef context, JSObjectRef object, size_t index, JSValueRef *exception) { CYTry { +static JSValueRef Pointer_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { + CYPool pool; Pointer *internal(reinterpret_cast(JSObjectGetPrivate(object))); - Type_privateData *typical(internal->type_); - ffi_type *ffi(typical->GetFFI()); - - uint8_t *base(reinterpret_cast(internal->value_)); - base += ffi->size * index; - - JSObjectRef owner(internal->GetOwner() ?: object); - return CYFromFFI(context, typical->type_, ffi, base, false, owner); -} CYCatch } + if (JSStringIsEqual(property, length_)) + return internal->length_ == _not(size_t) ? CYJSUndefined(context) : CYCastJSValue(context, internal->length_); -static JSValueRef Pointer_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { - CYPool pool; - Pointer *internal(reinterpret_cast(JSObjectGetPrivate(object))); Type_privateData *typical(internal->type_); if (typical->type_ == NULL) return NULL; ssize_t offset; - if (!CYGetOffset(pool, context, property, offset)) + if (JSStringIsEqualToUTF8CString(property, "$cyi")) + offset = 0; + else if (!CYGetOffset(pool, context, property, offset)) return NULL; - return Pointer_getIndex(context, object, offset, exception); -} - -static JSValueRef Pointer_getProperty_$cyi(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { - return Pointer_getIndex(context, object, 0, exception); -} - -static bool Pointer_setIndex(JSContextRef context, JSObjectRef object, size_t index, JSValueRef value, JSValueRef *exception) { CYTry { - Pointer *internal(reinterpret_cast(JSObjectGetPrivate(object))); - Type_privateData *typical(internal->type_); - ffi_type *ffi(typical->GetFFI()); uint8_t *base(reinterpret_cast(internal->value_)); - base += ffi->size * index; + base += ffi->size * offset; - CYPoolFFI(NULL, context, typical->type_, ffi, base, value); - return true; + JSObjectRef owner(internal->GetOwner() ?: object); + return CYFromFFI(context, typical->type_, ffi, base, false, owner); } CYCatch } -static bool Pointer_setProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) { +static bool Pointer_setProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) { CYTry { CYPool pool; Pointer *internal(reinterpret_cast(JSObjectGetPrivate(object))); Type_privateData *typical(internal->type_); @@ -973,20 +961,24 @@ static bool Pointer_setProperty(JSContextRef context, JSObjectRef object, JSStri return NULL; ssize_t offset; - if (!CYGetOffset(pool, context, property, offset)) + if (JSStringIsEqualToUTF8CString(property, "$cyi")) + offset = 0; + else if (!CYGetOffset(pool, context, property, offset)) return NULL; - return Pointer_setIndex(context, object, offset, value, exception); -} + ffi_type *ffi(typical->GetFFI()); -static bool Pointer_setProperty_$cyi(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef *exception) { - return Pointer_setIndex(context, object, 0, value, exception); -} + uint8_t *base(reinterpret_cast(internal->value_)); + base += ffi->size * offset; + + CYPoolFFI(NULL, context, typical->type_, ffi, base, value); + return true; +} CYCatch } static JSValueRef Struct_callAsFunction_$cya(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { Struct_privateData *internal(reinterpret_cast(JSObjectGetPrivate(_this))); Type_privateData *typical(internal->type_); - return CYMakePointer(context, internal->value_, typical->type_, typical->ffi_, _this); + return CYMakePointer(context, internal->value_, _not(size_t), typical->type_, typical->ffi_, _this); } static JSValueRef Struct_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { @@ -1079,7 +1071,7 @@ static JSValueRef Functor_callAsFunction(JSContextRef context, JSObjectRef objec } static JSObjectRef CYMakeType(JSContextRef context, const char *type) { - Type_privateData *internal(new Type_privateData(NULL, type)); + Type_privateData *internal(new Type_privateData(type)); return JSObjectMake(context, Type_privateData::Class_, internal); } @@ -1169,7 +1161,7 @@ static JSObjectRef Pointer_new(JSContextRef context, JSObjectRef object, size_t sig::Signature signature; sig::Parse(pool, &signature, type, &Structor_); - return CYMakePointer(context, value, signature.elements[0].type, NULL, NULL); + 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 { @@ -1235,7 +1227,7 @@ static JSObjectRef Type_callAsConstructor(JSContextRef context, JSObjectRef obje } void *value(malloc(internal->GetFFI()->size)); - return CYMakePointer(context, value, type, NULL, NULL); + return CYMakePointer(context, value, _not(size_t), type, NULL, NULL); } CYCatch } static JSObjectRef Functor_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { @@ -1256,13 +1248,24 @@ static JSValueRef CYValue_callAsFunction_toJSON(JSContextRef context, JSObjectRe } static JSValueRef CYValue_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { -CYValue *internal(reinterpret_cast(JSObjectGetPrivate(_this))); + CYValue *internal(reinterpret_cast(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(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(JSObjectGetPrivate(_this))); CYPool pool; @@ -1288,13 +1291,8 @@ static JSValueRef Type_callAsFunction_toJSON(JSContextRef context, JSObjectRef o return Type_callAsFunction_toString(context, object, _this, count, arguments, exception); } -static JSStaticValue Pointer_staticValues[2] = { - {"$cyi", &Pointer_getProperty_$cyi, &Pointer_setProperty_$cyi, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, - {NULL, NULL, NULL, 0} -}; - static JSStaticFunction Pointer_staticFunctions[4] = { - {"toCYON", &CYValue_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, + {"toCYON", &Pointer_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"toJSON", &CYValue_callAsFunction_toJSON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"valueOf", &CYValue_callAsFunction_valueOf, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {NULL, NULL, 0} @@ -1491,7 +1489,6 @@ JSGlobalContextRef CYGetJSContext() { definition = kJSClassDefinitionEmpty; definition.className = "Pointer"; - definition.staticValues = Pointer_staticValues; definition.staticFunctions = Pointer_staticFunctions; definition.getProperty = &Pointer_getProperty; definition.setProperty = &Pointer_setProperty;