+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 <a...@chromium.org> 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
> v8-users@googlegroups.com
> http://groups.google.com/group/v8-users

-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users

Reply via email to