value.go 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177
  1. package goja
  2. import (
  3. "fmt"
  4. "hash/maphash"
  5. "math"
  6. "reflect"
  7. "strconv"
  8. "unsafe"
  9. "github.com/dop251/goja/ftoa"
  10. "github.com/dop251/goja/unistring"
  11. )
  12. var (
  13. // Not goroutine-safe, do not use for anything other than package level init
  14. pkgHasher maphash.Hash
  15. hashFalse = randomHash()
  16. hashTrue = randomHash()
  17. hashNull = randomHash()
  18. hashUndef = randomHash()
  19. )
  20. // Not goroutine-safe, do not use for anything other than package level init
  21. func randomHash() uint64 {
  22. pkgHasher.WriteByte(0)
  23. return pkgHasher.Sum64()
  24. }
  25. var (
  26. valueFalse Value = valueBool(false)
  27. valueTrue Value = valueBool(true)
  28. _null Value = valueNull{}
  29. _NaN Value = valueFloat(math.NaN())
  30. _positiveInf Value = valueFloat(math.Inf(+1))
  31. _negativeInf Value = valueFloat(math.Inf(-1))
  32. _positiveZero Value = valueInt(0)
  33. negativeZero = math.Float64frombits(0 | (1 << 63))
  34. _negativeZero Value = valueFloat(negativeZero)
  35. _epsilon = valueFloat(2.2204460492503130808472633361816e-16)
  36. _undefined Value = valueUndefined{}
  37. )
  38. var (
  39. reflectTypeInt = reflect.TypeOf(int64(0))
  40. reflectTypeBool = reflect.TypeOf(false)
  41. reflectTypeNil = reflect.TypeOf(nil)
  42. reflectTypeFloat = reflect.TypeOf(float64(0))
  43. reflectTypeMap = reflect.TypeOf(map[string]interface{}{})
  44. reflectTypeArray = reflect.TypeOf([]interface{}{})
  45. reflectTypeString = reflect.TypeOf("")
  46. reflectTypeFunc = reflect.TypeOf((func(FunctionCall) Value)(nil))
  47. reflectTypeError = reflect.TypeOf((*error)(nil)).Elem()
  48. )
  49. var intCache [256]Value
  50. // Value represents an ECMAScript value.
  51. //
  52. // Export returns a "plain" Go value which type depends on the type of the Value.
  53. //
  54. // For integer numbers it's int64.
  55. //
  56. // For any other numbers (including Infinities, NaN and negative zero) it's float64.
  57. //
  58. // For string it's a string. Note that unicode strings are converted into UTF-8 with invalid code points replaced with utf8.RuneError.
  59. //
  60. // For boolean it's bool.
  61. //
  62. // For null and undefined it's nil.
  63. //
  64. // For Object it depends on the Object type, see Object.Export() for more details.
  65. type Value interface {
  66. ToInteger() int64
  67. toString() valueString
  68. string() unistring.String
  69. ToString() Value
  70. String() string
  71. ToFloat() float64
  72. ToNumber() Value
  73. ToBoolean() bool
  74. ToObject(*Runtime) *Object
  75. SameAs(Value) bool
  76. Equals(Value) bool
  77. StrictEquals(Value) bool
  78. Export() interface{}
  79. ExportType() reflect.Type
  80. baseObject(r *Runtime) *Object
  81. hash(hasher *maphash.Hash) uint64
  82. }
  83. type valueContainer interface {
  84. toValue(*Runtime) Value
  85. }
  86. type typeError string
  87. type rangeError string
  88. type referenceError string
  89. type syntaxError string
  90. type valueInt int64
  91. type valueFloat float64
  92. type valueBool bool
  93. type valueNull struct{}
  94. type valueUndefined struct {
  95. valueNull
  96. }
  97. // *Symbol is a Value containing ECMAScript Symbol primitive. Symbols must only be created
  98. // using NewSymbol(). Zero values and copying of values (i.e. *s1 = *s2) are not permitted.
  99. // Well-known Symbols can be accessed using Sym* package variables (SymIterator, etc...)
  100. // Symbols can be shared by multiple Runtimes.
  101. type Symbol struct {
  102. h uintptr
  103. desc valueString
  104. }
  105. type valueUnresolved struct {
  106. r *Runtime
  107. ref unistring.String
  108. }
  109. type memberUnresolved struct {
  110. valueUnresolved
  111. }
  112. type valueProperty struct {
  113. value Value
  114. writable bool
  115. configurable bool
  116. enumerable bool
  117. accessor bool
  118. getterFunc *Object
  119. setterFunc *Object
  120. }
  121. var (
  122. errAccessBeforeInit = referenceError("Cannot access a variable before initialization")
  123. errAssignToConst = typeError("Assignment to constant variable.")
  124. )
  125. func propGetter(o Value, v Value, r *Runtime) *Object {
  126. if v == _undefined {
  127. return nil
  128. }
  129. if obj, ok := v.(*Object); ok {
  130. if _, ok := obj.self.assertCallable(); ok {
  131. return obj
  132. }
  133. }
  134. r.typeErrorResult(true, "Getter must be a function: %s", v.toString())
  135. return nil
  136. }
  137. func propSetter(o Value, v Value, r *Runtime) *Object {
  138. if v == _undefined {
  139. return nil
  140. }
  141. if obj, ok := v.(*Object); ok {
  142. if _, ok := obj.self.assertCallable(); ok {
  143. return obj
  144. }
  145. }
  146. r.typeErrorResult(true, "Setter must be a function: %s", v.toString())
  147. return nil
  148. }
  149. func fToStr(num float64, mode ftoa.FToStrMode, prec int) string {
  150. var buf1 [128]byte
  151. return string(ftoa.FToStr(num, mode, prec, buf1[:0]))
  152. }
  153. func (i valueInt) ToInteger() int64 {
  154. return int64(i)
  155. }
  156. func (i valueInt) toString() valueString {
  157. return asciiString(i.String())
  158. }
  159. func (i valueInt) string() unistring.String {
  160. return unistring.String(i.String())
  161. }
  162. func (i valueInt) ToString() Value {
  163. return i
  164. }
  165. func (i valueInt) String() string {
  166. return strconv.FormatInt(int64(i), 10)
  167. }
  168. func (i valueInt) ToFloat() float64 {
  169. return float64(i)
  170. }
  171. func (i valueInt) ToBoolean() bool {
  172. return i != 0
  173. }
  174. func (i valueInt) ToObject(r *Runtime) *Object {
  175. return r.newPrimitiveObject(i, r.global.NumberPrototype, classNumber)
  176. }
  177. func (i valueInt) ToNumber() Value {
  178. return i
  179. }
  180. func (i valueInt) SameAs(other Value) bool {
  181. return i == other
  182. }
  183. func (i valueInt) Equals(other Value) bool {
  184. switch o := other.(type) {
  185. case valueInt:
  186. return i == o
  187. case valueFloat:
  188. return float64(i) == float64(o)
  189. case valueString:
  190. return o.ToNumber().Equals(i)
  191. case valueBool:
  192. return int64(i) == o.ToInteger()
  193. case *Object:
  194. return i.Equals(o.toPrimitive())
  195. }
  196. return false
  197. }
  198. func (i valueInt) StrictEquals(other Value) bool {
  199. switch o := other.(type) {
  200. case valueInt:
  201. return i == o
  202. case valueFloat:
  203. return float64(i) == float64(o)
  204. }
  205. return false
  206. }
  207. func (i valueInt) baseObject(r *Runtime) *Object {
  208. return r.global.NumberPrototype
  209. }
  210. func (i valueInt) Export() interface{} {
  211. return int64(i)
  212. }
  213. func (i valueInt) ExportType() reflect.Type {
  214. return reflectTypeInt
  215. }
  216. func (i valueInt) hash(*maphash.Hash) uint64 {
  217. return uint64(i)
  218. }
  219. func (b valueBool) ToInteger() int64 {
  220. if b {
  221. return 1
  222. }
  223. return 0
  224. }
  225. func (b valueBool) toString() valueString {
  226. if b {
  227. return stringTrue
  228. }
  229. return stringFalse
  230. }
  231. func (b valueBool) ToString() Value {
  232. return b
  233. }
  234. func (b valueBool) String() string {
  235. if b {
  236. return "true"
  237. }
  238. return "false"
  239. }
  240. func (b valueBool) string() unistring.String {
  241. return unistring.String(b.String())
  242. }
  243. func (b valueBool) ToFloat() float64 {
  244. if b {
  245. return 1.0
  246. }
  247. return 0
  248. }
  249. func (b valueBool) ToBoolean() bool {
  250. return bool(b)
  251. }
  252. func (b valueBool) ToObject(r *Runtime) *Object {
  253. return r.newPrimitiveObject(b, r.global.BooleanPrototype, "Boolean")
  254. }
  255. func (b valueBool) ToNumber() Value {
  256. if b {
  257. return valueInt(1)
  258. }
  259. return valueInt(0)
  260. }
  261. func (b valueBool) SameAs(other Value) bool {
  262. if other, ok := other.(valueBool); ok {
  263. return b == other
  264. }
  265. return false
  266. }
  267. func (b valueBool) Equals(other Value) bool {
  268. if o, ok := other.(valueBool); ok {
  269. return b == o
  270. }
  271. if b {
  272. return other.Equals(intToValue(1))
  273. } else {
  274. return other.Equals(intToValue(0))
  275. }
  276. }
  277. func (b valueBool) StrictEquals(other Value) bool {
  278. if other, ok := other.(valueBool); ok {
  279. return b == other
  280. }
  281. return false
  282. }
  283. func (b valueBool) baseObject(r *Runtime) *Object {
  284. return r.global.BooleanPrototype
  285. }
  286. func (b valueBool) Export() interface{} {
  287. return bool(b)
  288. }
  289. func (b valueBool) ExportType() reflect.Type {
  290. return reflectTypeBool
  291. }
  292. func (b valueBool) hash(*maphash.Hash) uint64 {
  293. if b {
  294. return hashTrue
  295. }
  296. return hashFalse
  297. }
  298. func (n valueNull) ToInteger() int64 {
  299. return 0
  300. }
  301. func (n valueNull) toString() valueString {
  302. return stringNull
  303. }
  304. func (n valueNull) string() unistring.String {
  305. return stringNull.string()
  306. }
  307. func (n valueNull) ToString() Value {
  308. return n
  309. }
  310. func (n valueNull) String() string {
  311. return "null"
  312. }
  313. func (u valueUndefined) toString() valueString {
  314. return stringUndefined
  315. }
  316. func (u valueUndefined) ToString() Value {
  317. return u
  318. }
  319. func (u valueUndefined) String() string {
  320. return "undefined"
  321. }
  322. func (u valueUndefined) string() unistring.String {
  323. return "undefined"
  324. }
  325. func (u valueUndefined) ToNumber() Value {
  326. return _NaN
  327. }
  328. func (u valueUndefined) SameAs(other Value) bool {
  329. _, same := other.(valueUndefined)
  330. return same
  331. }
  332. func (u valueUndefined) StrictEquals(other Value) bool {
  333. _, same := other.(valueUndefined)
  334. return same
  335. }
  336. func (u valueUndefined) ToFloat() float64 {
  337. return math.NaN()
  338. }
  339. func (u valueUndefined) hash(*maphash.Hash) uint64 {
  340. return hashUndef
  341. }
  342. func (n valueNull) ToFloat() float64 {
  343. return 0
  344. }
  345. func (n valueNull) ToBoolean() bool {
  346. return false
  347. }
  348. func (n valueNull) ToObject(r *Runtime) *Object {
  349. r.typeErrorResult(true, "Cannot convert undefined or null to object")
  350. return nil
  351. //return r.newObject()
  352. }
  353. func (n valueNull) ToNumber() Value {
  354. return intToValue(0)
  355. }
  356. func (n valueNull) SameAs(other Value) bool {
  357. _, same := other.(valueNull)
  358. return same
  359. }
  360. func (n valueNull) Equals(other Value) bool {
  361. switch other.(type) {
  362. case valueUndefined, valueNull:
  363. return true
  364. }
  365. return false
  366. }
  367. func (n valueNull) StrictEquals(other Value) bool {
  368. _, same := other.(valueNull)
  369. return same
  370. }
  371. func (n valueNull) baseObject(*Runtime) *Object {
  372. return nil
  373. }
  374. func (n valueNull) Export() interface{} {
  375. return nil
  376. }
  377. func (n valueNull) ExportType() reflect.Type {
  378. return reflectTypeNil
  379. }
  380. func (n valueNull) hash(*maphash.Hash) uint64 {
  381. return hashNull
  382. }
  383. func (p *valueProperty) ToInteger() int64 {
  384. return 0
  385. }
  386. func (p *valueProperty) toString() valueString {
  387. return stringEmpty
  388. }
  389. func (p *valueProperty) string() unistring.String {
  390. return ""
  391. }
  392. func (p *valueProperty) ToString() Value {
  393. return _undefined
  394. }
  395. func (p *valueProperty) String() string {
  396. return ""
  397. }
  398. func (p *valueProperty) ToFloat() float64 {
  399. return math.NaN()
  400. }
  401. func (p *valueProperty) ToBoolean() bool {
  402. return false
  403. }
  404. func (p *valueProperty) ToObject(*Runtime) *Object {
  405. return nil
  406. }
  407. func (p *valueProperty) ToNumber() Value {
  408. return nil
  409. }
  410. func (p *valueProperty) isWritable() bool {
  411. return p.writable || p.setterFunc != nil
  412. }
  413. func (p *valueProperty) get(this Value) Value {
  414. if p.getterFunc == nil {
  415. if p.value != nil {
  416. return p.value
  417. }
  418. return _undefined
  419. }
  420. call, _ := p.getterFunc.self.assertCallable()
  421. return call(FunctionCall{
  422. This: this,
  423. })
  424. }
  425. func (p *valueProperty) set(this, v Value) {
  426. if p.setterFunc == nil {
  427. p.value = v
  428. return
  429. }
  430. call, _ := p.setterFunc.self.assertCallable()
  431. call(FunctionCall{
  432. This: this,
  433. Arguments: []Value{v},
  434. })
  435. }
  436. func (p *valueProperty) SameAs(other Value) bool {
  437. if otherProp, ok := other.(*valueProperty); ok {
  438. return p == otherProp
  439. }
  440. return false
  441. }
  442. func (p *valueProperty) Equals(Value) bool {
  443. return false
  444. }
  445. func (p *valueProperty) StrictEquals(Value) bool {
  446. return false
  447. }
  448. func (p *valueProperty) baseObject(r *Runtime) *Object {
  449. r.typeErrorResult(true, "BUG: baseObject() is called on valueProperty") // TODO error message
  450. return nil
  451. }
  452. func (p *valueProperty) Export() interface{} {
  453. panic("Cannot export valueProperty")
  454. }
  455. func (p *valueProperty) ExportType() reflect.Type {
  456. panic("Cannot export valueProperty")
  457. }
  458. func (p *valueProperty) hash(*maphash.Hash) uint64 {
  459. panic("valueProperty should never be used in maps or sets")
  460. }
  461. func floatToIntClip(n float64) int64 {
  462. switch {
  463. case math.IsNaN(n):
  464. return 0
  465. case n >= math.MaxInt64:
  466. return math.MaxInt64
  467. case n <= math.MinInt64:
  468. return math.MinInt64
  469. }
  470. return int64(n)
  471. }
  472. func (f valueFloat) ToInteger() int64 {
  473. return floatToIntClip(float64(f))
  474. }
  475. func (f valueFloat) toString() valueString {
  476. return asciiString(f.String())
  477. }
  478. func (f valueFloat) string() unistring.String {
  479. return unistring.String(f.String())
  480. }
  481. func (f valueFloat) ToString() Value {
  482. return f
  483. }
  484. func (f valueFloat) String() string {
  485. return fToStr(float64(f), ftoa.ModeStandard, 0)
  486. }
  487. func (f valueFloat) ToFloat() float64 {
  488. return float64(f)
  489. }
  490. func (f valueFloat) ToBoolean() bool {
  491. return float64(f) != 0.0 && !math.IsNaN(float64(f))
  492. }
  493. func (f valueFloat) ToObject(r *Runtime) *Object {
  494. return r.newPrimitiveObject(f, r.global.NumberPrototype, "Number")
  495. }
  496. func (f valueFloat) ToNumber() Value {
  497. return f
  498. }
  499. func (f valueFloat) SameAs(other Value) bool {
  500. switch o := other.(type) {
  501. case valueFloat:
  502. this := float64(f)
  503. o1 := float64(o)
  504. if math.IsNaN(this) && math.IsNaN(o1) {
  505. return true
  506. } else {
  507. ret := this == o1
  508. if ret && this == 0 {
  509. ret = math.Signbit(this) == math.Signbit(o1)
  510. }
  511. return ret
  512. }
  513. case valueInt:
  514. this := float64(f)
  515. ret := this == float64(o)
  516. if ret && this == 0 {
  517. ret = !math.Signbit(this)
  518. }
  519. return ret
  520. }
  521. return false
  522. }
  523. func (f valueFloat) Equals(other Value) bool {
  524. switch o := other.(type) {
  525. case valueFloat:
  526. return f == o
  527. case valueInt:
  528. return float64(f) == float64(o)
  529. case valueString, valueBool:
  530. return float64(f) == o.ToFloat()
  531. case *Object:
  532. return f.Equals(o.toPrimitive())
  533. }
  534. return false
  535. }
  536. func (f valueFloat) StrictEquals(other Value) bool {
  537. switch o := other.(type) {
  538. case valueFloat:
  539. return f == o
  540. case valueInt:
  541. return float64(f) == float64(o)
  542. }
  543. return false
  544. }
  545. func (f valueFloat) baseObject(r *Runtime) *Object {
  546. return r.global.NumberPrototype
  547. }
  548. func (f valueFloat) Export() interface{} {
  549. return float64(f)
  550. }
  551. func (f valueFloat) ExportType() reflect.Type {
  552. return reflectTypeFloat
  553. }
  554. func (f valueFloat) hash(*maphash.Hash) uint64 {
  555. if f == _negativeZero {
  556. return 0
  557. }
  558. return math.Float64bits(float64(f))
  559. }
  560. func (o *Object) ToInteger() int64 {
  561. return o.toPrimitiveNumber().ToNumber().ToInteger()
  562. }
  563. func (o *Object) toString() valueString {
  564. return o.toPrimitiveString().toString()
  565. }
  566. func (o *Object) string() unistring.String {
  567. return o.toPrimitiveString().string()
  568. }
  569. func (o *Object) ToString() Value {
  570. return o.toPrimitiveString().ToString()
  571. }
  572. func (o *Object) String() string {
  573. return o.toPrimitiveString().String()
  574. }
  575. func (o *Object) ToFloat() float64 {
  576. return o.toPrimitiveNumber().ToFloat()
  577. }
  578. func (o *Object) ToBoolean() bool {
  579. return true
  580. }
  581. func (o *Object) ToObject(*Runtime) *Object {
  582. return o
  583. }
  584. func (o *Object) ToNumber() Value {
  585. return o.toPrimitiveNumber().ToNumber()
  586. }
  587. func (o *Object) SameAs(other Value) bool {
  588. if other, ok := other.(*Object); ok {
  589. return o == other
  590. }
  591. return false
  592. }
  593. func (o *Object) Equals(other Value) bool {
  594. if other, ok := other.(*Object); ok {
  595. return o == other || o.self.equal(other.self)
  596. }
  597. switch o1 := other.(type) {
  598. case valueInt, valueFloat, valueString, *Symbol:
  599. return o.toPrimitive().Equals(other)
  600. case valueBool:
  601. return o.Equals(o1.ToNumber())
  602. }
  603. return false
  604. }
  605. func (o *Object) StrictEquals(other Value) bool {
  606. if other, ok := other.(*Object); ok {
  607. return o == other || o.self.equal(other.self)
  608. }
  609. return false
  610. }
  611. func (o *Object) baseObject(*Runtime) *Object {
  612. return o
  613. }
  614. // Export the Object to a plain Go type.
  615. // If the Object is a wrapped Go value (created using ToValue()) returns the original value.
  616. //
  617. // If the Object is a function, returns func(FunctionCall) Value. Note that exceptions thrown inside the function
  618. // result in panics, which can also leave the Runtime in an unusable state. Therefore, these values should only
  619. // be used inside another ES function implemented in Go. For calling a function from Go, use AssertFunction() or
  620. // Runtime.ExportTo() as described in the README.
  621. //
  622. // For a Map, returns the list of entries as [][2]interface{}.
  623. //
  624. // For a Set, returns the list of elements as []interface{}.
  625. //
  626. // For a Proxy, returns Proxy.
  627. //
  628. // For a Promise, returns Promise.
  629. //
  630. // For a DynamicObject or a DynamicArray, returns the underlying handler.
  631. //
  632. // For an array, returns its items as []interface{}.
  633. //
  634. // In all other cases returns own enumerable non-symbol properties as map[string]interface{}.
  635. //
  636. // This method will panic with an *Exception if a JavaScript exception is thrown in the process.
  637. func (o *Object) Export() (ret interface{}) {
  638. o.runtime.tryPanic(func() {
  639. ret = o.self.export(&objectExportCtx{})
  640. })
  641. return
  642. }
  643. // ExportType returns the type of the value that is returned by Export().
  644. func (o *Object) ExportType() reflect.Type {
  645. return o.self.exportType()
  646. }
  647. func (o *Object) hash(*maphash.Hash) uint64 {
  648. return o.getId()
  649. }
  650. // Get an object's property by name.
  651. // This method will panic with an *Exception if a JavaScript exception is thrown in the process.
  652. func (o *Object) Get(name string) Value {
  653. return o.self.getStr(unistring.NewFromString(name), nil)
  654. }
  655. // GetSymbol returns the value of a symbol property. Use one of the Sym* values for well-known
  656. // symbols (such as SymIterator, SymToStringTag, etc...).
  657. // This method will panic with an *Exception if a JavaScript exception is thrown in the process.
  658. func (o *Object) GetSymbol(sym *Symbol) Value {
  659. return o.self.getSym(sym, nil)
  660. }
  661. // Keys returns a list of Object's enumerable keys.
  662. // This method will panic with an *Exception if a JavaScript exception is thrown in the process.
  663. func (o *Object) Keys() (keys []string) {
  664. iter := &enumerableIter{
  665. o: o,
  666. wrapped: o.self.iterateStringKeys(),
  667. }
  668. for item, next := iter.next(); next != nil; item, next = next() {
  669. keys = append(keys, item.name.String())
  670. }
  671. return
  672. }
  673. // Symbols returns a list of Object's enumerable symbol properties.
  674. // This method will panic with an *Exception if a JavaScript exception is thrown in the process.
  675. func (o *Object) Symbols() []*Symbol {
  676. symbols := o.self.symbols(false, nil)
  677. ret := make([]*Symbol, len(symbols))
  678. for i, sym := range symbols {
  679. ret[i], _ = sym.(*Symbol)
  680. }
  681. return ret
  682. }
  683. // DefineDataProperty is a Go equivalent of Object.defineProperty(o, name, {value: value, writable: writable,
  684. // configurable: configurable, enumerable: enumerable})
  685. func (o *Object) DefineDataProperty(name string, value Value, writable, configurable, enumerable Flag) error {
  686. return o.runtime.try(func() {
  687. o.self.defineOwnPropertyStr(unistring.NewFromString(name), PropertyDescriptor{
  688. Value: value,
  689. Writable: writable,
  690. Configurable: configurable,
  691. Enumerable: enumerable,
  692. }, true)
  693. })
  694. }
  695. // DefineAccessorProperty is a Go equivalent of Object.defineProperty(o, name, {get: getter, set: setter,
  696. // configurable: configurable, enumerable: enumerable})
  697. func (o *Object) DefineAccessorProperty(name string, getter, setter Value, configurable, enumerable Flag) error {
  698. return o.runtime.try(func() {
  699. o.self.defineOwnPropertyStr(unistring.NewFromString(name), PropertyDescriptor{
  700. Getter: getter,
  701. Setter: setter,
  702. Configurable: configurable,
  703. Enumerable: enumerable,
  704. }, true)
  705. })
  706. }
  707. // DefineDataPropertySymbol is a Go equivalent of Object.defineProperty(o, name, {value: value, writable: writable,
  708. // configurable: configurable, enumerable: enumerable})
  709. func (o *Object) DefineDataPropertySymbol(name *Symbol, value Value, writable, configurable, enumerable Flag) error {
  710. return o.runtime.try(func() {
  711. o.self.defineOwnPropertySym(name, PropertyDescriptor{
  712. Value: value,
  713. Writable: writable,
  714. Configurable: configurable,
  715. Enumerable: enumerable,
  716. }, true)
  717. })
  718. }
  719. // DefineAccessorPropertySymbol is a Go equivalent of Object.defineProperty(o, name, {get: getter, set: setter,
  720. // configurable: configurable, enumerable: enumerable})
  721. func (o *Object) DefineAccessorPropertySymbol(name *Symbol, getter, setter Value, configurable, enumerable Flag) error {
  722. return o.runtime.try(func() {
  723. o.self.defineOwnPropertySym(name, PropertyDescriptor{
  724. Getter: getter,
  725. Setter: setter,
  726. Configurable: configurable,
  727. Enumerable: enumerable,
  728. }, true)
  729. })
  730. }
  731. func (o *Object) Set(name string, value interface{}) error {
  732. return o.runtime.try(func() {
  733. o.self.setOwnStr(unistring.NewFromString(name), o.runtime.ToValue(value), true)
  734. })
  735. }
  736. func (o *Object) SetSymbol(name *Symbol, value interface{}) error {
  737. return o.runtime.try(func() {
  738. o.self.setOwnSym(name, o.runtime.ToValue(value), true)
  739. })
  740. }
  741. func (o *Object) Delete(name string) error {
  742. return o.runtime.try(func() {
  743. o.self.deleteStr(unistring.NewFromString(name), true)
  744. })
  745. }
  746. func (o *Object) DeleteSymbol(name *Symbol) error {
  747. return o.runtime.try(func() {
  748. o.self.deleteSym(name, true)
  749. })
  750. }
  751. // Prototype returns the Object's prototype, same as Object.getPrototypeOf(). If the prototype is null
  752. // returns nil.
  753. func (o *Object) Prototype() *Object {
  754. return o.self.proto()
  755. }
  756. // SetPrototype sets the Object's prototype, same as Object.setPrototypeOf(). Setting proto to nil
  757. // is an equivalent of Object.setPrototypeOf(null).
  758. func (o *Object) SetPrototype(proto *Object) error {
  759. return o.runtime.try(func() {
  760. o.self.setProto(proto, true)
  761. })
  762. }
  763. // MarshalJSON returns JSON representation of the Object. It is equivalent to JSON.stringify(o).
  764. // Note, this implements json.Marshaler so that json.Marshal() can be used without the need to Export().
  765. func (o *Object) MarshalJSON() ([]byte, error) {
  766. ctx := _builtinJSON_stringifyContext{
  767. r: o.runtime,
  768. }
  769. ex := o.runtime.vm.try(func() {
  770. if !ctx.do(o) {
  771. ctx.buf.WriteString("null")
  772. }
  773. })
  774. if ex != nil {
  775. return nil, ex
  776. }
  777. return ctx.buf.Bytes(), nil
  778. }
  779. // UnmarshalJSON implements the json.Unmarshaler interface. It is added to compliment MarshalJSON, because
  780. // some alternative JSON encoders refuse to use MarshalJSON unless UnmarshalJSON is also present.
  781. // It is a no-op and always returns nil.
  782. func (o *Object) UnmarshalJSON([]byte) error {
  783. return nil
  784. }
  785. // ClassName returns the class name
  786. func (o *Object) ClassName() string {
  787. return o.self.className()
  788. }
  789. func (o valueUnresolved) throw() {
  790. o.r.throwReferenceError(o.ref)
  791. }
  792. func (o valueUnresolved) ToInteger() int64 {
  793. o.throw()
  794. return 0
  795. }
  796. func (o valueUnresolved) toString() valueString {
  797. o.throw()
  798. return nil
  799. }
  800. func (o valueUnresolved) string() unistring.String {
  801. o.throw()
  802. return ""
  803. }
  804. func (o valueUnresolved) ToString() Value {
  805. o.throw()
  806. return nil
  807. }
  808. func (o valueUnresolved) String() string {
  809. o.throw()
  810. return ""
  811. }
  812. func (o valueUnresolved) ToFloat() float64 {
  813. o.throw()
  814. return 0
  815. }
  816. func (o valueUnresolved) ToBoolean() bool {
  817. o.throw()
  818. return false
  819. }
  820. func (o valueUnresolved) ToObject(*Runtime) *Object {
  821. o.throw()
  822. return nil
  823. }
  824. func (o valueUnresolved) ToNumber() Value {
  825. o.throw()
  826. return nil
  827. }
  828. func (o valueUnresolved) SameAs(Value) bool {
  829. o.throw()
  830. return false
  831. }
  832. func (o valueUnresolved) Equals(Value) bool {
  833. o.throw()
  834. return false
  835. }
  836. func (o valueUnresolved) StrictEquals(Value) bool {
  837. o.throw()
  838. return false
  839. }
  840. func (o valueUnresolved) baseObject(*Runtime) *Object {
  841. o.throw()
  842. return nil
  843. }
  844. func (o valueUnresolved) Export() interface{} {
  845. o.throw()
  846. return nil
  847. }
  848. func (o valueUnresolved) ExportType() reflect.Type {
  849. o.throw()
  850. return nil
  851. }
  852. func (o valueUnresolved) hash(*maphash.Hash) uint64 {
  853. o.throw()
  854. return 0
  855. }
  856. func (s *Symbol) ToInteger() int64 {
  857. panic(typeError("Cannot convert a Symbol value to a number"))
  858. }
  859. func (s *Symbol) toString() valueString {
  860. panic(typeError("Cannot convert a Symbol value to a string"))
  861. }
  862. func (s *Symbol) ToString() Value {
  863. return s
  864. }
  865. func (s *Symbol) String() string {
  866. if s.desc != nil {
  867. return s.desc.String()
  868. }
  869. return ""
  870. }
  871. func (s *Symbol) string() unistring.String {
  872. if s.desc != nil {
  873. return s.desc.string()
  874. }
  875. return ""
  876. }
  877. func (s *Symbol) ToFloat() float64 {
  878. panic(typeError("Cannot convert a Symbol value to a number"))
  879. }
  880. func (s *Symbol) ToNumber() Value {
  881. panic(typeError("Cannot convert a Symbol value to a number"))
  882. }
  883. func (s *Symbol) ToBoolean() bool {
  884. return true
  885. }
  886. func (s *Symbol) ToObject(r *Runtime) *Object {
  887. return s.baseObject(r)
  888. }
  889. func (s *Symbol) SameAs(other Value) bool {
  890. if s1, ok := other.(*Symbol); ok {
  891. return s == s1
  892. }
  893. return false
  894. }
  895. func (s *Symbol) Equals(o Value) bool {
  896. switch o := o.(type) {
  897. case *Object:
  898. return s.Equals(o.toPrimitive())
  899. }
  900. return s.SameAs(o)
  901. }
  902. func (s *Symbol) StrictEquals(o Value) bool {
  903. return s.SameAs(o)
  904. }
  905. func (s *Symbol) Export() interface{} {
  906. return s.String()
  907. }
  908. func (s *Symbol) ExportType() reflect.Type {
  909. return reflectTypeString
  910. }
  911. func (s *Symbol) baseObject(r *Runtime) *Object {
  912. return r.newPrimitiveObject(s, r.global.SymbolPrototype, classObject)
  913. }
  914. func (s *Symbol) hash(*maphash.Hash) uint64 {
  915. return uint64(s.h)
  916. }
  917. func exportValue(v Value, ctx *objectExportCtx) interface{} {
  918. if obj, ok := v.(*Object); ok {
  919. return obj.self.export(ctx)
  920. }
  921. return v.Export()
  922. }
  923. func newSymbol(s valueString) *Symbol {
  924. r := &Symbol{
  925. desc: s,
  926. }
  927. // This may need to be reconsidered in the future.
  928. // Depending on changes in Go's allocation policy and/or introduction of a compacting GC
  929. // this may no longer provide sufficient dispersion. The alternative, however, is a globally
  930. // synchronised random generator/hasher/sequencer and I don't want to go down that route just yet.
  931. r.h = uintptr(unsafe.Pointer(r))
  932. return r
  933. }
  934. func NewSymbol(s string) *Symbol {
  935. return newSymbol(newStringValue(s))
  936. }
  937. func (s *Symbol) descriptiveString() valueString {
  938. desc := s.desc
  939. if desc == nil {
  940. desc = stringEmpty
  941. }
  942. return asciiString("Symbol(").concat(desc).concat(asciiString(")"))
  943. }
  944. func funcName(prefix string, n Value) valueString {
  945. var b valueStringBuilder
  946. b.WriteString(asciiString(prefix))
  947. if sym, ok := n.(*Symbol); ok {
  948. if sym.desc != nil {
  949. b.WriteRune('[')
  950. b.WriteString(sym.desc)
  951. b.WriteRune(']')
  952. }
  953. } else {
  954. b.WriteString(n.toString())
  955. }
  956. return b.String()
  957. }
  958. func newTypeError(args ...interface{}) typeError {
  959. msg := ""
  960. if len(args) > 0 {
  961. f, _ := args[0].(string)
  962. msg = fmt.Sprintf(f, args[1:]...)
  963. }
  964. return typeError(msg)
  965. }
  966. func typeErrorResult(throw bool, args ...interface{}) {
  967. if throw {
  968. panic(newTypeError(args...))
  969. }
  970. }
  971. func init() {
  972. for i := 0; i < 256; i++ {
  973. intCache[i] = valueInt(i - 256)
  974. }
  975. }