Skip to content

Commit c0d27a6

Browse files
committed
Add Isolate creation and disposal for Yao (dev)
1 parent a6a98f8 commit c0d27a6

File tree

5 files changed

+222
-43
lines changed

5 files changed

+222
-43
lines changed

isolate.go

-18
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,6 @@ func NewIsolate() *Isolate {
6262
return iso
6363
}
6464

65-
// NewIsolateHeapSize creates a new V8 isolate. Only one thread may access
66-
// a given isolate at a time, but different threads may access
67-
// different isolates simultaneously.
68-
// When an isolate is no longer used its resources should be freed
69-
// by calling iso.Dispose().
70-
// An *Isolate can be used as a v8go.ContextOption to create a new
71-
// Context, rather than creating a new default Isolate.
72-
func NewIsolateHeapSize(maximumHeapSizeInMb int) *Isolate {
73-
initializeIfNecessary()
74-
iso := &Isolate{
75-
ptr: C.NewIsolateHeapSize(C.int(maximumHeapSizeInMb)),
76-
cbs: make(map[int]FunctionCallback),
77-
}
78-
iso.null = newValueNull(iso)
79-
iso.undefined = newValueUndefined(iso)
80-
return iso
81-
}
82-
8365
// TerminateExecution terminates forcefully the current thread
8466
// of JavaScript execution in the given isolate.
8567
func (i *Isolate) TerminateExecution() {

v8go.cc

+60-24
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,66 @@ m_unboundScript* tracked_unbound_script(m_ctx* ctx, m_unboundScript* us) {
126126

127127
extern "C" {
128128

129+
/********** Yao App Enine **********/
130+
static IsolatePtr globalIsolate = nullptr;
131+
132+
void YaoDispose() {
133+
if (globalIsolate != nullptr ) {
134+
globalIsolate->Dispose();
135+
globalIsolate = nullptr;
136+
}
137+
}
138+
139+
extern IsolatePtr YaoNewIsolate() {
140+
Isolate::CreateParams params;
141+
params.array_buffer_allocator = default_allocator;
142+
143+
Isolate* iso = Isolate::New(params);
144+
Locker locker(iso);
145+
Isolate::Scope isolate_scope(iso);
146+
HandleScope handle_scope(iso);
147+
148+
iso->SetCaptureStackTraceForUncaughtExceptions(true);
149+
150+
// Create a Context for internal use
151+
m_ctx* ctx = new m_ctx;
152+
ctx->ptr.Reset(iso, Context::New(iso));
153+
ctx->iso = iso;
154+
iso->SetData(0, ctx);
155+
return iso;
156+
}
157+
158+
159+
extern IsolatePtr YaoNewIsolateFromGlobal() {
160+
if (globalIsolate == nullptr) {
161+
return nullptr;
162+
}
163+
164+
IsolatePtr ptr = YaoCopyIsolate(globalIsolate);
165+
return ptr;
166+
}
167+
168+
169+
extern IsolatePtr YaoCopyIsolate( IsolatePtr iso ) {
170+
Isolate::CreateParams params;
171+
params.array_buffer_allocator = default_allocator;
172+
return iso->New(params);
173+
}
174+
175+
176+
// Should call in the main thread only
177+
extern void YaoIsolateAsGlobal( IsolatePtr iso ) {
178+
if (globalIsolate != nullptr) {
179+
globalIsolate->Dispose();
180+
globalIsolate = nullptr;
181+
}
182+
globalIsolate = YaoCopyIsolate(iso);
183+
}
184+
185+
/**** ----- END ------- ****/
186+
187+
188+
129189
/********** Isolate **********/
130190

131191
#define ISOLATE_SCOPE(iso) \
@@ -167,30 +227,6 @@ IsolatePtr NewIsolate() {
167227
return iso;
168228
}
169229

170-
extern IsolatePtr NewIsolateHeapSize(int maximum_heap_size_in_mb) {
171-
Isolate::CreateParams params;
172-
params.array_buffer_allocator = default_allocator;
173-
174-
// v8::ResourceConstraints constraints;
175-
// // constraints.ConfigureDefaultsFromHeapSize(0, 1ULL * maximum_heap_size_in_mb * 1024 * 1024);
176-
// constraints.set_max_old_generation_size_in_bytes(1ULL * maximum_heap_size_in_mb * 1024 * 1024);
177-
// params.constraints = constraints;
178-
179-
Isolate* iso = Isolate::New(params);
180-
Locker locker(iso);
181-
Isolate::Scope isolate_scope(iso);
182-
HandleScope handle_scope(iso);
183-
184-
iso->SetCaptureStackTraceForUncaughtExceptions(true);
185-
186-
// Create a Context for internal use
187-
m_ctx* ctx = new m_ctx;
188-
ctx->ptr.Reset(iso, Context::New(iso));
189-
ctx->iso = iso;
190-
iso->SetData(0, ctx);
191-
return iso;
192-
}
193-
194230
static inline m_ctx* isolateInternalContext(Isolate* iso) {
195231
return static_cast<m_ctx*>(iso->GetData(0));
196232
}

v8go.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,19 @@ typedef struct {
139139
int sign_bit;
140140
} ValueBigInt;
141141

142+
143+
/**** Yao App Engine ****/
144+
145+
extern void YaoDispose();
146+
extern IsolatePtr YaoNewIsolate();
147+
extern IsolatePtr YaoCopyIsolate( IsolatePtr iso );
148+
extern IsolatePtr YaoNewIsolateFromGlobal();
149+
extern void YaoIsolateAsGlobal( IsolatePtr iso );
150+
151+
/**** ----- END ------- ****/
152+
142153
extern void Init();
143154
extern IsolatePtr NewIsolate();
144-
extern IsolatePtr NewIsolateHeapSize(int maximum_heap_size_in_mb);
145155
extern void IsolatePerformMicrotaskCheckpoint(IsolatePtr ptr);
146156
extern void IsolateDispose(IsolatePtr ptr);
147157
extern void IsolateTerminateExecution(IsolatePtr ptr);

yao.go

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package v8go
2+
3+
import (
4+
"fmt"
5+
"unsafe"
6+
)
7+
8+
// #include "v8go.h"
9+
// #include <stdlib.h>
10+
import "C"
11+
12+
// YaoNewIsolate creates a new V8 isolate. Only one thread may access
13+
// a given isolate at a time, but different threads may access
14+
// different isolates simultaneously.
15+
// When an isolate is no longer used its resources should be freed
16+
// by calling iso.Dispose().
17+
// An *Isolate can be used as a v8go.ContextOption to create a new
18+
// Context, rather than creating a new default Isolate.
19+
func YaoNewIsolate() *Isolate {
20+
iso := &Isolate{
21+
ptr: C.YaoNewIsolate(),
22+
cbs: make(map[int]FunctionCallback),
23+
}
24+
iso.null = newValueNull(iso)
25+
iso.undefined = newValueUndefined(iso)
26+
return iso
27+
}
28+
29+
// YaoNewIsolateFromGlobal creates a new V8 isolate from global.
30+
func YaoNewIsolateFromGlobal() (*Isolate, error) {
31+
32+
ptr := C.YaoNewIsolateFromGlobal()
33+
if ptr == nil {
34+
return nil, fmt.Errorf("YaoNewIsolateFromGlobal failed")
35+
}
36+
37+
iso := &Isolate{
38+
ptr: ptr,
39+
cbs: make(map[int]FunctionCallback),
40+
}
41+
42+
return iso, nil
43+
}
44+
45+
// YaoDispose will dispose the Isolate VM; subsequent calls will panic.
46+
func YaoDispose() {
47+
C.YaoDispose()
48+
}
49+
50+
// Copy copies the current isolate.
51+
func (iso *Isolate) Copy() (*Isolate, error) {
52+
if iso == nil || iso.ptr == nil {
53+
return nil, fmt.Errorf("invalid isolate")
54+
}
55+
new := &Isolate{
56+
ptr: C.YaoCopyIsolate(iso.ptr),
57+
cbs: make(map[int]FunctionCallback),
58+
}
59+
return new, nil
60+
}
61+
62+
// AsGlobal makes the isolate into a global object.
63+
func (iso *Isolate) AsGlobal() {
64+
C.YaoIsolateAsGlobal(iso.ptr)
65+
}
66+
67+
// YaoInit initializes V8 with the given heap size limit.
68+
func YaoInit(heapSizeLimitMB uint) {
69+
v8once.Do(func() {
70+
cflags := C.CString("--no-freeze_flags_after_init")
71+
if heapSizeLimitMB > 0 {
72+
cflags = C.CString(fmt.Sprintf("--no-freeze_flags_after_init --max_old_space_size=%d", heapSizeLimitMB))
73+
}
74+
defer C.free(unsafe.Pointer(cflags))
75+
C.SetFlags(cflags)
76+
C.Init()
77+
})
78+
}

yao_test.go

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package v8go_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
v8 "rogchap.com/v8go"
8+
)
9+
10+
func TestYaoVersionPrint(t *testing.T) {
11+
v := v8.Version()
12+
fmt.Println("Version", v)
13+
}
14+
15+
func TestYaoInit(t *testing.T) {
16+
t.Parallel()
17+
v8.YaoInit(1024)
18+
defer v8.YaoDispose()
19+
20+
iso := v8.YaoNewIsolate()
21+
defer iso.Dispose()
22+
23+
// stat := iso.GetHeapStatistics()
24+
// if stat.HeapSizeLimit > 1100*1024*1024 {
25+
// t.Errorf("HeapSizeLimit error %d", stat.HeapSizeLimit)
26+
// }
27+
}
28+
29+
func TestYaoCopyIsolate(t *testing.T) {
30+
t.Parallel()
31+
v8.YaoInit(1024)
32+
defer v8.YaoDispose()
33+
34+
iso := v8.YaoNewIsolate()
35+
defer iso.Dispose()
36+
37+
new, err := iso.Copy()
38+
if err != nil {
39+
t.Error(err)
40+
}
41+
defer new.Dispose()
42+
}
43+
44+
func TestYaoIsolateAsGlobal(t *testing.T) {
45+
46+
v8.YaoInit(1024)
47+
defer v8.YaoDispose()
48+
49+
iso := v8.YaoNewIsolate()
50+
defer iso.Dispose()
51+
52+
iso.AsGlobal()
53+
}
54+
55+
func TestYaoNewIsolateFromGlobal(t *testing.T) {
56+
v8.YaoInit(1024)
57+
defer v8.YaoDispose()
58+
59+
iso := v8.YaoNewIsolate()
60+
iso.AsGlobal()
61+
iso.Dispose()
62+
iso = nil
63+
64+
new, err := v8.YaoNewIsolateFromGlobal()
65+
if err != nil {
66+
t.Error(err)
67+
}
68+
69+
if new == nil {
70+
t.Errorf("new is nil")
71+
}
72+
defer new.Dispose()
73+
}

0 commit comments

Comments
 (0)