Skip to content

Commit 0f14261

Browse files
liamappelbecommit-bot@chromium.org
authored andcommitted
Reland "[vm/wasm] Boilerplate for package:wasm"
This is a reland of 2bafc32 Original change's description: > [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]> Bug: #37882 Change-Id: I8056df1e301acde2772ba2273148faa53d03173e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/159321 Reviewed-by: Ryan Macnak <[email protected]> Commit-Queue: Liam Appelbe <[email protected]>
1 parent 0850763 commit 0f14261

19 files changed

+287
-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": "7e5ec82c99677a2e5b95ce296c4d68b0d3378ed8",
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

+76-13
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,103 @@
22
# for details. All rights reserved. Use of this source code is governed by a
33
# BSD-style license that can be found in the LICENSE file.
44

5+
_dart_root = get_path_info("../..", "abspath")
6+
57
template("rust_library") {
68
manifest = rebase_path("Cargo.toml")
79
if (defined(invoker.manifest)) {
810
manifest = invoker.manifest
911
}
1012

13+
debug = defined(invoker.debug) && invoker.debug
14+
shared = defined(invoker.shared) && invoker.shared
15+
1116
cmd = [
12-
rebase_path("//buildtools/${current_os}-${current_cpu}/rust/bin/cargo"),
17+
rebase_path("//buildtools/${host_os}-${host_cpu}/rust/bin/cargo"),
1318
"build",
1419
"--target-dir",
1520
rebase_path(target_out_dir),
1621
"--manifest-path",
1722
manifest,
1823
]
19-
output = "$target_out_dir/lib${invoker.lib_name}.a"
20-
debug = defined(invoker.debug) && invoker.debug
2124

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

26-
action(target_name) {
27-
script = "//build/rust/run.py"
65+
output_file = ""
66+
if (shared) {
67+
if (is_win) {
68+
output_file = "${invoker.lib_name}.dll"
69+
} else if (is_mac) {
70+
output_file = "lib${invoker.lib_name}.dylib"
71+
} else {
72+
output_file = "lib${invoker.lib_name}.so"
73+
}
74+
} else {
75+
if (is_win) {
76+
output_file = "${invoker.lib_name}.lib"
77+
}else {
78+
output_file = "lib${invoker.lib_name}.a"
79+
}
80+
}
81+
82+
action("${target_name}_cargo") {
83+
script = "${_dart_root}/build/rust/run.py"
2884
args = cmd
29-
outputs = [ output ]
85+
outputs = [ "${cargo_out_dir}/${output_file}" ]
3086
public_configs = [ ":${target_name}_config" ]
3187
}
3288

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" ]
89+
config("${target_name}_cargo_config") {
90+
if (!shared) {
91+
libs = [ invoker.lib_name ]
92+
lib_dirs = [ out_dir ]
3993
}
4094
}
95+
96+
# Cargo leaves the library in cargo_out_dir, which varies based on the target.
97+
# So we need to copy it to target_out_dir to make it easier for dependees to
98+
# locate the library.
99+
copy(target_name) {
100+
deps = [ ":${target_name}_cargo" ]
101+
sources = [ "${cargo_out_dir}/${output_file}" ]
102+
outputs = [ "${target_out_dir}/${output_file}" ]
103+
}
41104
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ declare_args() {
9191
# Whether libdart should export the symbols of the Dart API.
9292
dart_lib_export_symbols = true
9393

94-
# Whether dart:wasm should be enabled.
94+
# Whether package:wasm should be enabled.
9595
dart_enable_wasm = false
9696
}
9797

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)