diff --git a/src/hx/cppia/ArrayBuiltin.cpp b/src/hx/cppia/ArrayBuiltin.cpp index 2d321565e..5a7164e51 100644 --- a/src/hx/cppia/ArrayBuiltin.cpp +++ b/src/hx/cppia/ArrayBuiltin.cpp @@ -1482,7 +1482,7 @@ struct ArrayBuiltin : public ArrayBuiltinBase if (destType!=etInt || isMemoryVal(inDest)) { compiler->move(sJitTemp1.as(jtInt),sJitTemp1.atReg(sJitTemp0,1).as(jtShort)); - compiler->convert(sJitTemp1,etInt, inDest, destType); + compiler->convert(sJitTemp1.as(jtInt),etInt, inDest, destType); } else compiler->move( inDest.as(jtInt), sJitTemp1.atReg(sJitTemp0).as(jtShort) ); diff --git a/src/hx/cppia/Cppia.cpp b/src/hx/cppia/Cppia.cpp index 06375a1ec..05baeb3a4 100644 --- a/src/hx/cppia/Cppia.cpp +++ b/src/hx/cppia/Cppia.cpp @@ -6818,7 +6818,7 @@ struct OpSub : public BinOp else { compiler->sub(sJitTemp1.as(jtInt),lval,sJitTemp0,false); - compiler->convert(sJitTemp1,etInt, inDest, destType); + compiler->convert(sJitTemp1.as(jtInt),etInt, inDest, destType); } } else diff --git a/src/hx/cppia/CppiaCompiler.cpp b/src/hx/cppia/CppiaCompiler.cpp index e6f8087e9..6cda678b5 100644 --- a/src/hx/cppia/CppiaCompiler.cpp +++ b/src/hx/cppia/CppiaCompiler.cpp @@ -898,7 +898,7 @@ class CppiaJitCompiler : public CppiaCompiler { if (inSrc.uses(SLJIT_R1)) { - move(sJitArg0, inSrc); + move(sJitArg0.as(jtInt), inSrc.as(jtInt)); add( sJitTemp1, inTarget.getReg(), inTarget.offset ); callNative( (void *)intToStr, sJitArg0.as(jtInt), sJitTemp1.as(jtPointer)); } @@ -917,7 +917,7 @@ class CppiaJitCompiler : public CppiaCompiler case etObject: if (inSrc.uses(SLJIT_R1)) { - move(sJitArg0, inSrc); + move(sJitArg0.as(jtPointer), inSrc.as(jtPointer)); add( sJitTemp1, inTarget.getReg(), inTarget.offset ); callNative( (void *)objToStr, sJitArg0.as(jtPointer), sJitTemp1.as(jtPointer) ); } @@ -942,24 +942,24 @@ class CppiaJitCompiler : public CppiaCompiler break; case etObject: - if (inSrc==sJitTemp1) - { - move(sJitArg0, inSrc); - makeAddress(sJitTemp1,inTarget); - callNative( (void *)objToFloat, sJitArg0.as(jtPointer), sJitTemp1.as(jtPointer)); - } - else { + JitVal src = inSrc.as(jtPointer); + if (inSrc.uses(SLJIT_R1)) + { + move(sJitArg0.as(jtPointer), src); + src = sJitArg0.as(jtPointer); + } + if (isMemoryVal(inTarget)) { makeAddress(sJitTemp1,inTarget); - callNative( (void *)objToFloat, inSrc.as(jtPointer), sJitTemp1.as(jtPointer) ); + callNative( (void *)objToFloat, src, sJitTemp1.as(jtPointer) ); } else { JitTemp temp(this,jtFloat); makeAddress(sJitTemp1,temp); - callNative( (void *)objToFloat, inSrc.as(jtPointer), sJitTemp1.as(jtPointer) ); + callNative( (void *)objToFloat, src, sJitTemp1.as(jtPointer) ); move(inTarget,temp); } } diff --git a/test/cppia/Client.hx b/test/cppia/Client.hx index 710373f4b..a310fadbe 100644 --- a/test/cppia/Client.hx +++ b/test/cppia/Client.hx @@ -14,6 +14,48 @@ class ClientFoo implements IFoo { } } +class ClientJitConvert { + + public static function subtractToString():String { + var a:Int = 2; + + return "" + (a - 1); + } + + public static function subtractToFloat():Float { + var a:Int = 7; + + return (a - 2) / 2; + } + + public static function subtractToDynamic():Dynamic { + var a:Int = 9; + + return a - 4; + } + + public static function dynamicToString():String { + var d:Dynamic = "hello"; + var s:String = d; + + return s + "!"; + } + + public static function dynamicToFloat():Float { + var d:Dynamic = 2.5; + var f:Float = d; + + return f + 1; + } + + public static function dynamicToFloatInRegister():Float { + var d:Dynamic = 1.5; + var m:Float = 2; + + return m * d; + } +} + class Client { public static var clientBool0 = true; diff --git a/test/cppia/cases/TestCommon.hx b/test/cppia/cases/TestCommon.hx index eaacb5a76..1218b3c42 100644 --- a/test/cppia/cases/TestCommon.hx +++ b/test/cppia/cases/TestCommon.hx @@ -59,6 +59,46 @@ class TestCommon extends Test { Assert.equals(2, Common.callbackSet, 'Bad cppia closure'); } + function callConvert(name:String):Dynamic { + final cls = Type.resolveClass('ClientJitConvert'); + + if (!Assert.notNull(cls, 'Unable to resolve ClientJitConvert')) { + return null; + } + + return Reflect.callMethod(null, Reflect.field(cls, name), []); + } + + @:depends(testStatus) + function testSubtractionToString() { + Assert.equals('1', callConvert('subtractToString'), 'Int subtraction into a string did not answer'); + } + + @:depends(testStatus) + function testSubtractionToFloat() { + Assert.floatEquals(2.5, callConvert('subtractToFloat'), 'Int subtraction into a float did not answer'); + } + + @:depends(testStatus) + function testSubtractionToDynamic() { + Assert.equals(5, callConvert('subtractToDynamic'), 'Int subtraction into a dynamic did not answer'); + } + + @:depends(testStatus) + function testDynamicToString() { + Assert.equals('hello!', callConvert('dynamicToString'), 'Dynamic into a string did not answer'); + } + + @:depends(testStatus) + function testDynamicToFloat() { + Assert.floatEquals(3.5, callConvert('dynamicToFloat'), 'Dynamic into a float did not answer'); + } + + @:depends(testStatus) + function testDynamicToFloatInRegister() { + Assert.floatEquals(3.0, callConvert('dynamicToFloatInRegister'), 'Dynamic into a float register did not answer'); + } + @:depends(testStatus) function testInterfaceCalling() { final obj : IFoo = Type.createInstance(Type.resolveClass('ClientFoo'), []);