Skip to content

Commit

Permalink
Features C/JS API (#2049)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tlively committed May 17, 2019
1 parent 1184678 commit 9c63728
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
---

Expand Down
11 changes: 11 additions & 0 deletions build-js.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
44 changes: 42 additions & 2 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 ==========
//
Expand Down Expand Up @@ -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;
}

Expand Down
19 changes: 19 additions & 0 deletions src/binaryen-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 ==========
//
Expand Down
17 changes: 17 additions & 0 deletions src/js/binaryen.js-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -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']();
Expand Down Expand Up @@ -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 = '';
Expand Down
1 change: 0 additions & 1 deletion src/wasm-features.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ struct FeatureSet {
return *this;
}

private:
uint32_t features;
};

Expand Down
1 change: 1 addition & 0 deletions test/binaryen.js/atomics.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@ module.addFunction("main", signature, [], module.block("", [
)
]));

module.setFeatures(Binaryen.Features.Atomics);
module.validate();
console.log(module.emitText());
21 changes: 21 additions & 0 deletions test/binaryen.js/kitchen-sink.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -766,6 +786,7 @@ function test_internals() {

function main() {
test_types();
test_features();
test_ids();
test_core();
test_relooper();
Expand Down
9 changes: 9 additions & 0 deletions test/binaryen.js/kitchen-sink.js.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
21 changes: 21 additions & 0 deletions test/example/c-api-kitchen-sink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -830,6 +850,7 @@ void test_color_status() {

int main() {
test_types();
test_features();
test_core();
test_unreachable();
test_relooper();
Expand Down
9 changes: 9 additions & 0 deletions test/example/c-api-kitchen-sink.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
)
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 9c63728

Please sign in to comment.