Skip to content

Commit

Permalink
done
Browse files Browse the repository at this point in the history
  • Loading branch information
timoshisa committed Jan 24, 2023
1 parent 0194f73 commit 5fa6663
Show file tree
Hide file tree
Showing 12 changed files with 1,043 additions and 710 deletions.
7 changes: 6 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@ module github.com/grexie/isolates

go 1.17

require github.com/grexie/refutils v0.1.1
require (
github.com/grexie/refutils v0.1.1
github.com/huandu/go-tls v1.0.1
)

require golang.org/x/sys v0.0.0-20200107162124-548cf772de50 // indirect
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
github.com/grexie/refutils v0.1.1 h1:106Cml8XyqD9eiBNg9lNurvfe6IuvuydS1YJEc9cs4o=
github.com/grexie/refutils v0.1.1/go.mod h1:jnl4Ft2YXrxwMKPiBrHYwMO6tAEtFzn6M0oHBEgBWRA=
github.com/huandu/go-tls v1.0.1 h1:vdRzdlUFlqXWy0cfy5lVvHgUf6rt8QwEA/gCOCzsDX8=
github.com/huandu/go-tls v1.0.1/go.mod h1:WeItecBdaIdUBRb7cSMMk+rq41iFKhf6Q9mDRDpbdec=
golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA=
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
136 changes: 77 additions & 59 deletions v8_callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package isolates
import "C"

