dart-archive / wasm

Utilities for loading and running WASM modules from Dart code
https://pub.dev/packages/wasm
BSD 3-Clause "New" or "Revised" License
309 stars 25 forks source link

Android arm64-v8a: missing requires CPU features: "EnumSet(SSE2)" #74

Closed s20208413 closed 2 years ago

s20208413 commented 2 years ago

When run code with flutter on Android arm64-v8a:

import 'package:wasm/wasm.dart';

var mod = WasmModule(m);
var inst = mod.builder().build();  // error here

got this error:

E/flutter (10982): WasmError: Wasm module instantiation failed.
E/flutter (10982): missing requires CPU features: "EnumSet(SSE2)"
E/flutter (10982): #0      WasmRuntime._checkNotEqual (package:wasm/src/runtime.g.dart:952:7)
E/flutter (10982): #1      WasmRuntime.instantiate (package:wasm/src/runtime.g.dart:713:5)
E/flutter (10982): #2      new WasmInstance._ (package:wasm/src/module.dart:261:25)
E/flutter (10982): #3      WasmInstanceBuilder.build (package:wasm/src/module.dart:228:25)

The reason is this code: https://github.com/dart-lang/wasm/blob/0789947186747fad02d01f5e858b049f09b8cd81/wasm/lib/src/runtime.g.dart#L579

  Pointer<WasmerConfig> _createEngineConfig() {
    final config = _config_new();
    final triple = _wasmer_triple_new_from_host();
    final cpuFeatures = _wasmer_cpu_features_new();
    final sse2 = _allocateString('sse2');
    _wasmer_cpu_features_add(cpuFeatures, sse2);
    calloc.free(sse2.ref.data);
    calloc.free(sse2);
    final target = _wasmer_target_new(triple, cpuFeatures);
    _config_set_target(config, target);
    return config;
  }

after remove _wasmer_cpu_features_add(cpuFeatures, sse2); everything works fine ;-)


liamappelbe commented 2 years ago

I could just make that line conditional on the OS, but that would break precompilation. If the module is precompiled on a platform with certain CPU features, it can't be run on a different platform that doesn't have those features.

This is concerning. I was told by the wasmer folks that it's possible to configure wasmer such that precompiled modules will work on any platform, but this might mean it's not possible. If precompiled modules aren't cross platform it really complicates the developer experience.

kevmoo commented 2 years ago

FYI @liamappelbe – just hit this on my M1 Mac at 204d03c9f63818178492c0ac47dd2dfb3d9b077f 🤷

kevmoo commented 2 years ago
dart brotli.dart lipsum.txt
Loading "lipsum.txt"...
Input size: 3210 bytes

Loading wasm module
import function: int32 wasi_unstable::fd_close(int32)
import function: int32 wasi_unstable::fd_write(int32, int32, int32, int32)
import function: int32 wasi_unstable::fd_fdstat_get(int32, int32)
import function: int32 wasi_unstable::fd_seek(int32, int64, int32, int32)
import function: void wasi_unstable::proc_exit(int32)
export memory: memory
export function: int32 BrotliDecoderSetParameter(int32, int32, int32)
export function: int32 BrotliDecoderCreateInstance(int32, int32, int32)
export function: void BrotliDecoderDestroyInstance(int32)
export function: int32 BrotliDecoderDecompress(int32, int32, int32, int32)
export function: int32 BrotliDecoderDecompressStream(int32, int32, int32, int32, int32, int32)
export function: int32 BrotliDecoderHasMoreOutput(int32)
export function: int32 BrotliDecoderTakeOutput(int32, int32)
export function: int32 BrotliDecoderIsUsed(int32)
export function: int32 BrotliDecoderIsFinished(int32)
export function: int32 BrotliDecoderGetErrorCode(int32)
export function: int32 BrotliDecoderErrorString(int32)
export function: int32 BrotliDecoderVersion()
export function: int32 BrotliEncoderSetParameter(int32, int32, int32)
export function: int32 BrotliEncoderCreateInstance(int32, int32, int32)
export function: void BrotliEncoderDestroyInstance(int32)
export function: int32 BrotliEncoderMaxCompressedSize(int32)
export function: int32 BrotliEncoderCompress(int32, int32, int32, int32, int32, int32, int32)
export function: int32 BrotliEncoderCompressStream(int32, int32, int32, int32, int32, int32, int32)
export function: int32 BrotliEncoderIsFinished(int32)
export function: int32 BrotliEncoderHasMoreOutput(int32)
export function: int32 BrotliEncoderTakeOutput(int32, int32)
export function: int32 BrotliEncoderVersion()

Unhandled exception:
WasmError: Wasm module instantiation failed.
missing requires CPU features: "EnumSet(SSE2)"
#0      WasmRuntime._checkNotEqual (package:wasm/src/runtime.g.dart:921:7)
#1      WasmRuntime.instantiate (package:wasm/src/runtime.g.dart:682:5)
#2      new WasmInstance._ (package:wasm/src/module.dart:249:25)
#3      WasmInstanceBuilder.build (package:wasm/src/module.dart:216:25)
#4      main (file:///Users/kevmoo/github/wasm/wasm/example/brotli.dart:46:26)
#5      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:295:32)
#6      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
kevmoo commented 2 years ago

Nothing new for me. Doing the same fix from @sceext2 and everything works

kevmoo commented 2 years ago

@liamappelbe – could this be a wasmer bug?

liamappelbe commented 2 years ago

Now that I've removed module precompilation I can just make that flag conditional.

kevmoo commented 2 years ago

It'd be nice if there was a way to detect support for this – other than hard-wiring in if(ARM) – know what I mean?

This is a limitation of wasmer right?

s20208413 commented 2 years ago

SSE2 is a instruction set feature which only exist on x86 CPU, and does not exist on ARM CPU.

And all modern x86 CPU support SSE2. So there is no need to detect this.

kevmoo commented 2 years ago

@sceext2 – but it's NOT supported on ARM (it seems). At least in wasmer.

liamappelbe commented 2 years ago

I don't know of a way of detecting CPU feature support in wasmer. I'm going to try just switching from wasm_engine_new_with_config to wasm_engine_new, and see if that just auto-detects this stuff for me.

liamappelbe commented 2 years ago

@kevmoo or @sceext2 are you able to patch this and see if it fixes the issue for you: https://github.com/dart-lang/wasm/pull/83

kevmoo commented 2 years ago

Works for me on my M1 – 2.18.0-216.0.dev (dev) !! Thanks!