+mstarzinger +rossberg
I think we need a repro and V8 version. I could not repro on ToT with
an example like:
static Handle<Value> Getter(Local<String> property, const AccessorInfo& info) {
return Integer::New(24);
}
static Handle<Value> Foo(const Arguments& args) {
HandleScope scope;
Handle<Object> obj = Object::New();
obj->SetAccessor(String::New("foo"), &Getter, 0 /* setter */,
Handle<Value>(),
static_cast<v8::AccessControl>(v8::DEFAULT),
static_cast<v8::PropertyAttribute>(v8::ReadOnly));
return scope.Close(obj);
}
var obj = Foo();
var desc = Object.getOwnPropertyDescriptor(obj, "foo");
print(desc.value);
print(desc.get);
print(desc.set);
print(desc.writable);
print(obj.foo);
obj.foo = 42;
print(obj.foo);
% out/ia32.debug/d8 test.js
24
undefined
undefined
false
24
24
> What I want is a property that is writable but if not set should call the
> getter.
I don't see how it fits into JavaScript object model. If you have an
accessor property without a setter you can't write into it ([[CanPut]]
will be false).
> Is there a way to remove a V8 accessor?
delete object.name would delete it. But there seems to be a different
way, see below.
> Would a call to Delete() make this a slow object?
Yes.
Different way is to use v8::Object::ForceSet to replace accessor with
a real property. Good news: it will keep an object in fast mode if
possible (if object has enough space for another fast property). Bad
news: every time you replace an accessor with a normal data property
with ForceSet you will get a different map (hidden class) because
v8::internal::JSObject::ConvertDescriptorToField does not create a
transition.
// In theory accessor descriptors should be replaceable with data
descriptors via [[DefineOwnProperty]] (Object.defineProperty) but
there is some special handling in our code that prevents it.
https://github.com/v8/v8/blob/master/src/runtime.cc#L4459-4478
--
Vyacheslav Egorov
On Fri, Jun 8, 2012 at 9:33 PM, Erik Arvidsson <[email protected]> wrote:
> The V8 WebKit bindings generates something like this:
>
> object->SetAccessor(name, getter, 0 /* setter */, data,
> static_cast<v8::AccessControl>(v8::DEFAULT),
> static_cast<v8::PropertyAttribute>(v8::ReadOnly)
>
> There are two really strange behaviors with this:
>
> 1. The descriptor for this reports this as writable:
>
> var descr = Object.getOwnPropertyDescriptor(object, name);
> descr.writable // true!
>
> 2. Setting the property works
>
> object.name = 42;
> object.name // 42
>
> However, if we remove the ReadOnly flag in the call to SetAccessor we
> get a writable property that cannot be written to:
>
> object->SetAccessor(name, getter, 0 /* setter */, data,
> static_cast<v8::AccessControl>(v8::DEFAULT),
> static_cast<v8::PropertyAttribute>(v8::None)
>
> var descr = Object.getOwnPropertyDescriptor(object, name);
> descr.writable // true
>
> object.name = 42;
> object.name // not 42!
>
>
> This is pretty strange. What I want is a property that is writable but
> if not set should call the getter.
>
> One way I can implement this is to generate a setter too that when set
> reconfigures the property. Is there a way to remove a V8 accessor?
> Would a call to Delete() make this a slow object?
>
>
> --
> erik
>
> --
> v8-users mailing list
> [email protected]
> http://groups.google.com/group/v8-users
--
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users