1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-28 16:20:57 -05:00
denoland-deno/cli/napi
Nathan Whitaker 834371a592
fix(napi): Don't run microtasks in napi_resolve_deferred (#25246)
Fixes an incredibly obscure bug that causes parcel's file watcher to not
get any file update notifications on macOS.

The issue was that the native addon was calling `napi_resolve_deferred`,
but when we resolved the promise, v8 was running microtasks
automatically. That executed JS, which called back into the native addon
and broke the addon's assumption that the call wouldn't be reentrant.
2024-08-29 15:38:06 +02:00
..
sym 1.46.1 (#25153) 2024-08-22 07:18:55 -07:00
generated_symbol_exports_list_linux.def Revert "chore: move all node-api impl to ext (#24662)" (#24680) 2024-07-23 00:01:31 +00:00
generated_symbol_exports_list_macos.def Revert "chore: move all node-api impl to ext (#24662)" (#24680) 2024-07-23 00:01:31 +00:00
generated_symbol_exports_list_windows.def Revert "chore: move all node-api impl to ext (#24662)" (#24680) 2024-07-23 00:01:31 +00:00
js_native_api.rs fix(napi): Don't run microtasks in napi_resolve_deferred (#25246) 2024-08-29 15:38:06 +02:00
mod.rs Revert "chore: move all node-api impl to ext (#24662)" (#24680) 2024-07-23 00:01:31 +00:00
node_api.rs Revert "chore: move all node-api impl to ext (#24662)" (#24680) 2024-07-23 00:01:31 +00:00
README.md Revert "chore: move all node-api impl to ext (#24662)" (#24680) 2024-07-23 00:01:31 +00:00
util.rs Revert "chore: move all node-api impl to ext (#24662)" (#24680) 2024-07-23 00:01:31 +00:00

napi

This directory contains source for Deno's Node-API implementation. It depends on napi_sym and deno_napi.

Files are generally organized the same as in Node.js's implementation to ease in ensuring compatibility.

Adding a new function

Add the symbol name to cli/napi_sym/symbol_exports.json.

{
  "symbols": [
    ...
    "napi_get_undefined",
-   "napi_get_null"
+   "napi_get_null",
+   "napi_get_boolean"
  ]
}

Determine where to place the implementation. napi_get_boolean is related to JS values so we will place it in js_native_api.rs. If something is not clear, just create a new file module.

See napi_sym for writing the implementation:

#[napi_sym::napi_sym]
pub fn napi_get_boolean(
  env: *mut Env,
  value: bool,
  result: *mut napi_value,
) -> Result {
  // ...
  Ok(())
}

Update the generated symbol lists using the script:

deno run --allow-write tools/napi/generate_symbols_lists.js

Add a test in /tests/napi. You can also refer to Node.js test suite for Node-API.

// tests/napi/boolean_test.js
import { assertEquals, loadTestLibrary } from "./common.js";
const lib = loadTestLibrary();
Deno.test("napi get boolean", function () {
  assertEquals(lib.test_get_boolean(true), true);
  assertEquals(lib.test_get_boolean(false), false);
});
// tests/napi/src/boolean.rs

use napi_sys::Status::napi_ok;
use napi_sys::ValueType::napi_boolean;
use napi_sys::*;

extern "C" fn test_boolean(
  env: napi_env,
  info: napi_callback_info,
) -> napi_value {
  let (args, argc, _) = crate::get_callback_info!(env, info, 1);
  assert_eq!(argc, 1);

  let mut ty = -1;
  assert!(unsafe { napi_typeof(env, args[0], &mut ty) } == napi_ok);
  assert_eq!(ty, napi_boolean);

  // Use napi_get_boolean here...

  value
}

pub fn init(env: napi_env, exports: napi_value) {
  let properties = &[crate::new_property!(env, "test_boolean\0", test_boolean)];

  unsafe {
    napi_define_properties(env, exports, properties.len(), properties.as_ptr())
  };
}
// tests/napi/src/lib.rs

+ mod boolean;

...

#[no_mangle]
unsafe extern "C" fn napi_register_module_v1(
  env: napi_env,
  exports: napi_value,
) -> napi_value {
  ...
+ boolean::init(env, exports);

  exports
}

Run the test using cargo test -p tests/napi.