diff --git a/codegen/main.go b/codegen/main.go new file mode 100644 index 0000000..21d8660 --- /dev/null +++ b/codegen/main.go @@ -0,0 +1,133 @@ +package main + +import ( + "fmt" + "go/ast" + "go/parser" + "go/token" + + "os" + "strings" +) + +func main() { + // generate rtti + // generate typescript types + // generate adapters for different interfaces + // magic comments in the parser + var fileSet token.FileSet + if wd, err := os.Getwd(); err != nil { + panic(err) + } else if packages, err := parser.ParseDir(&fileSet, wd, nil, parser.ParseComments|parser.AllErrors); err != nil { + panic(err) + } else { + tags := []string{"js"} + for _, pkg := range packages { + for f, a := range pkg.Files { + if text, err := os.ReadFile(f); err != nil { + panic(err) + } else { + nodes := FindDeclarationCommentTags(string(text), tags, a) + + for _, node := range nodes { + fmt.Println(node) + } + } + + } + } + } +} + +func FindDeclarationCommentTags(file string, tags []string, a *ast.File) []*TaggedNode { + decls := []*TaggedNode{} + for _, comments := range a.Comments { + declTags := []Tag{} + for _, comment := range comments.List { + for _, tag := range tags { + text := strings.TrimSpace(strings.TrimPrefix(comment.Text, "//")) + if strings.HasPrefix(text, tag+":") { + declTags = append(declTags, Tag{ + Name: tag, + Text: strings.TrimSpace(strings.TrimPrefix(text, tag+":")), + }) + } + } + } + + if len(declTags) > 0 { + endPos := comments.End() + ast.Inspect(a, func(node ast.Node) bool { + if node == nil { + return false + } + + if node.Pos() > endPos && strings.TrimSpace(file[endPos:node.Pos()]) == "" { + record := false + if _, ok := node.(*ast.StructType); ok { + + record = true + } else if _, ok := node.(*ast.File); ok { + record = true + } else if _, ok := node.(*ast.FuncDecl); ok { + record = true + } else if _, ok := node.(*ast.Field); ok { + record = true + } + + if record { + d := &TaggedNode{ + Tags: declTags, + Node: node, + } + decls = append(decls, d) + return false + } else { + endPos = node.End() + } + } + return true + }) + } + + } + + return decls +} + +type Tag struct { + Name string + Text string +} + +func (t *Tag) String() string { + return fmt.Sprintf("%s:%s", t.Name, t.Text) +} + +type TaggedNode struct { + Tags []Tag + Node ast.Node +} + +func (t *TaggedNode) String() string { + out := []string{} + for _, tag := range t.Tags { + out = append(out, tag.String()) + } + + node := "" + + if v, ok := t.Node.(*ast.File); ok { + node = fmt.Sprintf("go package %s", v.Name) + } else if v, ok := t.Node.(*ast.TypeSpec); ok { + node = fmt.Sprintf("go struct %s", v) + } else if v, ok := t.Node.(*ast.Field); ok { + node = fmt.Sprintf("go field %s %s", v.Names[0], v.Type.(*ast.SelectorExpr).Sel) + } else if v, ok := t.Node.(*ast.FuncDecl); ok { + node = fmt.Sprintf("go func %s", v.Name) + } else { + node = fmt.Sprintf("%s", t.Node) + } + + return fmt.Sprintf("%s\n%v", strings.Join(out, "\n"), node) +} diff --git a/go.mod b/go.mod index efbe205..ed3e0e3 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/grexie/isolates -go 1.17 +go 1.18 require ( github.com/grexie/refutils v0.1.1 diff --git a/install-v8.sh b/install-v8.sh deleted file mode 100755 index 06205eb..0000000 --- a/install-v8.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -ex - -V8DIR="$(cd $(dirname ${BASH_SOURCE[0]}) && pwd)" - -WORKDIR=$(mktemp -d) -mkdir -p ${WORKDIR} -pushd ${WORKDIR} >/dev/null - -trap "rm -Rf ${WORKDIR}" EXIT - -shopt -s nocasematch - -go env >libv8.env -. libv8.env -rm libv8.env - -case $GOOS in - darwin) case $GOARCH in - arm64) curl -sSL https://rubygems.org/downloads/libv8-6.3.292.48.1-universal-darwin-18.gem | tar -xf -;; - amd64) curl -sSL https://rubygems.org/downloads/libv8-6.3.292.48.1-x86_64-darwin-18.gem | tar -xf -;; - *) curl -sSL https://rubygems.org/downloads/libv8-6.3.292.48.1-${GOARCH}-darwin-18.gem | tar -xf -;; - esac;; - linux) case $GOARCH in - arm) curl -sSL http://tim-behrsin-portfolio.s3.amazonaws.com/libv8-6.3.292.48.1-arm-linux.gem | tar -xf -;; - amd64) curl -sSL https://rubygems.org/downloads/libv8-6.3.292.48.1-x86_64-linux.gem | tar -xf -;; - *) curl -sSL https://rubygems.org/downloads/libv8-6.3.292.48.1-${GOARCH}-linux.gem | tar -xf -;; - esac;; - *) curl -sSL https://rubygems.org/downloads/libv8-6.3.292.48.1-${GOARCH}-${GOOS}.gem | tar -xf -;; -esac - -tar -xzf data.tar.gz -rm -Rf ${V8DIR}/{include,libv8} -cp -r $(pwd)/vendor/v8/include ${V8DIR}/include -cp -r $(pwd)/vendor/v8/out/*.release ${V8DIR}/libv8 - -popd >/dev/null diff --git a/install/install-v8.sh b/install/install-v8.sh new file mode 100755 index 0000000..db7f305 --- /dev/null +++ b/install/install-v8.sh @@ -0,0 +1,28 @@ +#!/bin/bash -e + +VERSION=$1 +VERSION=${VERSION:-10.4.132.23} +SCHEME=$2 +SCHEME=${SCHEME:-release} + +DIR=/usr/local/include/v8 +rm -Rf ${DIR} +mkdir -p ${DIR} +URL=https://github.com/grexie/v8-builder/releases/download/${VERSION}/v8-headers-${VERSION}.zip +cd ${DIR} +curl -sSL ${URL} -o v8-headers.zip +test -f v8-headers.zip && unzip v8-headers.zip 2>/dev/null >/dev/null && echo "Installed v8-headers-${VERSION}" || true +rm -f v8-headers.zip + +for PLATFORM in macos linux android windows; do + for ARCH in arm64 x64 x86 arm; do + DIR=/usr/local/lib/v8/${ARCH}/${PLATFORM} + rm -Rf ${DIR} + mkdir -p ${DIR} + URL=https://github.com/grexie/v8-builder/releases/download/${VERSION}/v8-${PLATFORM}-${ARCH}-${SCHEME}-${VERSION}.zip + cd ${DIR} + curl -sSL ${URL} -o v8.zip + test -f v8.zip && unzip -j v8.zip 2>/dev/null >/dev/null && echo "Installed v8-${VERSION} for ${PLATFORM} ${ARCH} (${SCHEME})" || true + rm -f v8.zip + done +done \ No newline at end of file diff --git a/install/main.go b/install/main.go new file mode 100644 index 0000000..50faa40 --- /dev/null +++ b/install/main.go @@ -0,0 +1,28 @@ +package main + +import ( + _ "embed" + "io" + "log" + "os" + "os/exec" +) + +//go:embed install-v8.sh +var script []byte + +func main() { + args := append([]string{"-es", "-"}, os.Args[1:]...) + cmd := exec.Command("/bin/bash", args...) + stdout, _ := cmd.StdoutPipe() + stderr, _ := cmd.StderrPipe() + stdin, _ := cmd.StdinPipe() + cmd.Start() + go io.Copy(os.Stdout, stdout) + go io.Copy(os.Stderr, stderr) + stdin.Write(script) + stdin.Close() + if err := cmd.Wait(); err != nil { + log.Println(err) + } +} diff --git a/v8.go b/v8.go index ffc5fde..5cbbeef 100644 --- a/v8.go +++ b/v8.go @@ -1,8 +1,12 @@ package isolates // #include "v8_c_bridge.h" -// #cgo CXXFLAGS: -I${SRCDIR} -I${SRCDIR}/include -g3 -fno-rtti -fpic -std=c++11 -// #cgo LDFLAGS: -pthread -L${SRCDIR}/libv8 -lv8_base -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_libsampler -lv8_nosnapshot +// #cgo CXXFLAGS: -I/usr/local/include/v8 -g3 -fno-rtti -fpic -std=c++20 +// #cgo LDFLAGS: -pthread -lv8_base_without_compiler -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_snapshot +// #cgo darwin,arm64 LDFLAGS: -L/usr/local/lib/v8/arm64/macos +// #cgo darwin,amd64 LDFLAGS: -L/usr/local/lib/v8/x64/macos +// #cgo linux,arm64 LDFLAGS: -L/usr/local/lib/v8/arm64/linux +// #cgo linux,amd64 LDFLAGS: -L/usr/local/lib/v8/x64/linux import "C" import ( diff --git a/v8_c_bridge.cc b/v8_c_bridge.cc index f886693..a6b448d 100644 --- a/v8_c_bridge.cc +++ b/v8_c_bridge.cc @@ -4,14 +4,16 @@ #include #include -extern "C" { +extern "C" +{ Version version = {V8_MAJOR_VERSION, V8_MINOR_VERSION, V8_BUILD_NUMBER, V8_PATCH_LEVEL}; - void v8_Initialize() { - const char* flags = "--expose_gc"; + void v8_Initialize() + { + const char *flags = "--expose_gc"; v8::V8::SetFlagsFromString(flags, strlen(flags)); - platform = v8::platform::CreateDefaultPlatform(); + platform = v8::platform::NewDefaultPlatform().get(); v8::V8::InitializePlatform(platform); v8::V8::Initialize(); return; diff --git a/v8_c_bridge.h b/v8_c_bridge.h index 5fb58cb..d5a843f 100644 --- a/v8_c_bridge.h +++ b/v8_c_bridge.h @@ -95,7 +95,7 @@ extern "C" kDataView, kSharedArrayBuffer, kProxy, - kWebAssemblyCompiledModule, + kWasmModuleObject, kNumKinds, } Kind; @@ -173,7 +173,6 @@ extern "C" extern void v8_FunctionTemplate_Release(ContextPtr ctxptr, FunctionTemplatePtr fnptr); extern void v8_FunctionTemplate_Inherit(ContextPtr ctxptr, FunctionTemplatePtr fnptr, FunctionTemplatePtr parentptr); extern void v8_FunctionTemplate_SetName(ContextPtr pContext, FunctionTemplatePtr pFunction, const char *name); - extern void v8_FunctionTemplate_SetHiddenPrototype(ContextPtr ctxptr, FunctionTemplatePtr fnptr, bool value); extern ValuePtr v8_FunctionTemplate_GetFunction(ContextPtr ctx, FunctionTemplatePtr fn); extern ObjectTemplatePtr v8_FunctionTemplate_PrototypeTemplate(ContextPtr ctxptr, FunctionTemplatePtr function_ptr); extern ObjectTemplatePtr v8_FunctionTemplate_InstanceTemplate(ContextPtr ctxptr, FunctionTemplatePtr function_ptr); diff --git a/v8_c_context.cc b/v8_c_context.cc index 82499df..651f612 100644 --- a/v8_c_context.cc +++ b/v8_c_context.cc @@ -1,96 +1,124 @@ #include "v8_c_private.h" -extern "C" { - ContextPtr v8_Context_New(IsolatePtr pIsolate) { - ISOLATE_SCOPE(static_cast(pIsolate)); +extern "C" +{ + ContextPtr v8_Context_New(IsolatePtr pIsolate) + { + ISOLATE_SCOPE(static_cast(pIsolate)); v8::HandleScope handleScope(isolate); isolate->SetCaptureStackTraceForUncaughtExceptions(true); v8::Local globals = v8::ObjectTemplate::New(isolate); - Context* context = new Context; + Context *context = new Context; context->pointer.Reset(isolate, v8::Context::New(isolate, NULL, globals)); context->isolate = isolate; return static_cast(context); } - ValueTuple v8_Context_Run(ContextPtr pContext, const char* code, const char* filename) { - VALUE_SCOPE(static_cast(pContext)); + ValueTuple v8_Context_Run(ContextPtr pContext, const char *code, const char *filename) + { + VALUE_SCOPE(static_cast(pContext)); v8::TryCatch tryCatch(isolate); tryCatch.SetVerbose(false); filename = filename ? filename : "(no file)"; - v8::Local script = v8::Script::Compile( - v8::String::NewFromUtf8(isolate, code), - v8::String::NewFromUtf8(isolate, filename) - ); + v8::ScriptOrigin origin(isolate, v8::String::NewFromUtf8(isolate, filename) + .ToLocalChecked()); + v8::MaybeLocal script = v8::Script::Compile( + context, + v8::String::NewFromUtf8(isolate, code).ToLocalChecked(), + &origin); - if (script.IsEmpty()) { - return v8_Value_ValueTuple_Error(v8_StackTrace_FormatException(isolate, context, tryCatch)); + if (script.IsEmpty()) + { + return v8_Value_ValueTuple_Error(isolate, v8_StackTrace_FormatException(isolate, context, tryCatch)); } - v8::Local result = script->Run(); + v8::MaybeLocal result = script.ToLocalChecked()->Run(context); - if (result.IsEmpty()) { - return v8_Value_ValueTuple_Error(v8_StackTrace_FormatException(isolate, context, tryCatch)); - } else { - return v8_Value_ValueTuple(isolate, result); + if (result.IsEmpty()) + { + return v8_Value_ValueTuple_Error(isolate, v8_StackTrace_FormatException(isolate, context, tryCatch)); + } + else + { + return v8_Value_ValueTuple(isolate, result.ToLocalChecked()); } } - ValuePtr v8_Context_Global(ContextPtr pContext) { + ValuePtr v8_Context_Global(ContextPtr pContext) + { VALUE_SCOPE(pContext); return new Value(isolate, context->Global()); } - void v8_Context_Release(ContextPtr pContext) { - if (pContext == NULL) { + void v8_Context_Release(ContextPtr pContext) + { + if (pContext == NULL) + { return; } - Context* context = static_cast(pContext); + Context *context = static_cast(pContext); ISOLATE_SCOPE(context->isolate); context->pointer.Reset(); } - ValuePtr v8_Context_Create(ContextPtr pContext, ImmediateValue value) { + ValuePtr v8_Context_Create(ContextPtr pContext, ImmediateValue value) + { VALUE_SCOPE(pContext); - switch (value._type) { - case tARRAY: { + switch (value._type) + { + case tARRAY: + { return new Value(isolate, v8::Array::New(isolate, value._data.length)); } - case tARRAYBUFFER: { + case tARRAYBUFFER: + { v8::Local buffer = v8::ArrayBuffer::New(isolate, value._data.length); - memcpy(buffer->GetContents().Data(), value._data.data, value._data.length); + memcpy(buffer->GetBackingStore()->Data(), value._data.data, value._data.length); return new Value(isolate, buffer); } - case tBOOL: { + case tBOOL: + { return new Value(isolate, v8::Boolean::New(isolate, value._bool == 1)); } - case tDATE: { - return new Value(isolate, v8::Date::New(isolate, value._float64)); + case tDATE: + { + v8::MaybeLocal date = v8::Date::New(context, value._float64); + if (!date.IsEmpty()) + { + return new Value(isolate, date.ToLocalChecked()); + } + break; } - case tFLOAT64: { + case tFLOAT64: + { return new Value(isolate, v8::Number::New(isolate, value._float64)); } // For now, this is converted to a double on entry. // TODO(aroman) Consider using BigInt, but only if the V8 version supports // it. Check to see what V8 versions support BigInt. - case tINT64: { + case tINT64: + { return new Value(isolate, v8::Number::New(isolate, double(value._int64))); } - case tOBJECT: { + case tOBJECT: + { return new Value(isolate, v8::Object::New(isolate)); } - case tSTRING: { + case tSTRING: + { return new Value(isolate, v8::String::NewFromUtf8(isolate, value._data.data, v8::NewStringType::kNormal, value._data.length).ToLocalChecked()); } - case tUNDEFINED: { + case tUNDEFINED: + { return new Value(isolate, v8::Undefined(isolate)); } } diff --git a/v8_c_function.cc b/v8_c_function.cc index da1579c..cfe0fe0 100644 --- a/v8_c_function.cc +++ b/v8_c_function.cc @@ -1,100 +1,108 @@ #include "v8_c_private.h" -extern "C" { - FunctionTemplatePtr v8_FunctionTemplate_New(ContextPtr pContext, const char* id) { +extern "C" +{ + FunctionTemplatePtr v8_FunctionTemplate_New(ContextPtr pContext, const char *id) + { VALUE_SCOPE(pContext); - v8::Local function = v8::FunctionTemplate::New(isolate, FunctionCallbackHandler, v8::String::NewFromUtf8(isolate, id)); + v8::Local function = v8::FunctionTemplate::New(isolate, FunctionCallbackHandler, v8::String::NewFromUtf8(isolate, id).ToLocalChecked()); return static_cast(new FunctionTemplate(isolate, function)); } - void v8_FunctionTemplate_Release(ContextPtr pContext, FunctionTemplatePtr pFunction) { - if (pFunction == NULL || pContext == NULL) { + void v8_FunctionTemplate_Release(ContextPtr pContext, FunctionTemplatePtr pFunction) + { + if (pFunction == NULL || pContext == NULL) + { return; } - ISOLATE_SCOPE(static_cast(pContext)->isolate); + ISOLATE_SCOPE(static_cast(pContext)->isolate); - FunctionTemplate* function = static_cast(pFunction); + FunctionTemplate *function = static_cast(pFunction); delete function; } - void v8_FunctionTemplate_Inherit(ContextPtr pContext, FunctionTemplatePtr pFunction, FunctionTemplatePtr pParentFunction) { + void v8_FunctionTemplate_Inherit(ContextPtr pContext, FunctionTemplatePtr pFunction, FunctionTemplatePtr pParentFunction) + { VALUE_SCOPE(pContext); - v8::Local function = static_cast(pFunction)->Get(isolate); - v8::Local parentFunction = static_cast(pParentFunction)->Get(isolate); + v8::Local function = static_cast(pFunction)->Get(isolate); + v8::Local parentFunction = static_cast(pParentFunction)->Get(isolate); function->Inherit(parentFunction); } - void v8_FunctionTemplate_SetName(ContextPtr pContext, FunctionTemplatePtr pFunction, const char* name) { - VALUE_SCOPE(pContext); - - v8::Local function = static_cast(pFunction)->Get(isolate); - function->SetClassName(v8::String::NewFromUtf8(isolate, name)); - } - - void v8_FunctionTemplate_SetHiddenPrototype(ContextPtr pContext, FunctionTemplatePtr pFunction, bool value) { + void v8_FunctionTemplate_SetName(ContextPtr pContext, FunctionTemplatePtr pFunction, const char *name) + { VALUE_SCOPE(pContext); - v8::Local function = static_cast(pFunction)->Get(isolate); - function->SetHiddenPrototype(value); + v8::Local function = static_cast(pFunction)->Get(isolate); + function->SetClassName(v8::String::NewFromUtf8(isolate, name).ToLocalChecked()); } - ValuePtr v8_FunctionTemplate_GetFunction(ContextPtr pContext, FunctionTemplatePtr pFunction) { + ValuePtr v8_FunctionTemplate_GetFunction(ContextPtr pContext, FunctionTemplatePtr pFunction) + { VALUE_SCOPE(pContext); - v8::Local function = static_cast(pFunction)->Get(isolate); - return new Value(isolate, function->GetFunction()); + v8::Local function = static_cast(pFunction)->Get(isolate); + return new Value(isolate, function->GetFunction(context).ToLocalChecked()); } - ObjectTemplatePtr v8_FunctionTemplate_PrototypeTemplate(ContextPtr pContext, FunctionTemplatePtr pFunction) { + ObjectTemplatePtr v8_FunctionTemplate_PrototypeTemplate(ContextPtr pContext, FunctionTemplatePtr pFunction) + { VALUE_SCOPE(pContext); - v8::Local function = static_cast(pFunction)->Get(isolate); + v8::Local function = static_cast(pFunction)->Get(isolate); return static_cast(new ObjectTemplate(isolate, function->PrototypeTemplate())); } - ObjectTemplatePtr v8_FunctionTemplate_InstanceTemplate(ContextPtr pContext, FunctionTemplatePtr pFunction) { + ObjectTemplatePtr v8_FunctionTemplate_InstanceTemplate(ContextPtr pContext, FunctionTemplatePtr pFunction) + { VALUE_SCOPE(pContext); - v8::Local function = static_cast(pFunction)->Get(isolate); + v8::Local function = static_cast(pFunction)->Get(isolate); return static_cast(new ObjectTemplate(isolate, function->InstanceTemplate())); } - void v8_ObjectTemplate_SetAccessor(ContextPtr pContext, ObjectTemplatePtr pObject, const char* name, const char* id, bool setter) { + void v8_ObjectTemplate_SetAccessor(ContextPtr pContext, ObjectTemplatePtr pObject, const char *name, const char *id, bool setter) + { VALUE_SCOPE(pContext); - v8::Local object = static_cast(pObject)->Get(isolate); - object->SetAccessor(v8::String::NewFromUtf8(isolate, name), GetterCallbackHandler, setter ? SetterCallbackHandler : 0, v8::String::NewFromUtf8(isolate, id), (v8::AccessControl)(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE), v8::PropertyAttribute::None); + v8::Local object = static_cast(pObject)->Get(isolate); + object->SetAccessor(v8::String::NewFromUtf8(isolate, name).ToLocalChecked(), GetterCallbackHandler, setter ? SetterCallbackHandler : 0, v8::String::NewFromUtf8(isolate, id).ToLocalChecked(), (v8::AccessControl)(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE), v8::PropertyAttribute::None); } - void v8_ObjectTemplate_SetInternalFieldCount(ContextPtr pContext, ObjectTemplatePtr pObject, int count) { + void v8_ObjectTemplate_SetInternalFieldCount(ContextPtr pContext, ObjectTemplatePtr pObject, int count) + { VALUE_SCOPE(pContext); - v8::Local object = static_cast(pObject)->Get(isolate); + v8::Local object = static_cast(pObject)->Get(isolate); object->SetInternalFieldCount(count); } - void v8_ObjectTemplate_Release(ContextPtr pContext, ObjectTemplatePtr pObject) { - if (pObject == NULL || pContext == NULL) { + void v8_ObjectTemplate_Release(ContextPtr pContext, ObjectTemplatePtr pObject) + { + if (pObject == NULL || pContext == NULL) + { return; } - ISOLATE_SCOPE(static_cast(pContext)->isolate); + ISOLATE_SCOPE(static_cast(pContext)->isolate); - ObjectTemplate* object = static_cast(pObject); + ObjectTemplate *object = static_cast(pObject); delete object; } - void FunctionCallbackHandler(const v8::FunctionCallbackInfo& info) { + void FunctionCallbackHandler(const v8::FunctionCallbackInfo &info) + { ISOLATE_SCOPE(info.GetIsolate()); v8::HandleScope handleScope(isolate); - String id = v8_String_Create(info.Data()); + String id = v8_String_Create(isolate, info.Data()); CallerInfo callerInfo = v8_StackTrace_CallerInfo(isolate); ValueTuple self = v8_Value_ValueTuple(isolate, info.This()); ValueTuple holder = v8_Value_ValueTuple(isolate, info.Holder()); int argc = info.Length(); ValueTuple argv[argc]; - for (int i = 0; i < argc; i++) { + for (int i = 0; i < argc; i++) + { argv[i] = v8_Value_ValueTuple(isolate, info[i]); } @@ -104,39 +112,47 @@ extern "C" { v8::Unlocker unlocker(isolate); result = callbackHandler(CallbackInfo{ - kFunctionCallback, - id, - callerInfo, - self, - holder, - info.IsConstructCall(), - argc, - argv, - String{NULL, 0}, - NULL - }); + kFunctionCallback, + id, + callerInfo, + self, + holder, + info.IsConstructCall(), + argc, + argv, + String{NULL, 0}, + NULL}); } isolate->Enter(); - if (result.error.data != NULL) { + if (result.error.data != NULL) + { v8::Local error = v8::Exception::Error(v8_String_FromString(isolate, result.error)); isolate->ThrowException(error); - } else if (result.value == NULL) { + } + else if (result.value == NULL) + { info.GetReturnValue().Set(v8::Undefined(isolate)); - } else { - info.GetReturnValue().Set(*static_cast(result.value)); + } + else + { + v8::Local value = static_cast(result.value)->Get(isolate); + + info.GetReturnValue() + .Set(value); } } - void GetterCallbackHandler(v8::Local property, const v8::PropertyCallbackInfo& info) { + void GetterCallbackHandler(v8::Local property, const v8::PropertyCallbackInfo &info) + { ISOLATE_SCOPE(info.GetIsolate()); v8::HandleScope handleScope(isolate); - String id = v8_String_Create(info.Data()); + String id = v8_String_Create(isolate, info.Data()); CallerInfo callerInfo = v8_StackTrace_CallerInfo(isolate); ValueTuple self = v8_Value_ValueTuple(isolate, info.This()); ValueTuple holder = v8_Value_ValueTuple(isolate, info.Holder()); - String key = v8_String_Create(property); + String key = v8_String_Create(isolate, property); ValueTuple result; { @@ -144,39 +160,45 @@ extern "C" { v8::Unlocker unlocker(isolate); result = callbackHandler(CallbackInfo{ - kGetterCallback, - id, - callerInfo, - self, - holder, - false, - 0, - NULL, - key, - NULL - }); + kGetterCallback, + id, + callerInfo, + self, + holder, + false, + 0, + NULL, + key, + NULL}); } isolate->Enter(); - if (result.error.data != NULL) { + if (result.error.data != NULL) + { v8::Local error = v8::Exception::Error(v8_String_FromString(isolate, result.error)); isolate->ThrowException(error); - } else if (result.value == NULL) { + } + else if (result.value == NULL) + { info.GetReturnValue().Set(v8::Undefined(isolate)); - } else { - info.GetReturnValue().Set(*static_cast(result.value)); + } + else + { + v8::Local value = static_cast(result.value)->Get(isolate); + info.GetReturnValue().Set(value); } } - void SetterCallbackHandler(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& info) { + void SetterCallbackHandler(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo &info) + { ISOLATE_SCOPE(info.GetIsolate()); v8::HandleScope handleScope(isolate); - String id = v8_String_Create(info.Data()); + String id = v8_String_Create(isolate, info.Data()); CallerInfo callerInfo = v8_StackTrace_CallerInfo(isolate); ValueTuple self = v8_Value_ValueTuple(isolate, info.This()); ValueTuple holder = v8_Value_ValueTuple(isolate, info.Holder()); - String key = v8_String_Create(property); + String key = v8_String_Create(isolate, property); ValueTuple valueTuple = v8_Value_ValueTuple(isolate, value); ValueTuple result; @@ -185,21 +207,21 @@ extern "C" { v8::Unlocker unlocker(isolate); result = callbackHandler(CallbackInfo{ - kSetterCallback, - id, - callerInfo, - self, - holder, - false, - 0, - NULL, - key, - valueTuple - }); + kSetterCallback, + id, + callerInfo, + self, + holder, + false, + 0, + NULL, + key, + valueTuple}); } isolate->Enter(); - if (result.error.data != NULL) { + if (result.error.data != NULL) + { v8::Local error = v8::Exception::Error(v8_String_FromString(isolate, result.error)); isolate->ThrowException(error); } diff --git a/v8_c_inspector.cc b/v8_c_inspector.cc index 695366f..b849c5e 100644 --- a/v8_c_inspector.cc +++ b/v8_c_inspector.cc @@ -1,31 +1,35 @@ #include "v8_c_private.h" -#include "v8-inspector.h" +#include -String StringFromStringView(v8::Isolate* isolate, const v8_inspector::StringView& view) { +String StringFromStringView(v8::Isolate *isolate, const v8_inspector::StringView &view) +{ v8::MaybeLocal s; - if (view.is8Bit()) { + if (view.is8Bit()) + { s = v8::String::NewFromOneByte(isolate, view.characters8(), v8::NewStringType::kNormal, view.length()); - } else { + } + else + { s = v8::String::NewFromTwoByte(isolate, view.characters16(), v8::NewStringType::kNormal, view.length()); } - return v8_String_Create(s.ToLocalChecked()); + return v8_String_Create(isolate, s.ToLocalChecked()); } - - -class Inspector : public v8_inspector::V8Inspector::Channel, public v8_inspector::V8InspectorClient { +class Inspector : public v8_inspector::V8Inspector::Channel, public v8_inspector::V8InspectorClient +{ public: - Inspector(v8::Isolate* isolate, int inspectorId) : isolate_(isolate), inspectorId_(inspectorId) { + Inspector(v8::Isolate *isolate, int inspectorId) : isolate_(isolate), inspectorId_(inspectorId) + { inspector_ = v8_inspector::V8Inspector::create(isolate, this); session_ = inspector_->connect(1, this, v8_inspector::StringView()); } - void contextCreated(const v8_inspector::V8ContextInfo& contextInfo); + void contextCreated(const v8_inspector::V8ContextInfo &contextInfo); void contextDestroyed(v8::Local context); - void dispatchProtocolMessage(v8_inspector::StringView& message); + void dispatchProtocolMessage(v8_inspector::StringView &message); void sendResponse(int callId, std::unique_ptr message) override; void sendNotification(std::unique_ptr message) override; void flushProtocolNotifications() override; @@ -33,7 +37,7 @@ class Inspector : public v8_inspector::V8Inspector::Channel, public v8_inspector void quitMessageLoopOnPause() override; private: - v8::Isolate* isolate_; + v8::Isolate *isolate_; v8::Eternal context_; std::unique_ptr inspector_; std::unique_ptr session_; @@ -42,93 +46,110 @@ class Inspector : public v8_inspector::V8Inspector::Channel, public v8_inspector bool terminated_ = false; }; -void Inspector::contextCreated(const v8_inspector::V8ContextInfo& contextInfo) { +void Inspector::contextCreated(const v8_inspector::V8ContextInfo &contextInfo) +{ v8::HandleScope handleScope(isolate_); context_.Set(isolate_, contextInfo.context); inspector_->contextCreated(contextInfo); } -void Inspector::contextDestroyed(v8::Local context) { +void Inspector::contextDestroyed(v8::Local context) +{ inspector_->contextDestroyed(context); } -void Inspector::dispatchProtocolMessage(v8_inspector::StringView& message) { +void Inspector::dispatchProtocolMessage(v8_inspector::StringView &message) +{ ISOLATE_SCOPE(isolate_); session_->dispatchProtocolMessage(message); } -void Inspector::sendResponse(int callId, std::unique_ptr message) { +void Inspector::sendResponse(int callId, std::unique_ptr message) +{ ISOLATE_SCOPE(isolate_); v8::HandleScope handle_scope(isolate); inspectorSendResponse(inspectorId_, callId, StringFromStringView(isolate, message->string())); } -void Inspector::sendNotification(std::unique_ptr message) { +void Inspector::sendNotification(std::unique_ptr message) +{ ISOLATE_SCOPE(isolate_); v8::HandleScope handle_scope(isolate); inspectorSendNotification(inspectorId_, StringFromStringView(isolate, message->string())); } -void Inspector::flushProtocolNotifications() { +void Inspector::flushProtocolNotifications() +{ ISOLATE_SCOPE(isolate_); inspectorFlushProtocolNotifications(inspectorId_); } -void Inspector::runMessageLoopOnPause(int contextGroupId) { - if (runningNestedLoop_) return; +void Inspector::runMessageLoopOnPause(int contextGroupId) +{ + if (runningNestedLoop_) + return; - terminated_ = false; - runningNestedLoop_ = true; + terminated_ = false; + runningNestedLoop_ = true; - while (!terminated_) { + while (!terminated_) + { bool more = true; - while (more) { - //ISOLATE_SCOPE(isolate_); + while (more) + { + // ISOLATE_SCOPE(isolate_); more = v8::platform::PumpMessageLoop(platform, isolate_); } - } + } - terminated_ = false; - runningNestedLoop_ = false; + terminated_ = false; + runningNestedLoop_ = false; } -void Inspector::quitMessageLoopOnPause() { - terminated_ = true; +void Inspector::quitMessageLoopOnPause() +{ + terminated_ = true; } -extern "C" { - InspectorPtr v8_Inspector_New(IsolatePtr pIsolate, int id) { - ISOLATE_SCOPE(static_cast(pIsolate)); +extern "C" +{ + InspectorPtr v8_Inspector_New(IsolatePtr pIsolate, int id) + { + ISOLATE_SCOPE(static_cast(pIsolate)); Inspector *inspector = new Inspector(isolate, id); return (InspectorPtr)inspector; } - void v8_Inspector_AddContext(InspectorPtr pInspector, ContextPtr pContext, const char* name) { + void v8_Inspector_AddContext(InspectorPtr pInspector, ContextPtr pContext, const char *name) + { VALUE_SCOPE(pContext); - Inspector *inspector = static_cast(pInspector); + Inspector *inspector = static_cast(pInspector); - v8_inspector::StringView contextName((const uint8_t*)name, strlen(name)); + v8_inspector::StringView contextName((const uint8_t *)name, strlen(name)); inspector->contextCreated(v8_inspector::V8ContextInfo(context, 1, contextName)); } - void v8_Inspector_RemoveContext(InspectorPtr pInspector, ContextPtr pContext) { + void v8_Inspector_RemoveContext(InspectorPtr pInspector, ContextPtr pContext) + { VALUE_SCOPE(pContext); - Inspector *inspector = static_cast(pInspector); + Inspector *inspector = static_cast(pInspector); inspector->contextDestroyed(context); } - void v8_Inspector_DispatchMessage(InspectorPtr pInspector, const char* message) { - Inspector *inspector = static_cast(pInspector); + void v8_Inspector_DispatchMessage(InspectorPtr pInspector, const char *message) + { + Inspector *inspector = static_cast(pInspector); - v8_inspector::StringView messageView((const uint8_t*)message, strlen(message)); + v8_inspector::StringView messageView((const uint8_t *)message, strlen(message)); inspector->dispatchProtocolMessage(messageView); } - void v8_Inspector_Release(InspectorPtr pInspector) { - Inspector *inspector = static_cast(pInspector); + void v8_Inspector_Release(InspectorPtr pInspector) + { + Inspector *inspector = static_cast(pInspector); delete inspector; } } diff --git a/v8_c_isolate.cc b/v8_c_isolate.cc index 1669e73..beefab4 100644 --- a/v8_c_isolate.cc +++ b/v8_c_isolate.cc @@ -5,12 +5,6 @@ auto allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator(); extern "C" { - StartupData v8_CreateSnapshotDataBlob(const char *js) - { - v8::StartupData data = v8::V8::CreateSnapshotDataBlob(js); - return StartupData{data.data, data.raw_size}; - } - IsolatePtr v8_Isolate_New(StartupData startupData) { v8::Isolate::CreateParams createParams; @@ -60,11 +54,11 @@ extern "C" return Error{NULL, 0}; } - void v8_Isolate_RunMicrotasks(IsolatePtr pIsolate) + void v8_Isolate_PerformMicrotaskCheckpoint(IsolatePtr pIsolate) { ISOLATE_SCOPE(static_cast(pIsolate)); - isolate->RunMicrotasks(); + isolate->PerformMicrotaskCheckpoint(); } void v8_Isolate_Terminate(IsolatePtr isolate_ptr) diff --git a/v8_c_private.h b/v8_c_private.h index 7526a9c..b9ba722 100644 --- a/v8_c_private.h +++ b/v8_c_private.h @@ -3,8 +3,8 @@ #define V8_C_PRIVATE_H #include "v8_c_bridge.h" -#include "libplatform/libplatform.h" -#include "v8.h" +#include +#include #define ISOLATE_SCOPE(iso) \ v8::Isolate *isolate = iso; \ @@ -29,10 +29,10 @@ typedef struct } Context; inline String v8_String_Create(const v8::String::Utf8Value &src); -inline String v8_String_Create(const v8::Local &val); +inline String v8_String_Create(v8::Isolate *isolate, const v8::Local &val); inline String v8_String_Create(const char *msg); inline String v8_String_Create(const std::string &src); -inline std::string v8_String_ToStdString(v8::Local value); +inline std::string v8_String_ToStdString(v8::Isolate *isolate, v8::Local value); inline v8::Local v8_String_FromString(v8::Isolate *isolate, const String &string); typedef v8::Persistent FunctionTemplate; @@ -41,7 +41,7 @@ typedef v8::Persistent Value; typedef v8::Persistent Private; inline ValueTuple v8_Value_ValueTuple(v8::Isolate *isolate, v8::Local value); -inline ValueTuple v8_Value_ValueTuple_Error(const v8::Local &value); +inline ValueTuple v8_Value_ValueTuple_Error(v8::Isolate *isolate, const v8::Local &value); inline v8::Local v8_StackTrace_FormatException(v8::Isolate *isolate, v8::Local ctx, v8::TryCatch &try_catch); inline CallerInfo v8_StackTrace_CallerInfo(v8::Isolate *isolate); diff --git a/v8_c_stack_trace.h b/v8_c_stack_trace.h index 540a871..63bc0a9 100644 --- a/v8_c_stack_trace.h +++ b/v8_c_stack_trace.h @@ -5,50 +5,67 @@ #include #include -inline v8::Local v8_StackTrace_FormatException(v8::Isolate* isolate, v8::Local ctx, v8::TryCatch& try_catch) { +inline v8::Local v8_StackTrace_FormatException(v8::Isolate *isolate, v8::Local ctx, v8::TryCatch &try_catch) +{ v8::EscapableHandleScope handleScope(isolate); std::stringstream ss; ss << "Uncaught exception: "; - std::string exceptionStr = v8_String_ToStdString(try_catch.Exception()); + std::string exceptionStr = v8_String_ToStdString(isolate, try_catch.Exception()); ss << exceptionStr; // TODO(aroman) JSON-ify objects? - if (!try_catch.Message().IsEmpty()) { - if (!try_catch.Message()->GetScriptResourceName()->IsUndefined()) { + if (!try_catch.Message().IsEmpty()) + { + if (!try_catch.Message()->GetScriptResourceName()->IsUndefined()) + { ss << std::endl - << "at " << v8_String_ToStdString(try_catch.Message()->GetScriptResourceName()); + << "at " << v8_String_ToStdString(isolate, try_catch.Message()->GetScriptResourceName()); v8::Maybe line_no = try_catch.Message()->GetLineNumber(ctx); v8::Maybe start = try_catch.Message()->GetStartColumn(ctx); v8::Maybe end = try_catch.Message()->GetEndColumn(ctx); v8::MaybeLocal sourceLine = try_catch.Message()->GetSourceLine(ctx); - if (line_no.IsJust()) { + if (line_no.IsJust()) + { ss << ":" << line_no.ToChecked(); } - if (start.IsJust()) { + if (start.IsJust()) + { ss << ":" << start.ToChecked(); } - if (!sourceLine.IsEmpty()) { + if (!sourceLine.IsEmpty()) + { ss << std::endl - << " " << v8_String_ToStdString(sourceLine.ToLocalChecked()); + << " " << v8_String_ToStdString(isolate, sourceLine.ToLocalChecked()); } - if (start.IsJust() && end.IsJust()) { + if (start.IsJust() && end.IsJust()) + { ss << std::endl << " "; - for (int i = 0; i < start.ToChecked(); i++) { + for (int i = 0; i < start.ToChecked(); i++) + { ss << " "; } - for (int i = start.ToChecked(); i < end.ToChecked(); i++) { + for (int i = start.ToChecked(); i < end.ToChecked(); i++) + { ss << "^"; } } } } - if (!try_catch.StackTrace().IsEmpty()) { - ss << std::endl << "Stack trace: " << v8_String_ToStdString(try_catch.StackTrace()); + if (!try_catch.StackTrace(ctx).IsEmpty()) + { + v8::Local stack; + + if (try_catch.StackTrace(ctx).ToLocal(&stack)) + { + ss + << std::endl + << "Stack trace: " << v8_String_ToStdString(isolate, stack); + } } std::string string = ss.str(); @@ -56,26 +73,27 @@ inline v8::Local v8_StackTrace_FormatException(v8::Isolate* isolate, return handleScope.Escape(v8::String::NewFromUtf8(isolate, string.c_str(), v8::NewStringType::kNormal, string.length()).ToLocalChecked()); } -inline CallerInfo v8_StackTrace_CallerInfo(v8::Isolate* isolate) { +inline CallerInfo v8_StackTrace_CallerInfo(v8::Isolate *isolate) +{ std::string src_file, src_func; int line_number = 0, column = 0; v8::Local trace(v8::StackTrace::CurrentStackTrace(isolate, 1)); - if (trace->GetFrameCount() >= 1) { - v8::Local frame(trace->GetFrame(0)); - src_file = v8_String_ToStdString(frame->GetScriptName()); - src_func = v8_String_ToStdString(frame->GetFunctionName()); + if (trace->GetFrameCount() >= 1) + { + v8::Local frame(trace->GetFrame(isolate, 0)); + src_file = v8_String_ToStdString(isolate, frame->GetScriptName()); + src_func = v8_String_ToStdString(isolate, frame->GetFunctionName()); line_number = frame->GetLineNumber(); column = frame->GetColumn(); } return CallerInfo{ - v8_String_Create(src_file), - v8_String_Create(src_func), - line_number, - column - }; + v8_String_Create(src_file), + v8_String_Create(src_func), + line_number, + column}; } #endif diff --git a/v8_c_string.h b/v8_c_string.h index 48ed311..592dc74 100644 --- a/v8_c_string.h +++ b/v8_c_string.h @@ -4,48 +4,57 @@ #include -inline std::string v8_String_ToStdString(v8::Local value) { - v8::String::Utf8Value s(value); +inline std::string v8_String_ToStdString(v8::Isolate *isolate, v8::Local value) +{ + v8::String::Utf8Value s(isolate, value); - if (s.length() == 0) { + if (s.length() == 0) + { return ""; } return *s; } -inline v8::Local v8_String_FromString(v8::Isolate* isolate, const String& string) { +inline v8::Local v8_String_FromString(v8::Isolate *isolate, const String &string) +{ v8::EscapableHandleScope handleScope(isolate); return handleScope.Escape(v8::String::NewFromUtf8(isolate, string.data, v8::NewStringType::kNormal, string.length).ToLocalChecked()); } -inline v8::Local v8_String_FromString(v8::Isolate* isolate, const std::string& string) { +inline v8::Local v8_String_FromString(v8::Isolate *isolate, const std::string &string) +{ v8::EscapableHandleScope handleScope(isolate); return handleScope.Escape(v8::String::NewFromUtf8(isolate, string.c_str(), v8::NewStringType::kNormal, string.length()).ToLocalChecked()); } -inline v8::Local v8_String_FromString(v8::Isolate* isolate, const char* string) { +inline v8::Local v8_String_FromString(v8::Isolate *isolate, const char *string) +{ v8::EscapableHandleScope handleScope(isolate); return handleScope.Escape(v8::String::NewFromUtf8(isolate, string, v8::NewStringType::kNormal, strlen(string)).ToLocalChecked()); } -inline String v8_String_Create(const v8::String::Utf8Value& src) { - char* data = static_cast(malloc(src.length())); +inline String v8_String_Create(const v8::String::Utf8Value &src) +{ + char *data = static_cast(malloc(src.length())); memcpy(data, *src, src.length()); return (String){data, src.length()}; } -inline String v8_String_Create(const v8::Local& val) { - return v8_String_Create(v8::String::Utf8Value(val)); +inline String v8_String_Create(v8::Isolate *isolate, const v8::Local &val) +{ + return v8_String_Create(v8::String::Utf8Value(isolate, val)); } -inline String v8_String_Create(const char* msg) { - const char* data = strdup(msg); +inline String v8_String_Create(const char *msg) +{ + const char *data = strdup(msg); return (String){data, int(strlen(msg))}; } -inline String v8_String_Create(const std::string& src) { - char* data = static_cast(malloc(src.length())); +inline String v8_String_Create(const std::string &src) +{ + char *data = static_cast(malloc(src.length())); memcpy(data, src.data(), src.length()); return (String){data, int(src.length())}; } diff --git a/v8_c_value.cc b/v8_c_value.cc index bc5ebb1..6940bd4 100644 --- a/v8_c_value.cc +++ b/v8_c_value.cc @@ -38,11 +38,11 @@ extern "C" v8::Local maybeObject = static_cast(pObject)->Get(isolate); if (!maybeObject->IsObject()) { - return v8_Value_ValueTuple_Error(v8_String_FromString(isolate, "Not an object")); + return v8_Value_ValueTuple_Error(isolate, v8_String_FromString(isolate, "Not an object")); } v8::Local object = maybeObject->ToObject(context).ToLocalChecked(); - v8::Local value = object->Get(context, v8::String::NewFromUtf8(isolate, field)).ToLocalChecked(); + v8::Local value = object->Get(context, v8::String::NewFromUtf8(isolate, field).ToLocalChecked()).ToLocalChecked(); return v8_Value_ValueTuple(isolate, value); } @@ -53,15 +53,15 @@ extern "C" v8::Local maybeObject = static_cast(pObject)->Get(isolate); if (!maybeObject->IsObject()) { - return v8_Value_ValueTuple_Error(v8_String_FromString(isolate, "Not an object")); + return v8_Value_ValueTuple_Error(isolate, v8_String_FromString(isolate, "Not an object")); } if (maybeObject->IsArrayBuffer()) { v8::Local arrayBuffer = v8::Local::Cast(maybeObject); - if (index < arrayBuffer->GetContents().ByteLength()) + if (index < arrayBuffer->ByteLength()) { - return v8_Value_ValueTuple(isolate, v8::Number::New(isolate, ((unsigned char *)arrayBuffer->GetContents().Data())[index])); + return v8_Value_ValueTuple(isolate, v8::Number::New(isolate, ((unsigned char *)arrayBuffer->GetBackingStore()->Data())[index])); } else { @@ -110,7 +110,7 @@ extern "C" v8::Local object = maybeObject->ToObject(context).ToLocalChecked(); v8::Local newValue = static_cast(pNewValue)->Get(isolate); - v8::Maybe result = object->Set(context, v8::String::NewFromUtf8(isolate, field), newValue); + v8::Maybe result = object->Set(context, v8::String::NewFromUtf8(isolate, field).ToLocalChecked(), newValue); if (result.IsNothing()) { @@ -142,13 +142,13 @@ extern "C" { return v8_String_Create("Cannot assign non-number into array buffer"); } - else if (index >= arrayBuffer->GetContents().ByteLength()) + else if (index >= arrayBuffer->GetBackingStore()->ByteLength()) { return v8_String_Create("Cannot assign to an index beyond the size of an array buffer"); } else { - ((unsigned char *)arrayBuffer->GetContents().Data())[index] = newValue->ToNumber(context).ToLocalChecked()->Value(); + ((unsigned char *)arrayBuffer->GetBackingStore()->Data())[index] = newValue->ToNumber(context).ToLocalChecked()->Value(); } } else @@ -216,7 +216,7 @@ extern "C" } v8::Local object = maybeObject->ToObject(context).ToLocalChecked(); - v8::Maybe result = object->DefineProperty(context, v8::String::NewFromUtf8(isolate, key), propertyDescriptor); + v8::Maybe result = object->DefineProperty(context, v8::String::NewFromUtf8(isolate, key).ToLocalChecked(), propertyDescriptor); if (result.IsNothing()) { @@ -237,7 +237,7 @@ extern "C" v8::Local maybeObject = static_cast(pValue)->Get(isolate); if (!maybeObject->IsObject()) { - return v8_Value_ValueTuple_Error(v8_String_FromString(isolate, "Not an object")); + return v8_Value_ValueTuple_Error(isolate, v8_String_FromString(isolate, "Not an object")); } v8::Local object = maybeObject->ToObject(context).ToLocalChecked(); v8::Local _private = static_cast(pPrivate)->Get(isolate); @@ -292,7 +292,7 @@ extern "C" v8::Local value = static_cast(pFunction)->Get(isolate); if (!value->IsFunction()) { - return v8_Value_ValueTuple_Error(v8_String_FromString(isolate, "Not a function")); + return v8_Value_ValueTuple_Error(isolate, v8_String_FromString(isolate, "Not a function")); } v8::Local function = v8::Local::Cast(value); @@ -318,7 +318,7 @@ extern "C" if (result.IsEmpty()) { - return v8_Value_ValueTuple_Error(v8_StackTrace_FormatException(isolate, context, tryCatch)); + return v8_Value_ValueTuple_Error(isolate, v8_StackTrace_FormatException(isolate, context, tryCatch)); } return v8_Value_ValueTuple(isolate, result.ToLocalChecked()); @@ -334,7 +334,7 @@ extern "C" v8::Local value = static_cast(pFunction)->Get(isolate); if (!value->IsFunction()) { - return v8_Value_ValueTuple_Error(v8_String_FromString(isolate, "Not a function")); + return v8_Value_ValueTuple_Error(isolate, v8_String_FromString(isolate, "Not a function")); } v8::Local function = v8::Local::Cast(value); @@ -350,7 +350,7 @@ extern "C" if (result.IsEmpty()) { - return v8_Value_ValueTuple_Error(v8_StackTrace_FormatException(isolate, context, tryCatch)); + return v8_Value_ValueTuple_Error(isolate, v8_StackTrace_FormatException(isolate, context, tryCatch)); } return v8_Value_ValueTuple(isolate, result.ToLocalChecked()); @@ -374,7 +374,7 @@ extern "C" { VALUE_SCOPE(pContext); v8::Local value = static_cast(pValue)->Get(isolate); - return v8_String_Create(value); + return v8_String_Create(isolate, value); } double v8_Value_Float64(ContextPtr pContext, ValuePtr pValue) @@ -411,14 +411,7 @@ extern "C" VALUE_SCOPE(pContext); v8::Local value = static_cast(pValue)->Get(isolate); - v8::Maybe maybe = value->BooleanValue(context); - - if (maybe.IsNothing()) - { - return 0; - } - - return maybe.ToChecked() ? 1 : 0; + return value->BooleanValue(isolate) ? 1 : 0; } ByteArray v8_Value_Bytes(ContextPtr pContext, ValuePtr pValue) @@ -448,8 +441,8 @@ extern "C" } return ByteArray{ - static_cast(arrayBuffer->GetContents().Data()), - static_cast(arrayBuffer->GetContents().ByteLength())}; + static_cast(arrayBuffer->GetBackingStore()->Data()), + static_cast(arrayBuffer->GetBackingStore()->ByteLength())}; } int v8_Value_ByteLength(ContextPtr pContext, ValuePtr pValue) @@ -478,7 +471,7 @@ extern "C" return 0; } - return static_cast(arrayBuffer->GetContents().ByteLength()); + return static_cast(arrayBuffer->GetBackingStore()->ByteLength()); } ValueTuple v8_Value_PromiseInfo(ContextPtr pContext, ValuePtr pValue, int *promiseState) @@ -488,7 +481,7 @@ extern "C" v8::Local value = static_cast(pValue)->Get(isolate); if (!value->IsPromise()) { - return v8_Value_ValueTuple_Error(v8_String_FromString(isolate, "Not a promise")); + return v8_Value_ValueTuple_Error(isolate, v8_String_FromString(isolate, "Not a promise")); } v8::Local promise = v8::Local::Cast(value); @@ -507,7 +500,7 @@ extern "C" ISOLATE_SCOPE(static_cast(pIsolate)); v8::HandleScope handleScope(isolate); - v8::Local _private = v8::Private::New(isolate, v8::String::NewFromUtf8(isolate, name)); + v8::Local _private = v8::Private::New(isolate, v8::String::NewFromUtf8(isolate, name).ToLocalChecked()); return static_cast(new Private(isolate, _private)); } @@ -520,7 +513,7 @@ extern "C" if (maybeValue.IsEmpty()) { - return v8_Value_ValueTuple_Error(v8_String_FromString(isolate, "json parse gave an empty result")); + return v8_Value_ValueTuple_Error(isolate, v8_String_FromString(isolate, "json parse gave an empty result")); } return v8_Value_ValueTuple(isolate, maybeValue.ToLocalChecked()); @@ -535,7 +528,7 @@ extern "C" if (maybeJson.IsEmpty()) { - return v8_Value_ValueTuple_Error(v8_String_FromString(isolate, "json stringify gave an empty result")); + return v8_Value_ValueTuple_Error(isolate, v8_String_FromString(isolate, "json stringify gave an empty result")); } return v8_Value_ValueTuple(isolate, maybeJson.ToLocalChecked()); diff --git a/v8_c_value.h b/v8_c_value.h index a860bb1..94b04bf 100644 --- a/v8_c_value.h +++ b/v8_c_value.h @@ -2,71 +2,121 @@ #ifndef V8_C_VALUE_H #define V8_C_VALUE_H -inline Kinds v8_Value_KindsFromLocal(v8::Local value) { +inline Kinds v8_Value_KindsFromLocal(v8::Local value) +{ Kinds kinds = 0; - if (value->IsUndefined()) kinds |= (1ULL << Kind::kUndefined ); - if (value->IsNull()) kinds |= (1ULL << Kind::kNull ); - if (value->IsName()) kinds |= (1ULL << Kind::kName ); - if (value->IsString()) kinds |= (1ULL << Kind::kString ); - if (value->IsSymbol()) kinds |= (1ULL << Kind::kSymbol ); - if (value->IsObject()) kinds |= (1ULL << Kind::kObject ); - if (value->IsArray()) kinds |= (1ULL << Kind::kArray ); - if (value->IsBoolean()) kinds |= (1ULL << Kind::kBoolean ); - if (value->IsNumber()) kinds |= (1ULL << Kind::kNumber ); - if (value->IsExternal()) kinds |= (1ULL << Kind::kExternal ); - if (value->IsInt32()) kinds |= (1ULL << Kind::kInt32 ); - if (value->IsUint32()) kinds |= (1ULL << Kind::kUint32 ); - if (value->IsDate()) kinds |= (1ULL << Kind::kDate ); - if (value->IsArgumentsObject()) kinds |= (1ULL << Kind::kArgumentsObject ); - if (value->IsBooleanObject()) kinds |= (1ULL << Kind::kBooleanObject ); - if (value->IsNumberObject()) kinds |= (1ULL << Kind::kNumberObject ); - if (value->IsStringObject()) kinds |= (1ULL << Kind::kStringObject ); - if (value->IsSymbolObject()) kinds |= (1ULL << Kind::kSymbolObject ); - if (value->IsNativeError()) kinds |= (1ULL << Kind::kNativeError ); - if (value->IsRegExp()) kinds |= (1ULL << Kind::kRegExp ); - if (value->IsFunction()) kinds |= (1ULL << Kind::kFunction ); - if (value->IsAsyncFunction()) kinds |= (1ULL << Kind::kAsyncFunction ); - if (value->IsGeneratorFunction()) kinds |= (1ULL << Kind::kGeneratorFunction); - if (value->IsGeneratorObject()) kinds |= (1ULL << Kind::kGeneratorObject ); - if (value->IsPromise()) kinds |= (1ULL << Kind::kPromise ); - if (value->IsMap()) kinds |= (1ULL << Kind::kMap ); - if (value->IsSet()) kinds |= (1ULL << Kind::kSet ); - if (value->IsMapIterator()) kinds |= (1ULL << Kind::kMapIterator ); - if (value->IsSetIterator()) kinds |= (1ULL << Kind::kSetIterator ); - if (value->IsWeakMap()) kinds |= (1ULL << Kind::kWeakMap ); - if (value->IsWeakSet()) kinds |= (1ULL << Kind::kWeakSet ); - if (value->IsArrayBuffer()) kinds |= (1ULL << Kind::kArrayBuffer ); - if (value->IsArrayBufferView()) kinds |= (1ULL << Kind::kArrayBufferView ); - if (value->IsTypedArray()) kinds |= (1ULL << Kind::kTypedArray ); - if (value->IsUint8Array()) kinds |= (1ULL << Kind::kUint8Array ); - if (value->IsUint8ClampedArray()) kinds |= (1ULL << Kind::kUint8ClampedArray); - if (value->IsInt8Array()) kinds |= (1ULL << Kind::kInt8Array ); - if (value->IsUint16Array()) kinds |= (1ULL << Kind::kUint16Array ); - if (value->IsInt16Array()) kinds |= (1ULL << Kind::kInt16Array ); - if (value->IsUint32Array()) kinds |= (1ULL << Kind::kUint32Array ); - if (value->IsInt32Array()) kinds |= (1ULL << Kind::kInt32Array ); - if (value->IsFloat32Array()) kinds |= (1ULL << Kind::kFloat32Array ); - if (value->IsFloat64Array()) kinds |= (1ULL << Kind::kFloat64Array ); - if (value->IsDataView()) kinds |= (1ULL << Kind::kDataView ); - if (value->IsSharedArrayBuffer()) kinds |= (1ULL << Kind::kSharedArrayBuffer); - if (value->IsProxy()) kinds |= (1ULL << Kind::kProxy ); - if (value->IsWebAssemblyCompiledModule()) - kinds |= (1ULL << Kind::kWebAssemblyCompiledModule); + if (value->IsUndefined()) + kinds |= (1ULL << Kind::kUndefined); + if (value->IsNull()) + kinds |= (1ULL << Kind::kNull); + if (value->IsName()) + kinds |= (1ULL << Kind::kName); + if (value->IsString()) + kinds |= (1ULL << Kind::kString); + if (value->IsSymbol()) + kinds |= (1ULL << Kind::kSymbol); + if (value->IsObject()) + kinds |= (1ULL << Kind::kObject); + if (value->IsArray()) + kinds |= (1ULL << Kind::kArray); + if (value->IsBoolean()) + kinds |= (1ULL << Kind::kBoolean); + if (value->IsNumber()) + kinds |= (1ULL << Kind::kNumber); + if (value->IsExternal()) + kinds |= (1ULL << Kind::kExternal); + if (value->IsInt32()) + kinds |= (1ULL << Kind::kInt32); + if (value->IsUint32()) + kinds |= (1ULL << Kind::kUint32); + if (value->IsDate()) + kinds |= (1ULL << Kind::kDate); + if (value->IsArgumentsObject()) + kinds |= (1ULL << Kind::kArgumentsObject); + if (value->IsBooleanObject()) + kinds |= (1ULL << Kind::kBooleanObject); + if (value->IsNumberObject()) + kinds |= (1ULL << Kind::kNumberObject); + if (value->IsStringObject()) + kinds |= (1ULL << Kind::kStringObject); + if (value->IsSymbolObject()) + kinds |= (1ULL << Kind::kSymbolObject); + if (value->IsNativeError()) + kinds |= (1ULL << Kind::kNativeError); + if (value->IsRegExp()) + kinds |= (1ULL << Kind::kRegExp); + if (value->IsFunction()) + kinds |= (1ULL << Kind::kFunction); + if (value->IsAsyncFunction()) + kinds |= (1ULL << Kind::kAsyncFunction); + if (value->IsGeneratorFunction()) + kinds |= (1ULL << Kind::kGeneratorFunction); + if (value->IsGeneratorObject()) + kinds |= (1ULL << Kind::kGeneratorObject); + if (value->IsPromise()) + kinds |= (1ULL << Kind::kPromise); + if (value->IsMap()) + kinds |= (1ULL << Kind::kMap); + if (value->IsSet()) + kinds |= (1ULL << Kind::kSet); + if (value->IsMapIterator()) + kinds |= (1ULL << Kind::kMapIterator); + if (value->IsSetIterator()) + kinds |= (1ULL << Kind::kSetIterator); + if (value->IsWeakMap()) + kinds |= (1ULL << Kind::kWeakMap); + if (value->IsWeakSet()) + kinds |= (1ULL << Kind::kWeakSet); + if (value->IsArrayBuffer()) + kinds |= (1ULL << Kind::kArrayBuffer); + if (value->IsArrayBufferView()) + kinds |= (1ULL << Kind::kArrayBufferView); + if (value->IsTypedArray()) + kinds |= (1ULL << Kind::kTypedArray); + if (value->IsUint8Array()) + kinds |= (1ULL << Kind::kUint8Array); + if (value->IsUint8ClampedArray()) + kinds |= (1ULL << Kind::kUint8ClampedArray); + if (value->IsInt8Array()) + kinds |= (1ULL << Kind::kInt8Array); + if (value->IsUint16Array()) + kinds |= (1ULL << Kind::kUint16Array); + if (value->IsInt16Array()) + kinds |= (1ULL << Kind::kInt16Array); + if (value->IsUint32Array()) + kinds |= (1ULL << Kind::kUint32Array); + if (value->IsInt32Array()) + kinds |= (1ULL << Kind::kInt32Array); + if (value->IsFloat32Array()) + kinds |= (1ULL << Kind::kFloat32Array); + if (value->IsFloat64Array()) + kinds |= (1ULL << Kind::kFloat64Array); + if (value->IsDataView()) + kinds |= (1ULL << Kind::kDataView); + if (value->IsSharedArrayBuffer()) + kinds |= (1ULL << Kind::kSharedArrayBuffer); + if (value->IsProxy()) + kinds |= (1ULL << Kind::kProxy); + if (value->IsWasmModuleObject()) + kinds |= (1ULL << Kind::kWasmModuleObject); return kinds; } -inline ValueTuple v8_Value_ValueTuple() { - return ValueTuple{ NULL, 0, NULL }; +inline ValueTuple v8_Value_ValueTuple() +{ + return ValueTuple{NULL, 0, NULL}; } -inline ValueTuple v8_Value_ValueTuple(v8::Isolate* isolate, v8::Local value) { - return ValueTuple{ new Value(isolate, value), v8_Value_KindsFromLocal(value) }; +inline ValueTuple v8_Value_ValueTuple(v8::Isolate *isolate, v8::Local value) +{ + return ValueTuple{new Value(isolate, value), v8_Value_KindsFromLocal(value)}; } -inline ValueTuple v8_Value_ValueTuple_Error(const v8::Local& value) { - return ValueTuple{ NULL, 0, v8_String_Create(value) }; +inline ValueTuple v8_Value_ValueTuple_Error(v8::Isolate *isolate, const v8::Local &value) +{ + return ValueTuple{NULL, 0, v8_String_Create(isolate, value)}; } #endif diff --git a/v8_callback.go b/v8_callback.go index dad466c..a80e42e 100644 --- a/v8_callback.go +++ b/v8_callback.go @@ -1,8 +1,6 @@ package isolates // #include "v8_c_bridge.h" -// #cgo CXXFLAGS: -I${SRCDIR} -I${SRCDIR}/include -g3 -fno-rtti -fpic -std=c++11 -// #cgo LDFLAGS: -pthread -L${SRCDIR}/libv8 -lv8_base -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_libsampler -lv8_nosnapshot import "C" import ( diff --git a/v8_context.go b/v8_context.go index ff33b32..4d694f3 100644 --- a/v8_context.go +++ b/v8_context.go @@ -1,8 +1,6 @@ package isolates // #include "v8_c_bridge.h" -// #cgo CXXFLAGS: -I${SRCDIR} -I${SRCDIR}/include -g3 -fno-rtti -fpic -std=c++11 -// #cgo LDFLAGS: -pthread -L${SRCDIR}/libv8 -lv8_base -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_libsampler -lv8_nosnapshot import "C" import ( diff --git a/v8_create.go b/v8_create.go index 5f556ae..3ef9d8d 100644 --- a/v8_create.go +++ b/v8_create.go @@ -1,8 +1,6 @@ package isolates // #include "v8_c_bridge.h" -// #cgo CXXFLAGS: -I${SRCDIR} -I${SRCDIR}/include -g3 -fno-rtti -fpic -std=c++11 -// #cgo LDFLAGS: -pthread -L${SRCDIR}/libv8 -lv8_base -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_libsampler -lv8_nosnapshot import "C" import ( diff --git a/v8_function.go b/v8_function.go index c62c291..b04e8e3 100644 --- a/v8_function.go +++ b/v8_function.go @@ -1,8 +1,6 @@ package isolates // #include "v8_c_bridge.h" -// #cgo CXXFLAGS: -I${SRCDIR} -I${SRCDIR}/include -g3 -fno-rtti -fpic -std=c++11 -// #cgo LDFLAGS: -pthread -L${SRCDIR}/libv8 -lv8_base -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_libsampler -lv8_nosnapshot import "C" import ( @@ -168,20 +166,6 @@ func (f *FunctionTemplate) SetName(ctx context.Context, name string) error { return nil } -func (f *FunctionTemplate) SetHiddenPrototype(ctx context.Context, value bool) error { - if locked, err := f.context.isolate.lock(ctx); err != nil { - return err - } else if locked { - defer f.context.isolate.unlock(ctx) - } - - f.context.ref() - defer f.context.unref() - - C.v8_FunctionTemplate_SetHiddenPrototype(f.context.pointer, f.pointer, C.bool(value)) - return nil -} - func (f *FunctionTemplate) GetFunction(ctx context.Context) (*Value, error) { if locked, err := f.context.isolate.lock(ctx); err != nil { return nil, err diff --git a/v8_inspector.go b/v8_inspector.go index 9393289..eca75f5 100644 --- a/v8_inspector.go +++ b/v8_inspector.go @@ -1,8 +1,6 @@ package isolates // #include "v8_c_bridge.h" -// #cgo CXXFLAGS: -I${SRCDIR} -I${SRCDIR}/include -g3 -fno-rtti -fpic -std=c++11 -// #cgo LDFLAGS: -pthread -L${SRCDIR}/libv8 -lv8_base -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_libsampler -lv8_nosnapshot import "C" import ( diff --git a/v8_isolate.go b/v8_isolate.go index 9c6d20d..3aba77e 100644 --- a/v8_isolate.go +++ b/v8_isolate.go @@ -1,8 +1,6 @@ package isolates // #include "v8_c_bridge.h" -// #cgo CXXFLAGS: -I${SRCDIR} -I${SRCDIR}/include -g3 -fno-rtti -fpic -std=c++11 -// #cgo LDFLAGS: -pthread -L${SRCDIR}/libv8 -lv8_base -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_libsampler -lv8_nosnapshot import "C" import ( diff --git a/v8_promise.go b/v8_promise.go index f385336..ac284f1 100644 --- a/v8_promise.go +++ b/v8_promise.go @@ -1,8 +1,6 @@ package isolates // #include "v8_c_bridge.h" -// #cgo CXXFLAGS: -I${SRCDIR} -I${SRCDIR}/include -g3 -fno-rtti -fpic -std=c++11 -// #cgo LDFLAGS: -pthread -L${SRCDIR}/libv8 -lv8_base -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_libsampler -lv8_nosnapshot import "C" import ( diff --git a/v8_unmarshal.go b/v8_unmarshal.go index 4b94ce3..648bd03 100644 --- a/v8_unmarshal.go +++ b/v8_unmarshal.go @@ -1,8 +1,6 @@ package isolates // #include "v8_c_bridge.h" -// #cgo CXXFLAGS: -I${SRCDIR} -I${SRCDIR}/include -g3 -fno-rtti -fpic -std=c++11 -// #cgo LDFLAGS: -pthread -L${SRCDIR}/libv8 -lv8_base -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_libsampler -lv8_nosnapshot import "C" import ( diff --git a/v8_value.go b/v8_value.go index 398802d..c0a9f63 100644 --- a/v8_value.go +++ b/v8_value.go @@ -1,8 +1,6 @@ package isolates // #include "v8_c_bridge.h" -// #cgo CXXFLAGS: -I${SRCDIR} -I${SRCDIR}/include -g3 -fno-rtti -fpic -std=c++11 -// #cgo LDFLAGS: -pthread -L${SRCDIR}/libv8 -lv8_base -lv8_init -lv8_initializers -lv8_libbase -lv8_libplatform -lv8_libsampler -lv8_nosnapshot import "C" import (