Skip to content

Commit 2bafc32

Browse files
liamappelbecommit-bot@chromium.org
authored andcommitted
[vm/wasm] Boilerplate for package:wasm
So far this just builds the wasmer library, copies it into the sdk directory, loads the library, and allows you to compile WASM modules. You can't actually do anything with the modules yet. Bug: #37882 Change-Id: I7d7cfe5721bbe38a6afe76f326518e714d236ed4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/158367 Commit-Queue: Liam Appelbe <[email protected]> Reviewed-by: Ryan Macnak <[email protected]>
1 parent 1cec77f commit 2bafc32

19 files changed

+279
-26
lines changed

.dart_tool/package_config.json

+8-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"constraint, update this by running tools/generate_package_config.dart."
1212
],
1313
"configVersion": 2,
14-
"generated": "2020-08-17T14:05:33.104579",
14+
"generated": "2020-08-18T11:26:08.472483",
1515
"generator": "tools/generate_package_config.dart",
1616
"packages": [
1717
{
@@ -515,7 +515,7 @@
515515
"name": "shelf",
516516
"rootUri": "../third_party/pkg/shelf",
517517
"packageUri": "lib/",
518-
"languageVersion": "2.0"
518+
"languageVersion": "2.1"
519519
},
520520
{
521521
"name": "shelf_packages_handler",
@@ -715,6 +715,12 @@
715715
"packageUri": "lib/",
716716
"languageVersion": "2.8"
717717
},
718+
{
719+
"name": "wasm",
720+
"rootUri": "../pkg/wasm",
721+
"packageUri": "lib/",
722+
"languageVersion": "2.6"
723+
},
718724
{
719725
"name": "watcher",
720726
"rootUri": "../third_party/pkg/watcher",

.packages

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ vector_math:third_party/pkg/vector_math/lib
116116
vm:pkg/vm/lib
117117
vm_service:pkg/vm_service/lib
118118
vm_snapshot_analysis:pkg/vm_snapshot_analysis/lib
119+
wasm:pkg/wasm/lib
119120
watcher:third_party/pkg/watcher/lib
120121
webdriver:third_party/pkg/webdriver/lib
121122
web_components:third_party/pkg/web_components/lib

DEPS

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ vars = {
133133
"quiver-dart_tag": "246e754fe45cecb6aa5f3f13b4ed61037ff0d784",
134134
"resource_rev": "f8e37558a1c4f54550aa463b88a6a831e3e33cd6",
135135
"root_certificates_rev": "16ef64be64c7dfdff2b9f4b910726e635ccc519e",
136-
"rust_revision": "60960a260f7b5c695fd0717311d72ce62dd4eb43",
136+
"rust_revision": "cbe7c5ce705896d4e22bf6096590bc1f17993b78",
137137
"shelf_static_rev": "v0.2.8",
138138
"shelf_packages_handler_tag": "2.0.0",
139139
"shelf_proxy_tag": "0.1.0+7",

build/rust/rust.gni

+73-12
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,95 @@ template("rust_library") {
88
manifest = invoker.manifest
99
}
1010

11+
debug = defined(invoker.debug) && invoker.debug
12+
shared = defined(invoker.shared) && invoker.shared
13+
1114
cmd = [
12-
rebase_path("//buildtools/${current_os}-${current_cpu}/rust/bin/cargo"),
15+
rebase_path("//buildtools/${host_os}-${host_cpu}/rust/bin/cargo"),
1316
"build",
1417
"--target-dir",
1518
rebase_path(target_out_dir),
1619
"--manifest-path",
1720
manifest,
1821
]
19-
output = "$target_out_dir/lib${invoker.lib_name}.a"
20-
debug = defined(invoker.debug) && invoker.debug
2122

22-
if (!debug) {
23+
# For cross compilation, figure out the target triple. You can get a full list
24+
# of the targets that rust supports like this: rustc --print target-list
25+
cargo_out_dir = target_out_dir
26+
if (is_linux) {
27+
rust_os = "unknown-linux-gnu"
28+
} else if (is_mac) {
29+
rust_os = "apple-darwin"
30+
} else if (is_win) {
31+
rust_os = "pc-windows-gnu"
32+
} else if (is_android) {
33+
rust_os = "linux-android"
34+
} else if (is_fuchsia) {
35+
rust_os = "fuchsia"
36+
}
37+
if (defined(rust_os)) {
38+
if (current_cpu == "x86") {
39+
rust_target = "i686-${rust_os}"
40+
} else if (current_cpu == "x64") {
41+
rust_target = "x86_64-${rust_os}"
42+
} else if (current_cpu == "arm") {
43+
rust_target = "arm-${rust_os}eabi"
44+
} else if (current_cpu == "arm64") {
45+
rust_target = "aarch64-${rust_os}"
46+
}
47+
}
48+
if (defined(rust_target)) {
49+
cmd += [
50+
"--target",
51+
rust_target,
52+
]
53+
cargo_out_dir += "/${rust_target}"
54+
}
55+
56+
if (debug) {
57+
cargo_out_dir += "/debug"
58+
} else {
59+
cargo_out_dir += "/release"
2360
cmd += [ "--release" ]
2461
}
2562

26-
action(target_name) {
63+
output_file = ""
64+
if (shared) {
65+
if (is_win) {
66+
output_file = "${invoker.lib_name}.dll"
67+
} else if (is_mac) {
68+
output_file = "lib${invoker.lib_name}.dylib"
69+
} else {
70+
output_file = "lib${invoker.lib_name}.so"
71+
}
72+
} else {
73+
if (is_win) {
74+
output_file = "${invoker.lib_name}.lib"
75+
}else {
76+
output_file = "lib${invoker.lib_name}.a"
77+
}
78+
}
79+
80+
action("${target_name}_cargo") {
2781
script = "//build/rust/run.py"
2882
args = cmd
29-
outputs = [ output ]
83+
outputs = [ "${cargo_out_dir}/${output_file}" ]
3084
public_configs = [ ":${target_name}_config" ]
3185
}
3286

33-
config("${target_name}_config") {
34-
libs = [ "wasmer" ]
35-
if (debug) {
36-
lib_dirs = [ "$target_out_dir/debug" ]
37-
} else {
38-
lib_dirs = [ "$target_out_dir/release" ]
87+
config("${target_name}_cargo_config") {
88+
if (!shared) {
89+
libs = [ invoker.lib_name ]
90+
lib_dirs = [ out_dir ]
3991
}
4092
}
93+
94+
# Cargo leaves the library in cargo_out_dir, which varies based on the target.
95+
# So we need to copy it to target_out_dir to make it easier for dependees to
96+
# locate the library.
97+
copy(target_name) {
98+
deps = [ ":${target_name}_cargo" ]
99+
sources = [ "${cargo_out_dir}/${output_file}" ]
100+
outputs = [ "${target_out_dir}/${output_file}" ]
101+
}
41102
}

pkg/wasm/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.dart_tool/
2+
.packages
3+
pubspec.lock

pkg/wasm/AUTHORS

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Below is a list of people and organizations that have contributed
2+
# to the Dart project. Names should be added to the list like so:
3+
#
4+
# Name/Organization <email address>
5+
6+
Google LLC

pkg/wasm/LICENSE

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Copyright 2020, the Dart project authors. All rights reserved.
2+
Redistribution and use in source and binary forms, with or without
3+
modification, are permitted provided that the following conditions are
4+
met:
5+
6+
* Redistributions of source code must retain the above copyright
7+
notice, this list of conditions and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above
9+
copyright notice, this list of conditions and the following
10+
disclaimer in the documentation and/or other materials provided
11+
with the distribution.
12+
* Neither the name of Google Inc. nor the names of its
13+
contributors may be used to endorse or promote products derived
14+
from this software without specific prior written permission.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

pkg/wasm/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# wasm
2+
3+
This package provides utilities for loading and running WASM modules. It is
4+
built on top of the [Wasmer](https://github.com/wasmerio/wasmer) runtime.

pkg/wasm/analysis_options.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include: package:pedantic/analysis_options.1.8.0.yaml

pkg/wasm/lib/module.dart

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'runtime.dart';
6+
import 'dart:typed_data';
7+
import 'dart:ffi';
8+
9+
class WasmModule {
10+
Pointer<WasmerModule> _module;
11+
12+
WasmModule(Uint8List data) {
13+
_module = WasmRuntime().compile(data);
14+
}
15+
}

pkg/wasm/lib/runtime.dart

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:ffi';
6+
import 'dart:io';
7+
import 'dart:typed_data';
8+
import 'package:ffi/ffi.dart';
9+
import 'package:path/path.dart' as path;
10+
11+
const int WasmerResultOk = 1;
12+
const int WasmerResultError = 2;
13+
14+
const int WasmerValueTagI32 = 0;
15+
const int WasmerValueTagI64 = 1;
16+
const int WasmerValueTagF32 = 2;
17+
const int WasmerValueTagF64 = 3;
18+
19+
class WasmerModule extends Struct {}
20+
21+
typedef NativeWasmerCompileFn = Uint32 Function(
22+
Pointer<Pointer<WasmerModule>>, Pointer<Uint8>, Uint32);
23+
typedef WasmerCompileFn = int Function(
24+
Pointer<Pointer<WasmerModule>>, Pointer<Uint8>, int);
25+
26+
class WasmRuntime {
27+
static WasmRuntime _inst;
28+
29+
DynamicLibrary _lib;
30+
WasmerCompileFn _compile;
31+
32+
factory WasmRuntime() {
33+
if (_inst == null) {
34+
_inst = WasmRuntime._init();
35+
}
36+
return _inst;
37+
}
38+
39+
static String _getLibName() {
40+
if (Platform.isMacOS) return "libwasmer.dylib";
41+
if (Platform.isLinux) return "libwasmer.so";
42+
throw Exception("Wasm not currently supported on this platform");
43+
}
44+
45+
static String _getLibDir() {
46+
// The common case, and how cli_util.dart computes the Dart SDK directory,
47+
// path.dirname called twice on Platform.resolvedExecutable.
48+
var commonLibDir = path.join(
49+
path.absolute(path.dirname(path.dirname(Platform.resolvedExecutable))),
50+
'bin',
51+
'third_party',
52+
'wasmer');
53+
if (Directory(commonLibDir).existsSync()) {
54+
return commonLibDir;
55+
}
56+
57+
// This is the less common case where the user is in the checked out Dart
58+
// SDK, and is executing dart via:
59+
// ./out/ReleaseX64/dart ...
60+
var checkedOutLibDir = path.join(
61+
path.absolute(path.dirname(Platform.resolvedExecutable)),
62+
'dart-sdk',
63+
'bin',
64+
'third_party',
65+
'wasmer');
66+
if (Directory(checkedOutLibDir).existsSync()) {
67+
return checkedOutLibDir;
68+
}
69+
70+
// If neither returned above, we return the common case:
71+
return commonLibDir;
72+
}
73+
74+
WasmRuntime._init() {
75+
var libPath = path.join(_getLibDir(), _getLibName());
76+
_lib = DynamicLibrary.open(libPath);
77+
_compile = _lib
78+
.lookup<NativeFunction<NativeWasmerCompileFn>>('wasmer_compile')
79+
.asFunction();
80+
}
81+
82+
Pointer<WasmerModule> compile(Uint8List data) {
83+
var dataPtr = allocate<Uint8>(count: data.length);
84+
for (int i = 0; i < data.length; ++i) {
85+
dataPtr[i] = data[i];
86+
}
87+
88+
var modulePtrPtr = allocate<Pointer<WasmerModule>>();
89+
int result = _compile(modulePtrPtr, dataPtr, data.length);
90+
Pointer<WasmerModule> modulePtr = modulePtrPtr.value;
91+
92+
free(modulePtrPtr);
93+
free(dataPtr);
94+
95+
if (result != WasmerResultOk) {
96+
throw Exception("Wasm module compile failed");
97+
}
98+
99+
return modulePtr;
100+
}
101+
}

pkg/wasm/lib/wasm.dart

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
export 'module.dart';

pkg/wasm/pubspec.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: wasm
2+
version: 0.1.0
3+
description: Load and run wasm bytecode.
4+
author: Dart Team <[email protected]>
5+
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/wasm
6+
# This package is not intended for consumption on pub.dev. DO NOT publish.
7+
publish_to: none
8+
environment:
9+
sdk: ">=2.6.0"
10+
dependencies:
11+
ffi: ^0.1.3
12+
path: ^1.0.0

runtime/BUILD.gn

-4
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,6 @@ library_for_all_configs("libdart") {
221221
":generate_version_cc_file",
222222
"third_party/double-conversion/src:libdouble_conversion",
223223
]
224-
if (dart_enable_wasm) {
225-
extra_deps += [ "//third_party/wasmer" ]
226-
defines = [ "DART_ENABLE_WASM" ]
227-
}
228224
if (is_fuchsia) {
229225
if (using_fuchsia_gn_sdk) {
230226
extra_deps += [

runtime/runtime_args.gni

-3
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,6 @@ declare_args() {
9090

9191
# Whether libdart should export the symbols of the Dart API.
9292
dart_lib_export_symbols = true
93-
94-
# Whether dart:wasm should be enabled.
95-
dart_enable_wasm = false
9693
}
9794

9895
declare_args() {

runtime/vm/BUILD.gn

-3
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,6 @@ library_for_all_configs("libdart_lib") {
156156
]
157157
}
158158
}
159-
if (dart_enable_wasm) {
160-
defines = [ "DART_ENABLE_WASM" ]
161-
}
162159
include_dirs = [ ".." ]
163160
allsources = async_runtime_cc_files + collection_runtime_cc_files +
164161
core_runtime_cc_files + developer_runtime_cc_files +

0 commit comments

Comments
 (0)