From: Jay Freeman (saurik) Date: Mon, 28 Dec 2015 02:13:19 +0000 (-0800) Subject: Support round trip of signed char through typedef. X-Git-Tag: v0.9.590~132 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/57f0643431ab99e0eba70d447e72a5d42e726fcc?ds=inline Support round trip of signed char through typedef. --- diff --git a/Decode.cpp b/Decode.cpp index bcf7713..acf8b95 100644 --- a/Decode.cpp +++ b/Decode.cpp @@ -77,7 +77,7 @@ CYTypedIdentifier *Decode_(CYPool &pool, struct sig::Type *type) { } break; case sig::bit_P: _assert(false); break; - case sig::char_P: return $ CYTypedIdentifier($ CYTypeVariable("char")); + case sig::schar_P: return $ CYTypedIdentifier($ CYTypeSigned($ CYTypeVariable("char"))); case sig::double_P: return $ CYTypedIdentifier($ CYTypeVariable("double")); case sig::float_P: return $ CYTypedIdentifier($ CYTypeVariable("float")); case sig::int_P: return $ CYTypedIdentifier($ CYTypeVariable("int")); @@ -86,6 +86,7 @@ CYTypedIdentifier *Decode_(CYPool &pool, struct sig::Type *type) { case sig::short_P: return $ CYTypedIdentifier($ CYTypeShort($ CYTypeVariable("int"))); case sig::void_P: return $ CYTypedIdentifier($ CYTypeVoid()); + case sig::char_P: return $ CYTypedIdentifier($ CYTypeVariable("char")); case sig::struct_P: { CYTypeStructField *fields(NULL); diff --git a/Execute.cpp b/Execute.cpp index 1c83e26..af4f366 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -662,7 +662,7 @@ void CYPoolFFI(CYPool *pool, JSContextRef context, sig::Type *type, ffi_type *ff break; CYPoolFFI_(uchar, unsigned char) - CYPoolFFI_(char, char) + CYPoolFFI_(schar, signed char) CYPoolFFI_(ushort, unsigned short) CYPoolFFI_(short, short) CYPoolFFI_(ulong, unsigned long) @@ -737,6 +737,9 @@ void CYPoolFFI(CYPool *pool, JSContextRef context, sig::Type *type, ffi_type *ff case sig::void_P: break; + // XXX: implement a conversion from a single character string? + CYPoolFFI_(char, char) + default: for (CYHook *hook : GetHooks()) if (hook->PoolFFI != NULL) @@ -757,7 +760,7 @@ JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void return CYCastJSValue(context, *reinterpret_cast(data)); \ CYFromFFI_(uchar, unsigned char) - CYFromFFI_(char, char) + CYFromFFI_(schar, signed char) CYFromFFI_(ushort, unsigned short) CYFromFFI_(short, short) CYFromFFI_(ulong, unsigned long) @@ -789,6 +792,8 @@ JSValueRef CYFromFFI(JSContextRef context, sig::Type *type, ffi_type *ffi, void case sig::void_P: return CYJSUndefined(context); + CYFromFFI_(char, char) + null: return CYJSNull(context); default: @@ -1114,8 +1119,8 @@ static JSValueRef Pointer_callAsFunction(JSContextRef context, JSObjectRef objec return CYCallAsFunction(context, functor, _this, count, arguments); } CYCatch(NULL) } -JSObjectRef CYMakeType(JSContextRef context, const char *encoding) { - Type_privateData *internal(new Type_privateData(encoding)); +JSObjectRef CYMakeType(JSContextRef context, sig::Primitive primitive) { + Type_privateData *internal(new Type_privateData(primitive)); return JSObjectMake(context, Type_privateData::Class_, internal); } @@ -1310,8 +1315,10 @@ static JSObjectRef Type_new(JSContextRef context, JSObjectRef object, size_t cou if (false) { } else if (count == 1) { - const char *type(CYPoolCString(pool, context, arguments[0])); - return CYMakeType(context, type); + const char *encoding(CYPoolCString(pool, context, arguments[0])); + sig::Signature signature; + sig::Parse(pool, &signature, encoding, &Structor_); + return CYMakeType(context, signature.elements[0].type); } else if (count == 2) { JSObjectRef types(CYCastJSObject(context, arguments[0])); size_t count(CYArrayLength(context, types)); @@ -1457,7 +1464,7 @@ static JSValueRef Type_callAsFunction_signed(JSContextRef context, JSObjectRef o sig::Type type(*internal->type_); switch (type.primitive) { - case sig::char_P: case sig::uchar_P: type.primitive = sig::char_P; break; + case sig::char_P: case sig::schar_P: case sig::uchar_P: type.primitive = sig::schar_P; break; case sig::short_P: case sig::ushort_P: type.primitive = sig::short_P; break; case sig::int_P: case sig::uint_P: type.primitive = sig::int_P; break; case sig::long_P: case sig::ulong_P: type.primitive = sig::long_P; break; @@ -1476,7 +1483,7 @@ static JSValueRef Type_callAsFunction_unsigned(JSContextRef context, JSObjectRef sig::Type type(*internal->type_); switch (type.primitive) { - case sig::char_P: case sig::uchar_P: type.primitive = sig::uchar_P; break; + case sig::char_P: case sig::schar_P: case sig::uchar_P: type.primitive = sig::uchar_P; break; case sig::short_P: case sig::ushort_P: type.primitive = sig::ushort_P; break; case sig::int_P: case sig::uint_P: type.primitive = sig::uint_P; break; case sig::long_P: case sig::ulong_P: type.primitive = sig::ulong_P; break; @@ -2274,13 +2281,13 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { CYSetProperty(context, cache, CYJSString("NULL"), CYJSNull(context), kJSPropertyAttributeDontEnum); - CYSetProperty(context, cache, CYJSString("bool"), CYMakeType(context, "B"), kJSPropertyAttributeDontEnum); - CYSetProperty(context, cache, CYJSString("char"), CYMakeType(context, "c"), kJSPropertyAttributeDontEnum); - CYSetProperty(context, cache, CYJSString("short"), CYMakeType(context, "s"), kJSPropertyAttributeDontEnum); - CYSetProperty(context, cache, CYJSString("int"), CYMakeType(context, "i"), kJSPropertyAttributeDontEnum); - CYSetProperty(context, cache, CYJSString("long"), CYMakeType(context, "l"), kJSPropertyAttributeDontEnum); - CYSetProperty(context, cache, CYJSString("float"), CYMakeType(context, "f"), kJSPropertyAttributeDontEnum); - CYSetProperty(context, cache, CYJSString("double"), CYMakeType(context, "d"), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("bool"), CYMakeType(context, sig::boolean_P), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("char"), CYMakeType(context, sig::char_P), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("short"), CYMakeType(context, sig::short_P), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("int"), CYMakeType(context, sig::int_P), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("long"), CYMakeType(context, sig::long_P), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("float"), CYMakeType(context, sig::float_P), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("double"), CYMakeType(context, sig::double_P), kJSPropertyAttributeDontEnum); for (CYHook *hook : GetHooks()) if (hook->SetupContext != NULL) diff --git a/JavaScript.hpp b/JavaScript.hpp index 33b3db8..074c7db 100644 --- a/JavaScript.hpp +++ b/JavaScript.hpp @@ -143,7 +143,7 @@ struct CYRegisterHook { JSObjectRef CYMakePointer(JSContextRef context, void *pointer, size_t length, sig::Type *type, ffi_type *ffi, JSObjectRef owner); -JSObjectRef CYMakeType(JSContextRef context, const char *encoding); +JSObjectRef CYMakeType(JSContextRef context, sig::Primitive primitive); JSObjectRef CYMakeType(JSContextRef context, sig::Type *type); JSObjectRef CYMakeType(JSContextRef context, sig::Signature *signature); diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index 177ff6f..0fb792a 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -3033,9 +3033,9 @@ void CYObjectiveC_SetupContext(JSContextRef context) { CYPoolTry { JSObjectRef cache(CYGetCachedObject(context, CYJSString("cache"))); CYSetProperty(context, cache, CYJSString("YES"), JSValueMakeBoolean(context, true), kJSPropertyAttributeDontEnum); CYSetProperty(context, cache, CYJSString("NO"), JSValueMakeBoolean(context, false), kJSPropertyAttributeDontEnum); - CYSetProperty(context, cache, CYJSString("id"), CYMakeType(context, "@"), kJSPropertyAttributeDontEnum); - CYSetProperty(context, cache, CYJSString("Class"), CYMakeType(context, "#"), kJSPropertyAttributeDontEnum); - CYSetProperty(context, cache, CYJSString("SEL"), CYMakeType(context, ":"), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("id"), CYMakeType(context, sig::object_P), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("Class"), CYMakeType(context, sig::typename_P), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("SEL"), CYMakeType(context, sig::selector_P), kJSPropertyAttributeDontEnum); } CYPoolCatch() } static void *CYObjectiveC_CastSymbol(const char *name) { diff --git a/sig/ffi_type.cpp b/sig/ffi_type.cpp index 836f7cd..b75d606 100644 --- a/sig/ffi_type.cpp +++ b/sig/ffi_type.cpp @@ -87,7 +87,7 @@ ffi_type *ObjectiveC(CYPool &pool, struct Type *type) { _assert(false); break; - case char_P: return &ffi_type_schar; + case schar_P: return &ffi_type_schar; case double_P: return &ffi_type_double; case float_P: return &ffi_type_float; case int_P: return &ffi_type_sint; @@ -96,6 +96,7 @@ ffi_type *ObjectiveC(CYPool &pool, struct Type *type) { case short_P: return &ffi_type_sshort; case void_P: return &ffi_type_void; + case char_P: return &ffi_type_schar; case struct_P: { ffi_type *aggregate(new(pool) ffi_type()); @@ -133,7 +134,7 @@ ffi_type *Java(CYPool &pool, struct Type *type) { case array_P: return &ffi_type_pointer; case pointer_P: return &ffi_type_pointer; case bit_P: _assert(false); break; - case char_P: return &ffi_type_schar; + case schar_P: return &ffi_type_schar; case double_P: return &ffi_type_double; case float_P: return &ffi_type_double; case int_P: return &ffi_type_sint; @@ -141,6 +142,7 @@ ffi_type *Java(CYPool &pool, struct Type *type) { case longlong_P: return &ffi_type_slonglong; case short_P: return &ffi_type_sshort; case void_P: return &ffi_type_void; + case char_P: return &ffi_type_schar; case struct_P: return &ffi_type_pointer; default: diff --git a/sig/parse.cpp b/sig/parse.cpp index 62d99cf..67a28bf 100644 --- a/sig/parse.cpp +++ b/sig/parse.cpp @@ -160,7 +160,7 @@ Type *Parse_(CYPool &pool, const char **name, char eos, bool named, Callback cal type->data.data.size = strtoul(*name, (char **) name, 10); break; - case 'c': type->primitive = char_P; break; + case 'c': type->primitive = schar_P; break; case 'd': type->primitive = double_P; break; case 'f': type->primitive = float_P; break; case 'i': type->primitive = int_P; break; @@ -286,7 +286,7 @@ const char *Unparse_(CYPool &pool, struct Type *type) { } break; case bit_P: return pool.strcat("b", pool.itoa(type->data.data.size), NULL); - case char_P: return "c"; + case schar_P: return "c"; case double_P: return "d"; case float_P: return "f"; case int_P: return "i"; @@ -294,6 +294,7 @@ const char *Unparse_(CYPool &pool, struct Type *type) { case longlong_P: return "q"; case short_P: return "s"; case void_P: return "v"; + case char_P: return "c"; case struct_P: return pool.strcat("{", type->name == NULL ? "?" : type->name, "=", Unparse(pool, &type->data.signature), "}", NULL); } diff --git a/sig/types.hpp b/sig/types.hpp index 175d172..7bf83b8 100644 --- a/sig/types.hpp +++ b/sig/types.hpp @@ -32,6 +32,7 @@ namespace sig { enum Primitive { function_P = '\0', block_P = '\a', + char_P = '\b', unknown_P = '?', typename_P = '#', @@ -48,7 +49,7 @@ enum Primitive { array_P = '[', pointer_P = '^', bit_P = 'b', - char_P = 'c', + schar_P = 'c', double_P = 'd', float_P = 'f', int_P = 'i',