object.go 16 KB

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