generate new functions at runtime?

General FreeBASIC programming questions.
Post Reply
Merick
Posts: 1038
Joined: May 28, 2007 1:52

generate new functions at runtime?

Post by Merick »

Other thatn using some sort of jit lib, is there any way to generate new functions during runtime?
notthecheatr
Posts: 1759
Joined: May 23, 2007 21:52
Location: Cut Bank, MT
Contact:

Post by notthecheatr »

It would be pretty hard, and I think there are probably easier ways of doing it... perhaps using a scripting language. I don't know anything about lua, but everyone is always talking about it - maybe that'll do what you need.
Merick
Posts: 1038
Joined: May 28, 2007 1:52

Post by Merick »

lol, I'm already using lua. My problem is that with a couple of the libs I'm using you need to be able to use callback functions to make full use of all the features, but I'm having trouble trying to figure out how to use a lua function for the callback. What I was thinking if I could create function that would generate a new FB function at runtime, or else somehow copy a function but with a few changes, then I could save a pointer to that function as a userdata in the lua vm, which could then be passed back to the function that uses the callbacks
notthecheatr
Posts: 1759
Joined: May 23, 2007 21:52
Location: Cut Bank, MT
Contact:

Post by notthecheatr »

At run-time you're no longer in the realm of FB, now you're in the realm of "binary opcodes" as well as "relocatable partitions" meaning it's really hard to do that type of thing...
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Post by Richard »

Compile time is compile time, run time is run time and never the twain shall meet. You cannot run the .exe file created until the compiler closes it. This messy way gives you the ability to create runtime functions and use pipes or files to return results.

Code: Select all

 ' Pack an expression into an envelope, compile, run then get the result
Dim As String expression = " 4 * atn(1) "        ' a test expression
Dim As String compiler = $"C:\FreeBASIC\fbc.exe "
' create a FreeBASIC program
Open "scratch.bas" For Output As #1 
Print #1, "open "; """scratch.txt"""; " for output as #2"
Print #1, "print #2, "; expression
Print #1, "close #2"
Close #1
' compile the scratch.bas program file 
If Exec( compiler, " scratch.bas" ) <> 0 Then Print "Compile failure" : sleep 
' run the exe program generated
If Exec( "scratch.exe", "" ) <> 0 Then Print "Execute failure" : sleep
' now get the result from the output file
Open "scratch.txt" For Input As #1
Dim As String result
Line Input #1, result
Close #1
Print "output = ";result
Sleep
subxero
Posts: 142
Joined: May 28, 2005 22:18
Location: Quincy, IL
Contact:

Post by subxero »

I, too, would love to know how to call a Lua function from a running FB program. For example, I have an object. It is created by a script, and when the user clicks on the object, I want a Lua routine to run. How is this done?
Merick
Posts: 1038
Joined: May 28, 2007 1:52

Post by Merick »

subxero, what I'm talking about here isn't just running a lua function, but using it as a callback. Just running a function is actually pretty easy.

