[KLIB] Make sure float/double bits have fixed representation for NaN.

- Store float and double constants as fixed32/64 proto value
 and encode/decode them in our side.
This commit is contained in:
Roman Artemev
2020-03-16 13:01:36 +03:00
committed by romanart
parent 5fb46e05da
commit 8e295de593
5 changed files with 100 additions and 68 deletions
@@ -170,8 +170,8 @@ message IrConst {
int32 short = 5; int32 short = 5;
int32 int = 6; int32 int = 6;
int64 long = 7; int64 long = 7;
float float = 8; fixed32 float_bits = 8; // float/double is stored via fixed 32/64 bit value to avoid raw bit conversion
double double = 9; fixed64 double_bits = 9;
int32 string = 10; int32 string = 10;
} }
} }
@@ -835,10 +835,10 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
-> IrConstImpl.long(start, end, type, proto.long) -> IrConstImpl.long(start, end, type, proto.long)
STRING STRING
-> IrConstImpl.string(start, end, type, deserializeString(proto.string)) -> IrConstImpl.string(start, end, type, deserializeString(proto.string))
FLOAT FLOAT_BITS
-> IrConstImpl.float(start, end, type, proto.float) -> IrConstImpl.float(start, end, type, Float.fromBits(proto.floatBits))
DOUBLE DOUBLE_BITS
-> IrConstImpl.double(start, end, type, proto.double) -> IrConstImpl.double(start, end, type, Double.fromBits(proto.doubleBits))
VALUE_NOT_SET VALUE_NOT_SET
-> error("Const deserialization error: ${proto.valueCase} ") -> error("Const deserialization error: ${proto.valueCase} ")
} }
@@ -585,8 +585,8 @@ open class IrFileSerializer(
IrConstKind.Int -> proto.int = value.value as Int IrConstKind.Int -> proto.int = value.value as Int
IrConstKind.Long -> proto.long = value.value as Long IrConstKind.Long -> proto.long = value.value as Long
IrConstKind.String -> proto.string = serializeString(value.value as String) IrConstKind.String -> proto.string = serializeString(value.value as String)
IrConstKind.Float -> proto.float = value.value as Float IrConstKind.Float -> proto.floatBits = (value.value as Float).toBits()
IrConstKind.Double -> proto.double = value.value as Double IrConstKind.Double -> proto.doubleBits = (value.value as Double).toBits()
} }
return proto.build() return proto.build()
} }
@@ -90,12 +90,12 @@ public final class IrConst extends
} }
case 69: { case 69: {
valueCase_ = 8; valueCase_ = 8;
value_ = input.readFloat(); value_ = input.readFixed32();
break; break;
} }
case 73: { case 73: {
valueCase_ = 9; valueCase_ = 9;
value_ = input.readDouble(); value_ = input.readFixed64();
break; break;
} }
case 80: { case 80: {
@@ -148,8 +148,8 @@ public final class IrConst extends
SHORT(5), SHORT(5),
INT(6), INT(6),
LONG(7), LONG(7),
FLOAT(8), FLOAT_BITS(8),
DOUBLE(9), DOUBLE_BITS(9),
STRING(10), STRING(10),
VALUE_NOT_SET(0); VALUE_NOT_SET(0);
private int value = 0; private int value = 0;
@@ -165,8 +165,8 @@ public final class IrConst extends
case 5: return SHORT; case 5: return SHORT;
case 6: return INT; case 6: return INT;
case 7: return LONG; case 7: return LONG;
case 8: return FLOAT; case 8: return FLOAT_BITS;
case 9: return DOUBLE; case 9: return DOUBLE_BITS;
case 10: return STRING; case 10: return STRING;
case 0: return VALUE_NOT_SET; case 0: return VALUE_NOT_SET;
default: throw new java.lang.IllegalArgumentException( default: throw new java.lang.IllegalArgumentException(
@@ -303,38 +303,46 @@ public final class IrConst extends
return 0L; return 0L;
} }
public static final int FLOAT_FIELD_NUMBER = 8; public static final int FLOAT_BITS_FIELD_NUMBER = 8;
/** /**
* <code>optional float float = 8;</code> * <code>optional fixed32 float_bits = 8;</code>
*
* <pre>
* float/double is stored via fixed 32/64 bit value to avoid raw bit conversion
* </pre>
*/ */
public boolean hasFloat() { public boolean hasFloatBits() {
return valueCase_ == 8; return valueCase_ == 8;
} }
/** /**
* <code>optional float float = 8;</code> * <code>optional fixed32 float_bits = 8;</code>
*
* <pre>
* float/double is stored via fixed 32/64 bit value to avoid raw bit conversion
* </pre>
*/ */
public float getFloat() { public int getFloatBits() {
if (valueCase_ == 8) { if (valueCase_ == 8) {
return (java.lang.Float) value_; return (java.lang.Integer) value_;
} }
return 0F; return 0;
} }
public static final int DOUBLE_FIELD_NUMBER = 9; public static final int DOUBLE_BITS_FIELD_NUMBER = 9;
/** /**
* <code>optional double double = 9;</code> * <code>optional fixed64 double_bits = 9;</code>
*/ */
public boolean hasDouble() { public boolean hasDoubleBits() {
return valueCase_ == 9; return valueCase_ == 9;
} }
/** /**
* <code>optional double double = 9;</code> * <code>optional fixed64 double_bits = 9;</code>
*/ */
public double getDouble() { public long getDoubleBits() {
if (valueCase_ == 9) { if (valueCase_ == 9) {
return (java.lang.Double) value_; return (java.lang.Long) value_;
} }
return 0D; return 0L;
} }
public static final int STRING_FIELD_NUMBER = 10; public static final int STRING_FIELD_NUMBER = 10;
@@ -398,12 +406,12 @@ public final class IrConst extends
7, (long)((java.lang.Long) value_)); 7, (long)((java.lang.Long) value_));
} }
if (valueCase_ == 8) { if (valueCase_ == 8) {
output.writeFloat( output.writeFixed32(
8, (float)((java.lang.Float) value_)); 8, (int)((java.lang.Integer) value_));
} }
if (valueCase_ == 9) { if (valueCase_ == 9) {
output.writeDouble( output.writeFixed64(
9, (double)((java.lang.Double) value_)); 9, (long)((java.lang.Long) value_));
} }
if (valueCase_ == 10) { if (valueCase_ == 10) {
output.writeInt32( output.writeInt32(
@@ -455,13 +463,13 @@ public final class IrConst extends
} }
if (valueCase_ == 8) { if (valueCase_ == 8) {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeFloatSize( .computeFixed32Size(
8, (float)((java.lang.Float) value_)); 8, (int)((java.lang.Integer) value_));
} }
if (valueCase_ == 9) { if (valueCase_ == 9) {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeDoubleSize( .computeFixed64Size(
9, (double)((java.lang.Double) value_)); 9, (long)((java.lang.Long) value_));
} }
if (valueCase_ == 10) { if (valueCase_ == 10) {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream size += org.jetbrains.kotlin.protobuf.CodedOutputStream
@@ -653,12 +661,12 @@ public final class IrConst extends
setLong(other.getLong()); setLong(other.getLong());
break; break;
} }
case FLOAT: { case FLOAT_BITS: {
setFloat(other.getFloat()); setFloatBits(other.getFloatBits());
break; break;
} }
case DOUBLE: { case DOUBLE_BITS: {
setDouble(other.getDouble()); setDoubleBits(other.getDoubleBits());
break; break;
} }
case STRING: { case STRING: {
@@ -964,33 +972,49 @@ public final class IrConst extends
} }
/** /**
* <code>optional float float = 8;</code> * <code>optional fixed32 float_bits = 8;</code>
*
* <pre>
* float/double is stored via fixed 32/64 bit value to avoid raw bit conversion
* </pre>
*/ */
public boolean hasFloat() { public boolean hasFloatBits() {
return valueCase_ == 8; return valueCase_ == 8;
} }
/** /**
* <code>optional float float = 8;</code> * <code>optional fixed32 float_bits = 8;</code>
*
* <pre>
* float/double is stored via fixed 32/64 bit value to avoid raw bit conversion
* </pre>
*/ */
public float getFloat() { public int getFloatBits() {
if (valueCase_ == 8) { if (valueCase_ == 8) {
return (java.lang.Float) value_; return (java.lang.Integer) value_;
} }
return 0F; return 0;
} }
/** /**
* <code>optional float float = 8;</code> * <code>optional fixed32 float_bits = 8;</code>
*
* <pre>
* float/double is stored via fixed 32/64 bit value to avoid raw bit conversion
* </pre>
*/ */
public Builder setFloat(float value) { public Builder setFloatBits(int value) {
valueCase_ = 8; valueCase_ = 8;
value_ = value; value_ = value;
return this; return this;
} }
/** /**
* <code>optional float float = 8;</code> * <code>optional fixed32 float_bits = 8;</code>
*
* <pre>
* float/double is stored via fixed 32/64 bit value to avoid raw bit conversion
* </pre>
*/ */
public Builder clearFloat() { public Builder clearFloatBits() {
if (valueCase_ == 8) { if (valueCase_ == 8) {
valueCase_ = 0; valueCase_ = 0;
value_ = null; value_ = null;
@@ -1000,33 +1024,33 @@ public final class IrConst extends
} }
/** /**
* <code>optional double double = 9;</code> * <code>optional fixed64 double_bits = 9;</code>
*/ */
public boolean hasDouble() { public boolean hasDoubleBits() {
return valueCase_ == 9; return valueCase_ == 9;
} }
/** /**
* <code>optional double double = 9;</code> * <code>optional fixed64 double_bits = 9;</code>
*/ */
public double getDouble() { public long getDoubleBits() {
if (valueCase_ == 9) { if (valueCase_ == 9) {
return (java.lang.Double) value_; return (java.lang.Long) value_;
} }
return 0D; return 0L;
} }
/** /**
* <code>optional double double = 9;</code> * <code>optional fixed64 double_bits = 9;</code>
*/ */
public Builder setDouble(double value) { public Builder setDoubleBits(long value) {
valueCase_ = 9; valueCase_ = 9;
value_ = value; value_ = value;
return this; return this;
} }
/** /**
* <code>optional double double = 9;</code> * <code>optional fixed64 double_bits = 9;</code>
*/ */
public Builder clearDouble() { public Builder clearDoubleBits() {
if (valueCase_ == 9) { if (valueCase_ == 9) {
valueCase_ = 0; valueCase_ = 0;
value_ = null; value_ = null;
@@ -71,22 +71,30 @@ public interface IrConstOrBuilder extends
long getLong(); long getLong();
/** /**
* <code>optional float float = 8;</code> * <code>optional fixed32 float_bits = 8;</code>
*
* <pre>
* float/double is stored via fixed 32/64 bit value to avoid raw bit conversion
* </pre>
*/ */
boolean hasFloat(); boolean hasFloatBits();
/** /**
* <code>optional float float = 8;</code> * <code>optional fixed32 float_bits = 8;</code>
*
* <pre>
* float/double is stored via fixed 32/64 bit value to avoid raw bit conversion
* </pre>
*/ */
float getFloat(); int getFloatBits();
/** /**
* <code>optional double double = 9;</code> * <code>optional fixed64 double_bits = 9;</code>
*/ */
boolean hasDouble(); boolean hasDoubleBits();
/** /**
* <code>optional double double = 9;</code> * <code>optional fixed64 double_bits = 9;</code>
*/ */
double getDouble(); long getDoubleBits();
/** /**
* <code>optional int32 string = 10;</code> * <code>optional int32 string = 10;</code>