+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