forked from rogchap/v8go
-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathfunction_template.cc
113 lines (95 loc) · 3.38 KB
/
function_template.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "_cgo_export.h"
#include "deps/include/v8-context.h"
#include "deps/include/v8-function.h"
#include "isolate-macros.h"
#include "template-macros.h"
#include "template.h"
using namespace v8;
void FunctionTemplateCallback(const FunctionCallbackInfo<Value>& info) {
Isolate* iso = info.GetIsolate();
ISOLATE_SCOPE(iso);
// This callback function can be called from any Context, which we only know
// at runtime. We extract the Context reference from the embedder data so that
// we can use the context registry to match the Context on the Go side
Local<Context> local_ctx = iso->GetCurrentContext();
int ctx_ref = local_ctx->GetEmbedderData(1).As<Integer>()->Value();
m_ctx* ctx = goContext(ctx_ref);
int callback_ref = info.Data().As<Integer>()->Value();
m_value* _this = new m_value;
_this->id = 0;
_this->iso = iso;
_this->ctx = ctx;
_this->ptr.Reset(iso, Global<Value>(iso, info.This()));
int args_count = info.Length();
ValuePtr thisAndArgs[args_count + 1];
thisAndArgs[0] = tracked_value(ctx, _this);
ValuePtr* args = thisAndArgs + 1;
for (int i = 0; i < args_count; i++) {
m_value* val = new m_value;
val->id = 0;
val->iso = iso;
val->ctx = ctx;
val->ptr.Reset(iso, Global<Value>(iso, info[i]));
args[i] = tracked_value(ctx, val);
}
goFunctionCallback_return retval =
goFunctionCallback(ctx_ref, callback_ref, thisAndArgs, args_count);
if (retval.r1 != nullptr) {
iso->ThrowException(retval.r1->ptr.Get(iso));
} else if (retval.r0 != nullptr) {
info.GetReturnValue().Set(retval.r0->ptr.Get(iso));
} else {
info.GetReturnValue().SetUndefined();
}
}
TemplatePtr NewFunctionTemplate(IsolatePtr iso, int callback_ref) {
Locker locker(iso);
Isolate::Scope isolate_scope(iso);
HandleScope handle_scope(iso);
// (rogchap) We only need to store one value, callback_ref, into the
// C++ callback function data, but if we needed to store more items we could
// use an V8::Array; this would require the internal context from
// iso->GetData(0)
Local<Integer> cbData = Integer::New(iso, callback_ref);
m_template* ot = new m_template;
ot->iso = iso;
ot->ptr.Reset(iso,
FunctionTemplate::New(iso, FunctionTemplateCallback, cbData));
return ot;
}
RtnValue FunctionTemplateGetFunction(m_template* ptr, m_ctx* ctx) {
LOCAL_TEMPLATE(ptr);
TryCatch try_catch(iso);
Local<Context> local_ctx = ctx->ptr.Get(iso);
Context::Scope context_scope(local_ctx);
Local<FunctionTemplate> fn_tmpl = tmpl.As<FunctionTemplate>();
RtnValue rtn = {};
Local<Function> fn;
if (!fn_tmpl->GetFunction(local_ctx).ToLocal(&fn)) {
rtn.error = ExceptionError(try_catch, iso, local_ctx);
return rtn;
}
m_value* val = new m_value;
val->id = 0;
val->iso = iso;
val->ctx = ctx;
val->ptr = Global<Value>(iso, fn);
rtn.value = tracked_value(ctx, val);
return rtn;
}
m_template* FunctionTemplateInstanceTemplate(m_template* ptr) {
LOCAL_TEMPLATE(ptr);
Local<FunctionTemplate> fn_tmpl = tmpl.As<FunctionTemplate>();
m_template* ot = new m_template;
ot->iso = iso;
ot->ptr.Reset(iso, fn_tmpl->InstanceTemplate());
return ot;
}
m_template* FunctionTemplatePrototypeTemplate(m_template* ptr) {
LOCAL_TEMPLATE(ptr);
Local<FunctionTemplate> fn_tmpl = tmpl.As<FunctionTemplate>();
m_template* ot = new m_template;
ot->iso = iso;
ot->ptr.Reset(iso, fn_tmpl->PrototypeTemplate());
return ot;
}