From e65234b42b4472b91116ed5519462d35651bad19 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Tue, 14 Jul 2026 12:32:41 -0400 Subject: [PATCH 1/3] fix: vs2026 ICE compatibility --- napi-inl.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/napi-inl.h b/napi-inl.h index 9c0c47859..ec63ffeee 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -4681,48 +4681,71 @@ template template ::InstanceVoidMethodCallback method> inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( const char* utf8name, napi_property_attributes attributes, void* data) { +#ifdef _MSC_VER + // MSVC (as of v145 / Visual Studio 2026) raises an internal compiler error + // (C1001) when a pointer-to-member-function is used as a non-type template + // parameter, as the static compile-time dispatch below does. On MSVC, fall + // back to the runtime overload, which passes `method` as a value instead. + return InstanceMethod(utf8name, method, attributes, data); +#else napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.method = details::TemplatedInstanceVoidCallback; desc.data = data; desc.attributes = attributes; return desc; +#endif } template template ::InstanceMethodCallback method> inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( const char* utf8name, napi_property_attributes attributes, void* data) { +#ifdef _MSC_VER + // See the note in the InstanceMethod overload above. + return InstanceMethod(utf8name, method, attributes, data); +#else napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.method = details::TemplatedInstanceCallback; desc.data = data; desc.attributes = attributes; return desc; +#endif } template template ::InstanceVoidMethodCallback method> inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( Symbol name, napi_property_attributes attributes, void* data) { +#ifdef _MSC_VER + // See the note in the InstanceMethod overload above. + return InstanceMethod(name, method, attributes, data); +#else napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.method = details::TemplatedInstanceVoidCallback; desc.data = data; desc.attributes = attributes; return desc; +#endif } template template ::InstanceMethodCallback method> inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( Symbol name, napi_property_attributes attributes, void* data) { +#ifdef _MSC_VER + // See the note in the InstanceMethod overload above. + return InstanceMethod(name, method, attributes, data); +#else napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.method = details::TemplatedInstanceCallback; desc.data = data; desc.attributes = attributes; return desc; +#endif } template @@ -4768,6 +4791,10 @@ template ::InstanceGetterCallback getter, typename InstanceWrap::InstanceSetterCallback setter> inline ClassPropertyDescriptor InstanceWrap::InstanceAccessor( const char* utf8name, napi_property_attributes attributes, void* data) { +#ifdef _MSC_VER + // See the note in the InstanceMethod overload above. + return InstanceAccessor(utf8name, getter, setter, attributes, data); +#else napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.getter = details::TemplatedInstanceCallback; @@ -4775,6 +4802,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceAccessor( desc.data = data; desc.attributes = attributes; return desc; +#endif } template @@ -4782,6 +4810,10 @@ template ::InstanceGetterCallback getter, typename InstanceWrap::InstanceSetterCallback setter> inline ClassPropertyDescriptor InstanceWrap::InstanceAccessor( Symbol name, napi_property_attributes attributes, void* data) { +#ifdef _MSC_VER + // See the note in the InstanceMethod overload above. + return InstanceAccessor(name, getter, setter, attributes, data); +#else napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.getter = details::TemplatedInstanceCallback; @@ -4789,6 +4821,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceAccessor( desc.data = data; desc.attributes = attributes; return desc; +#endif } template From cd38d1ee80345251da76e53593edc05a0b6fa166 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Tue, 14 Jul 2026 11:58:07 -0400 Subject: [PATCH 2/3] deps: conditionally install node-gyp for vs2026 --- .github/workflows/ci-win.yml | 7 +++++++ .github/workflows/ci.yml | 5 +++++ package.json | 1 + 3 files changed, 13 insertions(+) diff --git a/.github/workflows/ci-win.yml b/.github/workflows/ci-win.yml index 4b0ebfb23..65bc3fe9a 100644 --- a/.github/workflows/ci-win.yml +++ b/.github/workflows/ci-win.yml @@ -60,6 +60,13 @@ jobs: - name: Install dependencies run: | npm install + # node-gyp@12 (from package.json) supports Visual Studio 2026, but only + # node-gyp@13 emits the linker options that Node.js 26 builds require + # (older node-gyp trips LNK1117 on '/opt:lldltojobs'). Upgrade in place for + # Node.js >= 26; other versions keep node-gyp@12. + - name: Use node-gyp@13 for Node.js >= 26 + if: matrix.node-version == '26.x' + run: npm install --no-save node-gyp@13 - name: npm test shell: bash run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3813c3d62..3f078d8b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,6 +55,11 @@ jobs: - name: Install dependencies run: | npm install + # Node.js >= 26 requires node-gyp@13; older versions keep node-gyp@12 + # (from package.json). + - name: Use node-gyp@13 for Node.js >= 26 + if: matrix.node-version == '26.x' + run: npm install --no-save node-gyp@13 - name: npm test run: | if [ "${{ matrix.api_version }}" = "experimental" ]; then diff --git a/package.json b/package.json index f3d472a06..32a2a9c5a 100644 --- a/package.json +++ b/package.json @@ -424,6 +424,7 @@ "eslint": "^9.13.0", "fs-extra": "^11.1.1", "neostandard": "^0.12.0", + "node-gyp": "^12.4.0", "pre-commit": "^1.2.2", "semver": "^7.6.0" }, From a438147a58e46b68bcf90eed10fd68aadb9d3c9b Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Tue, 14 Jul 2026 13:58:44 -0400 Subject: [PATCH 3/3] fixup! increase CI timeout-minutes to 60 --- .github/workflows/ci-win.yml | 2 +- .github/workflows/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-win.yml b/.github/workflows/ci-win.yml index 65bc3fe9a..3bd60207a 100644 --- a/.github/workflows/ci-win.yml +++ b/.github/workflows/ci-win.yml @@ -10,7 +10,7 @@ permissions: jobs: test: - timeout-minutes: 30 + timeout-minutes: 60 strategy: fail-fast: false matrix: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f078d8b0..c583b8c8e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ permissions: jobs: test: - timeout-minutes: 30 + timeout-minutes: 60 strategy: fail-fast: false matrix: