InstanceTemplate, SetAccessor versus SetNativeDataProperty

315 views
Skip to first unread message

Flying Jester

unread,
Aug 7, 2014, 6:10:36 PM8/7/14
to v8-u...@googlegroups.com
What precisely is the difference between using SetAccessor and SetNativeDataProperty?

Ben Noordhuis

unread,
Aug 7, 2014, 6:52:53 PM8/7/14
to v8-u...@googlegroups.com
On Fri, Aug 8, 2014 at 12:10 AM, Flying Jester <foolki...@gmail.com> wrote:
> What precisely is the difference between using SetAccessor and
> SetNativeDataProperty?

Nothing, as far as I know. The order of arguments is different but
they have identical implementations.

J Decker

unread,
Oct 23, 2017, 11:53:17 PM10/23/17
to v8-users
They are not exactly the same...  I've been using SetNativeDataProperty, which works for getters, but when i started to use it for a setter, V8 ended up setting a property on the object instead of calling the setter.  Changing to SetAccessor allows the setter to be called correctly.

And while I realize this is a very old thread; it's about the only one that shows up for 'SetNativeDataProperty vs SetAccessor'

I can't find any other information that would indicate that setnativedataproperty shouldn't or doesn't work; other than my code.

Ben Noordhuis

unread,
Oct 24, 2017, 6:40:31 AM10/24/17
to v8-users
Blast from the past!

I believe what I wrote still holds (or holds again) if you start V8
with `--disable_old_api_accessors`. It's currently off by default but
that will likely change someday.

J Decker

unread,
Oct 24, 2017, 9:32:44 AM10/24/17
to v8-users
That option makes SetAccessor setter not work.  It creates a property on the object instead of calling the setter.

psiTemplate2->PrototypeTemplate()->SetAccessor( String::NewFromUtf8( isolate, "text" )
, ControlObject::getControlText, ControlObject::setControlText );

So that's discouraging....

Ben Noordhuis

unread,
Oct 24, 2017, 10:38:44 AM10/24/17
to v8-users
With `--disable_old_api_accessors` they are quite literally the same
implementation. Something else must be going on. Out-of-date V8
version?

J Decker

unread,
Oct 24, 2017, 11:49:03 AM10/24/17
to v8-users
M:\javascript\vfs\native>node
> process.version
'v8.4.0'
> process.versions
{ http_parser: '2.7.0',
  node: '8.4.0',
  v8: '6.0.286.52',
  uv: '1.13.1',
  zlib: '1.2.11',
  ares: '1.10.1-DEV',
  modules: '57',
  nghttp2: '1.22.0',
  openssl: '1.0.2l',
  icu: '59.1',
  unicode: '9.0',
  cldr: '31.0.1',
  tz: '2017b' } 

I doubt it.  It's not absolute bleeding edge, but it's pretty new.

I was going to include the whole thing I'm trying to test, but expect that to fail so here's a super simple test


It sets a SetAccessor called 'text' and a SetNativeDataProperty called 'native'

to build
npm install .  

test1 : ( only setter called is SetAccessor settter )
npm test

(sample output) 
> node test.js

plugin.cc: getter called... default value
Default: default value
plugin.cc: setter called... with newText
plugin.cc: getter called... newText
Default: [] newText
plugin.cc: getter called... newText
Default: newText
Default: [ 'native' ] nativeText


test2 : (passes --disable-old-api-accessors  which makes neither setter get called )
npm run test2

(sample output)
> node --disable-old-api-accessors test.js

plugin.cc: getter called... default value
Default: default value
Default: [ 'text' ] newText
plugin.cc: getter called... default value
Default: default value
Default: [ 'text', 'native' ] nativeText





--------- what I would have sent ---------

This is a node plugin - https://github.com/d3x0r/sack.vfs the new features I'm extending it with I can only confirm work under Windows.
Which is tested with this line... https://github.com/d3x0r/sack.vfs/blob/master/tests/sack_test4.js#L28  which should change the text in the resulting gui.



Toon Verwaest

unread,
Oct 25, 2017, 3:55:36 AM10/25/17
to v8-u...@googlegroups.com
As Ben stated, --disable-old-api-accessors makes them behave the same; but it indeed makes SetAccessor work like SetNativeDataProperty.

The reason is that SetAccessor creates a pseudo-data-property that's backed by accessors: Object.getOwnPropertyDescriptor(o, "p") will return something that looks like a data property, not like an accessor. Data properties are supposed to behave differently when on the prototype chain than accessors. If there's a getter, we should call into it. If there's a setter, however, we shouldn't call it. We should only check whether data properties on the prototype chain are read-only, and thrown an exception if they are. That's how data properties work.

If you want something similar to the old-style SetAccessor behavior, you should instead use SetAccessorProperty. That creates an actual getter/setter pair. That setter will be called through the prototype chain as well, just like other accessors in JS.

The old behavior for SetAccessor is a v8-only invention that looks like a data property but behaves like an accessor; which not only adds unnecessary complexity, but is actually impossible to implement correctly in certain cases.

HTH,
Toon

--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--

Toon Verwaest | Software Engineer, V8 | Google Germany GmbH | Erika-Mann Str. 33, 80636 München 

Registergericht und -nummer: Hamburg, HRB 86891 | Sitz der Gesellschaft: Hamburg | Geschäftsführer: Paul Manicle, Halimah DeLaine Prado

J Decker

unread,
Oct 25, 2017, 2:36:03 PM10/25/17
to v8-users


On Wednesday, October 25, 2017 at 12:55:36 AM UTC-7, Toon Verwaest wrote:
As Ben stated, --disable-old-api-accessors makes them behave the same; but it indeed makes SetAccessor work like SetNativeDataProperty.

The reason is that SetAccessor creates a pseudo-data-property that's backed by accessors: Object.getOwnPropertyDescriptor(o, "p") will return something that looks like a data property, not like an accessor. Data properties are supposed to behave differently when on the prototype chain than accessors. If there's a getter, we should call into it. If there's a setter, however, we shouldn't call it. We should only check whether data properties on the prototype chain are read-only, and thrown an exception if they are. That's how data properties work.

If you want something similar to the old-style SetAccessor behavior, you should instead use SetAccessorProperty. That creates an actual getter/setter pair. That setter will be called through the prototype chain as well, just like other accessors in JS.


Thank you :)  After updating to SetAccessorProperty and setting ReadOnly as appropriate I get [getter] or [getter/setter] notations on them which is what I would expect (rather than calling them with non-instance This()s )
Reply all
Reply to author
Forward
0 new messages