1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 funcs
= make(map[uint32]func(Value
, []Value
) interface{})
17 var _ Wrapper
= Func
{} // Func must implement Wrapper
19 // Func is a wrapped Go function to be called by JavaScript.
21 Value
// the JavaScript function that invokes the Go function
25 // FuncOf returns a wrapped function.
27 // Invoking the JavaScript function will synchronously call the Go function fn with the value of JavaScript's
28 // "this" keyword and the arguments of the invocation.
29 // The return value of the invocation is the result of the Go function mapped back to JavaScript according to ValueOf.
31 // A wrapped function triggered during a call from Go to JavaScript gets executed on the same goroutine.
32 // A wrapped function triggered by JavaScript's event loop gets executed on an extra goroutine.
33 // Blocking operations in the wrapped function will block the event loop.
34 // As a consequence, if one wrapped function blocks, other wrapped funcs will not be processed.
35 // A blocking function should therefore explicitly start a new goroutine.
37 // Func.Release must be called to free up resources when the function will not be used any more.
38 func FuncOf(fn
func(this Value
, args
[]Value
) interface{}) Func
{
46 Value
: jsGo
.Call("_makeFuncWrapper", id
),
50 // Release frees up resources allocated for the function.
51 // The function must not be invoked after calling Release.
52 func (c Func
) Release() {
58 // setEventHandler is defined in the runtime package.
59 func setEventHandler(fn
func())
62 setEventHandler(handleEvent
)
66 cb
:= jsGo
.Get("_pendingEvent")
70 jsGo
.Set("_pendingEvent", Null())
72 id
:= uint32(cb
.Get("id").Int())
73 if id
== 0 { // zero indicates deadlock
80 Global().Get("console").Call("error", "call to released function")
84 this
:= cb
.Get("this")
85 argsObj
:= cb
.Get("args")
86 args
:= make([]Value
, argsObj
.Length())
88 args
[i
] = argsObj
.Index(i
)
90 result
:= f(this
, args
)
91 cb
.Set("result", result
)