flexprop
flexprop copied to clipboard
I'm not sure if this is a bug...
Thanks for fixing all the bugs related to method pointers in Spin2.
During my testing of 5.9.21 I ran into the following issue:

My understading is that method_pointers[0]
contains an address that refers to a hub memory location, and that hub memory is 8 bits wide. That is why in Propeller Tool I use LONG[method_pointers][0]
to make sure to access all 32 bits of the method pointer. In Propeller Tool if I dont use LONG[]
it does not recognize the return address as a method pointer.
However in FlexProp
LONG[method_pointers][0](1,2)
does not work and the syntax
method_pointers[0](1,2)
does.
method_pointers is declared as a LONG variable in the VAR section, so there should be no need to use LONG[method_pointers] in either compiler. On the other hand it should probably work, so I'll look into it.
When you say "in Propeller Tool if I don't use LONG it does not recognize the return address as a method pointer" what error does Propeller Tool produce? And by "return address" do you mean the expression method_pointers[0]
?
Actually no, looking at this in more detail, LONG[method_pointers][0]
is not at all the same as method_pointers[0]
. The first one adds an additional level of indirection, that is, it fetches the value stored at method_pointers, and then the LONG[] fetches the value stored in memory there. That isn't expected to work. I don't understand why it would in PNut.
I just tried with PNut v37, and the following program does what I would expect:
CON
_clkfreq = 160_000_000
VAR
long methods[3]
long method_pointers[3]
PUB main()|f
init()
method_pointers[0] := methods[0]
debug(uhex(methods[0]), uhex(long[methods][0]))
function1(1, 0)
methods[0](1, 1)
method_pointers[0](1, 2)
function2(2, 0)
methods[1](2, 1)
function3(3, 0)
methods[2](3, 1)
PUB init()
methods[0] := @function1
methods[1] := @function2
methods[2] := @function3
PUB function1(a, b) : val
val := 1
DEBUG(udec(val), udec(b))
PUB function2(a, b) : val
val := 2
DEBUG(udec(val), udec(b))
PUB function3(a, b) : val
val := 3
DEBUG(udec(val), udec(b))
So you should never use LONG[method_pointers][0].
Ha! I did not test that. However my use case scenario is the following (using Propeller Tool):
Main application object that has two objects:
- Services Object - Contains methods common to all other objects
- Child Object - Object that uses the services provided by the Services object of the parent
Note: This test code is an over simplification of my use case. I have 10+ child objects that all use the methods provided by a service object wrapped by the parent object. But this illustrates the issue with the syntax.
''Main application object
CON
_clkfreq = 200_000_000
OBJ
services : "test_services_obj"
child : "test_method_pointer_obj"
VAR
LONG methods[3]
PUB main()|f
init()
''This works at this level
methods[0]()
''But when invoking them in a child object...
''(see comments in test_method_pointer_obj)
'Pass pointer to child object
child.set_methods_pointer(@methods)
'Now invoke one of the service methods from the child
child.call_service_method(0)
PUB init()
methods[0] := @services.method1
methods[1] := @services.method2
methods[2] := @services.method3
The services object:
''Services object
PUB null()
PUB method1():r
r := 1
debug(udec(r))
PUB method2():r
r := 2
debug(udec(r))
PUB method3():r
r := 3
debug(udec(r))
and the child object
''Child object
VAR
LONG methods_pointer
PUB set_methods_pointer(ptr)
methods_pointer := ptr
PUB call_service_method(m)
debug("services method ", udec(m))
'This crashes
' methods_pointer[m]()
'This does not crash
LONG[methods_pointer][m]()
The syntax you point out works at the main object level, however when calling them from another child it seems to require the LONG[]
syntax.
In FlexProp, calling methods_pointer[m]()
in the child object does not work, but it doesn't crash. However trying to call LONG[methods_pointer[m]()
throws an error.
Ah, I see. I'll try to fix this. For now you can work around it with:
PUB call_service_method(m) | f
f := LONG[methods_pointer][m];
f()
Great! I will probably be able to port my project to FlexProp once these method pointers compatibility issues are solved. Thanks.
This is fixed in flexprop 5.9.22-beta.