Skip to content

Commit

Permalink
fix(napi-derive): catch_unwind on constructor (#1869)
Browse files Browse the repository at this point in the history
- Close #1852
  • Loading branch information
Brooooooklyn authored Dec 27, 2023
1 parent b411b87 commit 02dd4c3
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 3 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/zig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: Zig-Cross-Compile

env:
DEBUG: 'napi:*'
TEST_ZIG_CROSS: '1'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down Expand Up @@ -33,7 +34,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
cache: 'yarn'
- name: Install
uses: dtolnay/rust-toolchain@stable
Expand Down Expand Up @@ -99,7 +100,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
cache: 'yarn'
- name: Install dependencies
run: |
Expand Down
7 changes: 6 additions & 1 deletion crates/backend/src/codegen/fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,16 @@ impl TryToTokens for NapiFn {
{
quote! { #native_call }
} else if self.kind == FnKind::Constructor {
let return_from_factory = if self.catch_unwind {
quote! { return Ok(std::ptr::null_mut()); }
} else {
quote! { return std::ptr::null_mut(); }
};
quote! {
// constructor function is called from class `factory`
// so we should skip the original `constructor` logic
if napi::__private::___CALL_FROM_FACTORY.with(|inner| inner.load(std::sync::atomic::Ordering::Relaxed)) {
return std::ptr::null_mut();
#return_from_factory
}
#function_call_inner
}
Expand Down
8 changes: 8 additions & 0 deletions examples/napi/__tests__/__snapshots__/typegen.spec.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ Generated by [AVA](https://avajs.dev).
}␊
export type Blake2bKey = Blake2BKey␊
export class CatchOnConstructor {␊
constructor()␊
}␊
export class CatchOnConstructor2 {␊
constructor()␊
}␊
export class ClassWithFactory {␊
name: string␊
static withName(name: string): ClassWithFactory␊
Expand Down
Binary file modified examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap
Binary file not shown.
20 changes: 20 additions & 0 deletions examples/napi/__tests__/values.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ const {
arrayBufferPassThrough,
JsRepo,
CssStyleSheet,
CatchOnConstructor,
CatchOnConstructor2,
asyncReduceBuffer,
callbackReturnPromise,
callbackReturnPromiseAndSpawn,
Expand Down Expand Up @@ -234,6 +236,24 @@ test('class', (t) => {
// @ts-expect-error
plusOne.call('')
})

t.notThrows(() => {
new CatchOnConstructor()
})

if (!process.env.TEST_ZIG_CROSS) {
t.throws(
() => {
new CatchOnConstructor2()
},
(() =>
process.env.WASI_TEST
? undefined
: {
message: 'CatchOnConstructor2 panic',
})(),
)
}
})

test('async self in class', async (t) => {
Expand Down
8 changes: 8 additions & 0 deletions examples/napi/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ export class Blake2BKey {
}
export type Blake2bKey = Blake2BKey

export class CatchOnConstructor {
constructor()
}

export class CatchOnConstructor2 {
constructor()
}

export class ClassWithFactory {
name: string
static withName(name: string): ClassWithFactory
Expand Down
22 changes: 22 additions & 0 deletions examples/napi/src/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,3 +432,25 @@ impl GetterSetterWithClosures {
Ok(Self {})
}
}

#[napi]
pub struct CatchOnConstructor {}

#[napi]
impl CatchOnConstructor {
#[napi(constructor, catch_unwind)]
pub fn new() -> Self {
Self {}
}
}

#[napi]
pub struct CatchOnConstructor2 {}

#[napi]
impl CatchOnConstructor2 {
#[napi(constructor, catch_unwind)]
pub fn new() -> Self {
panic!("CatchOnConstructor2 panic");
}
}

0 comments on commit 02dd4c3

Please sign in to comment.