summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2019-05-17 12:56:53 -0700
committerGitHub <noreply@github.com>2019-05-17 12:56:53 -0700
commit9c637288cf3b1c7505fa7d8edc1536b6e64d5967 (patch)
treefc7b0e579f3f9de41fca28c65551fb3359c8f40b
parent1184678086b284944bb119a97ca048b64d4078b6 (diff)
downloadbinaryen-9c637288cf3b1c7505fa7d8edc1536b6e64d5967.tar.gz
binaryen-9c637288cf3b1c7505fa7d8edc1536b6e64d5967.tar.bz2
binaryen-9c637288cf3b1c7505fa7d8edc1536b6e64d5967.zip
Features C/JS API (#2049)
Add feature handling to the C/JS APIs. No features are enabled by default, so all used features will have to be explicitly enabled in order for modules to validate.
-rw-r--r--CHANGELOG.md2
-rwxr-xr-xbuild-js.sh11
-rw-r--r--src/binaryen-c.cpp44
-rw-r--r--src/binaryen-c.h19
-rw-r--r--src/js/binaryen.js-post.js17
-rw-r--r--src/wasm-features.h1
-rw-r--r--test/binaryen.js/atomics.js1
-rw-r--r--test/binaryen.js/kitchen-sink.js21
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt9
-rw-r--r--test/example/c-api-kitchen-sink.c21
-rw-r--r--test/example/c-api-kitchen-sink.txt9
11 files changed, 152 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 03e9ec35f..06080dd5f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,8 @@ full changeset diff at the end of each section.
Current Trunk
-------------
+- Add feature handling to the C/JS API with no feature enabled by default.
+
v84
---
diff --git a/build-js.sh b/build-js.sh
index 7d9f51b5d..8317bce4a 100755
--- a/build-js.sh
+++ b/build-js.sh
@@ -230,6 +230,15 @@ export_function "_BinaryenExternalTable"
export_function "_BinaryenExternalMemory"
export_function "_BinaryenExternalGlobal"
+# Features
+export_function "_BinaryenFeatureAtomics"
+export_function "_BinaryenFeatureBulkMemory"
+export_function "_BinaryenFeatureMutableGlobals"
+export_function "_BinaryenFeatureNontrappingFPToInt"
+export_function "_BinaryenFeatureSignExt"
+export_function "_BinaryenFeatureSIMD128"
+export_function "_BinaryenFeatureExceptionHandling"
+
# Literals
export_function "_BinaryenLiteralInt32"
export_function "_BinaryenLiteralInt64"
@@ -758,6 +767,8 @@ export_function "_BinaryenRemoveExport"
export_function "_BinaryenSetFunctionTable"
export_function "_BinaryenSetMemory"
export_function "_BinaryenSetStart"
+export_function "_BinaryenGetFeatures"
+export_function "_BinaryenSetFeatures"
export_function "_BinaryenModuleParse"
export_function "_BinaryenModulePrint"
export_function "_BinaryenModulePrintAsmjs"
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index be06cce83..03c6912f0 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -367,6 +367,30 @@ BinaryenExternalKind BinaryenExternalGlobal(void) {
return static_cast<BinaryenExternalKind>(ExternalKind::Global);
}
+// Features
+
+BinaryenFeatures BinaryenFeatureAtomics(void) {
+ return static_cast<BinaryenFeatures>(FeatureSet::Feature::Atomics);
+}
+BinaryenFeatures BinaryenFeatureBulkMemory(void) {
+ return static_cast<BinaryenFeatures>(FeatureSet::Feature::BulkMemory);
+}
+BinaryenFeatures BinaryenFeatureMutableGlobals(void) {
+ return static_cast<BinaryenFeatures>(FeatureSet::Feature::MutableGlobals);
+}
+BinaryenFeatures BinaryenFeatureNontrappingFPToInt(void) {
+ return static_cast<BinaryenFeatures>(FeatureSet::Feature::TruncSat);
+}
+BinaryenFeatures BinaryenFeatureSignExt(void) {
+ return static_cast<BinaryenFeatures>(FeatureSet::Feature::SignExt);
+}
+BinaryenFeatures BinaryenFeatureSIMD128(void) {
+ return static_cast<BinaryenFeatures>(FeatureSet::Feature::SIMD);
+}
+BinaryenFeatures BinaryenFeatureExceptionHandling(void) {
+ return static_cast<BinaryenFeatures>(FeatureSet::Feature::ExceptionHandling);
+}
+
// Modules
BinaryenModuleRef BinaryenModuleCreate(void) {
@@ -3053,6 +3077,24 @@ void BinaryenSetStart(BinaryenModuleRef module, BinaryenFunctionRef start) {
wasm->addStart(((Function*)start)->name);
}
+// Features
+
+BinaryenFeatures BinaryenGetFeatures(BinaryenModuleRef module) {
+ if (tracing) {
+ std::cout << " BinaryenGetFeatures(the_module);\n";
+ }
+ auto* wasm = static_cast<Module*>(module);
+ return wasm->features.features;
+}
+
+void BinaryenSetFeatures(BinaryenModuleRef module, BinaryenFeatures features) {
+ if (tracing) {
+ std::cout << " BinaryenSetFeatures(the_module, " << features << ");\n";
+ }
+ auto* wasm = static_cast<Module*>(module);
+ wasm->features.features = features;
+}
+
//
// ========== Module Operations ==========
//
@@ -3106,8 +3148,6 @@ int BinaryenModuleValidate(BinaryenModuleRef module) {
}
Module* wasm = (Module*)module;
- // TODO(tlively): Add C API for managing features
- wasm->features = FeatureSet::All;
return WasmValidator().validate(*wasm) ? 1 : 0;
}
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index 820b23cca..19434692b 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -137,6 +137,19 @@ BinaryenExternalKind BinaryenExternalTable(void);
BinaryenExternalKind BinaryenExternalMemory(void);
BinaryenExternalKind BinaryenExternalGlobal(void);
+// Features. Call to get the value of each; you can cache them. Use bitwise
+// operators to combine and test particular features.
+
+typedef uint32_t BinaryenFeatures;
+
+BinaryenFeatures BinaryenFeatureAtomics(void);
+BinaryenFeatures BinaryenFeatureBulkMemory(void);
+BinaryenFeatures BinaryenFeatureMutableGlobals(void);
+BinaryenFeatures BinaryenFeatureNontrappingFPToInt(void);
+BinaryenFeatures BinaryenFeatureSignExt(void);
+BinaryenFeatures BinaryenFeatureSIMD128(void);
+BinaryenFeatures BinaryenFeatureExceptionHandling(void);
+
// Modules
//
// Modules contain lists of functions, imports, exports, function types. The
@@ -929,6 +942,12 @@ void BinaryenSetMemory(BinaryenModuleRef module,
void BinaryenSetStart(BinaryenModuleRef module, BinaryenFunctionRef start);
+// Features
+
+// These control what features are allowed when validation and in passes.
+BinaryenFeatures BinaryenGetFeatures(BinaryenModuleRef module);
+void BinaryenSetFeatures(BinaryenModuleRef module, BinaryenFeatures features);
+
//
// ========== Module Operations ==========
//
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 8aa28a08c..fe0594b91 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -85,6 +85,17 @@ Module['ExternalTable'] = Module['_BinaryenExternalTable']();
Module['ExternalMemory'] = Module['_BinaryenExternalMemory']();
Module['ExternalGlobal'] = Module['_BinaryenExternalGlobal']();
+// Features
+Module['Features'] = {
+ 'Atomics': Module['_BinaryenFeatureAtomics'](),
+ 'BulkMemory': Module['_BinaryenFeatureBulkMemory'](),
+ 'MutableGlobals': Module['_BinaryenFeatureMutableGlobals'](),
+ 'NontrappingFPToInt': Module['_BinaryenFeatureNontrappingFPToInt'](),
+ 'SignExt': Module['_BinaryenFeatureSignExt'](),
+ 'SIMD128': Module['_BinaryenFeatureSIMD128'](),
+ 'ExceptionHandling': Module['_BinaryenFeatureExceptionHandling'](),
+};
+
// Operations
Module['ClzInt32'] = Module['_BinaryenClzInt32']();
Module['CtzInt32'] = Module['_BinaryenCtzInt32']();
@@ -1866,6 +1877,12 @@ function wrapModule(module, self) {
self['setStart'] = function(start) {
return Module['_BinaryenSetStart'](module, start);
};
+ self['getFeatures'] = function() {
+ return Module['_BinaryenGetFeatures'](module);
+ };
+ self['setFeatures'] = function(features) {
+ Module['_BinaryenSetFeatures'](module, features);
+ };
self['emitText'] = function() {
var old = out;
var ret = '';
diff --git a/src/wasm-features.h b/src/wasm-features.h
index 340ca86ae..325f413a1 100644
--- a/src/wasm-features.h
+++ b/src/wasm-features.h
@@ -128,7 +128,6 @@ struct FeatureSet {
return *this;
}
-private:
uint32_t features;
};
diff --git a/test/binaryen.js/atomics.js b/test/binaryen.js/atomics.js
index a3880902f..7eb9cb8ec 100644
--- a/test/binaryen.js/atomics.js
+++ b/test/binaryen.js/atomics.js
@@ -59,5 +59,6 @@ module.addFunction("main", signature, [], module.block("", [
)
]));
+module.setFeatures(Binaryen.Features.Atomics);
module.validate();
console.log(module.emitText());
diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js
index 9e376e436..a798c4092 100644
--- a/test/binaryen.js/kitchen-sink.js
+++ b/test/binaryen.js/kitchen-sink.js
@@ -62,6 +62,16 @@ function test_types() {
console.log("BinaryenTypeAuto: " + Binaryen.auto);
}
+function test_features() {
+ console.log("Binaryen.Features.Atomics: " + Binaryen.Features.Atomics);
+ console.log("Binaryen.Features.BulkMemory: " + Binaryen.Features.BulkMemory);
+ console.log("Binaryen.Features.MutableGlobals: " + Binaryen.Features.MutableGlobals);
+ console.log("Binaryen.Features.NontrappingFPToInt: " + Binaryen.Features.NontrappingFPToInt);
+ console.log("Binaryen.Features.SignExt: " + Binaryen.Features.SignExt);
+ console.log("Binaryen.Features.SIMD128: " + Binaryen.Features.SIMD128);
+ console.log("Binaryen.Features.ExceptionHandling: " + Binaryen.Features.ExceptionHandling);
+}
+
function test_ids() {
console.log("BinaryenInvalidId: " + Binaryen.InvalidId);
console.log("BinaryenBlockId: " + Binaryen.BlockId);
@@ -454,6 +464,16 @@ function test_core() {
// A bunch of our code needs drop, auto-add it
module.autoDrop();
+ var features =
+ Binaryen.Features.Atomics |
+ Binaryen.Features.BulkMemory |
+ Binaryen.Features.NontrappingFPToInt |
+ Binaryen.Features.SignExt |
+ Binaryen.Features.SIMD128;
+
+ module.setFeatures(features);
+ assert(module.getFeatures() == features);
+
// Verify it validates
assert(module.validate());
@@ -766,6 +786,7 @@ function test_internals() {
function main() {
test_types();
+ test_features();
test_ids();
test_core();
test_relooper();
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index a1e8df2b4..fb937e39d 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -7,6 +7,13 @@ BinaryenTypeVec128: 5
BinaryenTypeExceptRef: 6
BinaryenTypeUnreachable: 7
BinaryenTypeAuto: -1
+Binaryen.Features.Atomics: 1
+Binaryen.Features.BulkMemory: 16
+Binaryen.Features.MutableGlobals: 2
+Binaryen.Features.NontrappingFPToInt: 4
+Binaryen.Features.SignExt: 32
+Binaryen.Features.SIMD128: 8
+Binaryen.Features.ExceptionHandling: 64
BinaryenInvalidId: 0
BinaryenBlockId: 1
BinaryenIfId: 2
@@ -3383,6 +3390,8 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5}
functionTypes[3] = BinaryenAddFunctionType(the_module, NULL, 0, paramTypes, 0);
}
BinaryenModuleAutoDrop(the_module);
+ BinaryenSetFeatures(the_module, 61);
+ BinaryenGetFeatures(the_module);
BinaryenModuleValidate(the_module);
BinaryenModulePrint(the_module);
(module
diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c
index 1761ab0bb..1359385eb 100644
--- a/test/example/c-api-kitchen-sink.c
+++ b/test/example/c-api-kitchen-sink.c
@@ -160,6 +160,16 @@ void test_types() {
printf("BinaryenTypeAuto: %d\n", BinaryenTypeAuto());
}
+void test_features() {
+ printf("BinaryenFeatureAtomics: %d\n", BinaryenFeatureAtomics());
+ printf("BinaryenFeatureBulkMemory: %d\n", BinaryenFeatureBulkMemory());
+ printf("BinaryenFeatureMutableGlobals: %d\n", BinaryenFeatureMutableGlobals());
+ printf("BinaryenFeatureNontrappingFPToInt: %d\n", BinaryenFeatureNontrappingFPToInt());
+ printf("BinaryenFeatureSignExt: %d\n", BinaryenFeatureSignExt());
+ printf("BinaryenFeatureSIMD128: %d\n", BinaryenFeatureSIMD128());
+ printf("BinaryenFeatureExceptionHandling: %d\n", BinaryenFeatureExceptionHandling());
+}
+
void test_core() {
// Module creation
@@ -511,6 +521,16 @@ void test_core() {
// A bunch of our code needs drop(), auto-add it
BinaryenModuleAutoDrop(module);
+ BinaryenFeatures features =
+ BinaryenFeatureAtomics() |
+ BinaryenFeatureBulkMemory() |
+ BinaryenFeatureNontrappingFPToInt() |
+ BinaryenFeatureSignExt() |
+ BinaryenFeatureSIMD128();
+
+ BinaryenSetFeatures(module, features);
+ assert(BinaryenGetFeatures(module) == features);
+
// Verify it validates
assert(BinaryenModuleValidate(module));
@@ -830,6 +850,7 @@ void test_color_status() {
int main() {
test_types();
+ test_features();
test_core();
test_unreachable();
test_relooper();
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index 693782b60..9b5c10a05 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -7,6 +7,13 @@ BinaryenTypeVec128: 5
BinaryenTypeExceptRef: 6
BinaryenTypeUnreachable: 7
BinaryenTypeAuto: -1
+BinaryenFeatureAtomics: 1
+BinaryenFeatureBulkMemory: 16
+BinaryenFeatureMutableGlobals: 2
+BinaryenFeatureNontrappingFPToInt: 4
+BinaryenFeatureSignExt: 32
+BinaryenFeatureSIMD128: 8
+BinaryenFeatureExceptionHandling: 64
(f32.neg
(f32.const -33.61199951171875)
)
@@ -3312,6 +3319,8 @@ int main() {
functionTypes[3] = BinaryenAddFunctionType(the_module, NULL, 0, paramTypes, 0);
}
BinaryenModuleAutoDrop(the_module);
+ BinaryenSetFeatures(the_module, 61);
+ BinaryenGetFeatures(the_module);
BinaryenModuleValidate(the_module);
BinaryenModulePrint(the_module);
(module