builtin_object.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. package goja
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. func (r *Runtime) builtin_Object(args []Value, newTarget *Object) *Object {
  7. if newTarget != nil && newTarget != r.getObject() {
  8. proto := r.getPrototypeFromCtor(newTarget, nil, r.global.ObjectPrototype)
  9. return r.newBaseObject(proto, classObject).val
  10. }
  11. if len(args) > 0 {
  12. arg := args[0]
  13. if arg != _undefined && arg != _null {
  14. return arg.ToObject(r)
  15. }
  16. }
  17. return r.NewObject()
  18. }
  19. func (r *Runtime) object_getPrototypeOf(call FunctionCall) Value {
  20. o := call.Argument(0).ToObject(r)
  21. p := o.self.proto()
  22. if p == nil {
  23. return _null
  24. }
  25. return p
  26. }
  27. func (r *Runtime) valuePropToDescriptorObject(desc Value) Value {
  28. if desc == nil {
  29. return _undefined
  30. }
  31. var writable, configurable, enumerable, accessor bool
  32. var get, set *Object
  33. var value Value
  34. if v, ok := desc.(*valueProperty); ok {
  35. writable = v.writable
  36. configurable = v.configurable
  37. enumerable = v.enumerable
  38. accessor = v.accessor
  39. value = v.value
  40. get = v.getterFunc
  41. set = v.setterFunc
  42. } else {
  43. writable = true
  44. configurable = true
  45. enumerable = true
  46. value = desc
  47. }
  48. ret := r.NewObject()
  49. obj := ret.self
  50. if !accessor {
  51. obj.setOwnStr("value", value, false)
  52. obj.setOwnStr("writable", r.toBoolean(writable), false)
  53. } else {
  54. if get != nil {
  55. obj.setOwnStr("get", get, false)
  56. } else {
  57. obj.setOwnStr("get", _undefined, false)
  58. }
  59. if set != nil {
  60. obj.setOwnStr("set", set, false)
  61. } else {
  62. obj.setOwnStr("set", _undefined, false)
  63. }
  64. }
  65. obj.setOwnStr("enumerable", r.toBoolean(enumerable), false)
  66. obj.setOwnStr("configurable", r.toBoolean(configurable), false)
  67. return ret
  68. }
  69. func (r *Runtime) object_getOwnPropertyDescriptor(call FunctionCall) Value {
  70. o := call.Argument(0).ToObject(r)
  71. propName := toPropertyKey(call.Argument(1))
  72. return r.valuePropToDescriptorObject(o.getOwnProp(propName))
  73. }
  74. func (r *Runtime) object_getOwnPropertyDescriptors(call FunctionCall) Value {
  75. o := call.Argument(0).ToObject(r)
  76. result := r.newBaseObject(r.global.ObjectPrototype, classObject).val
  77. for item, next := o.self.iterateKeys()(); next != nil; item, next = next() {
  78. var prop Value
  79. if item.value == nil {
  80. prop = o.getOwnProp(item.name)
  81. if prop == nil {
  82. continue
  83. }
  84. } else {
  85. prop = item.value
  86. }
  87. descriptor := r.valuePropToDescriptorObject(prop)
  88. if descriptor != _undefined {
  89. createDataPropertyOrThrow(result, item.name, descriptor)
  90. }
  91. }
  92. return result
  93. }
  94. func (r *Runtime) object_getOwnPropertyNames(call FunctionCall) Value {
  95. obj := call.Argument(0).ToObject(r)
  96. return r.newArrayValues(obj.self.stringKeys(true, nil))
  97. }
  98. func (r *Runtime) object_getOwnPropertySymbols(call FunctionCall) Value {
  99. obj := call.Argument(0).ToObject(r)
  100. return r.newArrayValues(obj.self.symbols(true, nil))
  101. }
  102. func (r *Runtime) toValueProp(v Value) *valueProperty {
  103. if v == nil || v == _undefined {
  104. return nil
  105. }
  106. obj := r.toObject(v)
  107. getter := obj.self.getStr("get", nil)
  108. setter := obj.self.getStr("set", nil)
  109. writable := obj.self.getStr("writable", nil)
  110. value := obj.self.getStr("value", nil)
  111. if (getter != nil || setter != nil) && (value != nil || writable != nil) {
  112. r.typeErrorResult(true, "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute")
  113. }
  114. ret := &valueProperty{}
  115. if writable != nil && writable.ToBoolean() {
  116. ret.writable = true
  117. }
  118. if e := obj.self.getStr("enumerable", nil); e != nil && e.ToBoolean() {
  119. ret.enumerable = true
  120. }
  121. if c := obj.self.getStr("configurable", nil); c != nil && c.ToBoolean() {
  122. ret.configurable = true
  123. }
  124. ret.value = value
  125. if getter != nil && getter != _undefined {
  126. o := r.toObject(getter)
  127. if _, ok := o.self.assertCallable(); !ok {
  128. r.typeErrorResult(true, "getter must be a function")
  129. }
  130. ret.getterFunc = o
  131. }
  132. if setter != nil && setter != _undefined {
  133. o := r.toObject(setter)
  134. if _, ok := o.self.assertCallable(); !ok {
  135. r.typeErrorResult(true, "setter must be a function")
  136. }
  137. ret.setterFunc = o
  138. }
  139. if ret.getterFunc != nil || ret.setterFunc != nil {
  140. ret.accessor = true
  141. }
  142. return ret
  143. }
  144. func (r *Runtime) toPropertyDescriptor(v Value) (ret PropertyDescriptor) {
  145. if o, ok := v.(*Object); ok {
  146. descr := o.self
  147. // Save the original descriptor for reference
  148. ret.jsDescriptor = o
  149. ret.Value = descr.getStr("value", nil)
  150. if p := descr.getStr("writable", nil); p != nil {
  151. ret.Writable = ToFlag(p.ToBoolean())
  152. }
  153. if p := descr.getStr("enumerable", nil); p != nil {
  154. ret.Enumerable = ToFlag(p.ToBoolean())
  155. }
  156. if p := descr.getStr("configurable", nil); p != nil {
  157. ret.Configurable = ToFlag(p.ToBoolean())
  158. }
  159. ret.Getter = descr.getStr("get", nil)
  160. ret.Setter = descr.getStr("set", nil)
  161. if ret.Getter != nil && ret.Getter != _undefined {
  162. if _, ok := r.toObject(ret.Getter).self.assertCallable(); !ok {
  163. r.typeErrorResult(true, "getter must be a function")
  164. }
  165. }
  166. if ret.Setter != nil && ret.Setter != _undefined {
  167. if _, ok := r.toObject(ret.Setter).self.assertCallable(); !ok {
  168. r.typeErrorResult(true, "setter must be a function")
  169. }
  170. }
  171. if (ret.Getter != nil || ret.Setter != nil) && (ret.Value != nil || ret.Writable != FLAG_NOT_SET) {
  172. r.typeErrorResult(true, "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute")
  173. }
  174. } else {
  175. r.typeErrorResult(true, "Property description must be an object: %s", v.String())
  176. }
  177. return
  178. }
  179. func (r *Runtime) _defineProperties(o *Object, p Value) {
  180. type propItem struct {
  181. name Value
  182. prop PropertyDescriptor
  183. }
  184. props := p.ToObject(r)
  185. var list []propItem
  186. for item, next := iterateEnumerableProperties(props)(); next != nil; item, next = next() {
  187. list = append(list, propItem{
  188. name: item.name,
  189. prop: r.toPropertyDescriptor(item.value),
  190. })
  191. }
  192. for _, prop := range list {
  193. o.defineOwnProperty(prop.name, prop.prop, true)
  194. }
  195. }
  196. func (r *Runtime) object_create(call FunctionCall) Value {
  197. var proto *Object
  198. if arg := call.Argument(0); arg != _null {
  199. if o, ok := arg.(*Object); ok {
  200. proto = o
  201. } else {
  202. r.typeErrorResult(true, "Object prototype may only be an Object or null: %s", arg.String())
  203. }
  204. }
  205. o := r.newBaseObject(proto, classObject).val
  206. if props := call.Argument(1); props != _undefined {
  207. r._defineProperties(o, props)
  208. }
  209. return o
  210. }
  211. func (r *Runtime) object_defineProperty(call FunctionCall) (ret Value) {
  212. if obj, ok := call.Argument(0).(*Object); ok {
  213. descr := r.toPropertyDescriptor(call.Argument(2))
  214. obj.defineOwnProperty(toPropertyKey(call.Argument(1)), descr, true)
  215. ret = call.Argument(0)
  216. } else {
  217. r.typeErrorResult(true, "Object.defineProperty called on non-object")
  218. }
  219. return
  220. }
  221. func (r *Runtime) object_defineProperties(call FunctionCall) Value {
  222. obj := r.toObject(call.Argument(0))
  223. r._defineProperties(obj, call.Argument(1))
  224. return obj
  225. }
  226. func (r *Runtime) object_seal(call FunctionCall) Value {
  227. // ES6
  228. arg := call.Argument(0)
  229. if obj, ok := arg.(*Object); ok {
  230. obj.self.preventExtensions(true)
  231. descr := PropertyDescriptor{
  232. Configurable: FLAG_FALSE,
  233. }
  234. for item, next := obj.self.iterateKeys()(); next != nil; item, next = next() {
  235. if prop, ok := item.value.(*valueProperty); ok {
  236. prop.configurable = false
  237. } else {
  238. obj.defineOwnProperty(item.name, descr, true)
  239. }
  240. }
  241. return obj
  242. }
  243. return arg
  244. }
  245. func (r *Runtime) object_freeze(call FunctionCall) Value {
  246. arg := call.Argument(0)
  247. if obj, ok := arg.(*Object); ok {
  248. obj.self.preventExtensions(true)
  249. for item, next := obj.self.iterateKeys()(); next != nil; item, next = next() {
  250. if prop, ok := item.value.(*valueProperty); ok {
  251. prop.configurable = false
  252. if !prop.accessor {
  253. prop.writable = false
  254. }
  255. } else {
  256. prop := obj.getOwnProp(item.name)
  257. descr := PropertyDescriptor{
  258. Configurable: FLAG_FALSE,
  259. }
  260. if prop, ok := prop.(*valueProperty); ok && prop.accessor {
  261. // no-op
  262. } else {
  263. descr.Writable = FLAG_FALSE
  264. }
  265. obj.defineOwnProperty(item.name, descr, true)
  266. }
  267. }
  268. return obj
  269. } else {
  270. // ES6 behavior
  271. return arg
  272. }
  273. }
  274. func (r *Runtime) object_preventExtensions(call FunctionCall) (ret Value) {
  275. arg := call.Argument(0)
  276. if obj, ok := arg.(*Object); ok {
  277. obj.self.preventExtensions(true)
  278. }
  279. return arg
  280. }
  281. func (r *Runtime) object_isSealed(call FunctionCall) Value {
  282. if obj, ok := call.Argument(0).(*Object); ok {
  283. if obj.self.isExtensible() {
  284. return valueFalse
  285. }
  286. for item, next := obj.self.iterateKeys()(); next != nil; item, next = next() {
  287. var prop Value
  288. if item.value == nil {
  289. prop = obj.getOwnProp(item.name)
  290. if prop == nil {
  291. continue
  292. }
  293. } else {
  294. prop = item.value
  295. }
  296. if prop, ok := prop.(*valueProperty); ok {
  297. if prop.configurable {
  298. return valueFalse
  299. }
  300. } else {
  301. return valueFalse
  302. }
  303. }
  304. }
  305. return valueTrue
  306. }
  307. func (r *Runtime) object_isFrozen(call FunctionCall) Value {
  308. if obj, ok := call.Argument(0).(*Object); ok {
  309. if obj.self.isExtensible() {
  310. return valueFalse
  311. }
  312. for item, next := obj.self.iterateKeys()(); next != nil; item, next = next() {
  313. var prop Value
  314. if item.value == nil {
  315. prop = obj.getOwnProp(item.name)
  316. if prop == nil {
  317. continue
  318. }
  319. } else {
  320. prop = item.value
  321. }
  322. if prop, ok := prop.(*valueProperty); ok {
  323. if prop.configurable || prop.value != nil && prop.writable {
  324. return valueFalse
  325. }
  326. } else {
  327. return valueFalse
  328. }
  329. }
  330. }
  331. return valueTrue
  332. }
  333. func (r *Runtime) object_isExtensible(call FunctionCall) Value {
  334. if obj, ok := call.Argument(0).(*Object); ok {
  335. if obj.self.isExtensible() {
  336. return valueTrue
  337. }
  338. return valueFalse
  339. } else {
  340. // ES6
  341. //r.typeErrorResult(true, "Object.isExtensible called on non-object")
  342. return valueFalse
  343. }
  344. }
  345. func (r *Runtime) object_keys(call FunctionCall) Value {
  346. obj := call.Argument(0).ToObject(r)
  347. return r.newArrayValues(obj.self.stringKeys(false, nil))
  348. }
  349. func (r *Runtime) object_entries(call FunctionCall) Value {
  350. obj := call.Argument(0).ToObject(r)
  351. var values []Value
  352. for item, next := iterateEnumerableStringProperties(obj)(); next != nil; item, next = next() {
  353. values = append(values, r.newArrayValues([]Value{item.name, item.value}))
  354. }
  355. return r.newArrayValues(values)
  356. }
  357. func (r *Runtime) object_values(call FunctionCall) Value {
  358. obj := call.Argument(0).ToObject(r)
  359. var values []Value
  360. for item, next := iterateEnumerableStringProperties(obj)(); next != nil; item, next = next() {
  361. values = append(values, item.value)
  362. }
  363. return r.newArrayValues(values)
  364. }
  365. func (r *Runtime) objectproto_hasOwnProperty(call FunctionCall) Value {
  366. p := toPropertyKey(call.Argument(0))
  367. o := call.This.ToObject(r)
  368. if o.hasOwnProperty(p) {
  369. return valueTrue
  370. } else {
  371. return valueFalse
  372. }
  373. }
  374. func (r *Runtime) objectproto_isPrototypeOf(call FunctionCall) Value {
  375. if v, ok := call.Argument(0).(*Object); ok {
  376. o := call.This.ToObject(r)
  377. for {
  378. v = v.self.proto()
  379. if v == nil {
  380. break
  381. }
  382. if v == o {
  383. return valueTrue
  384. }
  385. }
  386. }
  387. return valueFalse
  388. }
  389. func (r *Runtime) objectproto_propertyIsEnumerable(call FunctionCall) Value {
  390. p := toPropertyKey(call.Argument(0))
  391. o := call.This.ToObject(r)
  392. pv := o.getOwnProp(p)
  393. if pv == nil {
  394. return valueFalse
  395. }
  396. if prop, ok := pv.(*valueProperty); ok {
  397. if !prop.enumerable {
  398. return valueFalse
  399. }
  400. }
  401. return valueTrue
  402. }
  403. func (r *Runtime) objectproto_toString(call FunctionCall) Value {
  404. switch o := call.This.(type) {
  405. case valueNull:
  406. return stringObjectNull
  407. case valueUndefined:
  408. return stringObjectUndefined
  409. default:
  410. obj := o.ToObject(r)
  411. if o, ok := obj.self.(*objectGoReflect); ok {
  412. if toString := o.toString; toString != nil {
  413. return toString()
  414. }
  415. }
  416. var clsName string
  417. if isArray(obj) {
  418. clsName = classArray
  419. } else {
  420. clsName = obj.self.className()
  421. }
  422. if tag := obj.self.getSym(SymToStringTag, nil); tag != nil {
  423. if str, ok := tag.(String); ok {
  424. clsName = str.String()
  425. }
  426. }
  427. return newStringValue(fmt.Sprintf("[object %s]", clsName))
  428. }
  429. }
  430. func (r *Runtime) objectproto_toLocaleString(call FunctionCall) Value {
  431. toString := toMethod(r.getVStr(call.This, "toString"))
  432. return toString(FunctionCall{This: call.This})
  433. }
  434. func (r *Runtime) objectproto_getProto(call FunctionCall) Value {
  435. proto := call.This.ToObject(r).self.proto()
  436. if proto != nil {
  437. return proto
  438. }
  439. return _null
  440. }
  441. func (r *Runtime) setObjectProto(o, arg Value) {
  442. r.checkObjectCoercible(o)
  443. var proto *Object
  444. if arg != _null {
  445. if obj, ok := arg.(*Object); ok {
  446. proto = obj
  447. } else {
  448. return
  449. }
  450. }
  451. if o, ok := o.(*Object); ok {
  452. o.self.setProto(proto, true)
  453. }
  454. }
  455. func (r *Runtime) objectproto_setProto(call FunctionCall) Value {
  456. r.setObjectProto(call.This, call.Argument(0))
  457. return _undefined
  458. }
  459. func (r *Runtime) objectproto_valueOf(call FunctionCall) Value {
  460. return call.This.ToObject(r)
  461. }
  462. func (r *Runtime) object_assign(call FunctionCall) Value {
  463. to := call.Argument(0).ToObject(r)
  464. if len(call.Arguments) > 1 {
  465. for _, arg := range call.Arguments[1:] {
  466. if arg != _undefined && arg != _null {
  467. source := arg.ToObject(r)
  468. for item, next := iterateEnumerableProperties(source)(); next != nil; item, next = next() {
  469. to.setOwn(item.name, item.value, true)
  470. }
  471. }
  472. }
  473. }
  474. return to
  475. }
  476. func (r *Runtime) object_is(call FunctionCall) Value {
  477. return r.toBoolean(call.Argument(0).SameAs(call.Argument(1)))
  478. }
  479. func (r *Runtime) toProto(proto Value) *Object {
  480. if proto != _null {
  481. if obj, ok := proto.(*Object); ok {
  482. return obj
  483. } else {
  484. panic(r.NewTypeError("Object prototype may only be an Object or null: %s", proto))
  485. }
  486. }
  487. return nil
  488. }
  489. func (r *Runtime) object_setPrototypeOf(call FunctionCall) Value {
  490. o := call.Argument(0)
  491. r.checkObjectCoercible(o)
  492. proto := r.toProto(call.Argument(1))
  493. if o, ok := o.(*Object); ok {
  494. o.self.setProto(proto, true)
  495. }
  496. return o
  497. }
  498. func (r *Runtime) object_fromEntries(call FunctionCall) Value {
  499. o := call.Argument(0)
  500. r.checkObjectCoercible(o)
  501. result := r.newBaseObject(r.global.ObjectPrototype, classObject).val
  502. iter := r.getIterator(o, nil)
  503. iter.iterate(func(nextValue Value) {
  504. i0 := valueInt(0)
  505. i1 := valueInt(1)
  506. itemObj := r.toObject(nextValue)
  507. k := itemObj.self.getIdx(i0, nil)
  508. v := itemObj.self.getIdx(i1, nil)
  509. key := toPropertyKey(k)
  510. createDataPropertyOrThrow(result, key, v)
  511. })
  512. return result
  513. }
  514. func (r *Runtime) object_hasOwn(call FunctionCall) Value {
  515. o := call.Argument(0)
  516. obj := o.ToObject(r)
  517. p := toPropertyKey(call.Argument(1))
  518. if obj.hasOwnProperty(p) {
  519. return valueTrue
  520. } else {
  521. return valueFalse
  522. }
  523. }
  524. func createObjectTemplate() *objectTemplate {
  525. t := newObjectTemplate()
  526. t.protoFactory = func(r *Runtime) *Object {
  527. return r.getFunctionPrototype()
  528. }
  529. t.putStr("length", func(r *Runtime) Value { return valueProp(intToValue(1), false, false, true) })
  530. t.putStr("name", func(r *Runtime) Value { return valueProp(asciiString("Object"), false, false, true) })
  531. t.putStr("prototype", func(r *Runtime) Value { return valueProp(r.global.ObjectPrototype, false, false, false) })
  532. t.putStr("assign", func(r *Runtime) Value { return r.methodProp(r.object_assign, "assign", 2) })
  533. t.putStr("defineProperty", func(r *Runtime) Value { return r.methodProp(r.object_defineProperty, "defineProperty", 3) })
  534. t.putStr("defineProperties", func(r *Runtime) Value { return r.methodProp(r.object_defineProperties, "defineProperties", 2) })
  535. t.putStr("entries", func(r *Runtime) Value { return r.methodProp(r.object_entries, "entries", 1) })
  536. t.putStr("getOwnPropertyDescriptor", func(r *Runtime) Value {
  537. return r.methodProp(r.object_getOwnPropertyDescriptor, "getOwnPropertyDescriptor", 2)
  538. })
  539. t.putStr("getOwnPropertyDescriptors", func(r *Runtime) Value {
  540. return r.methodProp(r.object_getOwnPropertyDescriptors, "getOwnPropertyDescriptors", 1)
  541. })
  542. t.putStr("getPrototypeOf", func(r *Runtime) Value { return r.methodProp(r.object_getPrototypeOf, "getPrototypeOf", 1) })
  543. t.putStr("is", func(r *Runtime) Value { return r.methodProp(r.object_is, "is", 2) })
  544. t.putStr("getOwnPropertyNames", func(r *Runtime) Value { return r.methodProp(r.object_getOwnPropertyNames, "getOwnPropertyNames", 1) })
  545. t.putStr("getOwnPropertySymbols", func(r *Runtime) Value {
  546. return r.methodProp(r.object_getOwnPropertySymbols, "getOwnPropertySymbols", 1)
  547. })
  548. t.putStr("create", func(r *Runtime) Value { return r.methodProp(r.object_create, "create", 2) })
  549. t.putStr("seal", func(r *Runtime) Value { return r.methodProp(r.object_seal, "seal", 1) })
  550. t.putStr("freeze", func(r *Runtime) Value { return r.methodProp(r.object_freeze, "freeze", 1) })
  551. t.putStr("preventExtensions", func(r *Runtime) Value { return r.methodProp(r.object_preventExtensions, "preventExtensions", 1) })
  552. t.putStr("isSealed", func(r *Runtime) Value { return r.methodProp(r.object_isSealed, "isSealed", 1) })
  553. t.putStr("isFrozen", func(r *Runtime) Value { return r.methodProp(r.object_isFrozen, "isFrozen", 1) })
  554. t.putStr("isExtensible", func(r *Runtime) Value { return r.methodProp(r.object_isExtensible, "isExtensible", 1) })
  555. t.putStr("keys", func(r *Runtime) Value { return r.methodProp(r.object_keys, "keys", 1) })
  556. t.putStr("setPrototypeOf", func(r *Runtime) Value { return r.methodProp(r.object_setPrototypeOf, "setPrototypeOf", 2) })
  557. t.putStr("values", func(r *Runtime) Value { return r.methodProp(r.object_values, "values", 1) })
  558. t.putStr("fromEntries", func(r *Runtime) Value { return r.methodProp(r.object_fromEntries, "fromEntries", 1) })
  559. t.putStr("hasOwn", func(r *Runtime) Value { return r.methodProp(r.object_hasOwn, "hasOwn", 2) })
  560. return t
  561. }
  562. var _objectTemplate *objectTemplate
  563. var objectTemplateOnce sync.Once
  564. func getObjectTemplate() *objectTemplate {
  565. objectTemplateOnce.Do(func() {
  566. _objectTemplate = createObjectTemplate()
  567. })
  568. return _objectTemplate
  569. }
  570. func (r *Runtime) getObject() *Object {
  571. ret := r.global.Object
  572. if ret == nil {
  573. ret = &Object{runtime: r}
  574. r.global.Object = ret
  575. r.newTemplatedFuncObject(getObjectTemplate(), ret, func(call FunctionCall) Value {
  576. return r.builtin_Object(call.Arguments, nil)
  577. }, r.builtin_Object)
  578. }
  579. return ret
  580. }
  581. /*
  582. func (r *Runtime) getObjectPrototype() *Object {
  583. ret := r.global.ObjectPrototype
  584. if ret == nil {
  585. ret = &Object{runtime: r}
  586. r.global.ObjectPrototype = ret
  587. r.newTemplatedObject(getObjectProtoTemplate(), ret)
  588. }
  589. return ret
  590. }
  591. */
  592. var objectProtoTemplate *objectTemplate
  593. var objectProtoTemplateOnce sync.Once
  594. func getObjectProtoTemplate() *objectTemplate {
  595. objectProtoTemplateOnce.Do(func() {
  596. objectProtoTemplate = createObjectProtoTemplate()
  597. })
  598. return objectProtoTemplate
  599. }
  600. func createObjectProtoTemplate() *objectTemplate {
  601. t := newObjectTemplate()
  602. // null prototype
  603. t.putStr("constructor", func(r *Runtime) Value { return valueProp(r.getObject(), true, false, true) })
  604. t.putStr("toString", func(r *Runtime) Value { return r.methodProp(r.objectproto_toString, "toString", 0) })
  605. t.putStr("toLocaleString", func(r *Runtime) Value { return r.methodProp(r.objectproto_toLocaleString, "toLocaleString", 0) })
  606. t.putStr("valueOf", func(r *Runtime) Value { return r.methodProp(r.objectproto_valueOf, "valueOf", 0) })
  607. t.putStr("hasOwnProperty", func(r *Runtime) Value { return r.methodProp(r.objectproto_hasOwnProperty, "hasOwnProperty", 1) })
  608. t.putStr("isPrototypeOf", func(r *Runtime) Value { return r.methodProp(r.objectproto_isPrototypeOf, "isPrototypeOf", 1) })
  609. t.putStr("propertyIsEnumerable", func(r *Runtime) Value {
  610. return r.methodProp(r.objectproto_propertyIsEnumerable, "propertyIsEnumerable", 1)
  611. })
  612. t.putStr(__proto__, func(r *Runtime) Value {
  613. return &valueProperty{
  614. accessor: true,
  615. getterFunc: r.newNativeFunc(r.objectproto_getProto, "get __proto__", 0),
  616. setterFunc: r.newNativeFunc(r.objectproto_setProto, "set __proto__", 1),
  617. configurable: true,
  618. }
  619. })
  620. return t
  621. }