Page 1 of 1
Duktape JS
Posted: Sun Sep 05, 2021 9:05 pm
by the.weavster
I'm trying to get
duktape to work with PB but I'm not getting very far. I can push a PB function on the stack and call it but I can't seem to expose it to JS
Windows binaries are
here
This works:
Code: Select all
Enumeration
#duk_dll
EndEnumeration
Define.i lResult = OpenLibrary(#duk_dll, "libduktape.dll")
If Not lResult
MessageRequester("Error", "Failed to open library", 0)
End
EndIf
Procedure.i show_text(*ctx)
Define.i b
b = CallCFunction(#duk_dll, "duk_get_string", *ctx, 0)
Debug PeekS(b, -1, #PB_UTF8)
ProcedureReturn 0
EndProcedure
*ctx = CallCFunction(#duk_dll, "duk_create_heap", #Null, #Null, #Null, #Null, #Null)
CallCFunction(#duk_dll, "duk_push_c_function", *ctx, @show_text(), 1)
CallCFunction(#duk_dll, "duk_push_string", *ctx, UTF8("Hello"))
CallCFunction(#duk_dll, "duk_call", *ctx, 1)
CallCFunction(#duk_dll, "duk_destroy_heap", *ctx)
But this doesn't:
Code: Select all
Enumeration
#duk_dll
EndEnumeration
Define.i lResult = OpenLibrary(#duk_dll, "libduktape.dll")
If Not lResult
MessageRequester("Error", "Failed to open library", 0)
End
EndIf
Procedure.i show_text(*ctx)
Define.i b
b = CallCFunction(#duk_dll, "duk_get_string", *ctx, 0)
Debug PeekS(b, -1, #PB_UTF8)
ProcedureReturn 0
EndProcedure
*ctx = CallCFunction(#duk_dll, "duk_create_heap", #Null, #Null, #Null, #Null, #Null)
CallCFunction(#duk_dll, "duk_push_c_function", *ctx, @show_text(), 1)
CallCFunction(#duk_dll, "duk_put_global_string", *ctx, UTF8("foo"))
CallCFunction(#duk_dll, "duk_eval_string", *ctx, UTF8("foo('Hello');"))
CallCFunction(#duk_dll, "duk_destroy_heap", *ctx)
If anybody could point me in the right direction I'd be grateful.
Re: Duktape JS
Posted: Mon Sep 06, 2021 7:51 am
by infratec
Example 1:
Code: Select all
PrototypeC.i Prototype_duk_create_heap(*alloc_func, *realloc_func, *free_func, *heap_udata, *fatal_handler)
PrototypeC Prototype_duk_destroy_heap(*ctx)
PrototypeC.i Prototype_duk_get_string(*ctx, idx.i)
PrototypeC.i Prototype_duk_push_string(*ctx, str.p-utf8)
PrototypeC.i Prototype_duk_push_c_function(*ctx, *func, nargs.i)
PrototypeC Prototype_duk_call(*ctx, nargs.i)
Global duk_create_heap.Prototype_duk_create_heap
Global duk_destroy_heap.Prototype_duk_destroy_heap
Global duk_get_string_.Prototype_duk_get_string
Global duk_push_string.Prototype_duk_push_string
Global duk_push_c_function.Prototype_duk_push_c_function
Global duk_call.Prototype_duk_call
Procedure.s duk_get_string(*ctx, idx.i)
Protected Result$, *String
*String = duk_get_string_(*ctx, idx.i)
If *String
Result$ = PeekS(*String, -1, #PB_UTF8)
EndIf
ProcedureReturn Result$
EndProcedure
Define.i duk_library
duk_library = OpenLibrary(#PB_Any, "libduktape.dll")
If Not duk_library
MessageRequester("Error", "Failed to open library", 0)
End
EndIf
duk_create_heap = GetFunction(duk_library, "duk_create_heap")
duk_destroy_heap = GetFunction(duk_library, "duk_destroy_heap")
duk_get_string_ = GetFunction(duk_library, "duk_get_string")
duk_push_string = GetFunction(duk_library, "duk_push_string")
duk_push_c_function = GetFunction(duk_library, "duk_push_c_function")
duk_call = GetFunction(duk_library, "duk_call")
ProcedureC.i show_text(*ctx)
Debug duk_get_string(*ctx, 0)
ProcedureReturn 0
EndProcedure
*ctx = duk_create_heap(#Null, #Null, #Null, #Null, #Null)
If *ctx
duk_push_c_function(*ctx, @show_text(), 1)
duk_push_string(*ctx, "Hello")
duk_call(*ctx, 1)
duk_destroy_heap(*ctx)
EndIf
Example 2:
Code: Select all
#DUK_COMPILE_EVAL = (1 << 3)
#DUK_COMPILE_NOSOURCE = (1 << 9)
#DUK_COMPILE_STRLEN = (1 << 10)
#DUK_COMPILE_NOFILENAME = (1 << 11)
PrototypeC.i Prototype_duk_create_heap(*alloc_func, *realloc_func, *free_func, *heap_udata, *fatal_handler)
PrototypeC Prototype_duk_destroy_heap(*ctx)
PrototypeC.i Prototype_duk_get_string(*ctx, idx.i)
PrototypeC.i Prototype_duk_push_string(*ctx, str.p-utf8)
PrototypeC.i Prototype_duk_push_c_function(*ctx, *func, nargs.i)
PrototypeC Prototype_duk_call(*ctx, nargs.i)
PrototypeC.i Prototype_duk_put_global_string(*ctx, key.p-utf8)
PrototypeC.i Prototype_duk_eval_raw(*ctx, *src_buffer, src_length.i, flags.i)
Global duk_create_heap.Prototype_duk_create_heap
Global duk_destroy_heap.Prototype_duk_destroy_heap
Global duk_get_string_.Prototype_duk_get_string
Global duk_push_string.Prototype_duk_push_string
Global duk_push_c_function.Prototype_duk_push_c_function
Global duk_call.Prototype_duk_call
Global duk_put_global_string.Prototype_duk_put_global_string
Global duk_eval_raw.Prototype_duk_eval_raw
Procedure duk_eval_string(*ctx, src.s)
Protected *src
*src = UTF8(src)
duk_eval_raw(*ctx, *src, 0, 0 | #DUK_COMPILE_EVAL | #DUK_COMPILE_NOSOURCE | #DUK_COMPILE_STRLEN | #DUK_COMPILE_NOFILENAME)
FreeMemory(*src)
EndProcedure
Procedure.s duk_get_string(*ctx, idx.i)
Protected Result$, *String
*String = duk_get_string_(*ctx, idx.i)
If *String
Result$ = PeekS(*String, -1, #PB_UTF8)
EndIf
ProcedureReturn Result$
EndProcedure
Define.i duk_library
duk_library = OpenLibrary(#PB_Any, "libduktape.dll")
If Not duk_library
MessageRequester("Error", "Failed to open library", 0)
End
EndIf
duk_create_heap = GetFunction(duk_library, "duk_create_heap")
duk_destroy_heap = GetFunction(duk_library, "duk_destroy_heap")
duk_get_string_ = GetFunction(duk_library, "duk_get_string")
duk_push_string = GetFunction(duk_library, "duk_push_string")
duk_push_c_function = GetFunction(duk_library, "duk_push_c_function")
duk_call = GetFunction(duk_library, "duk_call")
duk_put_global_string = GetFunction(duk_library, "duk_put_global_string")
duk_eval_raw = GetFunction(duk_library, "duk_eval_raw")
ProcedureC.i show_text(*ctx)
Debug duk_get_string(*ctx, 0)
ProcedureReturn 0
EndProcedure
*ctx = duk_create_heap(#Null, #Null, #Null, #Null, #Null)
duk_push_c_function(*ctx, @show_text(), 1)
duk_put_global_string(*ctx, "foo")
duk_eval_string(*ctx, "foo('Hello');")
duk_destroy_heap(*ctx)
Re: Duktape JS
Posted: Mon Sep 06, 2021 8:10 am
by the.weavster
Thank you @infratec
I had just discovered not all the functions detailed in the API actually existed in the DLL but I still don't think I'd have figured it out without your help.
Re: Duktape JS
Posted: Mon Sep 06, 2021 8:16 am
by infratec
You should always use Prototypes.
Because then you can do things like
Code: Select all
duk_put_global_string(*ctx, "foo")
WIth p-utf8 the compiler does the necesarry conversion.
Re: Duktape JS
Posted: Mon Sep 06, 2021 9:00 am
by Caronte3D
I don't understand what this Duktape JS is used for

Can you tell me some examples of use?
Thanks!

Re: Duktape JS
Posted: Mon Sep 06, 2021 9:35 am
by the.weavster
Caronte3D wrote: Mon Sep 06, 2021 9:00 am
I don't understand what this Duktape JS is used for

Can you tell me some examples of use?
Thanks!
In my case I have a web server I've coded in PB and I'd like to have some scripting capability built in.
Re: Duktape JS
Posted: Mon Sep 06, 2021 10:03 am
by infratec
I would prefer lua if js is not needed.
Re: Duktape JS
Posted: Mon Sep 06, 2021 10:55 am
by the.weavster
infratec wrote: Mon Sep 06, 2021 10:03 am
I would prefer lua if js is not needed.
This is day 1 of my pondering so I'm still very persuadable
I'm only really looking at JS because of JSON rather than any fondness for the language. I was also influenced by the fact duktape just wants null terminated UTF8 strings which I thought would make passing data back and forth to PB easier. Is there a Lua library (preferably pure Lua) for converting a table to JSON?
If you have an example demonstrating opening a Lua script, exposing a PB function to Lua and passing the script's output back to PB I'd really appreciate it.
Re: Duktape JS
Posted: Mon Sep 06, 2021 11:41 am
by infratec
Re: Duktape JS
Posted: Mon Sep 06, 2021 2:16 pm
by Dadido3
Regarding a JSON lib for lua. This one quite fast and small:
https://github.com/rxi/json.lua
You just have to figure out how to get it to work with require. Lua has some rules where it searches for files that are "required", so either put that file into the same folder as the script you are calling it from, or put it in another folder and utilize
to tell lua where to look for those files.
Re: Duktape JS
Posted: Mon Sep 06, 2021 4:02 pm
by the.weavster
Thanks @Dadido3
I've decided to stick with duktape, once @infratec's demo got me up and running I was very quickly able to implement a proof of concept that gives me the functionality I want to incorporate into my server.
Re: Duktape JS
Posted: Tue Sep 07, 2021 10:38 am
by Caronte3D
Would be nice if you share the source code of your server with DucktapeJS when you finish it
I'm curious about the use
