summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binary-reader-interp.cc41
-rw-r--r--src/feature.cc10
-rw-r--r--src/feature.def16
-rw-r--r--src/feature.h10
-rw-r--r--src/tools/wasm2c.cc13
5 files changed, 62 insertions, 28 deletions
diff --git a/src/binary-reader-interp.cc b/src/binary-reader-interp.cc
index fe98947c..5e19720a 100644
--- a/src/binary-reader-interp.cc
+++ b/src/binary-reader-interp.cc
@@ -25,6 +25,7 @@
#include "src/binary-reader-nop.h"
#include "src/cast.h"
#include "src/error-handler.h"
+#include "src/feature.h"
#include "src/interp.h"
#include "src/stream.h"
#include "src/type-checker.h"
@@ -71,7 +72,8 @@ class BinaryReaderInterp : public BinaryReaderNop {
BinaryReaderInterp(Environment* env,
DefinedModule* module,
std::unique_ptr<OutputBuffer> istream,
- ErrorHandler* error_handler);
+ ErrorHandler* error_handler,
+ const Features& features);
wabt::Result ReadBinary(DefinedModule* out_module);
@@ -287,6 +289,7 @@ class BinaryReaderInterp : public BinaryReaderNop {
HostImportDelegate::ErrorCallback MakePrintErrorCallback();
+ Features features_;
ErrorHandler* error_handler_ = nullptr;
Environment* env_ = nullptr;
DefinedModule* module_ = nullptr;
@@ -320,8 +323,10 @@ class BinaryReaderInterp : public BinaryReaderNop {
BinaryReaderInterp::BinaryReaderInterp(Environment* env,
DefinedModule* module,
std::unique_ptr<OutputBuffer> istream,
- ErrorHandler* error_handler)
- : error_handler_(error_handler),
+ ErrorHandler* error_handler,
+ const Features& features)
+ : features_(features),
+ error_handler_(error_handler),
env_(env),
module_(module),
istream_(std::move(istream)),
@@ -841,6 +846,10 @@ wabt::Result BinaryReaderInterp::OnImportGlobal(Index import_index,
CHECK_RESULT(host_import_module->import_delegate->ImportGlobal(
import, global, MakePrintErrorCallback()));
+ // Make sure the ImportGlobal callback gave us a global that matches.
+ assert(global->typed_value.type == type);
+ assert(global->mutable_ == mutable_);
+
global_env_index = env_->GetGlobalCount() - 1;
AppendExport(host_import_module, ExternalKind::Global, global_env_index,
import->field_name);
@@ -849,11 +858,26 @@ wabt::Result BinaryReaderInterp::OnImportGlobal(Index import_index,
CHECK_RESULT(GetModuleExport(import_module, import->field_name, &export_));
CHECK_RESULT(CheckImportKind(import, export_->kind));
- // TODO: check type and mutability
- import->type = type;
- import->mutable_ = mutable_;
+ Global* exported_global = env_->GetGlobal(export_->index);
+ if (exported_global->typed_value.type != type) {
+ PrintError("type mismatch in imported global, expected %s but got %s.",
+ GetTypeName(exported_global->typed_value.type),
+ GetTypeName(type));
+ return wabt::Result::Error;
+ }
+
+ if (exported_global->mutable_ != mutable_) {
+ const char* kMutableNames[] = {"immutable", "mutable"};
+ PrintError(
+ "mutability mismatch in imported global, expected %s but got %s.",
+ kMutableNames[exported_global->mutable_], kMutableNames[mutable_]);
+ return wabt::Result::Error;
+ }
+
global_env_index = export_->index;
}
+ import->type = type;
+ import->mutable_ = mutable_;
global_index_mapping_.push_back(global_env_index);
num_global_imports_++;
return wabt::Result::Ok;
@@ -991,7 +1015,7 @@ wabt::Result BinaryReaderInterp::OnExport(Index index,
case ExternalKind::Global: {
item_index = TranslateGlobalIndexToEnv(item_index);
Global* global = env_->GetGlobal(item_index);
- if (global->mutable_) {
+ if (global->mutable_ && !features_.mutable_globals_enabled()) {
PrintError("mutable globals cannot be exported");
return wabt::Result::Error;
}
@@ -1617,7 +1641,8 @@ wabt::Result ReadBinaryInterp(Environment* env,
IstreamOffset istream_offset = istream->size();
DefinedModule* module = new DefinedModule();
- BinaryReaderInterp reader(env, module, std::move(istream), error_handler);
+ BinaryReaderInterp reader(env, module, std::move(istream), error_handler,
+ options->features);
env->EmplaceBackModule(module);
wabt::Result result = ReadBinary(data, size, &reader, options);
diff --git a/src/feature.cc b/src/feature.cc
index 193e53f2..95cfbd16 100644
--- a/src/feature.cc
+++ b/src/feature.cc
@@ -21,8 +21,14 @@
namespace wabt {
void Features::AddOptions(OptionParser* parser) {
-#define WABT_FEATURE(variable, flag, help) \
- parser->AddOption("enable-" flag, help, [this]() { enable_##variable(); });
+#define WABT_FEATURE(variable, flag, default_, help) \
+ if (default_ == true) { \
+ parser->AddOption("disable-" flag, "Disable " help, \
+ [this]() { disable_##variable(); }); \
+ } else { \
+ parser->AddOption("enable-" flag, "Enable " help, \
+ [this]() { enable_##variable(); }); \
+ }
#include "src/feature.def"
#undef WABT_FEATURE
diff --git a/src/feature.def b/src/feature.def
index 0e21fadc..9eec57b0 100644
--- a/src/feature.def
+++ b/src/feature.def
@@ -19,13 +19,13 @@
#endif
/*
- * variable flag help
+ * variable flag default help
* ========================================================================= */
-WABT_FEATURE(exceptions, "exceptions", "Experimental exception handling")
-WABT_FEATURE(mutable_globals, "mutable-globals", "Import/export mutable globals")
-WABT_FEATURE(sat_float_to_int, "saturating-float-to-int", "Saturating float-to-int operators")
-WABT_FEATURE(sign_extension, "sign-extension", "Sign-extension operators")
-WABT_FEATURE(simd, "simd", "SIMD support")
-WABT_FEATURE(threads, "threads", "Threading support")
-WABT_FEATURE(multi_value, "multi-value", "Multi-value")
+WABT_FEATURE(exceptions, "exceptions", false, "Experimental exception handling")
+WABT_FEATURE(mutable_globals, "mutable-globals", true, "Import/export mutable globals")
+WABT_FEATURE(sat_float_to_int, "saturating-float-to-int", false, "Saturating float-to-int operators")
+WABT_FEATURE(sign_extension, "sign-extension", false, "Sign-extension operators")
+WABT_FEATURE(simd, "simd", false, "SIMD support")
+WABT_FEATURE(threads, "threads", false, "Threading support")
+WABT_FEATURE(multi_value, "multi-value", false, "Multi-value")
diff --git a/src/feature.h b/src/feature.h
index 8d9b093b..61be9e68 100644
--- a/src/feature.h
+++ b/src/feature.h
@@ -28,19 +28,21 @@ class Features {
void AddOptions(OptionParser*);
void EnableAll() {
-#define WABT_FEATURE(variable, flag, help) enable_##variable();
+#define WABT_FEATURE(variable, flag, default_, help) enable_##variable();
#include "src/feature.def"
#undef WABT_FEATURE
}
-#define WABT_FEATURE(variable, flag, help) \
+#define WABT_FEATURE(variable, flag, default_, help) \
bool variable##_enabled() const { return variable##_enabled_; } \
- void enable_##variable() { variable##_enabled_ = true; }
+ void enable_##variable() { variable##_enabled_ = true; } \
+ void disable_##variable() { variable##_enabled_ = false; }
#include "src/feature.def"
#undef WABT_FEATURE
private:
-#define WABT_FEATURE(variable, flag, help) bool variable##_enabled_ = false;
+#define WABT_FEATURE(variable, flag, default_, help) \
+ bool variable##_enabled_ = default_;
#include "src/feature.def"
#undef WABT_FEATURE
};
diff --git a/src/tools/wasm2c.cc b/src/tools/wasm2c.cc
index cf6e4eec..0d6654cb 100644
--- a/src/tools/wasm2c.cc
+++ b/src/tools/wasm2c.cc
@@ -80,15 +80,16 @@ static void ParseOptions(int argc, char** argv) {
});
parser.Parse(argc, argv);
- // TODO(binji): currently wasm2c doesn't support any feature flags.
- bool any_feature_enabled = false;
-#define WABT_FEATURE(variable, flag, help) \
- any_feature_enabled |= s_features.variable##_enabled();
+ // TODO(binji): currently wasm2c doesn't support any non-default feature
+ // flags.
+ bool any_non_default_feature = false;
+#define WABT_FEATURE(variable, flag, default_, help) \
+ any_non_default_feature |= (s_features.variable##_enabled() != default_);
#include "src/feature.def"
#undef WABT_FEATURE
- if (any_feature_enabled) {
- fprintf(stderr, "wasm2c doesn't currently support any --enable-* flags.\n");
+ if (any_non_default_feature) {
+ fprintf(stderr, "wasm2c currently support only default feature flags.\n");
exit(1);
}
}