builtin_typedarrays.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package goja
  2. type objectArrayBuffer struct {
  3. baseObject
  4. data []byte
  5. }
  6. func (o *objectArrayBuffer) export() interface{} {
  7. return o.data
  8. }
  9. func (r *Runtime) _newArrayBuffer(proto *Object, o *Object) *objectArrayBuffer {
  10. if o == nil {
  11. o = &Object{runtime: r}
  12. }
  13. b := &objectArrayBuffer{
  14. baseObject: baseObject{
  15. class: classObject,
  16. val: o,
  17. prototype: proto,
  18. extensible: true,
  19. },
  20. }
  21. o.self = b
  22. b.init()
  23. return b
  24. }
  25. func (r *Runtime) builtin_ArrayBuffer(args []Value, proto *Object) *Object {
  26. b := r._newArrayBuffer(proto, nil)
  27. if len(args) > 0 {
  28. b.data = make([]byte, toLength(args[0]))
  29. }
  30. return b.val
  31. }
  32. func (r *Runtime) arrayBufferProto_getByteLength(call FunctionCall) Value {
  33. o := r.toObject(call.This)
  34. if b, ok := o.self.(*objectArrayBuffer); ok {
  35. return intToValue(int64(len(b.data)))
  36. }
  37. r.typeErrorResult(true, "Object is not ArrayBuffer: %s", o)
  38. panic("unreachable")
  39. }
  40. func (r *Runtime) arrayBufferProto_slice(call FunctionCall) Value {
  41. o := r.toObject(call.This)
  42. if b, ok := o.self.(*objectArrayBuffer); ok {
  43. l := int64(len(b.data))
  44. start := toLength(call.Argument(0))
  45. if start < 0 {
  46. start = l + start
  47. }
  48. if start < 0 {
  49. start = 0
  50. } else if start > l {
  51. start = l
  52. }
  53. var stop int64
  54. if arg := call.Argument(1); arg != _undefined {
  55. stop = toLength(arg)
  56. if stop < 0 {
  57. stop = int64(len(b.data)) + stop
  58. }
  59. if stop < 0 {
  60. stop = 0
  61. } else if stop > l {
  62. stop = l
  63. }
  64. } else {
  65. stop = l
  66. }
  67. ret := r._newArrayBuffer(r.global.ArrayBufferPrototype, nil)
  68. if stop > start {
  69. ret.data = b.data[start:stop]
  70. }
  71. return ret.val
  72. }
  73. r.typeErrorResult(true, "Object is not ArrayBuffer: %s", o)
  74. panic("unreachable")
  75. }
  76. func (r *Runtime) createArrayBufferProto(val *Object) objectImpl {
  77. b := r._newArrayBuffer(r.global.Object, val)
  78. byteLengthProp := &valueProperty{
  79. accessor: true,
  80. configurable: true,
  81. getterFunc: r.newNativeFunc(r.arrayBufferProto_getByteLength, nil, "get byteLength", nil, 0),
  82. }
  83. b._put("byteLength", byteLengthProp)
  84. b._putProp("slice", r.newNativeFunc(r.arrayBufferProto_slice, nil, "slice", nil, 2), true, false, true)
  85. return b
  86. }
  87. func (r *Runtime) initTypedArrays() {
  88. r.global.ArrayBufferPrototype = r.newLazyObject(r.createArrayBufferProto)
  89. r.global.ArrayBuffer = r.newNativeFuncConstruct(r.builtin_ArrayBuffer, "ArrayBuffer", r.global.ArrayBufferPrototype, 1)
  90. r.addToGlobal("ArrayBuffer", r.global.ArrayBuffer)
  91. }