Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Brl.Reflection] Issues invoking Meth/Funcs with Float-params in debug builds #227

Open
GWRon opened this issue Mar 12, 2022 · 4 comments
Open

Comments

@GWRon
Copy link
Contributor

GWRon commented Mar 12, 2022

SuperStrict
Framework Brl.StandardIO
Import Brl.Reflection

Type TTest
	Method Hello(f:Float)
		Print "Hello() f = " + f
	End Method
	
	Function HelloFunc(f:Float)
		Print "HelloFunc() f = " + f
	End Function
End Type

Local t:TTest = New TTest
Print "via direct:"
t.Hello(1.2345:Float)

Print "via method invoke:"
Local m:TMethod = TTypeId.ForObject(t).FindMethod("Hello")
m.Invoke(t, [String(1.2345:Float)])

Print "via function invoke:"
Local f:TFunction = TTypeId.ForObject(t).FindFunction("HelloFunc")
f.Invoke([String(1.2345:Float)])

Release:

Executing:untitled1
via direct:
Hello() f = 1.23450005
via method invoke:
Hello() f = 1.23450005
via function invoke:
HelloFunc() f = 1.23450005

Debug:

Executing:untitled1.debug
via direct:
Hello() f = 1.23450005
via method invoke:
Hello() f = 0.00000000
via function invoke:
HelloFunc() f = 0.00000000

so there seems some "offset" or so which interfers in the reflection code - might be connected to #204 and #205

@GWRon
Copy link
Contributor Author

GWRon commented Mar 12, 2022

This also happens for ":double"

SuperStrict
Framework Brl.StandardIO
Import Brl.Reflection

Type TTest
	Method HelloDouble(d:Double)
		Print "HelloDouble() " + d
	End Method
	
	Method HelloFloat(f:Float)
		Print "HelloFloat() " + f
	End Method

	Method HelloLong(l:Long)
		Print "HelloLong() " + l
	End Method

	Method HelloInt(i:Int)
		Print "HelloInt() " + i
	End Method
	
End Type

Local t:TTest = New TTest
Print "via direct:"
t.HelloDouble(1.2345:Float)
t.HelloFloat(1.2345:Float)
t.HelloLong(12345:Long)
t.HelloInt(12345:Int)

Print "via method invoke:"
TTypeId.ForObject(t).FindMethod("HelloDouble").Invoke(t, [String(1.2345:Double)])
TTypeId.ForObject(t).FindMethod("HelloFloat").Invoke(t, [String(1.2345:Float)])
TTypeId.ForObject(t).FindMethod("HelloLong").Invoke(t, [String(12345:Long)])
TTypeId.ForObject(t).FindMethod("HelloInt").Invoke(t, [String(12345:Int)])

Release:

Executing:untitled1
via direct:
HelloDouble() 1.2344999999999999
HelloFloat() 1.23450005
HelloLong() 12345
HelloInt() 12345
via method invoke:
HelloDouble() 1.2344999999999999
HelloFloat() 1.23450005
HelloLong() 12345
HelloInt() 12345

Debug:

Executing:untitled1.debug
via direct:
HelloDouble() 1.2344999999999999
HelloFloat() 1.23450005
HelloLong() 12345
HelloInt() 12345
via method invoke:
HelloDouble() 0.0000000000000000
HelloFloat() 0.00000000
HelloLong() 12345
HelloInt() 12345

@GWRon
Copy link
Contributor Author

GWRon commented Jul 23, 2022

Seems it does not happen on with i386/32bit (with a recent BlitzMax tool chain (bmk, bcc, modules))
On Mac and Linux at least the x64 release build seems to work. Windows... partially works in x64 release (only function call invokation).

All (Mac, Windows and Linux) are running on bcc 0.133.

OS Release x86 Debug x86 Release x64 Debug x64
Windows 10 OK OK FAIL (Method call) FAIL
Linux Cent OS 7 (32 Bit) OK OK -- --
Linux Mint 19.3 (64 Bit) -- -- OK FAIL
Linux Mint 20.3 (64 Bit) -- -- OK FAIL
Mac OS X Monterey (64 Bit) -- -- OK FAIL

Example Screenshots for Windows and Mac:

image

image

image

image

@GWRon
Copy link
Contributor Author

GWRon commented Jul 23, 2022

I added some "prints" to check what happens inside the reflection-code to invoke a function ... this broke it for "x64 release" too (so it no longer passed the right number to the function call)

Simply adding this print there:

	Default
print "_CallFunction: " + argTypes.length
		If typeid.ExtendsType(PointerTypeId) Or typeid.ExtendsType(FunctionTypeId) Then
?Not ptr64
			Select argTypes.length

Replacing the print with an "Local x:Int = argTypes.length" and the function receives the correct number, but with print it becomes

_CallFunction: 1
HelloFunc() f = 9.18340949e-41

Ok, so I checked what is needed to bork the result:

'No change
'Local x:Int = argTypes.length
'No change
'Local x:Long = Long(argTypes.length)
'borks result
'Local x:String = String(argTypes.length)
'borks result
'print "_CallFunction: " + argTypes.length

So it works for casts to Long or Int - but when casting it to a String, it somehow affects the stuff behind that code.

Dunno if that helps... and as said, this is only tested onr x64 linux

@GWRon
Copy link
Contributor Author

GWRon commented Jul 23, 2022

What else changes that value?

'No change
'print "hello"
'borks result
myprintf(1)

with myprintf being added to reflection.c:

void myprintf(int n) {
	printf("%d\n", n);
	fflush(stdout);
}

And when replacing that with simply printing "hello", then I get a "0.000000" instead of a one like "9.14767638e-41"

void myprintf(int n) {
	printf("hello\n");
	fflush(stdout);
}

Some memory address/offsets borked?


Edit:

			Select argTypes.length
				Case 0
					Local f:Byte Ptr()=p
					Return String.Fromlong(Long f())
				Case 1
print " --- 1 argument: " + p
					Local f:Byte Ptr(p0:Byte Ptr)=p
					Return String.Fromlong(Long f(q[0]))

Simply printing the memory address of the function will lead to the call returning a different value:

 --- 1 argument: 4214192
HelloFunc() f = -nan

and without the print:

HelloFunc() f = 9.18340949e-41

Edit:
This is surely connected to #147

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant