Files
sdk/tests/web/wasm/externs_assert_error_test.dart
Simon Binder 7d8cd032dc [dart2wasm] Interfaces for accessing memories
This adds the `Memory` class to `dart:_wasm`, allowing Dart code to
load and store numeric types in linear memory.
Since `dart2wasm` doesn't generate a memory instance by default, there
is no singleton instance of `Memory`. Instead, memories are defined as
`external` top-level getters annotated with a pragma like
`@pragma('wasm:memory-tyype', MemoryType(limits: Limits(1, 10)))` to
declare their type.

Interop happens in a static way: Methods on `Memory` cannot be torn-off
and, since the target memory is encoded directly in the store/load
instruction, there's also no polymorphism for memories in Dart.
Attempting to call methods on a memory instance that isn't a direct
reference to its definition is a compile-time error.

Memories can also be imported and exported through the existing
`wasm:import` and `wasm:export` pragmas.

TEST=tests/web/wasm/memory_test.dart

Change-Id: I726f33ac2ec04afab55c5a2b6bc09079d0193e02
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/470020
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2026-01-15 03:45:21 -08:00

46 lines
1.5 KiB
Dart

// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// dart2wasmOptions=--extra-compiler-option=--enable-experimental-wasm-interop
import 'dart:_wasm';
external Memory get missingAnnotation;
// ^
// [web] This external getter returns a memory instance, but no annotation describing it was found
@pragma('wasm:memory-type', MemoryType(limits: Limits(1, 10)))
external Memory get validDefinition;
void main() {
validDefinition.loadUint8(10);
validDefinition.size;
print(validDefinition);
// ^
// [web] WebAssembly elements may only be referenced to directly call a method on them.
print(validDefinition.fill);
// ^
// [web] This intrinsic extension member may not be torn off.
}
void invalidDynamicMemory(Memory memory) {
memory.loadUint8(10);
// ^
// [web] The receiver of this call must be a top-level variable describing the WebAssembly element.
}
int get notAConstant => 3;
void invalidNonConstantArguments() {
validDefinition.loadUint8(0, offset: 12, align: 1);
validDefinition.loadUint8(0, offset: notAConstant);
// ^
// [web] The variable 'offset' is not a constant, only constant expressions are allowed.
validDefinition.loadUint8(0, align: notAConstant);
// ^
// [web] The variable 'align' is not a constant, only constant expressions are allowed.
}