builtin_typedarrays.go 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529
  1. package goja
  2. import (
  3. "fmt"
  4. "math"
  5. "sort"
  6. "unsafe"
  7. "github.com/dop251/goja/unistring"
  8. )
  9. type typedArraySortCtx struct {
  10. ta *typedArrayObject
  11. compare func(FunctionCall) Value
  12. needValidate bool
  13. }
  14. func (ctx *typedArraySortCtx) Len() int {
  15. return ctx.ta.length
  16. }
  17. func (ctx *typedArraySortCtx) Less(i, j int) bool {
  18. if ctx.needValidate {
  19. ctx.ta.viewedArrayBuf.ensureNotDetached(true)
  20. ctx.needValidate = false
  21. }
  22. offset := ctx.ta.offset
  23. if ctx.compare != nil {
  24. x := ctx.ta.typedArray.get(offset + i)
  25. y := ctx.ta.typedArray.get(offset + j)
  26. res := ctx.compare(FunctionCall{
  27. This: _undefined,
  28. Arguments: []Value{x, y},
  29. }).ToNumber()
  30. ctx.needValidate = true
  31. if i, ok := res.(valueInt); ok {
  32. return i < 0
  33. }
  34. f := res.ToFloat()
  35. if f < 0 {
  36. return true
  37. }
  38. if f > 0 {
  39. return false
  40. }
  41. if math.Signbit(f) {
  42. return true
  43. }
  44. return false
  45. }
  46. return ctx.ta.typedArray.less(offset+i, offset+j)
  47. }
  48. func (ctx *typedArraySortCtx) Swap(i, j int) {
  49. if ctx.needValidate {
  50. ctx.ta.viewedArrayBuf.ensureNotDetached(true)
  51. ctx.needValidate = false
  52. }
  53. offset := ctx.ta.offset
  54. ctx.ta.typedArray.swap(offset+i, offset+j)
  55. }
  56. func allocByteSlice(size int) (b []byte) {
  57. defer func() {
  58. if x := recover(); x != nil {
  59. panic(rangeError(fmt.Sprintf("Buffer size is too large: %d", size)))
  60. }
  61. }()
  62. if size < 0 {
  63. panic(rangeError(fmt.Sprintf("Invalid buffer size: %d", size)))
  64. }
  65. b = make([]byte, size)
  66. return
  67. }
  68. func (r *Runtime) builtin_newArrayBuffer(args []Value, newTarget *Object) *Object {
  69. if newTarget == nil {
  70. panic(r.needNew("ArrayBuffer"))
  71. }
  72. b := r._newArrayBuffer(r.getPrototypeFromCtor(newTarget, r.global.ArrayBuffer, r.global.ArrayBufferPrototype), nil)
  73. if len(args) > 0 {
  74. b.data = allocByteSlice(r.toIndex(args[0]))
  75. }
  76. return b.val
  77. }
  78. func (r *Runtime) arrayBufferProto_getByteLength(call FunctionCall) Value {
  79. o := r.toObject(call.This)
  80. if b, ok := o.self.(*arrayBufferObject); ok {
  81. if b.ensureNotDetached(false) {
  82. return intToValue(int64(len(b.data)))
  83. }
  84. return intToValue(0)
  85. }
  86. panic(r.NewTypeError("Object is not ArrayBuffer: %s", o))
  87. }
  88. func (r *Runtime) arrayBufferProto_slice(call FunctionCall) Value {
  89. o := r.toObject(call.This)
  90. if b, ok := o.self.(*arrayBufferObject); ok {
  91. l := int64(len(b.data))
  92. start := relToIdx(call.Argument(0).ToInteger(), l)
  93. var stop int64
  94. if arg := call.Argument(1); arg != _undefined {
  95. stop = arg.ToInteger()
  96. } else {
  97. stop = l
  98. }
  99. stop = relToIdx(stop, l)
  100. newLen := max(stop-start, 0)
  101. ret := r.speciesConstructor(o, r.global.ArrayBuffer)([]Value{intToValue(newLen)}, nil)
  102. if ab, ok := ret.self.(*arrayBufferObject); ok {
  103. if newLen > 0 {
  104. b.ensureNotDetached(true)
  105. if ret == o {
  106. panic(r.NewTypeError("Species constructor returned the same ArrayBuffer"))
  107. }
  108. if int64(len(ab.data)) < newLen {
  109. panic(r.NewTypeError("Species constructor returned an ArrayBuffer that is too small: %d", len(ab.data)))
  110. }
  111. ab.ensureNotDetached(true)
  112. copy(ab.data, b.data[start:stop])
  113. }
  114. return ret
  115. }
  116. panic(r.NewTypeError("Species constructor did not return an ArrayBuffer: %s", ret.String()))
  117. }
  118. panic(r.NewTypeError("Object is not ArrayBuffer: %s", o))
  119. }
  120. func (r *Runtime) arrayBuffer_isView(call FunctionCall) Value {
  121. if o, ok := call.Argument(0).(*Object); ok {
  122. if _, ok := o.self.(*dataViewObject); ok {
  123. return valueTrue
  124. }
  125. if _, ok := o.self.(*typedArrayObject); ok {
  126. return valueTrue
  127. }
  128. }
  129. return valueFalse
  130. }
  131. func (r *Runtime) newDataView(args []Value, newTarget *Object) *Object {
  132. if newTarget == nil {
  133. panic(r.needNew("DataView"))
  134. }
  135. proto := r.getPrototypeFromCtor(newTarget, r.global.DataView, r.global.DataViewPrototype)
  136. var bufArg Value
  137. if len(args) > 0 {
  138. bufArg = args[0]
  139. }
  140. var buffer *arrayBufferObject
  141. if o, ok := bufArg.(*Object); ok {
  142. if b, ok := o.self.(*arrayBufferObject); ok {
  143. buffer = b
  144. }
  145. }
  146. if buffer == nil {
  147. panic(r.NewTypeError("First argument to DataView constructor must be an ArrayBuffer"))
  148. }
  149. var byteOffset, byteLen int
  150. if len(args) > 1 {
  151. offsetArg := nilSafe(args[1])
  152. byteOffset = r.toIndex(offsetArg)
  153. buffer.ensureNotDetached(true)
  154. if byteOffset > len(buffer.data) {
  155. panic(r.newError(r.global.RangeError, "Start offset %s is outside the bounds of the buffer", offsetArg.String()))
  156. }
  157. }
  158. if len(args) > 2 && args[2] != nil && args[2] != _undefined {
  159. byteLen = r.toIndex(args[2])
  160. if byteOffset+byteLen > len(buffer.data) {
  161. panic(r.newError(r.global.RangeError, "Invalid DataView length %d", byteLen))
  162. }
  163. } else {
  164. byteLen = len(buffer.data) - byteOffset
  165. }
  166. o := &Object{runtime: r}
  167. b := &dataViewObject{
  168. baseObject: baseObject{
  169. class: classObject,
  170. val: o,
  171. prototype: proto,
  172. extensible: true,
  173. },
  174. viewedArrayBuf: buffer,
  175. byteOffset: byteOffset,
  176. byteLen: byteLen,
  177. }
  178. o.self = b
  179. b.init()
  180. return o
  181. }
  182. func (r *Runtime) dataViewProto_getBuffer(call FunctionCall) Value {
  183. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  184. return dv.viewedArrayBuf.val
  185. }
  186. panic(r.NewTypeError("Method get DataView.prototype.buffer called on incompatible receiver %s", call.This.String()))
  187. }
  188. func (r *Runtime) dataViewProto_getByteLen(call FunctionCall) Value {
  189. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  190. dv.viewedArrayBuf.ensureNotDetached(true)
  191. return intToValue(int64(dv.byteLen))
  192. }
  193. panic(r.NewTypeError("Method get DataView.prototype.byteLength called on incompatible receiver %s", call.This.String()))
  194. }
  195. func (r *Runtime) dataViewProto_getByteOffset(call FunctionCall) Value {
  196. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  197. dv.viewedArrayBuf.ensureNotDetached(true)
  198. return intToValue(int64(dv.byteOffset))
  199. }
  200. panic(r.NewTypeError("Method get DataView.prototype.byteOffset called on incompatible receiver %s", call.This.String()))
  201. }
  202. func (r *Runtime) dataViewProto_getFloat32(call FunctionCall) Value {
  203. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  204. return floatToValue(float64(dv.viewedArrayBuf.getFloat32(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 4))))
  205. }
  206. panic(r.NewTypeError("Method DataView.prototype.getFloat32 called on incompatible receiver %s", call.This.String()))
  207. }
  208. func (r *Runtime) dataViewProto_getFloat64(call FunctionCall) Value {
  209. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  210. return floatToValue(dv.viewedArrayBuf.getFloat64(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 8)))
  211. }
  212. panic(r.NewTypeError("Method DataView.prototype.getFloat64 called on incompatible receiver %s", call.This.String()))
  213. }
  214. func (r *Runtime) dataViewProto_getInt8(call FunctionCall) Value {
  215. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  216. idx, _ := dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 1)
  217. return intToValue(int64(dv.viewedArrayBuf.getInt8(idx)))
  218. }
  219. panic(r.NewTypeError("Method DataView.prototype.getInt8 called on incompatible receiver %s", call.This.String()))
  220. }
  221. func (r *Runtime) dataViewProto_getInt16(call FunctionCall) Value {
  222. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  223. return intToValue(int64(dv.viewedArrayBuf.getInt16(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 2))))
  224. }
  225. panic(r.NewTypeError("Method DataView.prototype.getInt16 called on incompatible receiver %s", call.This.String()))
  226. }
  227. func (r *Runtime) dataViewProto_getInt32(call FunctionCall) Value {
  228. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  229. return intToValue(int64(dv.viewedArrayBuf.getInt32(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 4))))
  230. }
  231. panic(r.NewTypeError("Method DataView.prototype.getInt32 called on incompatible receiver %s", call.This.String()))
  232. }
  233. func (r *Runtime) dataViewProto_getUint8(call FunctionCall) Value {
  234. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  235. idx, _ := dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 1)
  236. return intToValue(int64(dv.viewedArrayBuf.getUint8(idx)))
  237. }
  238. panic(r.NewTypeError("Method DataView.prototype.getUint8 called on incompatible receiver %s", call.This.String()))
  239. }
  240. func (r *Runtime) dataViewProto_getUint16(call FunctionCall) Value {
  241. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  242. return intToValue(int64(dv.viewedArrayBuf.getUint16(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 2))))
  243. }
  244. panic(r.NewTypeError("Method DataView.prototype.getUint16 called on incompatible receiver %s", call.This.String()))
  245. }
  246. func (r *Runtime) dataViewProto_getUint32(call FunctionCall) Value {
  247. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  248. return intToValue(int64(dv.viewedArrayBuf.getUint32(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 4))))
  249. }
  250. panic(r.NewTypeError("Method DataView.prototype.getUint32 called on incompatible receiver %s", call.This.String()))
  251. }
  252. func (r *Runtime) dataViewProto_setFloat32(call FunctionCall) Value {
  253. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  254. idxVal := r.toIndex(call.Argument(0))
  255. val := toFloat32(call.Argument(1))
  256. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 4)
  257. dv.viewedArrayBuf.setFloat32(idx, val, bo)
  258. return _undefined
  259. }
  260. panic(r.NewTypeError("Method DataView.prototype.setFloat32 called on incompatible receiver %s", call.This.String()))
  261. }
  262. func (r *Runtime) dataViewProto_setFloat64(call FunctionCall) Value {
  263. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  264. idxVal := r.toIndex(call.Argument(0))
  265. val := call.Argument(1).ToFloat()
  266. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 8)
  267. dv.viewedArrayBuf.setFloat64(idx, val, bo)
  268. return _undefined
  269. }
  270. panic(r.NewTypeError("Method DataView.prototype.setFloat64 called on incompatible receiver %s", call.This.String()))
  271. }
  272. func (r *Runtime) dataViewProto_setInt8(call FunctionCall) Value {
  273. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  274. idxVal := r.toIndex(call.Argument(0))
  275. val := toInt8(call.Argument(1))
  276. idx, _ := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 1)
  277. dv.viewedArrayBuf.setInt8(idx, val)
  278. return _undefined
  279. }
  280. panic(r.NewTypeError("Method DataView.prototype.setInt8 called on incompatible receiver %s", call.This.String()))
  281. }
  282. func (r *Runtime) dataViewProto_setInt16(call FunctionCall) Value {
  283. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  284. idxVal := r.toIndex(call.Argument(0))
  285. val := toInt16(call.Argument(1))
  286. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 2)
  287. dv.viewedArrayBuf.setInt16(idx, val, bo)
  288. return _undefined
  289. }
  290. panic(r.NewTypeError("Method DataView.prototype.setInt16 called on incompatible receiver %s", call.This.String()))
  291. }
  292. func (r *Runtime) dataViewProto_setInt32(call FunctionCall) Value {
  293. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  294. idxVal := r.toIndex(call.Argument(0))
  295. val := toInt32(call.Argument(1))
  296. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 4)
  297. dv.viewedArrayBuf.setInt32(idx, val, bo)
  298. return _undefined
  299. }
  300. panic(r.NewTypeError("Method DataView.prototype.setInt32 called on incompatible receiver %s", call.This.String()))
  301. }
  302. func (r *Runtime) dataViewProto_setUint8(call FunctionCall) Value {
  303. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  304. idxVal := r.toIndex(call.Argument(0))
  305. val := toUint8(call.Argument(1))
  306. idx, _ := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 1)
  307. dv.viewedArrayBuf.setUint8(idx, val)
  308. return _undefined
  309. }
  310. panic(r.NewTypeError("Method DataView.prototype.setUint8 called on incompatible receiver %s", call.This.String()))
  311. }
  312. func (r *Runtime) dataViewProto_setUint16(call FunctionCall) Value {
  313. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  314. idxVal := r.toIndex(call.Argument(0))
  315. val := toUint16(call.Argument(1))
  316. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 2)
  317. dv.viewedArrayBuf.setUint16(idx, val, bo)
  318. return _undefined
  319. }
  320. panic(r.NewTypeError("Method DataView.prototype.setUint16 called on incompatible receiver %s", call.This.String()))
  321. }
  322. func (r *Runtime) dataViewProto_setUint32(call FunctionCall) Value {
  323. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  324. idxVal := r.toIndex(call.Argument(0))
  325. val := toUint32(call.Argument(1))
  326. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 4)
  327. dv.viewedArrayBuf.setUint32(idx, val, bo)
  328. return _undefined
  329. }
  330. panic(r.NewTypeError("Method DataView.prototype.setUint32 called on incompatible receiver %s", call.This.String()))
  331. }
  332. func (r *Runtime) typedArrayProto_getBuffer(call FunctionCall) Value {
  333. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  334. return ta.viewedArrayBuf.val
  335. }
  336. panic(r.NewTypeError("Method get TypedArray.prototype.buffer called on incompatible receiver %s", call.This.String()))
  337. }
  338. func (r *Runtime) typedArrayProto_getByteLen(call FunctionCall) Value {
  339. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  340. if ta.viewedArrayBuf.data == nil {
  341. return _positiveZero
  342. }
  343. return intToValue(int64(ta.length) * int64(ta.elemSize))
  344. }
  345. panic(r.NewTypeError("Method get TypedArray.prototype.byteLength called on incompatible receiver %s", call.This.String()))
  346. }
  347. func (r *Runtime) typedArrayProto_getLength(call FunctionCall) Value {
  348. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  349. if ta.viewedArrayBuf.data == nil {
  350. return _positiveZero
  351. }
  352. return intToValue(int64(ta.length))
  353. }
  354. panic(r.NewTypeError("Method get TypedArray.prototype.length called on incompatible receiver %s", call.This.String()))
  355. }
  356. func (r *Runtime) typedArrayProto_getByteOffset(call FunctionCall) Value {
  357. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  358. if ta.viewedArrayBuf.data == nil {
  359. return _positiveZero
  360. }
  361. return intToValue(int64(ta.offset) * int64(ta.elemSize))
  362. }
  363. panic(r.NewTypeError("Method get TypedArray.prototype.byteOffset called on incompatible receiver %s", call.This.String()))
  364. }
  365. func (r *Runtime) typedArrayProto_copyWithin(call FunctionCall) Value {
  366. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  367. ta.viewedArrayBuf.ensureNotDetached(true)
  368. l := int64(ta.length)
  369. var relEnd int64
  370. to := toIntStrict(relToIdx(call.Argument(0).ToInteger(), l))
  371. from := toIntStrict(relToIdx(call.Argument(1).ToInteger(), l))
  372. if end := call.Argument(2); end != _undefined {
  373. relEnd = end.ToInteger()
  374. } else {
  375. relEnd = l
  376. }
  377. final := toIntStrict(relToIdx(relEnd, l))
  378. data := ta.viewedArrayBuf.data
  379. offset := ta.offset
  380. elemSize := ta.elemSize
  381. if final > from {
  382. ta.viewedArrayBuf.ensureNotDetached(true)
  383. copy(data[(offset+to)*elemSize:], data[(offset+from)*elemSize:(offset+final)*elemSize])
  384. }
  385. return call.This
  386. }
  387. panic(r.NewTypeError("Method TypedArray.prototype.copyWithin called on incompatible receiver %s", call.This.String()))
  388. }
  389. func (r *Runtime) typedArrayProto_entries(call FunctionCall) Value {
  390. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  391. ta.viewedArrayBuf.ensureNotDetached(true)
  392. return r.createArrayIterator(ta.val, iterationKindKeyValue)
  393. }
  394. panic(r.NewTypeError("Method TypedArray.prototype.entries called on incompatible receiver %s", call.This.String()))
  395. }
  396. func (r *Runtime) typedArrayProto_every(call FunctionCall) Value {
  397. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  398. ta.viewedArrayBuf.ensureNotDetached(true)
  399. callbackFn := r.toCallable(call.Argument(0))
  400. fc := FunctionCall{
  401. This: call.Argument(1),
  402. Arguments: []Value{nil, nil, call.This},
  403. }
  404. for k := 0; k < ta.length; k++ {
  405. if ta.isValidIntegerIndex(k) {
  406. fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
  407. } else {
  408. fc.Arguments[0] = _undefined
  409. }
  410. fc.Arguments[1] = intToValue(int64(k))
  411. if !callbackFn(fc).ToBoolean() {
  412. return valueFalse
  413. }
  414. }
  415. return valueTrue
  416. }
  417. panic(r.NewTypeError("Method TypedArray.prototype.every called on incompatible receiver %s", call.This.String()))
  418. }
  419. func (r *Runtime) typedArrayProto_fill(call FunctionCall) Value {
  420. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  421. ta.viewedArrayBuf.ensureNotDetached(true)
  422. l := int64(ta.length)
  423. k := toIntStrict(relToIdx(call.Argument(1).ToInteger(), l))
  424. var relEnd int64
  425. if endArg := call.Argument(2); endArg != _undefined {
  426. relEnd = endArg.ToInteger()
  427. } else {
  428. relEnd = l
  429. }
  430. final := toIntStrict(relToIdx(relEnd, l))
  431. value := ta.typedArray.toRaw(call.Argument(0))
  432. ta.viewedArrayBuf.ensureNotDetached(true)
  433. for ; k < final; k++ {
  434. ta.typedArray.setRaw(ta.offset+k, value)
  435. }
  436. return call.This
  437. }
  438. panic(r.NewTypeError("Method TypedArray.prototype.fill called on incompatible receiver %s", call.This.String()))
  439. }
  440. func (r *Runtime) typedArrayProto_filter(call FunctionCall) Value {
  441. o := r.toObject(call.This)
  442. if ta, ok := o.self.(*typedArrayObject); ok {
  443. ta.viewedArrayBuf.ensureNotDetached(true)
  444. callbackFn := r.toCallable(call.Argument(0))
  445. fc := FunctionCall{
  446. This: call.Argument(1),
  447. Arguments: []Value{nil, nil, call.This},
  448. }
  449. buf := make([]byte, 0, ta.length*ta.elemSize)
  450. captured := 0
  451. rawVal := make([]byte, ta.elemSize)
  452. for k := 0; k < ta.length; k++ {
  453. if ta.isValidIntegerIndex(k) {
  454. fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
  455. i := (ta.offset + k) * ta.elemSize
  456. copy(rawVal, ta.viewedArrayBuf.data[i:])
  457. } else {
  458. fc.Arguments[0] = _undefined
  459. for i := range rawVal {
  460. rawVal[i] = 0
  461. }
  462. }
  463. fc.Arguments[1] = intToValue(int64(k))
  464. if callbackFn(fc).ToBoolean() {
  465. buf = append(buf, rawVal...)
  466. captured++
  467. }
  468. }
  469. c := r.speciesConstructorObj(o, ta.defaultCtor)
  470. ab := r._newArrayBuffer(r.global.ArrayBufferPrototype, nil)
  471. ab.data = buf
  472. kept := r.toConstructor(ta.defaultCtor)([]Value{ab.val}, ta.defaultCtor)
  473. if c == ta.defaultCtor {
  474. return kept
  475. } else {
  476. ret := r.typedArrayCreate(c, intToValue(int64(captured)))
  477. keptTa := kept.self.(*typedArrayObject)
  478. for i := 0; i < captured; i++ {
  479. ret.typedArray.set(i, keptTa.typedArray.get(keptTa.offset+i))
  480. }
  481. return ret.val
  482. }
  483. }
  484. panic(r.NewTypeError("Method TypedArray.prototype.filter called on incompatible receiver %s", call.This.String()))
  485. }
  486. func (r *Runtime) typedArrayProto_find(call FunctionCall) Value {
  487. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  488. ta.viewedArrayBuf.ensureNotDetached(true)
  489. predicate := r.toCallable(call.Argument(0))
  490. fc := FunctionCall{
  491. This: call.Argument(1),
  492. Arguments: []Value{nil, nil, call.This},
  493. }
  494. for k := 0; k < ta.length; k++ {
  495. var val Value
  496. if ta.isValidIntegerIndex(k) {
  497. val = ta.typedArray.get(ta.offset + k)
  498. }
  499. fc.Arguments[0] = val
  500. fc.Arguments[1] = intToValue(int64(k))
  501. if predicate(fc).ToBoolean() {
  502. return val
  503. }
  504. }
  505. return _undefined
  506. }
  507. panic(r.NewTypeError("Method TypedArray.prototype.find called on incompatible receiver %s", call.This.String()))
  508. }
  509. func (r *Runtime) typedArrayProto_findIndex(call FunctionCall) Value {
  510. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  511. ta.viewedArrayBuf.ensureNotDetached(true)
  512. predicate := r.toCallable(call.Argument(0))
  513. fc := FunctionCall{
  514. This: call.Argument(1),
  515. Arguments: []Value{nil, nil, call.This},
  516. }
  517. for k := 0; k < ta.length; k++ {
  518. if ta.isValidIntegerIndex(k) {
  519. fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
  520. } else {
  521. fc.Arguments[0] = _undefined
  522. }
  523. fc.Arguments[1] = intToValue(int64(k))
  524. if predicate(fc).ToBoolean() {
  525. return fc.Arguments[1]
  526. }
  527. }
  528. return intToValue(-1)
  529. }
  530. panic(r.NewTypeError("Method TypedArray.prototype.findIndex called on incompatible receiver %s", call.This.String()))
  531. }
  532. func (r *Runtime) typedArrayProto_forEach(call FunctionCall) Value {
  533. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  534. ta.viewedArrayBuf.ensureNotDetached(true)
  535. callbackFn := r.toCallable(call.Argument(0))
  536. fc := FunctionCall{
  537. This: call.Argument(1),
  538. Arguments: []Value{nil, nil, call.This},
  539. }
  540. for k := 0; k < ta.length; k++ {
  541. var val Value
  542. if ta.isValidIntegerIndex(k) {
  543. val = ta.typedArray.get(ta.offset + k)
  544. }
  545. fc.Arguments[0] = val
  546. fc.Arguments[1] = intToValue(int64(k))
  547. callbackFn(fc)
  548. }
  549. return _undefined
  550. }
  551. panic(r.NewTypeError("Method TypedArray.prototype.forEach called on incompatible receiver %s", call.This.String()))
  552. }
  553. func (r *Runtime) typedArrayProto_includes(call FunctionCall) Value {
  554. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  555. ta.viewedArrayBuf.ensureNotDetached(true)
  556. length := int64(ta.length)
  557. if length == 0 {
  558. return valueFalse
  559. }
  560. n := call.Argument(1).ToInteger()
  561. if n >= length {
  562. return valueFalse
  563. }
  564. if n < 0 {
  565. n = max(length+n, 0)
  566. }
  567. searchElement := call.Argument(0)
  568. if searchElement == _negativeZero {
  569. searchElement = _positiveZero
  570. }
  571. startIdx := toIntStrict(n)
  572. if !ta.viewedArrayBuf.ensureNotDetached(false) {
  573. if searchElement == _undefined && startIdx < ta.length {
  574. return valueTrue
  575. }
  576. return valueFalse
  577. }
  578. if ta.typedArray.typeMatch(searchElement) {
  579. se := ta.typedArray.toRaw(searchElement)
  580. for k := startIdx; k < ta.length; k++ {
  581. if ta.typedArray.getRaw(ta.offset+k) == se {
  582. return valueTrue
  583. }
  584. }
  585. }
  586. return valueFalse
  587. }
  588. panic(r.NewTypeError("Method TypedArray.prototype.includes called on incompatible receiver %s", call.This.String()))
  589. }
  590. func (r *Runtime) typedArrayProto_indexOf(call FunctionCall) Value {
  591. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  592. ta.viewedArrayBuf.ensureNotDetached(true)
  593. length := int64(ta.length)
  594. if length == 0 {
  595. return intToValue(-1)
  596. }
  597. n := call.Argument(1).ToInteger()
  598. if n >= length {
  599. return intToValue(-1)
  600. }
  601. if n < 0 {
  602. n = max(length+n, 0)
  603. }
  604. if ta.viewedArrayBuf.ensureNotDetached(false) {
  605. searchElement := call.Argument(0)
  606. if searchElement == _negativeZero {
  607. searchElement = _positiveZero
  608. }
  609. if !IsNaN(searchElement) && ta.typedArray.typeMatch(searchElement) {
  610. se := ta.typedArray.toRaw(searchElement)
  611. for k := toIntStrict(n); k < ta.length; k++ {
  612. if ta.typedArray.getRaw(ta.offset+k) == se {
  613. return intToValue(int64(k))
  614. }
  615. }
  616. }
  617. }
  618. return intToValue(-1)
  619. }
  620. panic(r.NewTypeError("Method TypedArray.prototype.indexOf called on incompatible receiver %s", call.This.String()))
  621. }
  622. func (r *Runtime) typedArrayProto_join(call FunctionCall) Value {
  623. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  624. ta.viewedArrayBuf.ensureNotDetached(true)
  625. s := call.Argument(0)
  626. var sep valueString
  627. if s != _undefined {
  628. sep = s.toString()
  629. } else {
  630. sep = asciiString(",")
  631. }
  632. l := ta.length
  633. if l == 0 {
  634. return stringEmpty
  635. }
  636. var buf valueStringBuilder
  637. var element0 Value
  638. if ta.isValidIntegerIndex(0) {
  639. element0 = ta.typedArray.get(ta.offset + 0)
  640. }
  641. if element0 != nil && element0 != _undefined && element0 != _null {
  642. buf.WriteString(element0.toString())
  643. }
  644. for i := 1; i < l; i++ {
  645. buf.WriteString(sep)
  646. if ta.isValidIntegerIndex(i) {
  647. element := ta.typedArray.get(ta.offset + i)
  648. if element != nil && element != _undefined && element != _null {
  649. buf.WriteString(element.toString())
  650. }
  651. }
  652. }
  653. return buf.String()
  654. }
  655. panic(r.NewTypeError("Method TypedArray.prototype.join called on incompatible receiver"))
  656. }
  657. func (r *Runtime) typedArrayProto_keys(call FunctionCall) Value {
  658. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  659. ta.viewedArrayBuf.ensureNotDetached(true)
  660. return r.createArrayIterator(ta.val, iterationKindKey)
  661. }
  662. panic(r.NewTypeError("Method TypedArray.prototype.keys called on incompatible receiver %s", call.This.String()))
  663. }
  664. func (r *Runtime) typedArrayProto_lastIndexOf(call FunctionCall) Value {
  665. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  666. ta.viewedArrayBuf.ensureNotDetached(true)
  667. length := int64(ta.length)
  668. if length == 0 {
  669. return intToValue(-1)
  670. }
  671. var fromIndex int64
  672. if len(call.Arguments) < 2 {
  673. fromIndex = length - 1
  674. } else {
  675. fromIndex = call.Argument(1).ToInteger()
  676. if fromIndex >= 0 {
  677. fromIndex = min(fromIndex, length-1)
  678. } else {
  679. fromIndex += length
  680. if fromIndex < 0 {
  681. fromIndex = -1 // prevent underflow in toIntStrict() on 32-bit platforms
  682. }
  683. }
  684. }
  685. if ta.viewedArrayBuf.ensureNotDetached(false) {
  686. searchElement := call.Argument(0)
  687. if searchElement == _negativeZero {
  688. searchElement = _positiveZero
  689. }
  690. if !IsNaN(searchElement) && ta.typedArray.typeMatch(searchElement) {
  691. se := ta.typedArray.toRaw(searchElement)
  692. for k := toIntStrict(fromIndex); k >= 0; k-- {
  693. if ta.typedArray.getRaw(ta.offset+k) == se {
  694. return intToValue(int64(k))
  695. }
  696. }
  697. }
  698. }
  699. return intToValue(-1)
  700. }
  701. panic(r.NewTypeError("Method TypedArray.prototype.lastIndexOf called on incompatible receiver %s", call.This.String()))
  702. }
  703. func (r *Runtime) typedArrayProto_map(call FunctionCall) Value {
  704. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  705. ta.viewedArrayBuf.ensureNotDetached(true)
  706. callbackFn := r.toCallable(call.Argument(0))
  707. fc := FunctionCall{
  708. This: call.Argument(1),
  709. Arguments: []Value{nil, nil, call.This},
  710. }
  711. dst := r.typedArraySpeciesCreate(ta, []Value{intToValue(int64(ta.length))})
  712. for i := 0; i < ta.length; i++ {
  713. if ta.isValidIntegerIndex(i) {
  714. fc.Arguments[0] = ta.typedArray.get(ta.offset + i)
  715. } else {
  716. fc.Arguments[0] = _undefined
  717. }
  718. fc.Arguments[1] = intToValue(int64(i))
  719. dst.typedArray.set(i, callbackFn(fc))
  720. }
  721. return dst.val
  722. }
  723. panic(r.NewTypeError("Method TypedArray.prototype.map called on incompatible receiver %s", call.This.String()))
  724. }
  725. func (r *Runtime) typedArrayProto_reduce(call FunctionCall) Value {
  726. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  727. ta.viewedArrayBuf.ensureNotDetached(true)
  728. callbackFn := r.toCallable(call.Argument(0))
  729. fc := FunctionCall{
  730. This: _undefined,
  731. Arguments: []Value{nil, nil, nil, call.This},
  732. }
  733. k := 0
  734. if len(call.Arguments) >= 2 {
  735. fc.Arguments[0] = call.Argument(1)
  736. } else {
  737. if ta.length > 0 {
  738. fc.Arguments[0] = ta.typedArray.get(ta.offset + 0)
  739. k = 1
  740. }
  741. }
  742. if fc.Arguments[0] == nil {
  743. panic(r.NewTypeError("Reduce of empty array with no initial value"))
  744. }
  745. for ; k < ta.length; k++ {
  746. if ta.isValidIntegerIndex(k) {
  747. fc.Arguments[1] = ta.typedArray.get(ta.offset + k)
  748. } else {
  749. fc.Arguments[1] = _undefined
  750. }
  751. idx := valueInt(k)
  752. fc.Arguments[2] = idx
  753. fc.Arguments[0] = callbackFn(fc)
  754. }
  755. return fc.Arguments[0]
  756. }
  757. panic(r.NewTypeError("Method TypedArray.prototype.reduce called on incompatible receiver %s", call.This.String()))
  758. }
  759. func (r *Runtime) typedArrayProto_reduceRight(call FunctionCall) Value {
  760. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  761. ta.viewedArrayBuf.ensureNotDetached(true)
  762. callbackFn := r.toCallable(call.Argument(0))
  763. fc := FunctionCall{
  764. This: _undefined,
  765. Arguments: []Value{nil, nil, nil, call.This},
  766. }
  767. k := ta.length - 1
  768. if len(call.Arguments) >= 2 {
  769. fc.Arguments[0] = call.Argument(1)
  770. } else {
  771. if k >= 0 {
  772. fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
  773. k--
  774. }
  775. }
  776. if fc.Arguments[0] == nil {
  777. panic(r.NewTypeError("Reduce of empty array with no initial value"))
  778. }
  779. for ; k >= 0; k-- {
  780. if ta.isValidIntegerIndex(k) {
  781. fc.Arguments[1] = ta.typedArray.get(ta.offset + k)
  782. } else {
  783. fc.Arguments[1] = _undefined
  784. }
  785. idx := valueInt(k)
  786. fc.Arguments[2] = idx
  787. fc.Arguments[0] = callbackFn(fc)
  788. }
  789. return fc.Arguments[0]
  790. }
  791. panic(r.NewTypeError("Method TypedArray.prototype.reduceRight called on incompatible receiver %s", call.This.String()))
  792. }
  793. func (r *Runtime) typedArrayProto_reverse(call FunctionCall) Value {
  794. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  795. ta.viewedArrayBuf.ensureNotDetached(true)
  796. l := ta.length
  797. middle := l / 2
  798. for lower := 0; lower != middle; lower++ {
  799. upper := l - lower - 1
  800. ta.typedArray.swap(ta.offset+lower, ta.offset+upper)
  801. }
  802. return call.This
  803. }
  804. panic(r.NewTypeError("Method TypedArray.prototype.reverse called on incompatible receiver %s", call.This.String()))
  805. }
  806. func (r *Runtime) typedArrayProto_set(call FunctionCall) Value {
  807. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  808. srcObj := call.Argument(0).ToObject(r)
  809. targetOffset := toIntStrict(call.Argument(1).ToInteger())
  810. if targetOffset < 0 {
  811. panic(r.newError(r.global.RangeError, "offset should be >= 0"))
  812. }
  813. ta.viewedArrayBuf.ensureNotDetached(true)
  814. targetLen := ta.length
  815. if src, ok := srcObj.self.(*typedArrayObject); ok {
  816. src.viewedArrayBuf.ensureNotDetached(true)
  817. srcLen := src.length
  818. if x := srcLen + targetOffset; x < 0 || x > targetLen {
  819. panic(r.newError(r.global.RangeError, "Source is too large"))
  820. }
  821. if src.defaultCtor == ta.defaultCtor {
  822. copy(ta.viewedArrayBuf.data[(ta.offset+targetOffset)*ta.elemSize:],
  823. src.viewedArrayBuf.data[src.offset*src.elemSize:(src.offset+srcLen)*src.elemSize])
  824. } else {
  825. curSrc := uintptr(unsafe.Pointer(&src.viewedArrayBuf.data[src.offset*src.elemSize]))
  826. endSrc := curSrc + uintptr(srcLen*src.elemSize)
  827. curDst := uintptr(unsafe.Pointer(&ta.viewedArrayBuf.data[(ta.offset+targetOffset)*ta.elemSize]))
  828. dstOffset := ta.offset + targetOffset
  829. srcOffset := src.offset
  830. if ta.elemSize == src.elemSize {
  831. if curDst <= curSrc || curDst >= endSrc {
  832. for i := 0; i < srcLen; i++ {
  833. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  834. }
  835. } else {
  836. for i := srcLen - 1; i >= 0; i-- {
  837. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  838. }
  839. }
  840. } else {
  841. x := int(curDst-curSrc) / (src.elemSize - ta.elemSize)
  842. if x < 0 {
  843. x = 0
  844. } else if x > srcLen {
  845. x = srcLen
  846. }
  847. if ta.elemSize < src.elemSize {
  848. for i := x; i < srcLen; i++ {
  849. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  850. }
  851. for i := x - 1; i >= 0; i-- {
  852. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  853. }
  854. } else {
  855. for i := 0; i < x; i++ {
  856. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  857. }
  858. for i := srcLen - 1; i >= x; i-- {
  859. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  860. }
  861. }
  862. }
  863. }
  864. } else {
  865. targetLen := ta.length
  866. srcLen := toIntStrict(toLength(srcObj.self.getStr("length", nil)))
  867. if x := srcLen + targetOffset; x < 0 || x > targetLen {
  868. panic(r.newError(r.global.RangeError, "Source is too large"))
  869. }
  870. for i := 0; i < srcLen; i++ {
  871. val := nilSafe(srcObj.self.getIdx(valueInt(i), nil))
  872. ta.viewedArrayBuf.ensureNotDetached(true)
  873. if ta.isValidIntegerIndex(i) {
  874. ta.typedArray.set(targetOffset+i, val)
  875. }
  876. }
  877. }
  878. return _undefined
  879. }
  880. panic(r.NewTypeError("Method TypedArray.prototype.set called on incompatible receiver %s", call.This.String()))
  881. }
  882. func (r *Runtime) typedArrayProto_slice(call FunctionCall) Value {
  883. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  884. ta.viewedArrayBuf.ensureNotDetached(true)
  885. length := int64(ta.length)
  886. start := toIntStrict(relToIdx(call.Argument(0).ToInteger(), length))
  887. var e int64
  888. if endArg := call.Argument(1); endArg != _undefined {
  889. e = endArg.ToInteger()
  890. } else {
  891. e = length
  892. }
  893. end := toIntStrict(relToIdx(e, length))
  894. count := end - start
  895. if count < 0 {
  896. count = 0
  897. }
  898. dst := r.typedArraySpeciesCreate(ta, []Value{intToValue(int64(count))})
  899. if dst.defaultCtor == ta.defaultCtor {
  900. if count > 0 {
  901. ta.viewedArrayBuf.ensureNotDetached(true)
  902. offset := ta.offset
  903. elemSize := ta.elemSize
  904. copy(dst.viewedArrayBuf.data, ta.viewedArrayBuf.data[(offset+start)*elemSize:(offset+start+count)*elemSize])
  905. }
  906. } else {
  907. for i := 0; i < count; i++ {
  908. ta.viewedArrayBuf.ensureNotDetached(true)
  909. dst.typedArray.set(i, ta.typedArray.get(ta.offset+start+i))
  910. }
  911. }
  912. return dst.val
  913. }
  914. panic(r.NewTypeError("Method TypedArray.prototype.slice called on incompatible receiver %s", call.This.String()))
  915. }
  916. func (r *Runtime) typedArrayProto_some(call FunctionCall) Value {
  917. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  918. ta.viewedArrayBuf.ensureNotDetached(true)
  919. callbackFn := r.toCallable(call.Argument(0))
  920. fc := FunctionCall{
  921. This: call.Argument(1),
  922. Arguments: []Value{nil, nil, call.This},
  923. }
  924. for k := 0; k < ta.length; k++ {
  925. if ta.isValidIntegerIndex(k) {
  926. fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
  927. } else {
  928. fc.Arguments[0] = _undefined
  929. }
  930. fc.Arguments[1] = intToValue(int64(k))
  931. if callbackFn(fc).ToBoolean() {
  932. return valueTrue
  933. }
  934. }
  935. return valueFalse
  936. }
  937. panic(r.NewTypeError("Method TypedArray.prototype.some called on incompatible receiver %s", call.This.String()))
  938. }
  939. func (r *Runtime) typedArrayProto_sort(call FunctionCall) Value {
  940. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  941. ta.viewedArrayBuf.ensureNotDetached(true)
  942. var compareFn func(FunctionCall) Value
  943. if arg := call.Argument(0); arg != _undefined {
  944. compareFn = r.toCallable(arg)
  945. }
  946. ctx := typedArraySortCtx{
  947. ta: ta,
  948. compare: compareFn,
  949. }
  950. sort.Stable(&ctx)
  951. return call.This
  952. }
  953. panic(r.NewTypeError("Method TypedArray.prototype.sort called on incompatible receiver %s", call.This.String()))
  954. }
  955. func (r *Runtime) typedArrayProto_subarray(call FunctionCall) Value {
  956. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  957. l := int64(ta.length)
  958. beginIdx := relToIdx(call.Argument(0).ToInteger(), l)
  959. var relEnd int64
  960. if endArg := call.Argument(1); endArg != _undefined {
  961. relEnd = endArg.ToInteger()
  962. } else {
  963. relEnd = l
  964. }
  965. endIdx := relToIdx(relEnd, l)
  966. newLen := max(endIdx-beginIdx, 0)
  967. return r.typedArraySpeciesCreate(ta, []Value{ta.viewedArrayBuf.val,
  968. intToValue((int64(ta.offset) + beginIdx) * int64(ta.elemSize)),
  969. intToValue(newLen),
  970. }).val
  971. }
  972. panic(r.NewTypeError("Method TypedArray.prototype.subarray called on incompatible receiver %s", call.This.String()))
  973. }
  974. func (r *Runtime) typedArrayProto_toLocaleString(call FunctionCall) Value {
  975. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  976. length := ta.length
  977. var buf valueStringBuilder
  978. for i := 0; i < length; i++ {
  979. ta.viewedArrayBuf.ensureNotDetached(true)
  980. if i > 0 {
  981. buf.WriteRune(',')
  982. }
  983. item := ta.typedArray.get(ta.offset + i)
  984. r.writeItemLocaleString(item, &buf)
  985. }
  986. return buf.String()
  987. }
  988. panic(r.NewTypeError("Method TypedArray.prototype.toLocaleString called on incompatible receiver %s", call.This.String()))
  989. }
  990. func (r *Runtime) typedArrayProto_values(call FunctionCall) Value {
  991. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  992. ta.viewedArrayBuf.ensureNotDetached(true)
  993. return r.createArrayIterator(ta.val, iterationKindValue)
  994. }
  995. panic(r.NewTypeError("Method TypedArray.prototype.values called on incompatible receiver %s", call.This.String()))
  996. }
  997. func (r *Runtime) typedArrayProto_toStringTag(call FunctionCall) Value {
  998. if obj, ok := call.This.(*Object); ok {
  999. if ta, ok := obj.self.(*typedArrayObject); ok {
  1000. return nilSafe(ta.defaultCtor.self.getStr("name", nil))
  1001. }
  1002. }
  1003. return _undefined
  1004. }
  1005. func (r *Runtime) newTypedArray([]Value, *Object) *Object {
  1006. panic(r.NewTypeError("Abstract class TypedArray not directly constructable"))
  1007. }
  1008. func (r *Runtime) typedArray_from(call FunctionCall) Value {
  1009. c := r.toObject(call.This)
  1010. var mapFc func(call FunctionCall) Value
  1011. thisValue := call.Argument(2)
  1012. if mapFn := call.Argument(1); mapFn != _undefined {
  1013. mapFc = r.toCallable(mapFn)
  1014. }
  1015. source := r.toObject(call.Argument(0))
  1016. usingIter := toMethod(source.self.getSym(SymIterator, nil))
  1017. if usingIter != nil {
  1018. values := r.iterableToList(source, usingIter)
  1019. ta := r.typedArrayCreate(c, intToValue(int64(len(values))))
  1020. if mapFc == nil {
  1021. for idx, val := range values {
  1022. ta.typedArray.set(idx, val)
  1023. }
  1024. } else {
  1025. fc := FunctionCall{
  1026. This: thisValue,
  1027. Arguments: []Value{nil, nil},
  1028. }
  1029. for idx, val := range values {
  1030. fc.Arguments[0], fc.Arguments[1] = val, intToValue(int64(idx))
  1031. val = mapFc(fc)
  1032. ta.typedArray.set(idx, val)
  1033. }
  1034. }
  1035. return ta.val
  1036. }
  1037. length := toIntStrict(toLength(source.self.getStr("length", nil)))
  1038. ta := r.typedArrayCreate(c, intToValue(int64(length)))
  1039. if mapFc == nil {
  1040. for i := 0; i < length; i++ {
  1041. ta.typedArray.set(i, nilSafe(source.self.getIdx(valueInt(i), nil)))
  1042. }
  1043. } else {
  1044. fc := FunctionCall{
  1045. This: thisValue,
  1046. Arguments: []Value{nil, nil},
  1047. }
  1048. for i := 0; i < length; i++ {
  1049. idx := valueInt(i)
  1050. fc.Arguments[0], fc.Arguments[1] = source.self.getIdx(idx, nil), idx
  1051. ta.typedArray.set(i, mapFc(fc))
  1052. }
  1053. }
  1054. return ta.val
  1055. }
  1056. func (r *Runtime) typedArray_of(call FunctionCall) Value {
  1057. ta := r.typedArrayCreate(r.toObject(call.This), intToValue(int64(len(call.Arguments))))
  1058. for i, val := range call.Arguments {
  1059. ta.typedArray.set(i, val)
  1060. }
  1061. return ta.val
  1062. }
  1063. func (r *Runtime) allocateTypedArray(newTarget *Object, length int, taCtor typedArrayObjectCtor, proto *Object) *typedArrayObject {
  1064. buf := r._newArrayBuffer(r.global.ArrayBufferPrototype, nil)
  1065. ta := taCtor(buf, 0, length, r.getPrototypeFromCtor(newTarget, nil, proto))
  1066. if length > 0 {
  1067. buf.data = allocByteSlice(length * ta.elemSize)
  1068. }
  1069. return ta
  1070. }
  1071. func (r *Runtime) typedArraySpeciesCreate(ta *typedArrayObject, args []Value) *typedArrayObject {
  1072. return r.typedArrayCreate(r.speciesConstructorObj(ta.val, ta.defaultCtor), args...)
  1073. }
  1074. func (r *Runtime) typedArrayCreate(ctor *Object, args ...Value) *typedArrayObject {
  1075. o := r.toConstructor(ctor)(args, ctor)
  1076. if ta, ok := o.self.(*typedArrayObject); ok {
  1077. ta.viewedArrayBuf.ensureNotDetached(true)
  1078. if len(args) == 1 {
  1079. if l, ok := args[0].(valueInt); ok {
  1080. if ta.length < int(l) {
  1081. panic(r.NewTypeError("Derived TypedArray constructor created an array which was too small"))
  1082. }
  1083. }
  1084. }
  1085. return ta
  1086. }
  1087. panic(r.NewTypeError("Invalid TypedArray: %s", o))
  1088. }
  1089. func (r *Runtime) typedArrayFrom(ctor, items *Object, mapFn, thisValue Value, taCtor typedArrayObjectCtor, proto *Object) *Object {
  1090. var mapFc func(call FunctionCall) Value
  1091. if mapFn != nil {
  1092. mapFc = r.toCallable(mapFn)
  1093. if thisValue == nil {
  1094. thisValue = _undefined
  1095. }
  1096. }
  1097. usingIter := toMethod(items.self.getSym(SymIterator, nil))
  1098. if usingIter != nil {
  1099. values := r.iterableToList(items, usingIter)
  1100. ta := r.allocateTypedArray(ctor, len(values), taCtor, proto)
  1101. if mapFc == nil {
  1102. for idx, val := range values {
  1103. ta.typedArray.set(idx, val)
  1104. }
  1105. } else {
  1106. fc := FunctionCall{
  1107. This: thisValue,
  1108. Arguments: []Value{nil, nil},
  1109. }
  1110. for idx, val := range values {
  1111. fc.Arguments[0], fc.Arguments[1] = val, intToValue(int64(idx))
  1112. val = mapFc(fc)
  1113. ta.typedArray.set(idx, val)
  1114. }
  1115. }
  1116. return ta.val
  1117. }
  1118. length := toIntStrict(toLength(items.self.getStr("length", nil)))
  1119. ta := r.allocateTypedArray(ctor, length, taCtor, proto)
  1120. if mapFc == nil {
  1121. for i := 0; i < length; i++ {
  1122. ta.typedArray.set(i, nilSafe(items.self.getIdx(valueInt(i), nil)))
  1123. }
  1124. } else {
  1125. fc := FunctionCall{
  1126. This: thisValue,
  1127. Arguments: []Value{nil, nil},
  1128. }
  1129. for i := 0; i < length; i++ {
  1130. idx := valueInt(i)
  1131. fc.Arguments[0], fc.Arguments[1] = items.self.getIdx(idx, nil), idx
  1132. ta.typedArray.set(i, mapFc(fc))
  1133. }
  1134. }
  1135. return ta.val
  1136. }
  1137. func (r *Runtime) _newTypedArrayFromArrayBuffer(ab *arrayBufferObject, args []Value, newTarget *Object, taCtor typedArrayObjectCtor, proto *Object) *Object {
  1138. ta := taCtor(ab, 0, 0, r.getPrototypeFromCtor(newTarget, nil, proto))
  1139. var byteOffset int
  1140. if len(args) > 1 && args[1] != nil && args[1] != _undefined {
  1141. byteOffset = r.toIndex(args[1])
  1142. if byteOffset%ta.elemSize != 0 {
  1143. panic(r.newError(r.global.RangeError, "Start offset of %s should be a multiple of %d", newTarget.self.getStr("name", nil), ta.elemSize))
  1144. }
  1145. }
  1146. var length int
  1147. if len(args) > 2 && args[2] != nil && args[2] != _undefined {
  1148. length = r.toIndex(args[2])
  1149. ab.ensureNotDetached(true)
  1150. if byteOffset+length*ta.elemSize > len(ab.data) {
  1151. panic(r.newError(r.global.RangeError, "Invalid typed array length: %d", length))
  1152. }
  1153. } else {
  1154. ab.ensureNotDetached(true)
  1155. if len(ab.data)%ta.elemSize != 0 {
  1156. panic(r.newError(r.global.RangeError, "Byte length of %s should be a multiple of %d", newTarget.self.getStr("name", nil), ta.elemSize))
  1157. }
  1158. length = (len(ab.data) - byteOffset) / ta.elemSize
  1159. if length < 0 {
  1160. panic(r.newError(r.global.RangeError, "Start offset %d is outside the bounds of the buffer", byteOffset))
  1161. }
  1162. }
  1163. ta.offset = byteOffset / ta.elemSize
  1164. ta.length = length
  1165. return ta.val
  1166. }
  1167. func (r *Runtime) _newTypedArrayFromTypedArray(src *typedArrayObject, newTarget *Object, taCtor typedArrayObjectCtor, proto *Object) *Object {
  1168. dst := r.allocateTypedArray(newTarget, 0, taCtor, proto)
  1169. src.viewedArrayBuf.ensureNotDetached(true)
  1170. l := src.length
  1171. dst.viewedArrayBuf.prototype = r.getPrototypeFromCtor(r.speciesConstructorObj(src.viewedArrayBuf.val, r.global.ArrayBuffer), r.global.ArrayBuffer, r.global.ArrayBufferPrototype)
  1172. dst.viewedArrayBuf.data = allocByteSlice(toIntStrict(int64(l) * int64(dst.elemSize)))
  1173. src.viewedArrayBuf.ensureNotDetached(true)
  1174. if src.defaultCtor == dst.defaultCtor {
  1175. copy(dst.viewedArrayBuf.data, src.viewedArrayBuf.data[src.offset*src.elemSize:])
  1176. dst.length = src.length
  1177. return dst.val
  1178. }
  1179. dst.length = l
  1180. for i := 0; i < l; i++ {
  1181. dst.typedArray.set(i, src.typedArray.get(src.offset+i))
  1182. }
  1183. return dst.val
  1184. }
  1185. func (r *Runtime) _newTypedArray(args []Value, newTarget *Object, taCtor typedArrayObjectCtor, proto *Object) *Object {
  1186. if newTarget == nil {
  1187. panic(r.needNew("TypedArray"))
  1188. }
  1189. if len(args) > 0 {
  1190. if obj, ok := args[0].(*Object); ok {
  1191. switch o := obj.self.(type) {
  1192. case *arrayBufferObject:
  1193. return r._newTypedArrayFromArrayBuffer(o, args, newTarget, taCtor, proto)
  1194. case *typedArrayObject:
  1195. return r._newTypedArrayFromTypedArray(o, newTarget, taCtor, proto)
  1196. default:
  1197. return r.typedArrayFrom(newTarget, obj, nil, nil, taCtor, proto)
  1198. }
  1199. }
  1200. }
  1201. var l int
  1202. if len(args) > 0 {
  1203. if arg0 := args[0]; arg0 != nil {
  1204. l = r.toIndex(arg0)
  1205. }
  1206. }
  1207. return r.allocateTypedArray(newTarget, l, taCtor, proto).val
  1208. }
  1209. func (r *Runtime) newUint8Array(args []Value, newTarget, proto *Object) *Object {
  1210. return r._newTypedArray(args, newTarget, r.newUint8ArrayObject, proto)
  1211. }
  1212. func (r *Runtime) newUint8ClampedArray(args []Value, newTarget, proto *Object) *Object {
  1213. return r._newTypedArray(args, newTarget, r.newUint8ClampedArrayObject, proto)
  1214. }
  1215. func (r *Runtime) newInt8Array(args []Value, newTarget, proto *Object) *Object {
  1216. return r._newTypedArray(args, newTarget, r.newInt8ArrayObject, proto)
  1217. }
  1218. func (r *Runtime) newUint16Array(args []Value, newTarget, proto *Object) *Object {
  1219. return r._newTypedArray(args, newTarget, r.newUint16ArrayObject, proto)
  1220. }
  1221. func (r *Runtime) newInt16Array(args []Value, newTarget, proto *Object) *Object {
  1222. return r._newTypedArray(args, newTarget, r.newInt16ArrayObject, proto)
  1223. }
  1224. func (r *Runtime) newUint32Array(args []Value, newTarget, proto *Object) *Object {
  1225. return r._newTypedArray(args, newTarget, r.newUint32ArrayObject, proto)
  1226. }
  1227. func (r *Runtime) newInt32Array(args []Value, newTarget, proto *Object) *Object {
  1228. return r._newTypedArray(args, newTarget, r.newInt32ArrayObject, proto)
  1229. }
  1230. func (r *Runtime) newFloat32Array(args []Value, newTarget, proto *Object) *Object {
  1231. return r._newTypedArray(args, newTarget, r.newFloat32ArrayObject, proto)
  1232. }
  1233. func (r *Runtime) newFloat64Array(args []Value, newTarget, proto *Object) *Object {
  1234. return r._newTypedArray(args, newTarget, r.newFloat64ArrayObject, proto)
  1235. }
  1236. func (r *Runtime) createArrayBufferProto(val *Object) objectImpl {
  1237. b := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
  1238. byteLengthProp := &valueProperty{
  1239. accessor: true,
  1240. configurable: true,
  1241. getterFunc: r.newNativeFunc(r.arrayBufferProto_getByteLength, nil, "get byteLength", nil, 0),
  1242. }
  1243. b._put("byteLength", byteLengthProp)
  1244. b._putProp("constructor", r.global.ArrayBuffer, true, false, true)
  1245. b._putProp("slice", r.newNativeFunc(r.arrayBufferProto_slice, nil, "slice", nil, 2), true, false, true)
  1246. b._putSym(SymToStringTag, valueProp(asciiString("ArrayBuffer"), false, false, true))
  1247. return b
  1248. }
  1249. func (r *Runtime) createArrayBuffer(val *Object) objectImpl {
  1250. o := r.newNativeConstructOnly(val, r.builtin_newArrayBuffer, r.global.ArrayBufferPrototype, "ArrayBuffer", 1)
  1251. o._putProp("isView", r.newNativeFunc(r.arrayBuffer_isView, nil, "isView", nil, 1), true, false, true)
  1252. r.putSpeciesReturnThis(o)
  1253. return o
  1254. }
  1255. func (r *Runtime) createDataViewProto(val *Object) objectImpl {
  1256. b := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
  1257. b._put("buffer", &valueProperty{
  1258. accessor: true,
  1259. configurable: true,
  1260. getterFunc: r.newNativeFunc(r.dataViewProto_getBuffer, nil, "get buffer", nil, 0),
  1261. })
  1262. b._put("byteLength", &valueProperty{
  1263. accessor: true,
  1264. configurable: true,
  1265. getterFunc: r.newNativeFunc(r.dataViewProto_getByteLen, nil, "get byteLength", nil, 0),
  1266. })
  1267. b._put("byteOffset", &valueProperty{
  1268. accessor: true,
  1269. configurable: true,
  1270. getterFunc: r.newNativeFunc(r.dataViewProto_getByteOffset, nil, "get byteOffset", nil, 0),
  1271. })
  1272. b._putProp("constructor", r.global.DataView, true, false, true)
  1273. b._putProp("getFloat32", r.newNativeFunc(r.dataViewProto_getFloat32, nil, "getFloat32", nil, 1), true, false, true)
  1274. b._putProp("getFloat64", r.newNativeFunc(r.dataViewProto_getFloat64, nil, "getFloat64", nil, 1), true, false, true)
  1275. b._putProp("getInt8", r.newNativeFunc(r.dataViewProto_getInt8, nil, "getInt8", nil, 1), true, false, true)
  1276. b._putProp("getInt16", r.newNativeFunc(r.dataViewProto_getInt16, nil, "getInt16", nil, 1), true, false, true)
  1277. b._putProp("getInt32", r.newNativeFunc(r.dataViewProto_getInt32, nil, "getInt32", nil, 1), true, false, true)
  1278. b._putProp("getUint8", r.newNativeFunc(r.dataViewProto_getUint8, nil, "getUint8", nil, 1), true, false, true)
  1279. b._putProp("getUint16", r.newNativeFunc(r.dataViewProto_getUint16, nil, "getUint16", nil, 1), true, false, true)
  1280. b._putProp("getUint32", r.newNativeFunc(r.dataViewProto_getUint32, nil, "getUint32", nil, 1), true, false, true)
  1281. b._putProp("setFloat32", r.newNativeFunc(r.dataViewProto_setFloat32, nil, "setFloat32", nil, 2), true, false, true)
  1282. b._putProp("setFloat64", r.newNativeFunc(r.dataViewProto_setFloat64, nil, "setFloat64", nil, 2), true, false, true)
  1283. b._putProp("setInt8", r.newNativeFunc(r.dataViewProto_setInt8, nil, "setInt8", nil, 2), true, false, true)
  1284. b._putProp("setInt16", r.newNativeFunc(r.dataViewProto_setInt16, nil, "setInt16", nil, 2), true, false, true)
  1285. b._putProp("setInt32", r.newNativeFunc(r.dataViewProto_setInt32, nil, "setInt32", nil, 2), true, false, true)
  1286. b._putProp("setUint8", r.newNativeFunc(r.dataViewProto_setUint8, nil, "setUint8", nil, 2), true, false, true)
  1287. b._putProp("setUint16", r.newNativeFunc(r.dataViewProto_setUint16, nil, "setUint16", nil, 2), true, false, true)
  1288. b._putProp("setUint32", r.newNativeFunc(r.dataViewProto_setUint32, nil, "setUint32", nil, 2), true, false, true)
  1289. b._putSym(SymToStringTag, valueProp(asciiString("DataView"), false, false, true))
  1290. return b
  1291. }
  1292. func (r *Runtime) createDataView(val *Object) objectImpl {
  1293. o := r.newNativeConstructOnly(val, r.newDataView, r.global.DataViewPrototype, "DataView", 1)
  1294. return o
  1295. }
  1296. func (r *Runtime) createTypedArrayProto(val *Object) objectImpl {
  1297. b := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
  1298. b._put("buffer", &valueProperty{
  1299. accessor: true,
  1300. configurable: true,
  1301. getterFunc: r.newNativeFunc(r.typedArrayProto_getBuffer, nil, "get buffer", nil, 0),
  1302. })
  1303. b._put("byteLength", &valueProperty{
  1304. accessor: true,
  1305. configurable: true,
  1306. getterFunc: r.newNativeFunc(r.typedArrayProto_getByteLen, nil, "get byteLength", nil, 0),
  1307. })
  1308. b._put("byteOffset", &valueProperty{
  1309. accessor: true,
  1310. configurable: true,
  1311. getterFunc: r.newNativeFunc(r.typedArrayProto_getByteOffset, nil, "get byteOffset", nil, 0),
  1312. })
  1313. b._putProp("constructor", r.global.TypedArray, true, false, true)
  1314. b._putProp("copyWithin", r.newNativeFunc(r.typedArrayProto_copyWithin, nil, "copyWithin", nil, 2), true, false, true)
  1315. b._putProp("entries", r.newNativeFunc(r.typedArrayProto_entries, nil, "entries", nil, 0), true, false, true)
  1316. b._putProp("every", r.newNativeFunc(r.typedArrayProto_every, nil, "every", nil, 1), true, false, true)
  1317. b._putProp("fill", r.newNativeFunc(r.typedArrayProto_fill, nil, "fill", nil, 1), true, false, true)
  1318. b._putProp("filter", r.newNativeFunc(r.typedArrayProto_filter, nil, "filter", nil, 1), true, false, true)
  1319. b._putProp("find", r.newNativeFunc(r.typedArrayProto_find, nil, "find", nil, 1), true, false, true)
  1320. b._putProp("findIndex", r.newNativeFunc(r.typedArrayProto_findIndex, nil, "findIndex", nil, 1), true, false, true)
  1321. b._putProp("forEach", r.newNativeFunc(r.typedArrayProto_forEach, nil, "forEach", nil, 1), true, false, true)
  1322. b._putProp("includes", r.newNativeFunc(r.typedArrayProto_includes, nil, "includes", nil, 1), true, false, true)
  1323. b._putProp("indexOf", r.newNativeFunc(r.typedArrayProto_indexOf, nil, "indexOf", nil, 1), true, false, true)
  1324. b._putProp("join", r.newNativeFunc(r.typedArrayProto_join, nil, "join", nil, 1), true, false, true)
  1325. b._putProp("keys", r.newNativeFunc(r.typedArrayProto_keys, nil, "keys", nil, 0), true, false, true)
  1326. b._putProp("lastIndexOf", r.newNativeFunc(r.typedArrayProto_lastIndexOf, nil, "lastIndexOf", nil, 1), true, false, true)
  1327. b._put("length", &valueProperty{
  1328. accessor: true,
  1329. configurable: true,
  1330. getterFunc: r.newNativeFunc(r.typedArrayProto_getLength, nil, "get length", nil, 0),
  1331. })
  1332. b._putProp("map", r.newNativeFunc(r.typedArrayProto_map, nil, "map", nil, 1), true, false, true)
  1333. b._putProp("reduce", r.newNativeFunc(r.typedArrayProto_reduce, nil, "reduce", nil, 1), true, false, true)
  1334. b._putProp("reduceRight", r.newNativeFunc(r.typedArrayProto_reduceRight, nil, "reduceRight", nil, 1), true, false, true)
  1335. b._putProp("reverse", r.newNativeFunc(r.typedArrayProto_reverse, nil, "reverse", nil, 0), true, false, true)
  1336. b._putProp("set", r.newNativeFunc(r.typedArrayProto_set, nil, "set", nil, 1), true, false, true)
  1337. b._putProp("slice", r.newNativeFunc(r.typedArrayProto_slice, nil, "slice", nil, 2), true, false, true)
  1338. b._putProp("some", r.newNativeFunc(r.typedArrayProto_some, nil, "some", nil, 1), true, false, true)
  1339. b._putProp("sort", r.newNativeFunc(r.typedArrayProto_sort, nil, "sort", nil, 1), true, false, true)
  1340. b._putProp("subarray", r.newNativeFunc(r.typedArrayProto_subarray, nil, "subarray", nil, 2), true, false, true)
  1341. b._putProp("toLocaleString", r.newNativeFunc(r.typedArrayProto_toLocaleString, nil, "toLocaleString", nil, 0), true, false, true)
  1342. b._putProp("toString", r.global.arrayToString, true, false, true)
  1343. valuesFunc := r.newNativeFunc(r.typedArrayProto_values, nil, "values", nil, 0)
  1344. b._putProp("values", valuesFunc, true, false, true)
  1345. b._putSym(SymIterator, valueProp(valuesFunc, true, false, true))
  1346. b._putSym(SymToStringTag, &valueProperty{
  1347. getterFunc: r.newNativeFunc(r.typedArrayProto_toStringTag, nil, "get [Symbol.toStringTag]", nil, 0),
  1348. accessor: true,
  1349. configurable: true,
  1350. })
  1351. return b
  1352. }
  1353. func (r *Runtime) createTypedArray(val *Object) objectImpl {
  1354. o := r.newNativeConstructOnly(val, r.newTypedArray, r.global.TypedArrayPrototype, "TypedArray", 0)
  1355. o._putProp("from", r.newNativeFunc(r.typedArray_from, nil, "from", nil, 1), true, false, true)
  1356. o._putProp("of", r.newNativeFunc(r.typedArray_of, nil, "of", nil, 0), true, false, true)
  1357. r.putSpeciesReturnThis(o)
  1358. return o
  1359. }
  1360. func (r *Runtime) typedArrayCreator(ctor func(args []Value, newTarget, proto *Object) *Object, name unistring.String, bytesPerElement int) func(val *Object) objectImpl {
  1361. return func(val *Object) objectImpl {
  1362. p := r.newBaseObject(r.global.TypedArrayPrototype, classObject)
  1363. o := r.newNativeConstructOnly(val, func(args []Value, newTarget *Object) *Object {
  1364. return ctor(args, newTarget, p.val)
  1365. }, p.val, name, 3)
  1366. p._putProp("constructor", o.val, true, false, true)
  1367. o.prototype = r.global.TypedArray
  1368. bpe := intToValue(int64(bytesPerElement))
  1369. o._putProp("BYTES_PER_ELEMENT", bpe, false, false, false)
  1370. p._putProp("BYTES_PER_ELEMENT", bpe, false, false, false)
  1371. return o
  1372. }
  1373. }
  1374. func (r *Runtime) initTypedArrays() {
  1375. r.global.ArrayBufferPrototype = r.newLazyObject(r.createArrayBufferProto)
  1376. r.global.ArrayBuffer = r.newLazyObject(r.createArrayBuffer)
  1377. r.addToGlobal("ArrayBuffer", r.global.ArrayBuffer)
  1378. r.global.DataViewPrototype = r.newLazyObject(r.createDataViewProto)
  1379. r.global.DataView = r.newLazyObject(r.createDataView)
  1380. r.addToGlobal("DataView", r.global.DataView)
  1381. r.global.TypedArrayPrototype = r.newLazyObject(r.createTypedArrayProto)
  1382. r.global.TypedArray = r.newLazyObject(r.createTypedArray)
  1383. r.global.Uint8Array = r.newLazyObject(r.typedArrayCreator(r.newUint8Array, "Uint8Array", 1))
  1384. r.addToGlobal("Uint8Array", r.global.Uint8Array)
  1385. r.global.Uint8ClampedArray = r.newLazyObject(r.typedArrayCreator(r.newUint8ClampedArray, "Uint8ClampedArray", 1))
  1386. r.addToGlobal("Uint8ClampedArray", r.global.Uint8ClampedArray)
  1387. r.global.Int8Array = r.newLazyObject(r.typedArrayCreator(r.newInt8Array, "Int8Array", 1))
  1388. r.addToGlobal("Int8Array", r.global.Int8Array)
  1389. r.global.Uint16Array = r.newLazyObject(r.typedArrayCreator(r.newUint16Array, "Uint16Array", 2))
  1390. r.addToGlobal("Uint16Array", r.global.Uint16Array)
  1391. r.global.Int16Array = r.newLazyObject(r.typedArrayCreator(r.newInt16Array, "Int16Array", 2))
  1392. r.addToGlobal("Int16Array", r.global.Int16Array)
  1393. r.global.Uint32Array = r.newLazyObject(r.typedArrayCreator(r.newUint32Array, "Uint32Array", 4))
  1394. r.addToGlobal("Uint32Array", r.global.Uint32Array)
  1395. r.global.Int32Array = r.newLazyObject(r.typedArrayCreator(r.newInt32Array, "Int32Array", 4))
  1396. r.addToGlobal("Int32Array", r.global.Int32Array)
  1397. r.global.Float32Array = r.newLazyObject(r.typedArrayCreator(r.newFloat32Array, "Float32Array", 4))
  1398. r.addToGlobal("Float32Array", r.global.Float32Array)
  1399. r.global.Float64Array = r.newLazyObject(r.typedArrayCreator(r.newFloat64Array, "Float64Array", 8))
  1400. r.addToGlobal("Float64Array", r.global.Float64Array)
  1401. }