Please allow setting PropertyHandlerFlags of NamedPropertyHandlerConfiguration
I have a named property interceptor and I use Nan::SetNamedPropertyHandler so that it works accross multiple node versions.
auto doctpl = Nan::New<FunctionTemplate>(DocumentWrap::ctor);
doctpl->SetClassName(Nan::New<String>("Document").ToLocalChecked());
doctpl->InstanceTemplate()->SetInternalFieldCount(1);
// Instance functions
Nan::SetPrototypeMethod(doctpl, "getTokenizerForField", DocumentWrap::getTokenizerForField);
Nan::SetPrototypeMethod(doctpl, "setTokenizerForField", DocumentWrap::setTokenizerForField);
Nan::SetPrototypeMethod(doctpl, "destroy", DocumentWrap::destroy);
Nan::SetPrototypeMethod(doctpl, "disableIndexingForField", DocumentWrap::disableIndexingForField);
// Interceptor for docid and fields
Nan::SetNamedPropertyHandler(
doctpl->InstanceTemplate(),
DocumentWrap::getField,
DocumentWrap::setField,
DocumentWrap::queryField,
DocumentWrap::removeField,
DocumentWrap::enumerateField
);
// Create constructor function
auto docctor = doctpl->GetFunction();
// Save persistent handle
documentWrapCtor.Reset(docctor);
The trouble is that the object also has some functions set on its prototype. By default, v8 uses the named property interceptor even if the user wants to call one of these functions:
doc.getTokenizerForField("hello", "world");
This results in a TypeError: doc.setTokenizerForField is not a function
The issue can be solved if one sets the correct PropertyHandlerFlags to the NamedPropertyHandlerConfiguration, however currently nan doesn't let me do this.
I suggest to simply add one more argument to Nan::SetNamedPropertyHandler.
For the sake of completeness, the flags I need to use are:
- v8::PropertyHandlerFlags::kNonMasking
- v8::PropertyHandlerFlags::kOnlyInterceptStrings
There is no PropertyHandlerFlags or an equivalent in node.js <= v0.12. As long as we still support those, we can't add the flag.
In your case I'd call v8::ObjectTemplate::SetNamedPropertyHandler() directly since you probably don't care about old node versions. The enum is available in node.js >= v4.x.
Unfortunately, I do care about old node versions, the module used to work with node 0.12.x and I encountered this problem while upgrading it to work with newer node.
Then you probably have no choice but to branch on #if NODE_MODULE_VERSION >= 46 to add v4.x+ specific code paths. PropertyHandlerFlags describes behavior that nan cannot shim in a general way except maybe PropertyHandlerFlags::kAllCanRead, but that is the least interesting of the bunch.
Thank you @bnoordhuis I can try that. However, why is it unfeasible for nan to add one more argument? It could be simply ignored on older node versions.
We only add what we can reasonably support across node versions, that is nan's raison d'être.
@bnoordhuis For now, I managed to solve this by copy-pasting nan's SetNamedPropertyHandler into my own code and modifying it to check NODE_MODULE_VERSION and if it is >4.0, set the flags I want.
However, there is one more thing. I believe I might be using this API incorrectly, because neither the query nor the enumerator functions are ever called on any of my objects. Am I doing something wrong here or is this normal?