diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 097fb810..5e8872af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: steps: - uses: actions/checkout@v4 - uses: pre-commit/action@v3.0.1 - + ci: strategy: fail-fast: false @@ -35,14 +35,6 @@ jobs: os: ubuntu-24.04-arm # Linux on arm64 - node-version: lts/* os: windows-2025 - - node-version: 14.x - os: windows-2019 - - node-version: 12.x - os: windows-2019 - - node-version: 10.x - os: windows-2019 - - node-version: 8.x - os: windows-2019 runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 diff --git a/appveyor.yml b/appveyor.yml index 7a5adc3a..5cbb7dbe 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,6 +15,8 @@ environment: NODE_GYP_FORCE_PYTHON: C:\Python39-x64\python.exe matrix: # Test against these versions of Io.js and Node.js. # - nodejs_version: "23" # Enable after nodejs/nan#979 or similar. + - nodejs_version: "24" + - nodejs_version: "23" - nodejs_version: "22" - nodejs_version: "22" NODE_GYP_FORCE_PYTHON: C:\Python312-x64\python.exe diff --git a/nan_callbacks.h b/nan_callbacks.h index 2c54857f..c3b1e9cd 100644 --- a/nan_callbacks.h +++ b/nan_callbacks.h @@ -13,6 +13,19 @@ template class FunctionCallbackInfo; template class PropertyCallbackInfo; template class Global; +#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 12 || \ + (V8_MAJOR_VERSION == 12 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION > 4)) +namespace Intercepted { + constexpr v8::Intercepted No() { return v8::Intercepted::kNo; } + constexpr v8::Intercepted Yes() { return v8::Intercepted::kYes; } +}; +#else +namespace Intercepted { + inline void No() {} + inline void Yes() {} +}; +#endif + typedef void(*FunctionCallback)(const FunctionCallbackInfo&); typedef void(*GetterCallback) (v8::Local, const PropertyCallbackInfo&); diff --git a/nan_callbacks_12_inl.h b/nan_callbacks_12_inl.h index f953989a..4fdfd10c 100644 --- a/nan_callbacks_12_inl.h +++ b/nan_callbacks_12_inl.h @@ -106,10 +106,25 @@ class FunctionCallbackInfo { } #if NODE_MAJOR_VERSION < 10 - inline v8::Local Callee() const { return info_.Callee(); } + NAN_DEPRECATED inline v8::Local Callee() const { + return info_.Callee(); + } #endif inline v8::Local Data() const { return data_; } - inline v8::Local Holder() const { return info_.Holder(); } + + inline v8::Local Holder() const { +#if defined(V8_MAJOR_VERSION) && \ + (V8_MAJOR_VERSION > 12 || \ + (V8_MAJOR_VERSION == 12 && \ + (defined(V8_MINOR_VERSION) && \ + (V8_MINOR_VERSION > 5 || \ + (V8_MINOR_VERSION == 5 && defined(V8_BUILD_NUMBER) && \ + V8_BUILD_NUMBER >= 214))))) + return info_.This(); +#else + return info_.Holder(); +#endif + } inline bool IsConstructCall() const { return info_.IsConstructCall(); } inline int Length() const { return info_.Length(); } inline v8::Local operator[](int i) const { return info_[i]; } diff --git a/nan_callbacks_pre_12_inl.h b/nan_callbacks_pre_12_inl.h index c9ba4993..76258638 100644 --- a/nan_callbacks_pre_12_inl.h +++ b/nan_callbacks_pre_12_inl.h @@ -136,9 +136,13 @@ class FunctionCallbackInfo { return ReturnValue(return_value_); } - inline v8::Local Callee() const { return args_.Callee(); } + NAN_DEPRECATED inline v8::Local Callee() const { + return args_.Callee(); + } inline v8::Local Data() const { return data_; } - inline v8::Local Holder() const { return args_.Holder(); } + inline v8::Local Holder() const { + return args_.Holder(); + } inline bool IsConstructCall() const { return args_.IsConstructCall(); } inline int Length() const { return args_.Length(); } inline v8::Local operator[](int i) const { return args_[i]; } diff --git a/test/cpp/indexedinterceptors.cpp b/test/cpp/indexedinterceptors.cpp index f2cd97ac..11f573f1 100644 --- a/test/cpp/indexedinterceptors.cpp +++ b/test/cpp/indexedinterceptors.cpp @@ -80,6 +80,7 @@ NAN_INDEX_GETTER(IndexedInterceptor::PropertyGetter) { } else { info.GetReturnValue().Set(Nan::New("bar").ToLocalChecked()); } + return Intercepted::Yes(); } NAN_INDEX_SETTER(IndexedInterceptor::PropertySetter) { @@ -94,12 +95,14 @@ NAN_INDEX_SETTER(IndexedInterceptor::PropertySetter) { } else { info.GetReturnValue().Set(info.This()); } + return Intercepted::Yes(); } NAN_INDEX_ENUMERATOR(IndexedInterceptor::PropertyEnumerator) { v8::Local arr = Nan::New(); Set(arr, 0, Nan::New(42)); info.GetReturnValue().Set(arr); + return Intercepted::Yes(); } NAN_INDEX_DELETER(IndexedInterceptor::PropertyDeleter) { @@ -107,15 +110,19 @@ NAN_INDEX_DELETER(IndexedInterceptor::PropertyDeleter) { ObjectWrap::Unwrap(info.Holder()); std::strncpy(interceptor->buf, "goober", sizeof (interceptor->buf)); info.GetReturnValue().Set(True()); + return Intercepted::Yes(); } NAN_INDEX_QUERY(IndexedInterceptor::PropertyQuery) { if (index == 1) { info.GetReturnValue().Set(Nan::New(v8::DontEnum)); + return Intercepted::Yes(); } if (index == 42) { info.GetReturnValue().Set(Nan::New(0)); + return Intercepted::Yes(); } + return Intercepted::Yes(); } NODE_MODULE(indexedinterceptors, IndexedInterceptor::Init) diff --git a/test/cpp/namedinterceptors.cpp b/test/cpp/namedinterceptors.cpp index 8ab5f47d..4d8bf5c5 100644 --- a/test/cpp/namedinterceptors.cpp +++ b/test/cpp/namedinterceptors.cpp @@ -80,6 +80,7 @@ NAN_PROPERTY_GETTER(NamedInterceptor::PropertyGetter) { } else { info.GetReturnValue().Set(Nan::New("bar").ToLocalChecked()); } + return Intercepted::Yes(); } NAN_PROPERTY_SETTER(NamedInterceptor::PropertySetter) { @@ -94,6 +95,7 @@ NAN_PROPERTY_SETTER(NamedInterceptor::PropertySetter) { } else { info.GetReturnValue().Set(info.This()); } + return Intercepted::Yes(); } NAN_PROPERTY_ENUMERATOR(NamedInterceptor::PropertyEnumerator) { @@ -107,16 +109,20 @@ NAN_PROPERTY_DELETER(NamedInterceptor::PropertyDeleter) { ObjectWrap::Unwrap(info.Holder()); std::strncpy(interceptor->buf, "goober", sizeof (interceptor->buf)); info.GetReturnValue().Set(True()); + return Intercepted::Yes(); } NAN_PROPERTY_QUERY(NamedInterceptor::PropertyQuery) { Nan::Utf8String s(property); if (!std::strcmp(*s, "thing")) { - return info.GetReturnValue().Set(Nan::New(v8::DontEnum)); + info.GetReturnValue().Set(Nan::New(v8::DontEnum)); + return Intercepted::Yes(); } if (!std::strcmp(*s, "value")) { - return info.GetReturnValue().Set(Nan::New(0)); + info.GetReturnValue().Set(Nan::New(0)); + return Intercepted::Yes(); } + return Intercepted::Yes(); } NODE_MODULE(namedinterceptors, NamedInterceptor::Init) diff --git a/test/cpp/news.cpp b/test/cpp/news.cpp index a218167c..3597f0fc 100644 --- a/test/cpp/news.cpp +++ b/test/cpp/news.cpp @@ -114,10 +114,7 @@ NAN_METHOD(NewScript) { } NAN_METHOD(NewScript2) { - v8::ScriptOrigin origin( -#if NODE_MODULE_VERSION >= NODE_18_0_MODULE_VERSION - info.GetIsolate(), -#endif + ScriptOrigin origin( New("x").ToLocalChecked()); v8::Local script = New( @@ -135,10 +132,7 @@ NAN_METHOD(CompileScript) { } NAN_METHOD(CompileScript2) { - v8::ScriptOrigin origin( -#if NODE_MODULE_VERSION >= NODE_18_0_MODULE_VERSION - info.GetIsolate(), -#endif + ScriptOrigin origin( New("x").ToLocalChecked()); v8::Local script = CompileScript(New("2+4").ToLocalChecked(), origin).ToLocalChecked(); diff --git a/test/js/accessors-test.js b/test/js/accessors-test.js index e6ad4573..85ff490c 100644 --- a/test/js/accessors-test.js +++ b/test/js/accessors-test.js @@ -9,24 +9,50 @@ const test = require('tap').test , testRoot = require('path').resolve(__dirname, '..') , bindings = require('bindings')({ module_root: testRoot, bindings: 'accessors' }); +const nodeVersion = parseInt(process.versions.node.split('.')[0]); test('accessors', function (t) { - t.plan(7) var settergetter = bindings.create() - t.equal(settergetter.prop1, 'this is property 1') - t.ok(settergetter.prop2 === '') - settergetter.prop2 = 'setting a value' - t.equal(settergetter.prop2, 'setting a value') - t.equal(settergetter.log(), - 'New()\n' + - 'Prop1:GETTER(this is property 1)\n' + - 'Prop2:GETTER()\n' + - 'Prop2:SETTER(setting a value)\n' + - 'Prop2:GETTER(setting a value)\n' - ) var derived = Object.create(settergetter) - t.equal(derived.prop1, 'this is property 1') - derived.prop2 = 'setting a new value' - t.equal(derived.prop2, 'setting a new value') - t.equal(settergetter.prop2, 'setting a new value') + if(nodeVersion > 22){ + t.plan(9) + t.equal(settergetter.prop1, 'this is property 1') + t.ok(settergetter.prop2 === '') + settergetter.prop2 = 'setting a value' + t.equal(settergetter.prop2, 'setting a value') + t.equal(settergetter.log(), + 'New()\n' + + 'Prop1:GETTER(this is property 1)\n' + + 'Prop2:GETTER()\n' + + 'Prop2:SETTER(setting a value)\n' + + 'Prop2:GETTER(setting a value)\n' + ) + t.equal(derived.prop1, 'this is property 1') + derived.prop2 = 'setting a new value' + t.equal(derived.prop2, 'setting a new value') + t.equal(settergetter.prop2, 'setting a value') + settergetter.prop2 = 'setting another value' + t.equal(settergetter.prop2, 'setting another value') + t.equal(derived.prop2, 'setting a new value') + + } + else{ + t.plan(7) + t.equal(settergetter.prop1, 'this is property 1') + t.ok(settergetter.prop2 === '') + settergetter.prop2 = 'setting a value' + t.equal(settergetter.prop2, 'setting a value') + t.equal(settergetter.log(), + 'New()\n' + + 'Prop1:GETTER(this is property 1)\n' + + 'Prop2:GETTER()\n' + + 'Prop2:SETTER(setting a value)\n' + + 'Prop2:GETTER(setting a value)\n' + ) + t.equal(derived.prop1, 'this is property 1') + derived.prop2 = 'setting a new value' + t.equal(derived.prop2, 'setting a new value') + t.equal(settergetter.prop2, 'setting a new value') + + } }) diff --git a/test/js/methodswithdata-test.js b/test/js/methodswithdata-test.js index c6d2b22f..c1ba3442 100644 --- a/test/js/methodswithdata-test.js +++ b/test/js/methodswithdata-test.js @@ -9,6 +9,7 @@ const test = require('tap').test , testRoot = require('path').resolve(__dirname, '..') , bindings = require('bindings')({ module_root: testRoot, bindings: 'methodswithdata' }) +const nodeVersion = parseInt(process.versions.node.split('.')[0]); test('SetMethod with data', function (t) { t.plan(1); @@ -16,23 +17,47 @@ test('SetMethod with data', function (t) { }); test('accessors with data', function (t) { - t.plan(7) var settergetter = bindings.create() - t.equal(settergetter.prop1, 'this is property 1') - t.ok(settergetter.prop2 === '') - settergetter.prop2 = 'setting a value' - t.equal(settergetter.prop2, 'setting a value') - t.equal(settergetter.log(), - 'New()\n' + - 'Prop1:GETTER(this is property 1)\n' + - 'Prop2:GETTER()\n' + - 'Prop2:SETTER(setting a value)\n' + - 'Prop2:GETTER(setting a value)\n' - ) var derived = Object.create(settergetter) - t.equal(derived.prop1, 'this is property 1') - derived.prop2 = 'setting a new value' - t.equal(derived.prop2, 'setting a new value') - t.equal(settergetter.prop2, 'setting a new value') + if(nodeVersion > 22){ + t.plan(9) + t.equal(settergetter.prop1, 'this is property 1') + t.ok(settergetter.prop2 === '') + settergetter.prop2 = 'setting a value' + t.equal(settergetter.prop2, 'setting a value') + t.equal(settergetter.log(), + 'New()\n' + + 'Prop1:GETTER(this is property 1)\n' + + 'Prop2:GETTER()\n' + + 'Prop2:SETTER(setting a value)\n' + + 'Prop2:GETTER(setting a value)\n' + ) + t.equal(derived.prop1, 'this is property 1') + derived.prop2 = 'setting a new value' + t.equal(derived.prop2, 'setting a new value') + t.equal(settergetter.prop2, 'setting a value') + settergetter.prop2 = 'setting another value' + t.equal(settergetter.prop2, 'setting another value') + t.equal(derived.prop2, 'setting a new value') + } + else{ + t.plan(7) + t.equal(settergetter.prop1, 'this is property 1') + t.ok(settergetter.prop2 === '') + settergetter.prop2 = 'setting a value' + t.equal(settergetter.prop2, 'setting a value') + t.equal(settergetter.log(), + 'New()\n' + + 'Prop1:GETTER(this is property 1)\n' + + 'Prop2:GETTER()\n' + + 'Prop2:SETTER(setting a value)\n' + + 'Prop2:GETTER(setting a value)\n' + ) + t.equal(derived.prop1, 'this is property 1') + derived.prop2 = 'setting a new value' + t.equal(derived.prop2, 'setting a new value') + t.equal(settergetter.prop2, 'setting a new value') + + } }) \ No newline at end of file diff --git a/test/js/weak-test.js b/test/js/weak-test.js index 00c4c7cc..75ec4771 100644 --- a/test/js/weak-test.js +++ b/test/js/weak-test.js @@ -10,38 +10,46 @@ const test = require('tap').test , testRoot = require('path').resolve(__dirname, '..') , bindings = require('bindings')({ module_root: testRoot, bindings: 'weak' }) , gc = require('./gc-fn'); +const nodeVersion = parseInt(process.versions.node.split('.')[0]); -test('weak', function (t) { - t.plan(3); +// https://github.com/nodejs/nan/issues/995 +// https://chromium-review.googlesource.com/c/v8/v8/+/4733273 +// Week tests are incompatible with recent V8 changes - var weak = bindings, count = 0; - t.type(weak.hustle, 'function'); +if(nodeVersion < 24){ + test('weak', function (t) { + t.plan(3); - weak.hustle(function () {}, function (val) { - t.equal(val, 42); - count++; - }); + var weak = bindings, count = 0; + t.type(weak.hustle, 'function'); + + weak.hustle(function () {}, function (val) { + t.equal(val, 42); + count++; + }); - var timeout = setTimeout(function () { - // run weak callback, should dispose - gc(); + var timeout = setTimeout(function () { + // run weak callback, should dispose + gc(); - // do not run weak callback - gc(); + // do not run weak callback + gc(); - if (count > 0) { - clearTimeout(timeout); - t.equal(count, 1); - } - }, 100); -}); + if (count > 0) { + clearTimeout(timeout); + t.equal(count, 1); + } + }, 100); + }); -test('weak external', function (t) { - t.plan(2); + test('weak external', function (t) { + t.plan(2); - var weak = bindings; - t.type(weak.weakExternal, 'function'); + var weak = bindings; + t.type(weak.weakExternal, 'function'); + + weak.weakExternal(); + t.ok(true); // All good if the previous line didn't crash. + }); +} - weak.weakExternal(); - t.ok(true); // All good if the previous line didn't crash. -}); diff --git a/test/js/weak2-test.js b/test/js/weak2-test.js index 41216449..1b7e6201 100644 --- a/test/js/weak2-test.js +++ b/test/js/weak2-test.js @@ -10,28 +10,35 @@ const test = require('tap').test , testRoot = require('path').resolve(__dirname, '..') , bindings = require('bindings')({ module_root: testRoot, bindings: 'weak2' }) , gc = require('./gc-fn'); +const nodeVersion = parseInt(process.versions.node.split('.')[0]); -test('weak2', function (t) { - t.plan(3); +// https://github.com/nodejs/nan/issues/995 +// https://chromium-review.googlesource.com/c/v8/v8/+/4733273 +// Week tests are incompatible with recent V8 changes - var weak2 = bindings, count = 0; - t.type(weak2.hustle, 'function'); +if(nodeVersion < 24){ + test('weak2', function (t) { + t.plan(3); - weak2.hustle(function (val) { - t.equal(val, 42); - count++; - }); + var weak2 = bindings, count = 0; + t.type(weak2.hustle, 'function'); + + weak2.hustle(function (val) { + t.equal(val, 42); + count++; + }); - // run weak callback, should dispose - gc(); + // run weak callback, should dispose + gc(); - // do not run weak callback - gc(); + // do not run weak callback + gc(); - var timeout = setTimeout(function () { - if (count > 0) { - clearTimeout(timeout); - t.equal(count, 1); - } - }, 100); -}); + var timeout = setTimeout(function () { + if (count > 0) { + clearTimeout(timeout); + t.equal(count, 1); + } + }, 100); + }); +} \ No newline at end of file