object.go 13 KB

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