Skip to content

Commit

Permalink
feat: add node helpers for interacting with functions
Browse files Browse the repository at this point in the history
  • Loading branch information
edusperoni committed Jul 23, 2023
1 parent 5a6c2ee commit 50f33e7
Show file tree
Hide file tree
Showing 2 changed files with 387 additions and 0 deletions.
130 changes: 130 additions & 0 deletions NativeScript/runtime/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,136 @@ void Assert(bool condition, v8::Isolate* isolate = nullptr, std::string const &r

void StopExecutionAndLogStackTrace(v8::Isolate* isolate);




// Helpers from Node
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
const char* data,
int length) {
return v8::String::NewFromOneByte(isolate,
reinterpret_cast<const uint8_t*>(data),
v8::NewStringType::kNormal,
length).ToLocalChecked();
}
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
const signed char* data,
int length) {
return v8::String::NewFromOneByte(isolate,
reinterpret_cast<const uint8_t*>(data),
v8::NewStringType::kNormal,
length).ToLocalChecked();
}
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
const unsigned char* data,
int length) {
return v8::String::NewFromOneByte(
isolate, data, v8::NewStringType::kNormal, length)
.ToLocalChecked();
}

// Convenience wrapper around v8::String::NewFromOneByte().
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
const char* data,
int length = -1);
// For the people that compile with -funsigned-char.
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
const signed char* data,
int length = -1);
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
const unsigned char* data,
int length = -1);



v8::Local<v8::FunctionTemplate> NewFunctionTemplate(
v8::Isolate* isolate,
v8::FunctionCallback callback,
v8::Local<v8::Signature> signature = v8::Local<v8::Signature>(),
v8::ConstructorBehavior behavior = v8::ConstructorBehavior::kAllow,
v8::SideEffectType side_effect = v8::SideEffectType::kHasSideEffect,
const v8::CFunction* c_function = nullptr);
// Convenience methods for NewFunctionTemplate().
void SetMethod(v8::Local<v8::Context> context,
v8::Local<v8::Object> that,
const char* name,
v8::FunctionCallback callback);
// Similar to SetProtoMethod but without receiver signature checks.
void SetMethod(v8::Isolate* isolate,
v8::Local<v8::Template> that,
const char* name,
v8::FunctionCallback callback);
void SetFastMethod(v8::Isolate* isolate,
v8::Local<v8::Template> that,
const char* name,
v8::FunctionCallback slow_callback,
const v8::CFunction* c_function);
void SetFastMethod(v8::Local<v8::Context> context,
v8::Local<v8::Object> that,
const char* name,
v8::FunctionCallback slow_callback,
const v8::CFunction* c_function);
void SetFastMethodNoSideEffect(v8::Isolate* isolate,
v8::Local<v8::Template> that,
const char* name,
v8::FunctionCallback slow_callback,
const v8::CFunction* c_function);
void SetFastMethodNoSideEffect(v8::Local<v8::Context> context,
v8::Local<v8::Object> that,
const char* name,
v8::FunctionCallback slow_callback,
const v8::CFunction* c_function);
void SetProtoMethod(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback);
void SetInstanceMethod(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback);
// Safe variants denote the function has no side effects.
void SetMethodNoSideEffect(v8::Local<v8::Context> context,
v8::Local<v8::Object> that,
const char* name,
v8::FunctionCallback callback);
void SetProtoMethodNoSideEffect(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback);
void SetMethodNoSideEffect(v8::Isolate* isolate,
v8::Local<v8::Template> that,
const char* name,
v8::FunctionCallback callback);
enum class SetConstructorFunctionFlag {
NONE,
SET_CLASS_NAME,
};
void SetConstructorFunction(v8::Local<v8::Context> context,
v8::Local<v8::Object> that,
const char* name,
v8::Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag =
SetConstructorFunctionFlag::SET_CLASS_NAME);
void SetConstructorFunction(v8::Local<v8::Context> context,
v8::Local<v8::Object> that,
v8::Local<v8::String> name,
v8::Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag =
SetConstructorFunctionFlag::SET_CLASS_NAME);
void SetConstructorFunction(v8::Isolate* isolate,
v8::Local<v8::Template> that,
const char* name,
v8::Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag =
SetConstructorFunctionFlag::SET_CLASS_NAME);
void SetConstructorFunction(v8::Isolate* isolate,
v8::Local<v8::Template> that,
v8::Local<v8::String> name,
v8::Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag =
SetConstructorFunctionFlag::SET_CLASS_NAME);


}

#endif /* Helpers_h */
257 changes: 257 additions & 0 deletions NativeScript/runtime/Helpers.mm
Original file line number Diff line number Diff line change
Expand Up @@ -679,3 +679,260 @@
void tns::StopExecutionAndLogStackTrace(v8::Isolate* isolate) {
Assert(false, isolate);
}


