123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- package otto
- // property
- type _propertyMode int
- const (
- modeWriteMask _propertyMode = 0700
- modeEnumerateMask = 0070
- modeConfigureMask = 0007
- modeOnMask = 0111
- modeSetMask = 0222 // If value is 2, then mode is neither "On" nor "Off"
- )
- type _propertyGetSet [2]*_object
- var _nilGetSetObject _object = _object{}
- type _property struct {
- value interface{}
- mode _propertyMode
- }
- func (self _property) writable() bool {
- return self.mode&modeWriteMask == modeWriteMask&modeOnMask
- }
- func (self *_property) writeOn() {
- self.mode = (self.mode & ^modeWriteMask) | (modeWriteMask & modeOnMask)
- }
- 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
- }
- func (self _property) enumerable() bool {
- return self.mode&modeEnumerateMask == modeEnumerateMask&modeOnMask
- }
- func (self *_property) enumerateOn() {
- self.mode = (self.mode & ^modeEnumerateMask) | (modeEnumerateMask & modeOnMask)
- }
- func (self *_property) enumerateOff() {
- self.mode &= ^modeEnumerateMask
- }
- func (self _property) enumerateSet() bool {
- return 0 == self.mode&modeEnumerateMask&modeSetMask
- }
- func (self _property) configurable() bool {
- return self.mode&modeConfigureMask == modeConfigureMask&modeOnMask
- }
- func (self *_property) configureOn() {
- self.mode = (self.mode & ^modeConfigureMask) | (modeConfigureMask & modeOnMask)
- }
- func (self *_property) configureOff() {
- self.mode &= ^modeConfigureMask
- }
- func (self _property) configureSet() bool {
- return 0 == self.mode&modeConfigureMask&modeSetMask
- }
- func (self _property) copy() *_property {
- property := self
- return &property
- }
- func (self _property) get(this *_object) Value {
- switch value := self.value.(type) {
- case Value:
- return value
- case _propertyGetSet:
- if value[0] != nil {
- return value[0].call(toValue(this), nil, false, nativeFrame)
- }
- }
- return Value{}
- }
- func (self _property) isAccessorDescriptor() bool {
- setGet, test := self.value.(_propertyGetSet)
- return test && (setGet[0] != nil || setGet[1] != nil)
- }
- func (self _property) isDataDescriptor() bool {
- if self.writeSet() { // Either "On" or "Off"
- return true
- }
- value, valid := self.value.(Value)
- return valid && !value.isEmpty()
- }
- func (self _property) isGenericDescriptor() bool {
- return !(self.isDataDescriptor() || self.isAccessorDescriptor())
- }
- func (self _property) isEmpty() bool {
- return self.mode == 0222 && self.isGenericDescriptor()
- }
- // _enumerableValue, _enumerableTrue, _enumerableFalse?
- // .enumerableValue() .enumerableExists()
- func toPropertyDescriptor(rt *_runtime, value Value) (descriptor _property) {
- objectDescriptor := value._object()
- if objectDescriptor == nil {
- panic(rt.panicTypeError())
- }
- {
- descriptor.mode = modeSetMask // Initially nothing is set
- if objectDescriptor.hasProperty("enumerable") {
- if objectDescriptor.get("enumerable").bool() {
- descriptor.enumerateOn()
- } else {
- descriptor.enumerateOff()
- }
- }
- if objectDescriptor.hasProperty("configurable") {
- if objectDescriptor.get("configurable").bool() {
- descriptor.configureOn()
- } else {
- descriptor.configureOff()
- }
- }
- if objectDescriptor.hasProperty("writable") {
- if objectDescriptor.get("writable").bool() {
- descriptor.writeOn()
- } else {
- descriptor.writeOff()
- }
- }
- }
- var getter, setter *_object
- getterSetter := false
- if objectDescriptor.hasProperty("get") {
- value := objectDescriptor.get("get")
- if value.IsDefined() {
- if !value.isCallable() {
- panic(rt.panicTypeError())
- }
- getter = value._object()
- getterSetter = true
- } else {
- getter = &_nilGetSetObject
- getterSetter = true
- }
- }
- if objectDescriptor.hasProperty("set") {
- value := objectDescriptor.get("set")
- if value.IsDefined() {
- if !value.isCallable() {
- panic(rt.panicTypeError())
- }
- setter = value._object()
- getterSetter = true
- } else {
- setter = &_nilGetSetObject
- getterSetter = true
- }
- }
- if getterSetter {
- if descriptor.writeSet() {
- panic(rt.panicTypeError())
- }
- descriptor.value = _propertyGetSet{getter, setter}
- }
- if objectDescriptor.hasProperty("value") {
- if getterSetter {
- panic(rt.panicTypeError())
- }
- descriptor.value = objectDescriptor.get("value")
- }
- return
- }
- func (self *_runtime) fromPropertyDescriptor(descriptor _property) *_object {
- object := self.newObject()
- if descriptor.isDataDescriptor() {
- object.defineProperty("value", descriptor.value.(Value), 0111, false)
- object.defineProperty("writable", toValue_bool(descriptor.writable()), 0111, false)
- } else if descriptor.isAccessorDescriptor() {
- getSet := descriptor.value.(_propertyGetSet)
- get := Value{}
- if getSet[0] != nil {
- get = toValue_object(getSet[0])
- }
- set := Value{}
- 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)
- return object
- }
|