Skip to content

Commit 4bf0d4e

Browse files
Gabriel SchulhofMylesBorins
Gabriel Schulhof
authored andcommitted
n-api: implement napi_run_script
Fixes: nodejs/abi-stable-node#51 PR-URL: #15216 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Colin Ihrig <[email protected] Reviewed-By: James M Snell <jasnell.gmail.com> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Timothy Gu <[email protected]>
1 parent dae86e4 commit 4bf0d4e

File tree

5 files changed

+78
-0
lines changed

5 files changed

+78
-0
lines changed

doc/api/n-api.md

+21
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ The documentation for N-API is structured as follows:
4343
* [Object Wrap][]
4444
* [Asynchronous Operations][]
4545
* [Promises][]
46+
* [Script Execution][]
4647

4748
The N-API is a C API that ensures ABI stability across Node.js versions
4849
and different compiler levels. However, we also understand that a C++
@@ -3556,6 +3557,25 @@ NAPI_EXTERN napi_status napi_is_promise(napi_env env,
35563557
- `[out] is_promise`: Flag indicating whether `promise` is a native promise
35573558
object - that is, a promise object created by the underlying engine.
35583559

3560+
## Script execution
3561+
3562+
N-API provides an API for executing a string containing JavaScript using the
3563+
underlying JavaScript engine.
3564+
3565+
### napi_run_script
3566+
<!-- YAML
3567+
added: REPLACEME
3568+
-->
3569+
```C
3570+
NAPI_EXTERN napi_status napi_run_script(napi_env env,
3571+
napi_value script,
3572+
napi_value* result);
3573+
```
3574+
3575+
- `[in] env`: The environment that the API is invoked under.
3576+
- `[in] script`: A JavaScript string containing the script to execute.
3577+
- `[out] result`: The value resulting from having executed the script.
3578+
35593579
[Promises]: #n_api_promises
35603580
[Asynchronous Operations]: #n_api_asynchronous_operations
35613581
[Basic N-API Data Types]: #n_api_basic_n_api_data_types
@@ -3565,6 +3585,7 @@ object - that is, a promise object created by the underlying engine.
35653585
[Native Abstractions for Node.js]: https://github.com/nodejs/nan
35663586
[Object Lifetime Management]: #n_api_object_lifetime_management
35673587
[Object Wrap]: #n_api_object_wrap
3588+
[Script Execution]: #n_api_script_execution
35683589
[Section 9.1.6]: https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc
35693590
[Section 12.5.5]: https://tc39.github.io/ecma262/#sec-typeof-operator
35703591
[Section 24.3]: https://tc39.github.io/ecma262/#sec-dataview-objects

src/node_api.cc

+27
Original file line numberDiff line numberDiff line change
@@ -3423,3 +3423,30 @@ NAPI_EXTERN napi_status napi_is_promise(napi_env env,
34233423

34243424
return napi_clear_last_error(env);
34253425
}
3426+
3427+
NAPI_EXTERN napi_status napi_run_script(napi_env env,
3428+
napi_value script,
3429+
napi_value* result) {
3430+
NAPI_PREAMBLE(env);
3431+
CHECK_ARG(env, script);
3432+
CHECK_ARG(env, result);
3433+
3434+
v8::Local<v8::Value> v8_script = v8impl::V8LocalValueFromJsValue(script);
3435+
3436+
if (!v8_script->IsString()) {
3437+
return napi_set_last_error(env, napi_string_expected);
3438+
}
3439+
3440+
v8::Local<v8::Context> context = env->isolate->GetCurrentContext();
3441+
3442+
auto maybe_script = v8::Script::Compile(context,
3443+
v8::Local<v8::String>::Cast(v8_script));
3444+
CHECK_MAYBE_EMPTY(env, maybe_script, napi_generic_failure);
3445+
3446+
auto script_result =
3447+
maybe_script.ToLocalChecked()->Run(context);
3448+
CHECK_MAYBE_EMPTY(env, script_result, napi_generic_failure);
3449+
3450+
*result = v8impl::JsValueFromV8LocalValue(script_result.ToLocalChecked());
3451+
return GET_RETURN_STATUS(env);
3452+
}

src/node_api.h

+5
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,11 @@ NAPI_EXTERN napi_status napi_adjust_external_memory(napi_env env,
562562
int64_t change_in_bytes,
563563
int64_t* adjusted_value);
564564

565+
// Runnig a script
566+
NAPI_EXTERN napi_status napi_run_script(napi_env env,
567+
napi_value script,
568+
napi_value* result);
569+
565570
EXTERN_C_END
566571

567572
#endif // SRC_NODE_API_H_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use strict';
2+
3+
const common = require('../../common');
4+
const assert = require('assert');
5+
6+
// addon is referenced through the eval expression in testFile
7+
// eslint-disable-next-line no-unused-vars
8+
const addon = require(`./build/${common.buildType}/test_general`);
9+
10+
assert.strictEqual(addon.testNapiRun('(41.92 + 0.08);'), 42,
11+
'napi_run_script() works correctly');
12+
assert.throws(() => addon.testNapiRun({ abc: 'def' }), /string was expected/);

test/addons-napi/test_general/test_general.c

+13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <node_api.h>
2+
#include <stdlib.h>
23
#include "../common.h"
34

45
napi_value testStrictEquals(napi_env env, napi_callback_info info) {
@@ -215,12 +216,24 @@ napi_value testAdjustExternalMemory(napi_env env, napi_callback_info info) {
215216
return result;
216217
}
217218

219+
napi_value testNapiRun(napi_env env, napi_callback_info info) {
220+
napi_value script, result;
221+
size_t argc = 1;
222+
223+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &script, NULL, NULL));
224+
225+
NAPI_CALL(env, napi_run_script(env, script, &result));
226+
227+
return result;
228+
}
229+
218230
void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
219231
napi_property_descriptor descriptors[] = {
220232
DECLARE_NAPI_PROPERTY("testStrictEquals", testStrictEquals),
221233
DECLARE_NAPI_PROPERTY("testGetPrototype", testGetPrototype),
222234
DECLARE_NAPI_PROPERTY("testGetVersion", testGetVersion),
223235
DECLARE_NAPI_PROPERTY("testGetNodeVersion", testGetNodeVersion),
236+
DECLARE_NAPI_PROPERTY("testNapiRun", testNapiRun),
224237
DECLARE_NAPI_PROPERTY("doInstanceOf", doInstanceOf),
225238
DECLARE_NAPI_PROPERTY("getUndefined", getUndefined),
226239
DECLARE_NAPI_PROPERTY("getNull", getNull),

0 commit comments

Comments
 (0)