import (
"context"
"fmt"
"runtime/debug"
"strconv"
Expand All @@ -22,66 +23,76 @@ type callbackArgs struct {
Holder *Value
}

func functionCallbackHandler(context *Context, info C.CallbackInfo, args callbackArgs, functionId refutils.ID) (*Value, error) {
functionRef := context.functions.Get(functionId)
if functionRef == nil {
panic(fmt.Errorf("missing function pointer during callback for function #%d", functionId))
}
function := (functionRef.(*functionInfo)).Function
func functionCallbackHandler(ctx context.Context, v8Context *Context, info C.CallbackInfo, args callbackArgs, functionId refutils.ID) (*Value, error) {
return v8Context.isolate.Sync(ctx, func(ctx context.Context) (*Value, error) {
functionRef := v8Context.functions.Get(functionId)
if functionRef == nil {
panic(fmt.Errorf("missing function pointer during callback for function #%d", functionId))
}
function := (functionRef.(*functionInfo)).Function

argc := int(info.argc)
pargv := (*[1 << (maxArraySize - 18)]C.ValueTuple)(unsafe.Pointer(info.argv))[:argc:argc]
argv := make([]*Value, argc)
for i := 0; i < argc; i++ {
argv[i] = context.newValue(pargv[i].value, pargv[i].kinds)
}
argc := int(info.argc)
pargv := (*[1 << (maxArraySize - 18)]C.ValueTuple)(unsafe.Pointer(info.argv))[:argc:argc]
argv := make([]*Value, argc)
for i := 0; i < argc; i++ {
argv[i] = v8Context.newValue(pargv[i].value, pargv[i].kinds)
}

return function(FunctionArgs{
context,
args.Caller,
args.This,
args.Holder,
bool(info.isConstructCall),
argv,
return function(FunctionArgs{
ctx,
v8Context,
args.Caller,
args.This,
args.Holder,
bool(info.isConstructCall),
argv,
})
})

}

func getterCallbackHandler(context *Context, info C.CallbackInfo, args callbackArgs, accessorId refutils.ID) (*Value, error) {
accessorRef := context.accessors.Get(accessorId)
if accessorRef == nil {
panic(fmt.Errorf("missing function pointer during callback for getter #%d", accessorId))
}
getter := (accessorRef.(*accessorInfo)).Getter

return getter(GetterArgs{
context,
args.Caller,
args.This,
args.Holder,
C.GoStringN(info.key.data, info.key.length),
func getterCallbackHandler(ctx context.Context, v8Context *Context, info C.CallbackInfo, args callbackArgs, accessorId refutils.ID) (*Value, error) {
return v8Context.isolate.Sync(ctx, func(ctx context.Context) (*Value, error) {
accessorRef := v8Context.accessors.Get(accessorId)
if accessorRef == nil {
panic(fmt.Errorf("missing function pointer during callback for getter #%d", accessorId))
}
getter := (accessorRef.(*accessorInfo)).Getter

return getter(GetterArgs{
ctx,
v8Context,
args.Caller,
args.This,
args.Holder,
C.GoStringN(info.key.data, info.key.length),
})
})
}

func setterCallbackHandler(context *Context, info C.CallbackInfo, args callbackArgs, accessorId refutils.ID) (*Value, error) {
accessorRef := context.accessors.Get(accessorId)
if accessorRef == nil {
panic(fmt.Errorf("missing function pointer during callback for setter #%d", accessorId))
}
setter := (accessorRef.(*accessorInfo)).Setter

v := context.newValue(info.value.value, info.value.kinds)

return nil, setter(SetterArgs{
context,
args.Caller,
args.This,
args.Holder,
C.GoStringN(info.key.data, info.key.length),
v,
func setterCallbackHandler(ctx context.Context, v8Context *Context, info C.CallbackInfo, args callbackArgs, accessorId refutils.ID) (*Value, error) {
return v8Context.isolate.Sync(ctx, func(ctx context.Context) (*Value, error) {
accessorRef := v8Context.accessors.Get(accessorId)
if accessorRef == nil {
panic(fmt.Errorf("missing function pointer during callback for setter #%d", accessorId))
}
setter := (accessorRef.(*accessorInfo)).Setter

v := v8Context.newValue(info.value.value, info.value.kinds)

return nil, setter(SetterArgs{
ctx,
v8Context,
args.Caller,
args.This,
args.Holder,
C.GoStringN(info.key.data, info.key.length),
v,
})
})
}

var callbackHandlers = map[C.CallbackType]func(*Context, C.CallbackInfo, callbackArgs, refutils.ID) (*Value, error){
var callbackHandlers = map[C.CallbackType]func(context.Context, *Context, C.CallbackInfo, callbackArgs, refutils.ID) (*Value, error){
C.kFunctionCallback: functionCallbackHandler,
C.kGetterCallback: getterCallbackHandler,
C.kSetterCallback: setterCallbackHandler,
Expand All @@ -97,10 +108,11 @@ func callbackHandler(info *C.CallbackInfo) (r C.ValueTuple) {

ids := C.GoStringN(info.id.data, info.id.length)

parts := strings.SplitN(ids, ":", 3)
parts := strings.SplitN(ids, ":", 4)
isolateId, _ := strconv.Atoi(parts[0])
contextId, _ := strconv.Atoi(parts[1])
callbackId, _ := strconv.Atoi(parts[2])
executionContextId, _ := strconv.Atoi(parts[3])

isolateRef := isolateRefs.Get(refutils.ID(isolateId))
if isolateRef == nil {
Expand All @@ -112,7 +124,13 @@ func callbackHandler(info *C.CallbackInfo) (r C.ValueTuple) {
if contextRef == nil {
panic(fmt.Errorf("missing context pointer during callback for context #%d", contextId))
}
context := contextRef.(*Context)
v8Context := contextRef.(*Context)

executionContextRef := executionContextRefs.Get(refutils.ID(executionContextId))
if executionContextRef == nil {
panic(fmt.Errorf("missing execution context pointer during callback for execution context #%d", executionContextId))
}
ctx := executionContextRef.(*ExecutionContext)

defer func() {
if v := recover(); v != nil {
Expand All @@ -130,16 +148,16 @@ func callbackHandler(info *C.CallbackInfo) (r C.ValueTuple) {
int(info.caller.column),
}

self, _ := context.newValueFromTuple(info.self)
holder, _ := context.newValueFromTuple(info.holder)
self, _ := v8Context.newValueFromTuple(ctx.ctx, info.self)
holder, _ := v8Context.newValueFromTuple(ctx.ctx, info.holder)

args := callbackArgs{context, callerInfo, self, holder}
v, err := callbackHandlers[info._type](context, *info, args, refutils.ID(callbackId))
args := callbackArgs{v8Context, callerInfo, self, holder}
v, err := callbackHandlers[info._type](ctx.ctx, v8Context, *info, args, refutils.ID(callbackId))

if err := isolate.lock(); err != nil {
if locked, err := isolate.lock(ctx.ctx); err != nil {
return C.ValueTuple{}
} else {
defer isolate.unlock()
} else if locked {
defer isolate.unlock(ctx.ctx)
}

if err != nil {
Expand All @@ -150,7 +168,7 @@ func callbackHandler(info *C.CallbackInfo) (r C.ValueTuple) {

if v == nil {
return C.ValueTuple{}
} else if v.context.isolate.pointer != context.isolate.pointer {
} else if v.context.isolate.pointer != v8Context.isolate.pointer {
m := fmt.Sprintf("callback returned a value from another isolate")
cerr := C.Error{data: C.CString(m), length: C.int(len(m))}
return C.ValueTuple{error: cerr}
Expand Down
Loading

0 comments on commit 5fa6663

Please sign in to comment.