package otto // property type _propertyMode int const ( modeWriteMask _propertyMode = 0700 modeEnumerateMask = 0070 modeConfigureMask = 0007 modeOnMask = 0111 modeOffMask = 0000 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 }