object.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. package goja
  2. import "reflect"
  3. const (
  4. classObject = "Object"
  5. classArray = "Array"
  6. classFunction = "Function"
  7. classNumber = "Number"
  8. classString = "String"
  9. classBoolean = "Boolean"
  10. classError = "Error"
  11. classRegExp = "RegExp"
  12. classDate = "Date"
  13. )
  14. type Object struct {
  15. runtime *Runtime
  16. self objectImpl
  17. }
  18. type iterNextFunc func() (propIterItem, iterNextFunc)
  19. type propertyDescr struct {
  20. Value Value
  21. Writable, Configurable, Enumerable Flag
  22. Getter, Setter Value
  23. }
  24. type objectImpl interface {
  25. sortable
  26. className() string
  27. get(Value) Value
  28. getProp(Value) Value
  29. getPropStr(string) Value
  30. getStr(string) Value
  31. getOwnProp(string) Value
  32. put(Value, Value, bool)
  33. putStr(string, Value, bool)
  34. hasProperty(Value) bool
  35. hasPropertyStr(string) bool
  36. hasOwnProperty(Value) bool
  37. hasOwnPropertyStr(string) bool
  38. _putProp(name string, value Value, writable, enumerable, configurable bool) Value
  39. defineOwnProperty(name Value, descr propertyDescr, throw bool) bool
  40. toPrimitiveNumber() Value
  41. toPrimitiveString() Value
  42. toPrimitive() Value
  43. assertCallable() (call func(FunctionCall) Value, ok bool)
  44. deleteStr(name string, throw bool) bool
  45. delete(name Value, throw bool) bool
  46. proto() *Object
  47. hasInstance(v Value) bool
  48. isExtensible() bool
  49. preventExtensions()
  50. enumerate(all, recusrive bool) iterNextFunc
  51. _enumerate(recursive bool) iterNextFunc
  52. export() interface{}
  53. exportType() reflect.Type
  54. equal(objectImpl) bool
  55. }
  56. type baseObject struct {
  57. class string
  58. val *Object
  59. prototype *Object
  60. extensible bool
  61. values map[string]Value
  62. propNames []string
  63. }
  64. type primitiveValueObject struct {
  65. baseObject
  66. pValue Value
  67. }
  68. func (o *primitiveValueObject) export() interface{} {
  69. return o.pValue.Export()
  70. }
  71. func (o *primitiveValueObject) exportType() reflect.Type {
  72. return o.pValue.ExportType()
  73. }
  74. type FunctionCall struct {
  75. This Value
  76. Arguments []Value
  77. }
  78. type ConstructorCall struct {
  79. This *Object
  80. Arguments []Value
  81. }
  82. func (f FunctionCall) Argument(idx int) Value {
  83. if idx < len(f.Arguments) {
  84. return f.Arguments[idx]
  85. }
  86. return _undefined
  87. }
  88. func (f ConstructorCall) Argument(idx int) Value {
  89. if idx < len(f.Arguments) {
  90. return f.Arguments[idx]
  91. }
  92. return _undefined
  93. }
  94. func (o *baseObject) init() {
  95. o.values = make(map[string]Value)
  96. }
  97. func (o *baseObject) className() string {
  98. return o.class
  99. }
  100. func (o *baseObject) getPropStr(name string) Value {
  101. if val := o.getOwnProp(name); val != nil {
  102. return val
  103. }
  104. if o.prototype != nil {
  105. return o.prototype.self.getPropStr(name)
  106. }
  107. return nil
  108. }
  109. func (o *baseObject) getProp(n Value) Value {
  110. return o.val.self.getPropStr(n.String())
  111. }
  112. func (o *baseObject) hasProperty(n Value) bool {
  113. return o.val.self.getProp(n) != nil
  114. }
  115. func (o *baseObject) hasPropertyStr(name string) bool {
  116. return o.val.self.getPropStr(name) != nil
  117. }
  118. func (o *baseObject) _getStr(name string) Value {
  119. p := o.getOwnProp(name)
  120. if p == nil && o.prototype != nil {
  121. p = o.prototype.self.getPropStr(name)
  122. }
  123. if p, ok := p.(*valueProperty); ok {
  124. return p.get(o.val)
  125. }
  126. return p
  127. }
  128. func (o *baseObject) getStr(name string) Value {
  129. p := o.val.self.getPropStr(name)
  130. if p, ok := p.(*valueProperty); ok {
  131. return p.get(o.val)
  132. }
  133. return p
  134. }
  135. func (o *baseObject) get(n Value) Value {
  136. return o.getStr(n.String())
  137. }
  138. func (o *baseObject) checkDeleteProp(name string, prop *valueProperty, throw bool) bool {
  139. if !prop.configurable {
  140. o.val.runtime.typeErrorResult(throw, "Cannot delete property '%s' of %s", name, o.val.ToString())
  141. return false
  142. }
  143. return true
  144. }
  145. func (o *baseObject) checkDelete(name string, val Value, throw bool) bool {
  146. if val, ok := val.(*valueProperty); ok {
  147. return o.checkDeleteProp(name, val, throw)
  148. }
  149. return true
  150. }
  151. func (o *baseObject) _delete(name string) {
  152. delete(o.values, name)
  153. for i, n := range o.propNames {
  154. if n == name {
  155. copy(o.propNames[i:], o.propNames[i+1:])
  156. o.propNames = o.propNames[:len(o.propNames)-1]
  157. break
  158. }
  159. }
  160. }
  161. func (o *baseObject) deleteStr(name string, throw bool) bool {
  162. if val, exists := o.values[name]; exists {
  163. if !o.checkDelete(name, val, throw) {
  164. return false
  165. }
  166. o._delete(name)
  167. return true
  168. }
  169. return true
  170. }
  171. func (o *baseObject) delete(n Value, throw bool) bool {
  172. return o.deleteStr(n.String(), throw)
  173. }
  174. func (o *baseObject) put(n Value, val Value, throw bool) {
  175. o.putStr(n.String(), val, throw)
  176. }
  177. func (o *baseObject) getOwnProp(name string) Value {
  178. v := o.values[name]
  179. if v == nil && name == "__proto" {
  180. return o.prototype
  181. }
  182. return v
  183. }
  184. func (o *baseObject) putStr(name string, val Value, throw bool) {
  185. if v, exists := o.values[name]; exists {
  186. if prop, ok := v.(*valueProperty); ok {
  187. if !prop.isWritable() {
  188. o.val.runtime.typeErrorResult(throw, "Cannot assign to read only property '%s'", name)
  189. return
  190. }
  191. prop.set(o.val, val)
  192. return
  193. }
  194. o.values[name] = val
  195. return
  196. }
  197. if name == "__proto__" {
  198. if !o.extensible {
  199. o.val.runtime.typeErrorResult(throw, "%s is not extensible", o.val)
  200. return
  201. }
  202. if val == _undefined || val == _null {
  203. o.prototype = nil
  204. return
  205. } else {
  206. if val, ok := val.(*Object); ok {
  207. o.prototype = val
  208. }
  209. }
  210. return
  211. }
  212. var pprop Value
  213. if proto := o.prototype; proto != nil {
  214. pprop = proto.self.getPropStr(name)
  215. }
  216. if pprop != nil {
  217. if prop, ok := pprop.(*valueProperty); ok {
  218. if !prop.isWritable() {
  219. o.val.runtime.typeErrorResult(throw)
  220. return
  221. }
  222. if prop.accessor {
  223. prop.set(o.val, val)
  224. return
  225. }
  226. }
  227. } else {
  228. if !o.extensible {
  229. o.val.runtime.typeErrorResult(throw)
  230. return
  231. }
  232. }
  233. o.values[name] = val
  234. o.propNames = append(o.propNames, name)
  235. }
  236. func (o *baseObject) hasOwnProperty(n Value) bool {
  237. v := o.values[n.String()]
  238. return v != nil
  239. }
  240. func (o *baseObject) hasOwnPropertyStr(name string) bool {
  241. v := o.values[name]
  242. return v != nil
  243. }
  244. func (o *baseObject) _defineOwnProperty(name, existingValue Value, descr propertyDescr, throw bool) (val Value, ok bool) {
  245. getterObj, _ := descr.Getter.(*Object)
  246. setterObj, _ := descr.Setter.(*Object)
  247. var existing *valueProperty
  248. if existingValue == nil {
  249. if !o.extensible {
  250. o.val.runtime.typeErrorResult(throw)
  251. return nil, false
  252. }
  253. existing = &valueProperty{}
  254. } else {
  255. if existing, ok = existingValue.(*valueProperty); !ok {
  256. existing = &valueProperty{
  257. writable: true,
  258. enumerable: true,
  259. configurable: true,
  260. value: existingValue,
  261. }
  262. }
  263. if !existing.configurable {
  264. if descr.Configurable == FLAG_TRUE {
  265. goto Reject
  266. }
  267. if descr.Enumerable != FLAG_NOT_SET && descr.Enumerable.Bool() != existing.enumerable {
  268. goto Reject
  269. }
  270. }
  271. if existing.accessor && descr.Value != nil || !existing.accessor && (getterObj != nil || setterObj != nil) {
  272. if !existing.configurable {
  273. goto Reject
  274. }
  275. } else if !existing.accessor {
  276. if !existing.configurable {
  277. if !existing.writable {
  278. if descr.Writable == FLAG_TRUE {
  279. goto Reject
  280. }
  281. if descr.Value != nil && !descr.Value.SameAs(existing.value) {
  282. goto Reject
  283. }
  284. }
  285. }
  286. } else {
  287. if !existing.configurable {
  288. if descr.Getter != nil && existing.getterFunc != getterObj || descr.Setter != nil && existing.setterFunc != setterObj {
  289. goto Reject
  290. }
  291. }
  292. }
  293. }
  294. if descr.Writable == FLAG_TRUE && descr.Enumerable == FLAG_TRUE && descr.Configurable == FLAG_TRUE && descr.Value != nil {
  295. return descr.Value, true
  296. }
  297. if descr.Writable != FLAG_NOT_SET {
  298. existing.writable = descr.Writable.Bool()
  299. }
  300. if descr.Enumerable != FLAG_NOT_SET {
  301. existing.enumerable = descr.Enumerable.Bool()
  302. }
  303. if descr.Configurable != FLAG_NOT_SET {
  304. existing.configurable = descr.Configurable.Bool()
  305. }
  306. if descr.Value != nil {
  307. existing.value = descr.Value
  308. existing.getterFunc = nil
  309. existing.setterFunc = nil
  310. }
  311. if descr.Value != nil || descr.Writable != FLAG_NOT_SET {
  312. existing.accessor = false
  313. }
  314. if descr.Getter != nil {
  315. existing.getterFunc = propGetter(o.val, descr.Getter, o.val.runtime)
  316. existing.value = nil
  317. existing.accessor = true
  318. }
  319. if descr.Setter != nil {
  320. existing.setterFunc = propSetter(o.val, descr.Setter, o.val.runtime)
  321. existing.value = nil
  322. existing.accessor = true
  323. }
  324. if !existing.accessor && existing.value == nil {
  325. existing.value = _undefined
  326. }
  327. return existing, true
  328. Reject:
  329. o.val.runtime.typeErrorResult(throw, "Cannot redefine property: %s", name.ToString())
  330. return nil, false
  331. }
  332. func (o *baseObject) defineOwnProperty(n Value, descr propertyDescr, throw bool) bool {
  333. name := n.String()
  334. existingVal := o.values[name]
  335. if v, ok := o._defineOwnProperty(n, existingVal, descr, throw); ok {
  336. o.values[name] = v
  337. if existingVal == nil {
  338. o.propNames = append(o.propNames, name)
  339. }
  340. return true
  341. }
  342. return false
  343. }
  344. func (o *baseObject) _put(name string, v Value) {
  345. if _, exists := o.values[name]; !exists {
  346. o.propNames = append(o.propNames, name)
  347. }
  348. o.values[name] = v
  349. }
  350. func (o *baseObject) _putProp(name string, value Value, writable, enumerable, configurable bool) Value {
  351. if writable && enumerable && configurable {
  352. o._put(name, value)
  353. return value
  354. } else {
  355. p := &valueProperty{
  356. value: value,
  357. writable: writable,
  358. enumerable: enumerable,
  359. configurable: configurable,
  360. }
  361. o._put(name, p)
  362. return p
  363. }
  364. }
  365. func (o *baseObject) tryPrimitive(methodName string) Value {
  366. if method, ok := o.getStr(methodName).(*Object); ok {
  367. if call, ok := method.self.assertCallable(); ok {
  368. v := call(FunctionCall{
  369. This: o.val,
  370. })
  371. if _, fail := v.(*Object); !fail {
  372. return v
  373. }
  374. }
  375. }
  376. return nil
  377. }
  378. func (o *baseObject) toPrimitiveNumber() Value {
  379. if v := o.tryPrimitive("valueOf"); v != nil {
  380. return v
  381. }
  382. if v := o.tryPrimitive("toString"); v != nil {
  383. return v
  384. }
  385. o.val.runtime.typeErrorResult(true, "Could not convert %v to primitive", o)
  386. return nil
  387. }
  388. func (o *baseObject) toPrimitiveString() Value {
  389. if v := o.tryPrimitive("toString"); v != nil {
  390. return v
  391. }
  392. if v := o.tryPrimitive("valueOf"); v != nil {
  393. return v
  394. }
  395. o.val.runtime.typeErrorResult(true, "Could not convert %v to primitive", o)
  396. return nil
  397. }
  398. func (o *baseObject) toPrimitive() Value {
  399. return o.toPrimitiveNumber()
  400. }
  401. func (o *baseObject) assertCallable() (func(FunctionCall) Value, bool) {
  402. return nil, false
  403. }
  404. func (o *baseObject) proto() *Object {
  405. return o.prototype
  406. }
  407. func (o *baseObject) isExtensible() bool {
  408. return o.extensible
  409. }
  410. func (o *baseObject) preventExtensions() {
  411. o.extensible = false
  412. }
  413. func (o *baseObject) sortLen() int64 {
  414. return toLength(o.val.self.getStr("length"))
  415. }
  416. func (o *baseObject) sortGet(i int64) Value {
  417. return o.val.self.get(intToValue(i))
  418. }
  419. func (o *baseObject) swap(i, j int64) {
  420. ii := intToValue(i)
  421. jj := intToValue(j)
  422. x := o.val.self.get(ii)
  423. y := o.val.self.get(jj)
  424. o.val.self.put(ii, y, false)
  425. o.val.self.put(jj, x, false)
  426. }
  427. func (o *baseObject) export() interface{} {
  428. m := make(map[string]interface{})
  429. for item, f := o.enumerate(false, false)(); f != nil; item, f = f() {
  430. v := item.value
  431. if v == nil {
  432. v = o.getStr(item.name)
  433. }
  434. if v != nil {
  435. m[item.name] = v.Export()
  436. } else {
  437. m[item.name] = nil
  438. }
  439. }
  440. return m
  441. }
  442. func (o *baseObject) exportType() reflect.Type {
  443. return reflectTypeMap
  444. }
  445. type enumerableFlag int
  446. const (
  447. _ENUM_UNKNOWN enumerableFlag = iota
  448. _ENUM_FALSE
  449. _ENUM_TRUE
  450. )
  451. type propIterItem struct {
  452. name string
  453. value Value // set only when enumerable == _ENUM_UNKNOWN
  454. enumerable enumerableFlag
  455. }
  456. type objectPropIter struct {
  457. o *baseObject
  458. propNames []string
  459. recursive bool
  460. idx int
  461. }
  462. type propFilterIter struct {
  463. wrapped iterNextFunc
  464. all bool
  465. seen map[string]bool
  466. }
  467. func (i *propFilterIter) next() (propIterItem, iterNextFunc) {
  468. for {
  469. var item propIterItem
  470. item, i.wrapped = i.wrapped()
  471. if i.wrapped == nil {
  472. return propIterItem{}, nil
  473. }
  474. if !i.seen[item.name] {
  475. i.seen[item.name] = true
  476. if !i.all {
  477. if item.enumerable == _ENUM_FALSE {
  478. continue
  479. }
  480. if item.enumerable == _ENUM_UNKNOWN {
  481. if prop, ok := item.value.(*valueProperty); ok {
  482. if !prop.enumerable {
  483. continue
  484. }
  485. }
  486. }
  487. }
  488. return item, i.next
  489. }
  490. }
  491. }
  492. func (i *objectPropIter) next() (propIterItem, iterNextFunc) {
  493. for i.idx < len(i.propNames) {
  494. name := i.propNames[i.idx]
  495. i.idx++
  496. prop := i.o.values[name]
  497. if prop != nil {
  498. return propIterItem{name: name, value: prop}, i.next
  499. }
  500. }
  501. if i.recursive && i.o.prototype != nil {
  502. return i.o.prototype.self._enumerate(i.recursive)()
  503. }
  504. return propIterItem{}, nil
  505. }
  506. func (o *baseObject) _enumerate(recusrive bool) iterNextFunc {
  507. propNames := make([]string, len(o.propNames))
  508. copy(propNames, o.propNames)
  509. return (&objectPropIter{
  510. o: o,
  511. propNames: propNames,
  512. recursive: recusrive,
  513. }).next
  514. }
  515. func (o *baseObject) enumerate(all, recursive bool) iterNextFunc {
  516. return (&propFilterIter{
  517. wrapped: o._enumerate(recursive),
  518. all: all,
  519. seen: make(map[string]bool),
  520. }).next
  521. }
  522. func (o *baseObject) equal(other objectImpl) bool {
  523. // Rely on parent reference comparison
  524. return false
  525. }
  526. func (o *baseObject) hasInstance(v Value) bool {
  527. o.val.runtime.typeErrorResult(true, "Expecting a function in instanceof check, but got %s", o.val.ToString())
  528. panic("Unreachable")
  529. }