property.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package otto
  2. // property
  3. type _propertyMode int
  4. const (
  5. modeWriteMask _propertyMode = 0700
  6. modeEnumerateMask = 0070
  7. modeConfigureMask = 0007
  8. modeOnMask = 0111
  9. modeSetMask = 0222 // If value is 2, then mode is neither "On" nor "Off"
  10. )
  11. type _propertyGetSet [2]*_object
  12. var _nilGetSetObject _object = _object{}
  13. type _property struct {
  14. value interface{}
  15. mode _propertyMode
  16. }
  17. func (self _property) writable() bool {
  18. return self.mode&modeWriteMask == modeWriteMask&modeOnMask
  19. }
  20. func (self *_property) writeOn() {
  21. self.mode = (self.mode & ^modeWriteMask) | (modeWriteMask & modeOnMask)
  22. }
  23. func (self *_property) writeOff() {
  24. self.mode &= ^modeWriteMask
  25. }
  26. func (self *_property) writeClear() {
  27. self.mode = (self.mode & ^modeWriteMask) | (modeWriteMask & modeSetMask)
  28. }
  29. func (self _property) writeSet() bool {
  30. return 0 == self.mode&modeWriteMask&modeSetMask
  31. }
  32. func (self _property) enumerable() bool {
  33. return self.mode&modeEnumerateMask == modeEnumerateMask&modeOnMask
  34. }
  35. func (self *_property) enumerateOn() {
  36. self.mode = (self.mode & ^modeEnumerateMask) | (modeEnumerateMask & modeOnMask)
  37. }
  38. func (self *_property) enumerateOff() {
  39. self.mode &= ^modeEnumerateMask
  40. }
  41. func (self _property) enumerateSet() bool {
  42. return 0 == self.mode&modeEnumerateMask&modeSetMask
  43. }
  44. func (self _property) configurable() bool {
  45. return self.mode&modeConfigureMask == modeConfigureMask&modeOnMask
  46. }
  47. func (self *_property) configureOn() {
  48. self.mode = (self.mode & ^modeConfigureMask) | (modeConfigureMask & modeOnMask)
  49. }
  50. func (self *_property) configureOff() {
  51. self.mode &= ^modeConfigureMask
  52. }
  53. func (self _property) configureSet() bool {
  54. return 0 == self.mode&modeConfigureMask&modeSetMask
  55. }
  56. func (self _property) copy() *_property {
  57. property := self
  58. return &property
  59. }
  60. func (self _property) get(this *_object) Value {
  61. switch value := self.value.(type) {
  62. case Value:
  63. return value
  64. case _propertyGetSet:
  65. if value[0] != nil {
  66. return value[0].call(toValue(this), nil, false, nativeFrame)
  67. }
  68. }
  69. return Value{}
  70. }
  71. func (self _property) isAccessorDescriptor() bool {
  72. setGet, test := self.value.(_propertyGetSet)
  73. return test && (setGet[0] != nil || setGet[1] != nil)
  74. }
  75. func (self _property) isDataDescriptor() bool {
  76. if self.writeSet() { // Either "On" or "Off"
  77. return true
  78. }
  79. value, valid := self.value.(Value)
  80. return valid && !value.isEmpty()
  81. }
  82. func (self _property) isGenericDescriptor() bool {
  83. return !(self.isDataDescriptor() || self.isAccessorDescriptor())
  84. }
  85. func (self _property) isEmpty() bool {
  86. return self.mode == 0222 && self.isGenericDescriptor()
  87. }
  88. // _enumerableValue, _enumerableTrue, _enumerableFalse?
  89. // .enumerableValue() .enumerableExists()
  90. func toPropertyDescriptor(rt *_runtime, value Value) (descriptor _property) {
  91. objectDescriptor := value._object()
  92. if objectDescriptor == nil {
  93. panic(rt.panicTypeError())
  94. }
  95. {
  96. descriptor.mode = modeSetMask // Initially nothing is set
  97. if objectDescriptor.hasProperty("enumerable") {
  98. if objectDescriptor.get("enumerable").bool() {
  99. descriptor.enumerateOn()
  100. } else {
  101. descriptor.enumerateOff()
  102. }
  103. }
  104. if objectDescriptor.hasProperty("configurable") {
  105. if objectDescriptor.get("configurable").bool() {
  106. descriptor.configureOn()
  107. } else {
  108. descriptor.configureOff()
  109. }
  110. }
  111. if objectDescriptor.hasProperty("writable") {
  112. if objectDescriptor.get("writable").bool() {
  113. descriptor.writeOn()
  114. } else {
  115. descriptor.writeOff()
  116. }
  117. }
  118. }
  119. var getter, setter *_object
  120. getterSetter := false
  121. if objectDescriptor.hasProperty("get") {
  122. value := objectDescriptor.get("get")
  123. if value.IsDefined() {
  124. if !value.isCallable() {
  125. panic(rt.panicTypeError())
  126. }
  127. getter = value._object()
  128. getterSetter = true
  129. } else {
  130. getter = &_nilGetSetObject
  131. getterSetter = true
  132. }
  133. }
  134. if objectDescriptor.hasProperty("set") {
  135. value := objectDescriptor.get("set")
  136. if value.IsDefined() {
  137. if !value.isCallable() {
  138. panic(rt.panicTypeError())
  139. }
  140. setter = value._object()
  141. getterSetter = true
  142. } else {
  143. setter = &_nilGetSetObject
  144. getterSetter = true
  145. }
  146. }
  147. if getterSetter {
  148. if descriptor.writeSet() {
  149. panic(rt.panicTypeError())
  150. }
  151. descriptor.value = _propertyGetSet{getter, setter}
  152. }
  153. if objectDescriptor.hasProperty("value") {
  154. if getterSetter {
  155. panic(rt.panicTypeError())
  156. }
  157. descriptor.value = objectDescriptor.get("value")
  158. }
  159. return
  160. }
  161. func (self *_runtime) fromPropertyDescriptor(descriptor _property) *_object {
  162. object := self.newObject()
  163. if descriptor.isDataDescriptor() {
  164. object.defineProperty("value", descriptor.value.(Value), 0111, false)
  165. object.defineProperty("writable", toValue_bool(descriptor.writable()), 0111, false)
  166. } else if descriptor.isAccessorDescriptor() {
  167. getSet := descriptor.value.(_propertyGetSet)
  168. get := Value{}
  169. if getSet[0] != nil {
  170. get = toValue_object(getSet[0])
  171. }
  172. set := Value{}
  173. if getSet[1] != nil {
  174. set = toValue_object(getSet[1])
  175. }
  176. object.defineProperty("get", get, 0111, false)
  177. object.defineProperty("set", set, 0111, false)
  178. }
  179. object.defineProperty("enumerable", toValue_bool(descriptor.enumerable()), 0111, false)
  180. object.defineProperty("configurable", toValue_bool(descriptor.configurable()), 0111, false)
  181. return object
  182. }