From 24ffc58c2367143a1cad64e4340e0fb5e863637a Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sun, 3 Jan 2016 12:02:12 -0800 Subject: [PATCH] Add support for __int128 (though not with libffi). --- Analyze.cpp | 3 +++ Decode.cpp | 14 ++++++++++++++ Execute.cpp | 20 ++++++++++++++++++++ Output.cpp | 10 ++++++++++ Parser.ypp.in | 15 ++++++++++++--- Replace.cpp | 4 ++++ Scanner.lpp.in | 1 + Syntax.hpp | 14 ++++++++++++++ sig/ffi_type.cpp | 18 ++++++++++++++++++ sig/parse.cpp | 19 +++++++++++++++++++ 10 files changed, 115 insertions(+), 3 deletions(-) diff --git a/Analyze.cpp b/Analyze.cpp index 922dfb1..466144d 100644 --- a/Analyze.cpp +++ b/Analyze.cpp @@ -381,6 +381,9 @@ static void CYParseType(CXType type, CYTypedIdentifier *typed) { case CXType_LongLong: typed->specifier_ = $ CYTypeIntegral(CYTypeSigned, 3); break; case CXType_ULongLong: typed->specifier_ = $ CYTypeIntegral(CYTypeUnsigned, 3); break; + case CXType_Int128: typed->specifier_ = $ CYTypeInt128(CYTypeSigned); break; + case CXType_UInt128: typed->specifier_ = $ CYTypeInt128(CYTypeUnsigned); break; + case CXType_BlockPointer: { CXType pointee(clang_getPointeeType(type)); _assert(!clang_isFunctionTypeVariadic(pointee)); diff --git a/Decode.cpp b/Decode.cpp index 823e6b4..819c675 100644 --- a/Decode.cpp +++ b/Decode.cpp @@ -56,6 +56,13 @@ CYTypedIdentifier *Primitive::Decode(CYPool &pool) const { return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 1)); } +#ifdef __SIZEOF_INT128__ +template <> +CYTypedIdentifier *Primitive::Decode(CYPool &pool) const { + return $ CYTypedIdentifier($ CYTypeInt128(CYTypeSigned)); +} +#endif + template <> CYTypedIdentifier *Primitive::Decode(CYPool &pool) const { return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 2)); @@ -81,6 +88,13 @@ CYTypedIdentifier *Primitive::Decode(CYPool &pool) const { return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 1)); } +#ifdef __SIZEOF_INT128__ +template <> +CYTypedIdentifier *Primitive::Decode(CYPool &pool) const { + return $ CYTypedIdentifier($ CYTypeInt128(CYTypeUnsigned)); +} +#endif + template <> CYTypedIdentifier *Primitive::Decode(CYPool &pool) const { return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 2)); diff --git a/Execute.cpp b/Execute.cpp index cc47fd6..36c400a 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -336,6 +336,11 @@ CYCastJSValue_(unsigned long int) CYCastJSValue_(signed long long int) CYCastJSValue_(unsigned long long int) +#ifdef __SIZEOF_INT128__ +CYCastJSValue_(signed __int128) +CYCastJSValue_(unsigned __int128) +#endif + JSValueRef CYJSUndefined(JSContextRef context) { return JSValueMakeUndefined(context); } @@ -698,6 +703,11 @@ CYPoolFFI_(unsigned long int) CYPoolFFI_(unsigned long long int) CYPoolFFI_(unsigned short int) +#ifdef __SIZEOF_INT128__ +CYPoolFFI_(signed __int128) +CYPoolFFI_(unsigned __int128) +#endif + void Void::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const { _assert(false); } @@ -813,6 +823,11 @@ CYFromFFI_(unsigned long int) CYFromFFI_(unsigned long long int) CYFromFFI_(unsigned short int) +#ifdef __SIZEOF_INT128__ +CYFromFFI_(signed __int128) +CYFromFFI_(unsigned __int128) +#endif + JSValueRef Void::FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const { return CYJSUndefined(context); } @@ -2337,6 +2352,11 @@ extern "C" void CYSetupContext(JSGlobalContextRef context) { CYSetProperty(context, cache, CYJSString("ulong"), CYMakeType(context, sig::Primitive()), kJSPropertyAttributeDontEnum); CYSetProperty(context, cache, CYJSString("ulonglong"), CYMakeType(context, sig::Primitive()), kJSPropertyAttributeDontEnum); +#ifdef __SIZEOF_INT128__ + CYSetProperty(context, cache, CYJSString("int128"), CYMakeType(context, sig::Primitive<__int128>()), kJSPropertyAttributeDontEnum); + CYSetProperty(context, cache, CYJSString("uint128"), CYMakeType(context, sig::Primitive()), kJSPropertyAttributeDontEnum); +#endif + CYSetProperty(context, cache, CYJSString("float"), CYMakeType(context, sig::Primitive()), kJSPropertyAttributeDontEnum); CYSetProperty(context, cache, CYJSString("double"), CYMakeType(context, sig::Primitive()), kJSPropertyAttributeDontEnum); diff --git a/Output.cpp b/Output.cpp index 06b60b2..ae441be 100644 --- a/Output.cpp +++ b/Output.cpp @@ -1071,6 +1071,16 @@ void CYTypeError::Output(CYOutput &out) const { out << "@error"; } +void CYTypeInt128::Output(CYOutput &out) const { + switch (signing_) { + case CYTypeNeutral: break; + case CYTypeSigned: out << "signed" << ' '; break; + case CYTypeUnsigned: out << "unsigned" << ' '; break; + } + + out << "__int128"; +} + void CYTypeIntegral::Output(CYOutput &out) const { if (signing_ == CYTypeUnsigned) out << "unsigned" << ' '; diff --git a/Parser.ypp.in b/Parser.ypp.in index 11d8d29..c2f48ce 100644 --- a/Parser.ypp.in +++ b/Parser.ypp.in @@ -73,6 +73,7 @@ %union { CYParenthetical *parenthetical_; } %union { CYProperty *property_; } %union { CYPropertyName *propertyName_; } +%union { CYTypeSigning signing_; } %union { CYSpan *span_; } %union { CYStatement *statement_; } %union { CYString *string_; } @@ -424,6 +425,7 @@ type; }) %token _goto_ "goto" %token _implements_ "implements" %token _int_ "int" +%token ___int128_ "__int128" %token _interface_ "interface" %token _let_ "let" %token _let__ "!let" @@ -677,6 +679,7 @@ type; }) %type TypeSignifier %type TypeSignifierNone %type TypeSignifierOpt +%type TypeSigning %type ParameterTail %type TypeQualifierLeft %type TypeQualifierLeftOpt @@ -1014,6 +1017,7 @@ IdentifierNoOf : IdentifierTypeNoOf | "char" { $$ = CYNew CYIdentifier("char"); } | "int" { $$ = CYNew CYIdentifier("int"); } + | "__int128" { $$ = CYNew CYIdentifier("__int128"); } | "long" { $$ = CYNew CYIdentifier("long"); } | "__restrict" { $$ = CYNew CYIdentifier("__restrict"); } | "restrict" { $$ = CYNew CYIdentifier("restrict"); } @@ -2105,12 +2109,17 @@ StructFieldListOpt | { $$ = NULL; } ; +TypeSigning + : { $$ = CYTypeNeutral; } + | "signed" { $$ = CYTypeSigned; } + | "unsigned" { $$ = CYTypeUnsigned; } + ; + PrimitiveType : IdentifierType[name] { $$ = CYNew CYTypeVariable($name); } | IntegerType[pass] { $$ = $pass; } - | "char" { $$ = CYNew CYTypeCharacter(CYTypeNeutral); } - | "signed" "char" { $$ = CYNew CYTypeCharacter(CYTypeSigned); } - | "unsigned" "char" { $$ = CYNew CYTypeCharacter(CYTypeUnsigned); } + | TypeSigning[signing] "char" { $$ = CYNew CYTypeCharacter($signing); } + | TypeSigning[signing] "__int128" { $$ = CYNew CYTypeInt128($signing); } | "struct" IdentifierType[name] { $$ = CYNew CYTypeReference($name); } ; diff --git a/Replace.cpp b/Replace.cpp index df47604..29a78a0 100644 --- a/Replace.cpp +++ b/Replace.cpp @@ -1245,6 +1245,10 @@ CYTarget *CYTypeExpression::Replace(CYContext &context) { return typed_->Replace(context); } +CYTarget *CYTypeInt128::Replace(CYContext &context) { + return $V(signing_ == CYTypeUnsigned ? "uint128" : "int128"); +} + CYTarget *CYTypeIntegral::Replace(CYContext &context) { bool u(signing_ == CYTypeUnsigned); switch (length_) { diff --git a/Scanner.lpp.in b/Scanner.lpp.in index a928264..58cfd7d 100644 --- a/Scanner.lpp.in +++ b/Scanner.lpp.in @@ -482,6 +482,7 @@ XMLName {XMLNameStart}{XMLNamePart}* "Infinity" L /*III*/ F(tk::_Infinity_, hi::Constant); "instanceof" L /*KKK*/ F(tk::_instanceof_, hi::Operator); "int" L /*FII*/ F(tk::_int_, hi::Type); +"__int128" L /*III*/ F(tk::___int128_, hi::Type); "interface" L /*FSS*/ F(tk::_interface_, hi::Meta); "let" L /*IS?*/ F(tk::_let_, hi::Meta); "long" L /*FII*/ F(tk::_long_, hi::Type); diff --git a/Syntax.hpp b/Syntax.hpp index a0e7942..f16b877 100644 --- a/Syntax.hpp +++ b/Syntax.hpp @@ -2072,6 +2072,20 @@ struct CYTypeCharacter : virtual void Output(CYOutput &out) const; }; +struct CYTypeInt128 : + CYTypeSpecifier +{ + CYTypeSigning signing_; + + CYTypeInt128(CYTypeSigning signing) : + signing_(signing) + { + } + + virtual CYTarget *Replace(CYContext &context); + virtual void Output(CYOutput &out) const; +}; + struct CYTypeIntegral : CYTypeSpecifier { diff --git a/sig/ffi_type.cpp b/sig/ffi_type.cpp index 35700e9..ab97f7a 100644 --- a/sig/ffi_type.cpp +++ b/sig/ffi_type.cpp @@ -24,8 +24,12 @@ #include "sig/ffi_type.hpp" #include "sig/types.hpp" +#if FFI_LONG_LONG_MAX == 9223372036854775807LL #define ffi_type_slonglong ffi_type_sint64 #define ffi_type_ulonglong ffi_type_uint64 +#else +#error need to configure for long long +#endif namespace sig { @@ -59,6 +63,13 @@ ffi_type *Primitive::GetFFI(CYPool &pool) const { return &ffi_type_sint; } +#ifdef __SIZEOF_INT128__ +template <> +ffi_type *Primitive::GetFFI(CYPool &pool) const { + _assert(false); +} +#endif + template <> ffi_type *Primitive::GetFFI(CYPool &pool) const { return &ffi_type_slong; @@ -84,6 +95,13 @@ ffi_type *Primitive::GetFFI(CYPool &pool) const { return &ffi_type_uint; } +#ifdef __SIZEOF_INT128__ +template <> +ffi_type *Primitive::GetFFI(CYPool &pool) const { + _assert(false); +} +#endif + template <> ffi_type *Primitive::GetFFI(CYPool &pool) const { return &ffi_type_ulong; diff --git a/sig/parse.cpp b/sig/parse.cpp index b78015d..52a974d 100644 --- a/sig/parse.cpp +++ b/sig/parse.cpp @@ -180,6 +180,11 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback case 's': type = new(pool) Primitive(); break; case 'v': type = new(pool) Void(); break; +#ifdef __SIZEOF_INT128__ + case 't': type = new(pool) Primitive(); break; + case 'T': type = new(pool) Primitive(); break; +#endif + case '{': type = new(pool) Aggregate(false); next = '}'; @@ -282,6 +287,13 @@ const char *Primitive::Encode(CYPool &pool) const { return "i"; } +#ifdef __SIZEOF_INT128__ +template <> +const char *Primitive::Encode(CYPool &pool) const { + return "t"; +} +#endif + template <> const char *Primitive::Encode(CYPool &pool) const { return "l"; @@ -307,6 +319,13 @@ const char *Primitive::Encode(CYPool &pool) const { return "I"; } +#ifdef __SIZEOF_INT128__ +template <> +const char *Primitive::Encode(CYPool &pool) const { + return "T"; +} +#endif + template <> const char *Primitive::Encode(CYPool &pool) const { return "L"; -- 2.47.2