From cd466442549b9b485c3e0f84a13b60f69ced8ad3 Mon Sep 17 00:00:00 2001 From: Bryan Tam Date: Mon, 29 Jan 2018 16:38:00 -0700 Subject: [PATCH] Handle Float Literal using BigDecimal --- include/swift/WALASupport/WALAWalker.h | 2 ++ lib/WALASupport/InstrKindInfoGetter.cpp | 22 ++++++++++++++++++---- lib/WALASupport/WALAWalker.cpp | 15 +++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/include/swift/WALASupport/WALAWalker.h b/include/swift/WALASupport/WALAWalker.h index ed20d7aec6d9d..45e01068807e0 100644 --- a/include/swift/WALASupport/WALAWalker.h +++ b/include/swift/WALASupport/WALAWalker.h @@ -55,6 +55,8 @@ class WALAIntegration { void print(jobject obj); jobject makePosition(int, int, int, int); + + jobject makeBigDecimal(const char *, int); WALAIntegration(JNIEnv *, Exceptions &, const char *); }; diff --git a/lib/WALASupport/InstrKindInfoGetter.cpp b/lib/WALASupport/InstrKindInfoGetter.cpp index abbc04f3ed9ff..232b6fec6569b 100644 --- a/lib/WALASupport/InstrKindInfoGetter.cpp +++ b/lib/WALASupport/InstrKindInfoGetter.cpp @@ -229,12 +229,26 @@ jobject InstrKindInfoGetter::handleFloatLiteralInst() { if (outs != NULL) { *outs << "<< FloatLiteralInst >>" << "\n"; } + jobject node = nullptr; FloatLiteralInst* castInst = cast(instr); APFloat value = castInst->getValue(); - bool APFLosesInfo; - value.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &APFLosesInfo); - jobject node = (*wala)->makeConstant(value.convertToDouble()); - nodeMap->insert(std::make_pair(castInst, node)); + + if (value.isFinite()) { + // To BigDecimal + SmallVector buf; + value.toString(buf); + jobject bigDecimal = (*wala).makeBigDecimal(buf.data(), buf.size()); + node = (*wala)->makeConstant(bigDecimal); + nodeMap->insert(std::make_pair(castInst, node)); + } + else { + // Infinity of NaN, convert to double + // as BigDecimal constructor cannot accept strings of these + bool APFLosesInfo; + value.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &APFLosesInfo); + node = (*wala)->makeConstant(value.convertToDouble()); + nodeMap->insert(std::make_pair(castInst, node)); + } return node; } diff --git a/lib/WALASupport/WALAWalker.cpp b/lib/WALASupport/WALAWalker.cpp index 803ae1620220a..10ab1aa491fab 100644 --- a/lib/WALASupport/WALAWalker.cpp +++ b/lib/WALASupport/WALAWalker.cpp @@ -54,6 +54,21 @@ jobject WALAIntegration::makePosition(int fl, int fc, int ll, int lc) { return result; } +jobject WALAIntegration::makeBigDecimal(const char *strData, int strLen) { + char *safeData = strndup(strData, strLen); + jobject val = java_env->NewStringUTF(safeData); + delete safeData; + jclass bigDecimalCls = java_env->FindClass("java/math/BigDecimal"); + THROW_ANY_EXCEPTION(cpp_ex); + jmethodID bigDecimalInit = java_env->GetMethodID(bigDecimalCls, + "", "(Ljava/lang/String;)V"); + THROW_ANY_EXCEPTION(cpp_ex); + jobject bigDecimal = java_env->NewObject(bigDecimalCls, bigDecimalInit, val); + THROW_ANY_EXCEPTION(cpp_ex); + java_env->DeleteLocalRef(val); + return bigDecimal; +} + void WALAIntegration::print(jobject obj) { print_object(java_env, obj); THROW_ANY_EXCEPTION(cpp_ex);