| // Copyright 2018 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // +build js,wasm |
| |
| package js |
| |
| import ( |
| "sync" |
| "unsafe" |
| ) |
| |
| var ( |
| int8Array = Global().Get("Int8Array") |
| int16Array = Global().Get("Int16Array") |
| int32Array = Global().Get("Int32Array") |
| uint8Array = Global().Get("Uint8Array") |
| uint16Array = Global().Get("Uint16Array") |
| uint32Array = Global().Get("Uint32Array") |
| float32Array = Global().Get("Float32Array") |
| float64Array = Global().Get("Float64Array") |
| ) |
| |
| var _ Wrapper = TypedArray{} // TypedArray must implement Wrapper |
| |
| // TypedArray represents a JavaScript typed array. |
| type TypedArray struct { |
| Value |
| } |
| |
| // Release frees up resources allocated for the typed array. |
| // The typed array and its buffer must not be accessed after calling Release. |
| func (a TypedArray) Release() { |
| openTypedArraysMutex.Lock() |
| delete(openTypedArrays, a) |
| openTypedArraysMutex.Unlock() |
| } |
| |
| var ( |
| openTypedArraysMutex sync.Mutex |
| openTypedArrays = make(map[TypedArray]interface{}) |
| ) |
| |
| // TypedArrayOf returns a JavaScript typed array backed by the slice's underlying array. |
| // |
| // The supported types are []int8, []int16, []int32, []uint8, []uint16, []uint32, []float32 and []float64. |
| // Passing an unsupported value causes a panic. |
| // |
| // TypedArray.Release must be called to free up resources when the typed array will not be used any more. |
| func TypedArrayOf(slice interface{}) TypedArray { |
| a := TypedArray{typedArrayOf(slice)} |
| openTypedArraysMutex.Lock() |
| openTypedArrays[a] = slice |
| openTypedArraysMutex.Unlock() |
| return a |
| } |
| |
| func typedArrayOf(slice interface{}) Value { |
| switch slice := slice.(type) { |
| case []int8: |
| if len(slice) == 0 { |
| return int8Array.New(memory.Get("buffer"), 0, 0) |
| } |
| return int8Array.New(memory.Get("buffer"), unsafe.Pointer(&slice[0]), len(slice)) |
| case []int16: |
| if len(slice) == 0 { |
| return int16Array.New(memory.Get("buffer"), 0, 0) |
| } |
| return int16Array.New(memory.Get("buffer"), unsafe.Pointer(&slice[0]), len(slice)) |
| case []int32: |
| if len(slice) == 0 { |
| return int32Array.New(memory.Get("buffer"), 0, 0) |
| } |
| return int32Array.New(memory.Get("buffer"), unsafe.Pointer(&slice[0]), len(slice)) |
| case []uint8: |
| if len(slice) == 0 { |
| return uint8Array.New(memory.Get("buffer"), 0, 0) |
| } |
| return uint8Array.New(memory.Get("buffer"), unsafe.Pointer(&slice[0]), len(slice)) |
| case []uint16: |
| if len(slice) == 0 { |
| return uint16Array.New(memory.Get("buffer"), 0, 0) |
| } |
| return uint16Array.New(memory.Get("buffer"), unsafe.Pointer(&slice[0]), len(slice)) |
| case []uint32: |
| if len(slice) == 0 { |
| return uint32Array.New(memory.Get("buffer"), 0, 0) |
| } |
| return uint32Array.New(memory.Get("buffer"), unsafe.Pointer(&slice[0]), len(slice)) |
| case []float32: |
| if len(slice) == 0 { |
| return float32Array.New(memory.Get("buffer"), 0, 0) |
| } |
| return float32Array.New(memory.Get("buffer"), unsafe.Pointer(&slice[0]), len(slice)) |
| case []float64: |
| if len(slice) == 0 { |
| return float64Array.New(memory.Get("buffer"), 0, 0) |
| } |
| return float64Array.New(memory.Get("buffer"), unsafe.Pointer(&slice[0]), len(slice)) |
| default: |
| panic("TypedArrayOf: not a supported slice") |
| } |
| } |