| // 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") | |
| ) | |
| // 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") | |
| } | |
| } |