...or at least, it's supposed to be easy, but I just tried writing a small example of how to use pcall to run a lua function but I couldn't get it to work properly :(
notthecheatr
Posts: 1759
Joined: May 23, 2007 21:52
Location: Cut Bank, MT
Contact:

Post by notthecheatr »

Assuming you already know what's going to go in your functions (I know of no program that generates functions without beforehand knowing what goes in them) can't you just compile all the possible functions you would want to use, then choose based on a pointer to one of them?

I fail to understand exactly what the problem is - you should be able to pass a function pointer to lua and be done with it.

But then, I don't use lua, don't know anything about lua, so I'm no expert. Could you try to explain the problem in terms I could understand?
Merick
Posts: 1038
Joined: May 28, 2007 1:52

Post by Merick »

Take this example:

test.lua:

Code: Select all

function add_numbers (a,b)
	return  a+b
end
test.bas:

Code: Select all

#include once "lua/lua.bi"
#include once "lua/lualib.bi"
#include once "lua/lauxlib.bi"

dim shared L as lua_State ptr 
dim as integer i, ret

L = lua_open( )             'create a lua state
luaL_openlibs(L)            'open the Lua standard libraries

if lual_dofile(L, "test.lua") <> 0 then ' load the test.lua script
	print *lua_tostring(L, -1)
	sleep
	lua_close(L)
	End
endif

lua_settop(L,0) ' clears the stack

lua_getglobal(L, "add_numbers") 'retrieves the add_numbers function
lua_pushnumber(L, 10) ' push 10 onto the stack as the first arg
lua_pushnumber(L, 25) ' push 25 onto the stack as the second arg
lua_call(L, 2, 1) ' calls the function with the args that have been pushed

ret = lual_checkinteger(L,1) 'checks if the return from the function is an integer, and if true assigns the value to ret  

? ret

sleep

lua_close( L )
lua_getglobal takes a string argument with the name of the function from a lua script. When using a library with callbacks, the functions which use the callback functions usually take only a pointer to the callback function, and supplies the arguments to that function itself. I need to find a way to make the callback function access the correct lua functions, but I can't really hardcode that into the Fb side of things without limiting what can be done with it.
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Post by Stonemonkey »

This isn't really much to do with this thread but while i was reading it I wondered if I could do this:

Code: Select all

'integer averaging function data
data &h83e58955,&h45c704ec,&h000000fc,&h0c458b00,&hd1084503,&hfc4589f8
data &h89fc458b,&h08c25dec,&h900deb00

dim average as function(a as integer,b as integer) As Integer=callocate(9*4)
for i as integer=0 to 8
    read *(cast(integer pointer,average)+i)
next

print average(42,120)

sleep
end
There might be some garbage at the end of the data so it might be shorter, i dunno.
RockTheSchock
Posts: 252
Joined: Mar 12, 2006 16:25

dll Generation at runtime

Post by RockTheSchock »

You can generate with the freebasic compiler dll's and include them dynamically at runtime. But you must bundle your software with the FBCompiler and then your Software has to be put under GPL, too, if it depends on that feature. (I am not totally sure if this interpretation of the GPL is right.)

The dll within a specific directory could be loaded at runtime.
The only restriction if you want to keep it simple, is to have hard coded interfaces. That means: the declaration of specific public functions und subs are given and cannot be changed. Most programms implement a plugin system like that.

Some example code using dlls:

fbc -s gui -dll -export "dll1.bas"

Code: Select all

Function AddNumbers cdecl Alias "AddNumbers" _
  ( _
    ByVal operand1 As Integer, ByVal operand2 As Integer _
  ) As Integer Export

  Return operand1 + operand2

End Function
fbc -s gui -dll -export "dll2.bas"

Code: Select all

Function AddNumbers cdecl Alias "AddNumbers" _
  ( _
    ByVal operand1 As Integer, ByVal operand2 As Integer _
  ) As Integer Export

  Return Cint(Str(operand1) + str(operand2))

End Function
fbc -s console "DLLTesting.bas"

Code: Select all

Dim AddNumbers As Function ( ByVal operand1 As Integer, ByVal operand2 As Integer ) As Integer

Dim As Any Ptr hndl, hnd2

hndl=DyLibLoad("dll1.dll")
hnd2=DyLibLoad("dll2.dll")

'' find the proc address (case matters!)
AddNumbers = DyLibSymbol( hndl, "AddNumbers" )

'' then call it..
Print "1 + 2 ="; AddNumbers( 1, 2 )

AddNumbers = DyLibSymbol( hnd2, "AddNumbers" )
Print "1 + 2 ="; AddNumbers( 1, 2 )

DyLibFree hndl
DyLibFree hnd2

Sleep

It's not good to have a dll function call in an inner loop. A dll function needs every time it's called much more time then a normal fb function call. Implement expensive inner loop routines in one bigger dll function and call that instead of calling a simple dll function thousand of times. Can someone post a benchmark on this topic?
Post Reply