1
0
mirror of https://github.com/robertkrimen/otto synced 2025-10-12 20:27:30 +08:00

Fix a few aspects of accessor properties

This commit is contained in:
Robert Krimen 2014-02-13 21:26:07 -08:00
parent dd88ce83b8
commit 57e0a468ac
3 changed files with 61 additions and 10 deletions

View File

@ -298,17 +298,19 @@ func objectDefineOwnProperty(self *_object, name string, descriptor _property, t
if descriptor.isGenericDescriptor() {
// GenericDescriptor
} else if isDataDescriptor != descriptor.isDataDescriptor() {
// FIXME This branch is non-functioning
panic("isDataDescriptor != descriptor.isDataDescriptor")
var interface_ interface{}
// DataDescriptor <=> AccessorDescriptor
if !configurable {
goto Reject
}
if isDataDescriptor {
property.writeOff()
property.value = interface_
property.writeClear()
property.value = descriptor.value
} else {
property.writeOn()
property.value = interface_
property.value = descriptor.value
}
} else if isDataDescriptor && descriptor.isDataDescriptor() {
// DataDescriptor <=> DataDescriptor
if !configurable {
if !property.writable() && descriptor.writable() {
goto Reject
@ -320,6 +322,7 @@ func objectDefineOwnProperty(self *_object, name string, descriptor _property, t
}
}
} else {
// AccessorDescriptor <=> AccessorDescriptor
if !configurable {
defineGetSet, _ := descriptor.value.(_propertyGetSet)
if getSet[0] != defineGetSet[0] || getSet[1] != defineGetSet[1] {
@ -340,7 +343,10 @@ func objectDefineOwnProperty(self *_object, name string, descriptor _property, t
// (Maybe put into switch ...)
mode0 := property.mode
if mode1&0200 != 0 {
mode1 |= (mode0 & 0100)
if descriptor.isDataDescriptor() {
mode1 &= ^0200 // Turn off "writable" missing
mode1 |= (mode0 & 0100)
}
}
if mode1&020 != 0 {
mode1 |= (mode0 & 010)
@ -348,7 +354,7 @@ func objectDefineOwnProperty(self *_object, name string, descriptor _property, t
if mode1&02 != 0 {
mode1 |= (mode0 & 01)
}
mode1 &= 0111
mode1 &= 0311 // 0311 to preserve the non-setting on "writable"
}
self._write(name, value1, mode1)
}

View File

@ -429,4 +429,37 @@ func TestObjectGetterSetter(t *testing.T) {
def.xyz = true;
[ abc ];
`, "true")
test(`
var abc = {};
Object.defineProperty(abc, "def", {
value: "xyzzy",
configurable: true
});
Object.preventExtensions(abc);
Object.defineProperty(abc, "def", {
get: function() {
return 5;
}
});
var def = Object.getOwnPropertyDescriptor(abc, "def");
[ abc.def, typeof def.get, typeof def.set, typeof def.value, def.configurable, def.enumerable, typeof def.writable ];
`, "5,function,undefined,undefined,true,false,undefined")
}
func TestProperty(t *testing.T) {
Terst(t)
property := _property{}
property.writeOn()
Is(property.writeSet(), true)
property.writeClear()
Is(property.writeSet(), false)
property.writeOff()
Is(property.writeSet(), true)
property.writeClear()
Is(property.writeSet(), false)
}

View File

@ -32,6 +32,10 @@ func (self *_property) writeOff() {
self.mode &= ^modeWriteMask
}
func (self *_property) writeClear() {
self.mode = (self.mode & ^modeWriteMask) | (modeWriteMask & modeSetMask)
}
func (self _property) writeSet() bool {
return 0 == self.mode&modeWriteMask&modeSetMask
}
@ -191,8 +195,16 @@ func (self *_runtime) fromPropertyDescriptor(descriptor _property) *_object {
object.defineProperty("writable", toValue_bool(descriptor.writable()), 0111, false)
} else if descriptor.isAccessorDescriptor() {
getSet := descriptor.value.(_propertyGetSet)
object.defineProperty("get", toValue_object(getSet[0]), 0111, false)
object.defineProperty("set", toValue_object(getSet[1]), 0111, false)
get := UndefinedValue()
if getSet[0] != nil {
get = toValue_object(getSet[0])
}
set := UndefinedValue()
if getSet[1] != nil {
set = toValue_object(getSet[1])
}
object.defineProperty("get", get, 0111, false)
object.defineProperty("set", set, 0111, false)
}
object.defineProperty("enumerable", toValue_bool(descriptor.enumerable()), 0111, false)
object.defineProperty("configurable", toValue_bool(descriptor.configurable()), 0111, false)