namespace tns {
Local<v8::FunctionTemplate> NewFunctionTemplate(
v8::Isolate* isolate,
v8::FunctionCallback callback,
Local<v8::Signature> signature,
v8::ConstructorBehavior behavior,
v8::SideEffectType side_effect_type,
const v8::CFunction* c_function) {
return v8::FunctionTemplate::New(isolate,
callback,
Local<v8::Value>(),
signature,
0,
behavior,
side_effect_type,
c_function);
}
void SetMethod(Local<v8::Context> context,
Local<v8::Object> that,
const char* name,
v8::FunctionCallback callback) {
Isolate* isolate = context->GetIsolate();
Local<v8::Function> function =
NewFunctionTemplate(isolate,
callback,
Local<v8::Signature>(),
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasSideEffect)
->GetFunction(context)
.ToLocalChecked();
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->Set(context, name_string, function).Check();
function->SetName(name_string); // NODE_SET_METHOD() compatibility.
}
void SetMethod(v8::Isolate* isolate,
v8::Local<v8::Template> that,
const char* name,
v8::FunctionCallback callback) {
Local<v8::FunctionTemplate> t =
NewFunctionTemplate(isolate,
callback,
Local<v8::Signature>(),
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasSideEffect);
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->Set(name_string, t);
}
void SetFastMethod(Isolate* isolate,
Local<Template> that,
const char* name,
v8::FunctionCallback slow_callback,
const v8::CFunction* c_function) {
Local<v8::FunctionTemplate> t =
NewFunctionTemplate(isolate,
slow_callback,
Local<v8::Signature>(),
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasSideEffect,
c_function);
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->Set(name_string, t);
}
void SetFastMethod(Local<v8::Context> context,
Local<v8::Object> that,
const char* name,
v8::FunctionCallback slow_callback,
const v8::CFunction* c_function) {
Isolate* isolate = context->GetIsolate();
Local<v8::Function> function =
NewFunctionTemplate(isolate,
slow_callback,
Local<v8::Signature>(),
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasSideEffect,
c_function)
->GetFunction(context)
.ToLocalChecked();
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->Set(context, name_string, function).Check();
}
void SetFastMethodNoSideEffect(Local<v8::Context> context,
Local<v8::Object> that,
const char* name,
v8::FunctionCallback slow_callback,
const v8::CFunction* c_function) {
Isolate* isolate = context->GetIsolate();
Local<v8::Function> function =
NewFunctionTemplate(isolate,
slow_callback,
Local<v8::Signature>(),
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasNoSideEffect,
c_function)
->GetFunction(context)
.ToLocalChecked();
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->Set(context, name_string, function).Check();
}
void SetFastMethodNoSideEffect(Isolate* isolate,
Local<Template> that,
const char* name,
v8::FunctionCallback slow_callback,
const v8::CFunction* c_function) {
Local<v8::FunctionTemplate> t =
NewFunctionTemplate(isolate,
slow_callback,
Local<v8::Signature>(),
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasNoSideEffect,
c_function);
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->Set(name_string, t);
}
void SetMethodNoSideEffect(Local<v8::Context> context,
Local<v8::Object> that,
const char* name,
v8::FunctionCallback callback) {
Isolate* isolate = context->GetIsolate();
Local<v8::Function> function =
NewFunctionTemplate(isolate,
callback,
Local<v8::Signature>(),
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasNoSideEffect)
->GetFunction(context)
.ToLocalChecked();
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->Set(context, name_string, function).Check();
function->SetName(name_string); // NODE_SET_METHOD() compatibility.
}
void SetMethodNoSideEffect(Isolate* isolate,
Local<v8::Template> that,
const char* name,
v8::FunctionCallback callback) {
Local<v8::FunctionTemplate> t =
NewFunctionTemplate(isolate,
callback,
Local<v8::Signature>(),
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasNoSideEffect);
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->Set(name_string, t);
}
void SetProtoMethod(v8::Isolate* isolate,
Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback) {
Local<v8::Signature> signature = v8::Signature::New(isolate, that);
Local<v8::FunctionTemplate> t =
NewFunctionTemplate(isolate,
callback,
signature,
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasSideEffect);
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->PrototypeTemplate()->Set(name_string, t);
t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility.
}
void SetProtoMethodNoSideEffect(v8::Isolate* isolate,
Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback) {
Local<v8::Signature> signature = v8::Signature::New(isolate, that);
Local<v8::FunctionTemplate> t =
NewFunctionTemplate(isolate,
callback,
signature,
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasNoSideEffect);
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->PrototypeTemplate()->Set(name_string, t);
t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility.
}
void SetInstanceMethod(v8::Isolate* isolate,
Local<v8::FunctionTemplate> that,
const char* name,
v8::FunctionCallback callback) {
Local<v8::Signature> signature = v8::Signature::New(isolate, that);
Local<v8::FunctionTemplate> t =
NewFunctionTemplate(isolate,
callback,
signature,
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasSideEffect);
// kInternalized strings are created in the old space.
const v8::NewStringType type = v8::NewStringType::kInternalized;
Local<v8::String> name_string =
v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked();
that->InstanceTemplate()->Set(name_string, t);
t->SetClassName(name_string);
}
void SetConstructorFunction(Local<v8::Context> context,
Local<v8::Object> that,
const char* name,
Local<v8::FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag) {
Isolate* isolate = context->GetIsolate();
SetConstructorFunction(
context, that, tns::OneByteString(isolate, name), tmpl, flag);
}
void SetConstructorFunction(Local<Context> context,
Local<Object> that,
Local<v8::String> name,
Local<FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag) {
if (flag == SetConstructorFunctionFlag::SET_CLASS_NAME)
tmpl->SetClassName(name);
that->Set(context, name, tmpl->GetFunction(context).ToLocalChecked()).Check();
}
void SetConstructorFunction(Isolate* isolate,
Local<Template> that,
const char* name,
Local<FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag) {
SetConstructorFunction(
isolate, that, OneByteString(isolate, name), tmpl, flag);
}
void SetConstructorFunction(Isolate* isolate,
Local<Template> that,
Local<v8::String> name,
Local<FunctionTemplate> tmpl,
SetConstructorFunctionFlag flag) {
if (flag == SetConstructorFunctionFlag::SET_CLASS_NAME)
tmpl->SetClassName(name);
that->Set(name, tmpl);
}
};

0 comments on commit 50f33e7

Please sign in to comment.