Skip to content

feat: type-tag-aware unwrap and removeWrap#7

Merged
wemeetagain merged 3 commits intomainfrom
nh/type-tag-unwrap
Mar 23, 2026
Merged

feat: type-tag-aware unwrap and removeWrap#7
wemeetagain merged 3 commits intomainfrom
nh/type-tag-unwrap

Conversation

@nazarhussain
Copy link
Copy Markdown
Contributor

@nazarhussain nazarhussain commented Mar 17, 2026

Summary

  • Adds unwrapChecked / removeWrapChecked to Env — thin wrappers that verify an object's type tag via napi_check_object_type_tag before unwrapping, returning error.InvalidArg on mismatch
  • Existing unwrap / removeWrap remain unchanged (plain N-API wrappers)
  • Adds examples/type_tag/ with a Cat/Dog example demonstrating how type tags prevent silently reinterpreting memory when the wrong this is passed to a native method

Motivation

When multiple classes use napi_wrap, passing the wrong JS object to a method silently casts the native pointer to the wrong type. Type tags (napi_type_tag_object + napi_check_object_type_tag) are the N-API solution for this, but the check-then-unwrap pattern is boilerplate unwrapChecked makes it a single explicit call.

Test plan

  • zig build compiles all examples
  • vitest run examples/type_tag/mod.test.ts — 3 tests pass (Cat, Dog, cross-type mismatch throws)

src/Env.zig Outdated
/// https://nodejs.org/api/n-api.html#napi_unwrap
pub fn unwrap(self: Env, comptime Data: type, object: Value) NapiError!*Data {
fn dataTypeTagFor(comptime Data: type) ?c.napi_type_tag {
if (!@hasDecl(Data, "type_tag")) return null;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is quite frameworky (as in -- not part of napi, something you're adding on top) and needs to be documented somewhere

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the implicit feature and added an explicit API with an example.

Copy link
Copy Markdown

@lodekeeper-z lodekeeper-z left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean implementation. Type-tagged unwrap is exactly what we need for production NAPI bindings — prevents silent memory reinterpretation when JS passes wrong this. Good example coverage with the Cat/Dog test.

Copy link
Copy Markdown
Member

@wemeetagain wemeetagain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really nice addition :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants