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:
parent
dd88ce83b8
commit
57e0a468ac
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
16
property.go
16
property.go
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user