Closed
Description
Optimized code for `_Float64List.[]`
(func $_Float64List.\5b\5d (type $type$63) (param $0 (ref $type$17)) (param $1 i64) (result (ref null $type$56))
(local $2 (ref $type$4))
(local $3 (ref $type$66))
(local $4 (ref $type$65))
(local $5 i32)
(local.set $3
(ref.cast $type$66
(local.get $0)))
(block $label$1
(if
(i64.ge_s
(local.get $1)
(i64.const 0))
(br_if $label$1
(i64.gt_s
(call $_TypedListBase.length
(local.get $3))
(local.get $1))))
(struct.set $type$65 0
(local.tee $4
(struct.new_default $type$65))
(i32.const 271))
(call $IndexError.withLength
(local.get $4)
(local.get $1)
(call $_TypedListBase.length
(local.get $3))
(global.get $global$54))
(call $Error._throw
(local.get $4)
(call $StackTrace.current))
(unreachable))
(struct.new $type$9
(i32.const 11)
(f64.reinterpret_i64
(i64.or
(i64.or
(i64.or
(i64.or
(i64.or
(i64.or
(i64.or
(i64.extend_i32_u
(array.get_u $type$4
(local.tee $2
(struct.get $type$66 3
(local.get $3)))
(local.tee $5
(i32.wrap_i64
(i64.shl
(local.get $1)
(i64.const 3))))))
(i64.shl
(i64.extend_i32_u
(array.get_u $type$4
(local.get $2)
(i32.add
(local.get $5)
(i32.const 1))))
(i64.const 8)))
(i64.shl
(i64.extend_i32_u
(array.get_u $type$4
(local.get $2)
(i32.add
(local.get $5)
(i32.const 2))))
(i64.const 16)))
(i64.shl
(i64.extend_i32_u
(array.get_u $type$4
(local.get $2)
(i32.add
(local.get $5)
(i32.const 3))))
(i64.const 24)))
(i64.shl
(i64.extend_i32_u
(array.get_u $type$4
(local.get $2)
(i32.add
(local.get $5)
(i32.const 4))))
(i64.const 32)))
(i64.shl
(i64.extend_i32_u
(array.get_u $type$4
(local.get $2)
(i32.add
(local.get $5)
(i32.const 5))))
(i64.const 40)))
(i64.shl
(i64.extend_i32_u
(array.get_u $type$4
(local.get $2)
(i32.add
(local.get $5)
(i32.const 6))))
(i64.const 48)))
(i64.shl
(i64.extend_i32_u
(array.get_u $type$4
(local.get $2)
(i32.add
(local.get $5)
(i32.const 7))))
(i64.const 56))))))
Currently typed data lists use a i8
array as the buffer and read/write one byte at a time. I can't tell from the code why we use a byte array in typed data lists, but I suspect it has to do with JS interop or getting different views of a lists without copying (which would break sharing).
Opening this issue to document the requirements and alternatives.
It's a bit difficult to find where the typed list constructors and accessors are generated, so here are a few links:
- Allocating typed data lists:
sdk/pkg/dart2wasm/lib/intrinsics.dart
Line 1375 in 82b7891
[]
and[]=
:sdk/pkg/dart2wasm/lib/intrinsics.dart
Line 216 in 82b7891
- For the class definitions we mostly use VM's patch: https://github.com/dart-lang/sdk/blob/main/sdk/lib/_internal/vm/lib/typed_data_patch.dart
- We override
_TypedList._getFloat32
,_TypedList._setInt64
etc.
- We override