Skip to content

Instantly share code, notes, and snippets.

@devsnek
Created April 27, 2018 22:42
Show Gist options
  • Save devsnek/2fd71cab12f3f077f6ee70d2efa60854 to your computer and use it in GitHub Desktop.
Save devsnek/2fd71cab12f3f077f6ee70d2efa60854 to your computer and use it in GitHub Desktop.
diff --git a/src/node_api.cc b/src/node_api.cc
index 3a02e5effa..0bdf244ab0 100644
--- a/src/node_api.cc
+++ b/src/node_api.cc
@@ -275,6 +275,12 @@ node::CallbackScope* V8CallbackScopeFromJsCallbackScope(
static_assert(sizeof(v8::Local<v8::Value>) == sizeof(napi_value),
"Cannot convert between v8::Local<v8::Value> and napi_value");
+static_assert(sizeof(v8::Local<v8::Script>) == sizeof(napi_script),
+ "Cannot convert between v8::Local<v8::Script> and napi_script");
+
+static_assert(sizeof(v8::Local<v8::Module>) == sizeof(napi_module),
+ "Cannot convert between v8::Local<v8::Module> and napi_module");
+
static
napi_deferred JsDeferredFromNodePersistent(node::Persistent<v8::Value>* local) {
return reinterpret_cast<napi_deferred>(local);
@@ -297,6 +303,30 @@ v8::Local<v8::Value> V8LocalValueFromJsValue(napi_value v) {
return local;
}
+static
+napi_script JsScriptFromV8LocalScript(v8::Local<v8::Script> local) {
+ return reinterpret_cast<napi_script>(*local);
+}
+
+static
+v8::Local<v8::Script> V8LocalScriptFromJsScript(napi_script v) {
+ v8::Local<v8::Script> local;
+ memcpy(&local, &v, sizeof(v));
+ return local;
+}
+
+static
+napi_module JsModuleFromV8LocalModule(v8::Local<v8::Module> local) {
+ return reinterpret_cast<napi_module>(*local);
+}
+
+static
+v8::Local<v8::Module> V8LocalModuleFromJsModule(napi_module v) {
+ v8::Local<v8::Module> local;
+ memcpy(&local, &v, sizeof(v));
+ return local;
+}
+
static inline void trigger_fatal_exception(
napi_env env, v8::Local<v8::Value> local_err) {
v8::Local<v8::Message> local_msg =
@@ -856,11 +886,11 @@ napi_status ConcludeDeferred(napi_env env,
// Intercepts the Node-V8 module registration callback. Converts parameters
// to NAPI equivalents and then calls the registration callback specified
// by the NAPI module.
-void napi_module_register_cb(v8::Local<v8::Object> exports,
+void napi_native_module_register_cb(v8::Local<v8::Object> exports,
v8::Local<v8::Value> module,
v8::Local<v8::Context> context,
void* priv) {
- napi_module* mod = static_cast<napi_module*>(priv);
+ napi_native_module* mod = static_cast<napi_native_module*>(priv);
// Create a new napi_env for this module or reference one if a pre-existing
// one is found.
@@ -884,14 +914,14 @@ void napi_module_register_cb(v8::Local<v8::Object> exports,
} // end of anonymous namespace
// Registers a NAPI module.
-void napi_module_register(napi_module* mod) {
+void napi_native_module_register(napi_native_module* mod) {
node::node_module* nm = new node::node_module {
-1,
mod->nm_flags,
nullptr,
mod->nm_filename,
nullptr,
- napi_module_register_cb,
+ napi_native_module_register_cb,
mod->nm_modname,
mod, // priv
nullptr,
@@ -2376,6 +2406,119 @@ napi_status napi_coerce_to_string(napi_env env,
return GET_RETURN_STATUS(env);
}
+static
+v8::ScriptOrigin V8ScriptOriginFromNapiOrigin(napi_env env,
+ napi_script_origin origin,
+ bool is_module) {
+ v8::Isolate* isolate = env->isolate;
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
+
+ v8::Local<v8::Value> value =
+ v8impl::V8LocalValueFromJsValue(origin.resource_name);
+ v8::Local<v8::String> filename_str = value->ToString();
+
+ v8::Local<v8::Integer> line_offset;
+ v8::Local<v8::Integer> column_offset;
+
+ value = v8impl::V8LocalValueFromJsValue(origin.line_offset);
+ if (!value.IsEmpty())
+ line_offset = value.As<v8::Integer>();
+ else
+ line_offset = v8::Integer::New(isolate, 0);
+
+ value = v8impl::V8LocalValueFromJsValue(origin.column_offset);
+ if (!value.IsEmpty())
+ column_offset = value.As<v8::Integer>();
+ else
+ column_offset = v8::Integer::New(isolate, 0);
+
+ v8::ScriptOrigin v8_origin(filename_str, // resource name
+ line_offset, // line offset
+ column_offset, // column offset
+ v8::Local<v8::Boolean>(), // resource_is_shared_cross_origin
+ v8::Local<v8::Integer>(), // script id
+ v8::Local<v8::Value>(), // source map url
+ v8::Local<v8::Boolean>(), // is opaque(?)
+ v8::False(isolate), // is wasm
+ v8::Boolean::New(isolate, is_module)); // is module
+
+ return v8_origin;
+}
+
+napi_status napi_create_script(napi_env env,
+ napi_value source,
+ napi_script_origin origin,
+ napi_script* result) {
+ NAPI_PREAMBLE(env);
+ CHECK_ARG(env, source);
+ CHECK_ARG(env, origin);
+
+ v8::Isolate* isolate = env->isolate;
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
+
+ v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(source);
+ RETURN_STATUS_IF_FALSE(env, value->IsString(), napi_invalid_arg);
+ v8::Local<v8::String> source_str = value.As<v8::String>();
+
+ v8::ScriptOrigin v8_origin = V8ScriptOriginFromNapiOrigin(env, origin, false);
+
+ v8::MaybeLocal<v8::Script> script = v8::Script::Compile(
+ context, source_str, &v8_origin);
+
+ if (try_catch.HasCaught()) {
+ return napi_set_last_error(env, napi_pending_exception);
+ } else {
+ CHECK_MAYBE_EMPTY(env, script, napi_generic_failure);
+ if (result != nullptr) {
+ *result = v8impl::JsScriptFromV8LocalScript(script.ToLocalChecked());
+ }
+ }
+
+ return GET_RETURN_STATUS(env);
+}
+
+napi_status napi_evaluate_script(napi_env env,
+ napi_script script,
+ napi_value* result) {
+ NAPI_PREAMBLE(env);
+ CHECK_ARG(env, script);
+
+ v8::Isolate* isolate = env->isolate;
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
+
+ v8::Local<v8::Script> v8_script = v8impl::V8LocalScriptFromJsScript(script);
+
+ v8::MaybeLocal<v8::Value> value = v8_script->Run(context);
+ if (try_catch.HasCaught()) {
+ return napi_set_last_error(env, napi_pending_exception);
+ } else {
+ CHECK_MAYBE_EMPTY(env, value, napi_generic_failure);
+ if (result != nullptr) {
+ *result = v8impl::JsValueFromV8LocalValue(value.ToLocalChecked());
+ }
+ }
+
+ return GET_RETURN_STATUS(env);
+}
+
+napi_status napi_create_module(napi_env env,
+ napi_value source,
+ napi_script_origin origin,
+ napi_module* result) {}
+
+// napi_status napi_link_module(napi_env env) {}
+
+napi_status napi_instantiate_module(napi_env env,
+ napi_module module) {}
+
+napi_status napi_evaluate_module(napi_env env,
+ napi_module module,
+ napi_value* result) {}
+
+napi_status napi_get_module_namespace(napi_env env,
+ napi_module module,
+ napi_value* result) {}
+
napi_status napi_wrap(napi_env env,
napi_value js_object,
void* native_object,
diff --git a/src/node_api.h b/src/node_api.h
index aaf002b758..1bb0e3d141 100644
--- a/src/node_api.h
+++ b/src/node_api.h
@@ -36,6 +36,8 @@ struct uv_loop_s; // Forward declaration.
#define NAPI_NO_RETURN
#endif
+#define NAPI_DEPRECATED(message, declarator) \
+ declarator __attribute__((deprecated(message)))
typedef napi_value (*napi_addon_register_func)(napi_env env,
napi_value exports);
@@ -48,7 +50,7 @@ typedef struct {
const char* nm_modname;
void* nm_priv;
void* reserved[4];
-} napi_module;
+} napi_native_module;
#define NAPI_MODULE_VERSION 1
@@ -75,7 +77,7 @@ typedef struct {
#define NAPI_MODULE_X(modname, regfunc, priv, flags) \
EXTERN_C_START \
- static napi_module _module = \
+ static napi_native_module _module = \
{ \
NAPI_MODULE_VERSION, \
flags, \
@@ -86,7 +88,7 @@ typedef struct {
{0}, \
}; \
NAPI_C_CTOR(_register_ ## modname) { \
- napi_module_register(&_module); \
+ napi_native_module_register(&_module); \
} \
EXTERN_C_END
@@ -97,7 +99,7 @@ typedef struct {
EXTERN_C_START
-NAPI_EXTERN void napi_module_register(napi_module* mod);
+NAPI_EXTERN void napi_native_module_register(napi_native_module* mod);
NAPI_EXTERN napi_status
napi_get_last_error_info(napi_env env,
@@ -343,6 +345,25 @@ napi_define_class(napi_env env,
const napi_property_descriptor* properties,
napi_value* result);
+NAPI_EXTERN napi_status napi_create_script(napi_env env,
+ napi_value source,
+ napi_value filename,
+ napi_script* result);
+NAPI_EXTERN napi_status napi_evaluate_script(napi_env env,
+ napi_script script,
+ napi_value* result);
+
+NAPI_EXTERN napi_status napi_create_module(napi_env env,
+ napi_value source,
+ napi_value url,
+ napi_module* result);
+// NAPI_EXTERN napi_status napi_link_module();
+NAPI_EXTERN napi_status napi_instantiate_module(napi_env env,
+ napi_module module);
+NAPI_EXTERN napi_status napi_evaluate_module(napi_env env,
+ napi_module module,
+ napi_value* result);
+
// Methods to work with external data objects
NAPI_EXTERN napi_status napi_wrap(napi_env env,
napi_value js_object,
diff --git a/src/node_api_types.h b/src/node_api_types.h
index 76f38802e8..bc2baac7b2 100644
--- a/src/node_api_types.h
+++ b/src/node_api_types.h
@@ -20,6 +20,8 @@ typedef struct napi_callback_info__ *napi_callback_info;
typedef struct napi_async_context__ *napi_async_context;
typedef struct napi_async_work__ *napi_async_work;
typedef struct napi_deferred__ *napi_deferred;
+typedef struct napi_script__ *napi_script;
+typedef struct napi_module__ *napi_module;
typedef enum {
napi_default = 0,
@@ -114,4 +116,10 @@ typedef struct {
const char* release;
} napi_node_version;
+typedef struct {
+ napi_value resource_name;
+ napi_value line_offset;
+ napi_value column_offset;
+} napi_script_origin;
+
#endif // SRC_NODE_API_TYPES_H_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment