Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split C files #84

Merged
merged 4 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions function_template.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#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;
}
2 changes: 1 addition & 1 deletion function_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
package v8go

// #include <stdlib.h>
// #include "v8go.h"
// #include "function_template.h"
import "C"
import (
"runtime"
Expand Down
30 changes: 30 additions & 0 deletions function_template.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef V8GO_FUNCTION_TEMPLATE_H
#define V8GO_FUNCTION_TEMPLATE_H

#include "errors.h"

#ifdef __cplusplus

namespace v8 {
class Isolate;
}

typedef v8::Isolate v8Isolate;

extern "C" {
#else

typedef struct v8Isolate v8Isolate;

#endif

typedef struct m_template m_template;
typedef struct m_ctx m_ctx;

extern m_template* NewFunctionTemplate(v8Isolate* iso_ptr, int callback_ref);
extern RtnValue FunctionTemplateGetFunction(m_template* ptr, m_ctx* ctx_ptr);

#ifdef __cplusplus
} // extern "C"
#endif
#endif
175 changes: 175 additions & 0 deletions object.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#include "object.h"
#include "deps/include/v8-object.h"
#include "isolate-macros.h"
#include "utils.h"
#include "value-macros.h"
#include "value.h"

using namespace v8;

/********** Object **********/

#define LOCAL_OBJECT(ptr) \
LOCAL_VALUE(ptr) \
Local<Object> obj = value.As<Object>()

void ObjectSet(ValuePtr ptr, const char* key, ValuePtr prop_val) {
LOCAL_OBJECT(ptr);
Local<String> key_val =
String::NewFromUtf8(iso, key, NewStringType::kNormal).ToLocalChecked();
obj->Set(local_ctx, key_val, prop_val->ptr.Get(iso)).Check();
}

void ObjectSetAnyKey(ValuePtr ptr, ValuePtr key, ValuePtr prop_val) {
LOCAL_OBJECT(ptr);
Local<Value> local_key = key->ptr.Get(iso);
obj->Set(local_ctx, local_key, prop_val->ptr.Get(iso)).Check();
}

void ObjectSetIdx(ValuePtr ptr, uint32_t idx, ValuePtr prop_val) {
LOCAL_OBJECT(ptr);
obj->Set(local_ctx, idx, prop_val->ptr.Get(iso)).Check();
}

int ObjectSetInternalField(ValuePtr ptr, int idx, ValuePtr val_ptr) {
LOCAL_OBJECT(ptr);
m_value* prop_val = static_cast<m_value*>(val_ptr);

if (idx >= obj->InternalFieldCount()) {
return 0;
}

obj->SetInternalField(idx, prop_val->ptr.Get(iso));

return 1;
}

int ObjectInternalFieldCount(ValuePtr ptr) {
LOCAL_OBJECT(ptr);
return obj->InternalFieldCount();
}

RtnValue ObjectGet(ValuePtr ptr, const char* key) {
LOCAL_OBJECT(ptr);
RtnValue rtn = {};

Local<String> key_val;
if (!String::NewFromUtf8(iso, key, NewStringType::kNormal)
.ToLocal(&key_val)) {
rtn.error = ExceptionError(try_catch, iso, local_ctx);
return rtn;
}
Local<Value> result;
if (!obj->Get(local_ctx, key_val).ToLocal(&result)) {
rtn.error = ExceptionError(try_catch, iso, local_ctx);
return rtn;
}
m_value* new_val = new m_value;
new_val->id = 0;
new_val->iso = iso;
new_val->ctx = ctx;
new_val->ptr = Global<Value>(iso, result);

rtn.value = tracked_value(ctx, new_val);
return rtn;
}

RtnValue ObjectGetAnyKey(ValuePtr ptr, ValuePtr key) {
LOCAL_OBJECT(ptr);
RtnValue rtn = {};

Local<Value> local_key = key->ptr.Get(iso);
Local<Value> result;
if (!obj->Get(local_ctx, local_key).ToLocal(&result)) {
rtn.error = ExceptionError(try_catch, iso, local_ctx);
return rtn;
}
m_value* new_val = new m_value;
new_val->id = 0;
new_val->iso = iso;
new_val->ctx = ctx;
new_val->ptr = Global<Value>(iso, result);

rtn.value = tracked_value(ctx, new_val);
return rtn;
}

RtnValue ObjectGetInternalField(ValuePtr ptr, int idx) {
LOCAL_OBJECT(ptr);
RtnValue rtn = {};

if (idx >= obj->InternalFieldCount()) {
rtn.error.msg = CopyString("internal field index out of range");
return rtn;
}

Local<Data> result = obj->GetInternalField(idx);
if (!result->IsValue()) {
rtn.error.msg = CopyString("the internal field did not contain a Value");
return rtn;
}

m_value* new_val = new m_value;
new_val->id = 0;
new_val->iso = iso;
new_val->ctx = ctx;
new_val->ptr = Global<Value>(iso, result.As<Value>());

rtn.value = tracked_value(ctx, new_val);
return rtn;
}

RtnValue ObjectGetIdx(ValuePtr ptr, uint32_t idx) {
LOCAL_OBJECT(ptr);
RtnValue rtn = {};

Local<Value> result;
if (!obj->Get(local_ctx, idx).ToLocal(&result)) {
rtn.error = ExceptionError(try_catch, iso, local_ctx);
return rtn;
}
m_value* new_val = new m_value;
new_val->id = 0;
new_val->iso = iso;
new_val->ctx = ctx;
new_val->ptr = Global<Value>(iso, result);

rtn.value = tracked_value(ctx, new_val);
return rtn;
}

int ObjectHas(ValuePtr ptr, const char* key) {
LOCAL_OBJECT(ptr);
Local<String> key_val =
String::NewFromUtf8(iso, key, NewStringType::kNormal).ToLocalChecked();
return obj->Has(local_ctx, key_val).ToChecked();
}

int ObjectHasAnyKey(ValuePtr ptr, ValuePtr key) {
LOCAL_OBJECT(ptr);
Local<Value> local_key = key->ptr.Get(iso);
return obj->Has(local_ctx, local_key).ToChecked();
}

int ObjectHasIdx(ValuePtr ptr, uint32_t idx) {
LOCAL_OBJECT(ptr);
return obj->Has(local_ctx, idx).ToChecked();
}

int ObjectDelete(ValuePtr ptr, const char* key) {
LOCAL_OBJECT(ptr);
Local<String> key_val =
String::NewFromUtf8(iso, key, NewStringType::kNormal).ToLocalChecked();
return obj->Delete(local_ctx, key_val).ToChecked();
}

int ObjectDeleteAnyKey(ValuePtr ptr, ValuePtr key) {
LOCAL_OBJECT(ptr);
Local<Value> local_key = key->ptr.Get(iso);
return obj->Delete(local_ctx, local_key).ToChecked();
}

int ObjectDeleteIdx(ValuePtr ptr, uint32_t idx) {
LOCAL_OBJECT(ptr);
return obj->Delete(local_ctx, idx).ToChecked();
}
2 changes: 1 addition & 1 deletion object.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
package v8go

// #include <stdlib.h>
// #include "v8go.h"
// #include "object.h"
import "C"
import (
"fmt"
Expand Down
33 changes: 33 additions & 0 deletions object.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef V8GO_OBJECT_H
#define V8GO_OBJECT_H

#include <stdint.h>

#include "errors.h"

#ifdef __cplusplus

extern "C" {
#endif

extern void ObjectSet(ValuePtr ptr, const char* key, ValuePtr val_ptr);
extern void ObjectSetAnyKey(ValuePtr ptr, ValuePtr key, ValuePtr val_ptr);
extern void ObjectSetIdx(ValuePtr ptr, uint32_t idx, ValuePtr val_ptr);
extern int ObjectSetInternalField(ValuePtr ptr, int idx, ValuePtr val_ptr);
extern int ObjectInternalFieldCount(ValuePtr ptr);

extern RtnValue ObjectGet(ValuePtr ptr, const char* key);
extern RtnValue ObjectGetAnyKey(ValuePtr ptr, ValuePtr key);
extern RtnValue ObjectGetIdx(ValuePtr ptr, uint32_t idx);
extern RtnValue ObjectGetInternalField(ValuePtr ptr, int idx);
int ObjectHas(ValuePtr ptr, const char* key);
int ObjectHasAnyKey(ValuePtr ptr, ValuePtr key);
int ObjectHasIdx(ValuePtr ptr, uint32_t idx);
int ObjectDelete(ValuePtr ptr, const char* key);
int ObjectDeleteAnyKey(ValuePtr ptr, ValuePtr key);
int ObjectDeleteIdx(ValuePtr ptr, uint32_t idx);

#ifdef __cplusplus
} // extern "C"
#endif
#endif
Loading
Loading