object.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package otto
  2. type _object struct {
  3. runtime *_runtime
  4. class string
  5. objectClass *_objectClass
  6. value interface{}
  7. prototype *_object
  8. extensible bool
  9. property map[string]_property
  10. propertyOrder []string
  11. }
  12. func newObject(runtime *_runtime, class string) *_object {
  13. self := &_object{
  14. runtime: runtime,
  15. class: class,
  16. objectClass: _classObject,
  17. property: make(map[string]_property),
  18. extensible: true,
  19. }
  20. return self
  21. }
  22. // 8.12
  23. // 8.12.1
  24. func (self *_object) getOwnProperty(name string) *_property {
  25. return self.objectClass.getOwnProperty(self, name)
  26. }
  27. // 8.12.2
  28. func (self *_object) getProperty(name string) *_property {
  29. return self.objectClass.getProperty(self, name)
  30. }
  31. // 8.12.3
  32. func (self *_object) get(name string) Value {
  33. return self.objectClass.get(self, name)
  34. }
  35. // 8.12.4
  36. func (self *_object) canPut(name string) bool {
  37. return self.objectClass.canPut(self, name)
  38. }
  39. // 8.12.5
  40. func (self *_object) put(name string, value Value, throw bool) {
  41. self.objectClass.put(self, name, value, throw)
  42. }
  43. // 8.12.6
  44. func (self *_object) hasProperty(name string) bool {
  45. return self.objectClass.hasProperty(self, name)
  46. }
  47. func (self *_object) hasOwnProperty(name string) bool {
  48. return self.objectClass.hasOwnProperty(self, name)
  49. }
  50. type _defaultValueHint int
  51. const (
  52. defaultValueNoHint _defaultValueHint = iota
  53. defaultValueHintString
  54. defaultValueHintNumber
  55. )
  56. // 8.12.8
  57. func (self *_object) DefaultValue(hint _defaultValueHint) Value {
  58. if hint == defaultValueNoHint {
  59. if self.class == classDate {
  60. // Date exception
  61. hint = defaultValueHintString
  62. } else {
  63. hint = defaultValueHintNumber
  64. }
  65. }
  66. methodSequence := []string{"valueOf", "toString"}
  67. if hint == defaultValueHintString {
  68. methodSequence = []string{"toString", "valueOf"}
  69. }
  70. for _, methodName := range methodSequence {
  71. method := self.get(methodName)
  72. // FIXME This is redundant...
  73. if method.isCallable() {
  74. result := method._object().call(toValue_object(self), nil, false, nativeFrame)
  75. if result.IsPrimitive() {
  76. return result
  77. }
  78. }
  79. }
  80. panic(self.runtime.panicTypeError())
  81. }
  82. func (self *_object) String() string {
  83. return self.DefaultValue(defaultValueHintString).string()
  84. }
  85. func (self *_object) defineProperty(name string, value Value, mode _propertyMode, throw bool) bool {
  86. return self.defineOwnProperty(name, _property{value, mode}, throw)
  87. }
  88. // 8.12.9
  89. func (self *_object) defineOwnProperty(name string, descriptor _property, throw bool) bool {
  90. return self.objectClass.defineOwnProperty(self, name, descriptor, throw)
  91. }
  92. func (self *_object) delete(name string, throw bool) bool {
  93. return self.objectClass.delete(self, name, throw)
  94. }
  95. func (self *_object) enumerate(all bool, each func(string) bool) {
  96. self.objectClass.enumerate(self, all, each)
  97. }
  98. func (self *_object) _exists(name string) bool {
  99. _, exists := self.property[name]
  100. return exists
  101. }
  102. func (self *_object) _read(name string) (_property, bool) {
  103. property, exists := self.property[name]
  104. return property, exists
  105. }
  106. func (self *_object) _write(name string, value interface{}, mode _propertyMode) {
  107. if value == nil {
  108. value = Value{}
  109. }
  110. _, exists := self.property[name]
  111. self.property[name] = _property{value, mode}
  112. if !exists {
  113. self.propertyOrder = append(self.propertyOrder, name)
  114. }
  115. }
  116. func (self *_object) _delete(name string) {
  117. _, exists := self.property[name]
  118. delete(self.property, name)
  119. if exists {
  120. for index, property := range self.propertyOrder {
  121. if name == property {
  122. if index == len(self.propertyOrder)-1 {
  123. self.propertyOrder = self.propertyOrder[:index]
  124. } else {
  125. self.propertyOrder = append(self.propertyOrder[:index], self.propertyOrder[index+1:]...)
  126. }
  127. }
  128. }
  129. }
  130. }