From 6aa2a253136d8d3d987c7fb8b3bc68208a5a532c Mon Sep 17 00:00:00 2001 From: "Ben L. Titzer" Date: Wed, 8 Aug 2018 16:54:44 +0200 Subject: [PATCH] [wasm] Add WasmFeatures to enable/detect features This CL introduces a set of configuration options implemented as a struct of booleans that together comprise the set of enabled or detected features. The configuration options replace command-line flags that were checked deep in the implementation. As such, it is necessary to plumb them through multiple levels of abstraction. R=ahaas@chromium.org CC=mstarzinger@chromium.org BUG=chromium:868844 Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng Change-Id: I1b82f5826e4fd263f68e8cafcd923bac5818a637 Reviewed-on: https://chromium-review.googlesource.com/1163670 Reviewed-by: Andreas Haas Commit-Queue: Ben Titzer Cr-Commit-Position: refs/heads/master@{#55018} --- BUILD.gn | 3 + src/api.cc | 7 +- src/compiler/wasm-compiler.cc | 12 +- src/flag-definitions.h | 28 +-- src/isolate.cc | 4 +- src/value-serializer.cc | 14 +- src/wasm/baseline/liftoff-compiler.cc | 7 +- src/wasm/function-body-decoder-impl.h | 54 +++-- src/wasm/function-body-decoder.cc | 37 +-- src/wasm/function-body-decoder.h | 27 +-- src/wasm/module-compiler.cc | 45 ++-- src/wasm/module-compiler.h | 11 +- src/wasm/module-decoder.cc | 74 +++--- src/wasm/module-decoder.h | 24 +- src/wasm/wasm-code-manager.cc | 17 +- src/wasm/wasm-code-manager.h | 16 +- src/wasm/wasm-engine.cc | 52 ++-- src/wasm/wasm-engine.h | 12 +- src/wasm/wasm-feature-flags.h | 26 ++ src/wasm/wasm-features.cc | 38 +++ src/wasm/wasm-features.h | 61 +++++ src/wasm/wasm-interpreter.cc | 16 +- src/wasm/wasm-js.cc | 33 ++- src/wasm/wasm-memory.cc | 1 - src/wasm/wasm-objects.cc | 9 +- src/wasm/wasm-objects.h | 8 +- src/wasm/wasm-serialization.cc | 10 +- src/wasm/wasm-text.cc | 3 +- test/cctest/compiler/test-multiple-return.cc | 3 +- test/cctest/wasm/test-run-wasm-module.cc | 4 +- .../cctest/wasm/test-streaming-compilation.cc | 8 +- test/cctest/wasm/test-wasm-serialization.cc | 6 +- test/cctest/wasm/test-wasm-shared-engine.cc | 3 +- test/cctest/wasm/wasm-run-utils.cc | 14 +- test/cctest/wasm/wasm-run-utils.h | 1 + test/common/wasm/wasm-macro-gen.h | 2 + test/common/wasm/wasm-module-runner.cc | 12 +- test/fuzzer/multi-return.cc | 4 +- test/fuzzer/wasm-async.cc | 4 +- test/fuzzer/wasm-fuzzer-common.cc | 15 +- test/fuzzer/wasm.cc | 8 +- .../wasm/function-body-decoder-unittest.cc | 71 ++++-- .../unittests/wasm/module-decoder-unittest.cc | 227 +++++++++++------- .../wasm/wasm-code-manager-unittest.cc | 4 +- 44 files changed, 680 insertions(+), 355 deletions(-) create mode 100644 src/wasm/wasm-feature-flags.h create mode 100644 src/wasm/wasm-features.cc create mode 100644 src/wasm/wasm-features.h diff --git a/BUILD.gn b/BUILD.gn index 9d00e8d3dc..7d87c6459a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -2508,6 +2508,9 @@ v8_source_set("v8_base") { "src/wasm/wasm-engine.h", "src/wasm/wasm-external-refs.cc", "src/wasm/wasm-external-refs.h", + "src/wasm/wasm-feature-flags.h", + "src/wasm/wasm-features.cc", + "src/wasm/wasm-features.h", "src/wasm/wasm-interpreter.cc", "src/wasm/wasm-interpreter.h", "src/wasm/wasm-js.cc", diff --git a/src/api.cc b/src/api.cc index ef5feece6e..05122b22e5 100644 --- a/src/api.cc +++ b/src/api.cc @@ -7738,9 +7738,11 @@ MaybeLocal WasmCompiledModule::Compile(Isolate* isolate, if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) { return MaybeLocal(); } + auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate); i::MaybeHandle maybe_compiled = i_isolate->wasm_engine()->SyncCompile( - i_isolate, &thrower, i::wasm::ModuleWireBytes(start, start + length)); + i_isolate, enabled_features, &thrower, + i::wasm::ModuleWireBytes(start, start + length)); if (maybe_compiled.is_null()) return MaybeLocal(); return Local::Cast( Utils::ToLocal(maybe_compiled.ToHandleChecked())); @@ -7787,8 +7789,9 @@ WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming( promise_.Reset(isolate, resolver->GetPromise()); i::Isolate* i_isolate = reinterpret_cast(isolate); + auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate); streaming_decoder_ = i_isolate->wasm_engine()->StartStreamingCompilation( - i_isolate, handle(i_isolate->context(), i_isolate), + i_isolate, enabled_features, handle(i_isolate->context(), i_isolate), base::make_unique(isolate, GetPromise())); } diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc index 71d1f7eda0..f7d1c6fb7b 100644 --- a/src/compiler/wasm-compiler.cc +++ b/src/compiler/wasm-compiler.cc @@ -2889,7 +2889,6 @@ void WasmGraphBuilder::GetGlobalBaseAndOffset(MachineType mem_type, Node** offset_node) { DCHECK_NOT_NULL(instance_node_); if (global.mutability && global.imported) { - DCHECK(FLAG_experimental_wasm_mut_global); if (imported_mutable_globals_ == nullptr) { // Load imported_mutable_globals_ from the instance object at runtime. imported_mutable_globals_ = graph()->NewNode( @@ -5035,9 +5034,14 @@ SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction( new (mcgraph->zone()) SourcePositionTable(mcgraph->graph()); WasmGraphBuilder builder(wasm_unit_->env_, mcgraph->zone(), mcgraph, wasm_unit_->func_body_.sig, source_position_table); - graph_construction_result_ = - wasm::BuildTFGraph(wasm_unit_->wasm_engine_->allocator(), &builder, - wasm_unit_->func_body_, node_origins); + // TODO(titzer): gather detected features into a per-module location + // in order to increment an embedder feature use count. + wasm::WasmFeatures unused_detected_features; + graph_construction_result_ = wasm::BuildTFGraph( + wasm_unit_->wasm_engine_->allocator(), + wasm_unit_->native_module_->enabled_features(), wasm_unit_->env_->module, + &builder, &unused_detected_features, wasm_unit_->func_body_, + node_origins); if (graph_construction_result_.failed()) { if (FLAG_trace_wasm_compiler) { StdoutStream{} << "Compilation failed: " diff --git a/src/flag-definitions.h b/src/flag-definitions.h index 7dfb0530f4..f2e25a958a 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -596,22 +596,18 @@ DEFINE_DEBUG_BOOL(dump_wasm_module, false, "dump wasm module bytes") DEFINE_STRING(dump_wasm_module_path, nullptr, "directory to dump wasm modules to") -DEFINE_BOOL(experimental_wasm_simd, false, - "enable prototype simd opcodes for wasm") -DEFINE_BOOL(experimental_wasm_eh, false, - "enable prototype exception handling opcodes for wasm") -DEFINE_BOOL(experimental_wasm_mv, false, - "enable prototype multi-value support for wasm") -DEFINE_BOOL(experimental_wasm_threads, false, - "enable prototype threads for wasm") -DEFINE_BOOL(experimental_wasm_sat_f2i_conversions, false, - "enable non-trapping float-to-int conversions for wasm") -DEFINE_BOOL(experimental_wasm_se, true, - "enable prototype sign extension opcodes for wasm") -DEFINE_BOOL(experimental_wasm_anyref, false, - "enable prototype anyref support for wasm") -DEFINE_BOOL(experimental_wasm_mut_global, true, - "enable prototype import/export mutable global support for wasm") +// Declare command-line flags for WASM features. Warning: avoid using these +// flags directly in the implementation. Instead accept wasm::WasmFeatures +// for configurability. +#include "src/wasm/wasm-feature-flags.h" + +#define SPACE +#define DECL_WASM_FLAG(feat, desc, val) \ + DEFINE_BOOL(experimental_wasm_##feat, val, \ + "enable prototype " desc " for wasm") +FOREACH_WASM_FEATURE_FLAG(DECL_WASM_FLAG, SPACE) +#undef DECL_WASM_FLAG +#undef SPACE DEFINE_BOOL(wasm_opt, false, "enable wasm optimization") DEFINE_BOOL(wasm_no_bounds_checks, false, diff --git a/src/isolate.cc b/src/isolate.cc index e1f0e52f46..6ba6d0feb3 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -1124,6 +1124,8 @@ void ReportBootstrappingException(Handle exception, } bool Isolate::is_catchable_by_wasm(Object* exception) { + // TODO(titzer): thread WASM features here, or just remove this check? + if (!FLAG_experimental_wasm_eh) return false; if (!is_catchable_by_javascript(exception) || !exception->IsJSError()) return false; HandleScope scope(this); @@ -1307,7 +1309,7 @@ Object* Isolate::UnwindAndFindHandler() { trap_handler::ClearThreadInWasm(); } - if (!FLAG_experimental_wasm_eh || !is_catchable_by_wasm(exception)) { + if (!is_catchable_by_wasm(exception)) { break; } int stack_slots = 0; // Will contain stack slot count of frame. diff --git a/src/value-serializer.cc b/src/value-serializer.cc index 4c560f396c..0c22040d10 100644 --- a/src/value-serializer.cc +++ b/src/value-serializer.cc @@ -522,11 +522,13 @@ Maybe ValueSerializer::WriteJSReceiver(Handle receiver) { return WriteWasmModule(Handle::cast(receiver)); } break; - case WASM_MEMORY_TYPE: - if (FLAG_experimental_wasm_threads) { + case WASM_MEMORY_TYPE: { + auto enabled_features = wasm::WasmFeaturesFromIsolate(isolate_); + if (enabled_features.threads) { return WriteWasmMemory(Handle::cast(receiver)); } break; + } default: break; } @@ -1805,8 +1807,11 @@ MaybeHandle ValueDeserializer::ReadWasmModule() { wasm::DeserializeNativeModule(isolate_, compiled_bytes, wire_bytes); if (result.is_null()) { wasm::ErrorThrower thrower(isolate_, "ValueDeserializer::ReadWasmModule"); + // TODO(titzer): are the current features appropriate for deserializing? + auto enabled_features = wasm::WasmFeaturesFromIsolate(isolate_); result = isolate_->wasm_engine()->SyncCompile( - isolate_, &thrower, wasm::ModuleWireBytes(wire_bytes)); + isolate_, enabled_features, &thrower, + wasm::ModuleWireBytes(wire_bytes)); } uint32_t id = next_id_++; if (!result.is_null()) { @@ -1818,7 +1823,8 @@ MaybeHandle ValueDeserializer::ReadWasmModule() { MaybeHandle ValueDeserializer::ReadWasmMemory() { uint32_t id = next_id_++; - if (!FLAG_experimental_wasm_threads) { + auto enabled_features = wasm::WasmFeaturesFromIsolate(isolate_); + if (!enabled_features.threads) { return MaybeHandle(); } diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index 21c557b0ef..7dc740c4d2 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -1135,7 +1135,6 @@ class LiftoffCompiler { uint32_t* offset) { LiftoffRegister addr = pinned.set(__ GetUnusedRegister(kGpReg)); if (global->mutability && global->imported) { - DCHECK(FLAG_experimental_wasm_mut_global); LOAD_INSTANCE_FIELD(addr, ImportedMutableGlobals, kPointerLoadType); __ Load(addr, addr.gp(), no_reg, global->index * sizeof(Address), kPointerLoadType, pinned); @@ -1851,9 +1850,11 @@ bool LiftoffCompilationUnit::ExecuteCompilation() { compiler::GetWasmCallDescriptor(&zone, wasm_unit_->func_body_.sig); base::Optional liftoff_compile_time_scope( base::in_place, wasm_unit_->counters_->liftoff_compile_time()); + WasmFeatures unused_detected_features; WasmFullDecoder decoder( - &zone, module, wasm_unit_->func_body_, call_descriptor, wasm_unit_->env_, - &zone); + &zone, module, wasm_unit_->native_module_->enabled_features(), + &unused_detected_features, wasm_unit_->func_body_, call_descriptor, + wasm_unit_->env_, &zone); decoder.Decode(); liftoff_compile_time_scope.reset(); LiftoffCompiler* compiler = &decoder.interface(); diff --git a/src/wasm/function-body-decoder-impl.h b/src/wasm/function-body-decoder-impl.h index bc44b14bed..1051d67a0a 100644 --- a/src/wasm/function-body-decoder-impl.h +++ b/src/wasm/function-body-decoder-impl.h @@ -12,6 +12,7 @@ #include "src/bit-vector.h" #include "src/wasm/decoder.h" #include "src/wasm/function-body-decoder.h" +#include "src/wasm/wasm-features.h" #include "src/wasm/wasm-limits.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-opcodes.h" @@ -38,17 +39,21 @@ struct WasmException; return true; \ }()) -#define RET_ON_PROTOTYPE_OPCODE(flag) \ +#define RET_ON_PROTOTYPE_OPCODE(feat) \ DCHECK(!this->module_ || this->module_->origin == kWasmOrigin); \ - if (!FLAG_experimental_wasm_##flag) { \ - this->error("Invalid opcode (enable with --experimental-wasm-" #flag ")"); \ + if (!this->enabled_.feat) { \ + this->error("Invalid opcode (enable with --experimental-wasm-" #feat ")"); \ + } else { \ + this->detected_->feat = true; \ } -#define CHECK_PROTOTYPE_OPCODE(flag) \ +#define CHECK_PROTOTYPE_OPCODE(feat) \ DCHECK(!this->module_ || this->module_->origin == kWasmOrigin); \ - if (!FLAG_experimental_wasm_##flag) { \ - this->error("Invalid opcode (enable with --experimental-wasm-" #flag ")"); \ + if (!this->enabled_.feat) { \ + this->error("Invalid opcode (enable with --experimental-wasm-" #feat ")"); \ break; \ + } else { \ + this->detected_->feat = true; \ } #define OPCODE_ERROR(opcode, message) \ @@ -209,11 +214,12 @@ struct BlockTypeImmediate { uint32_t sig_index = 0; FunctionSig* sig = nullptr; - inline BlockTypeImmediate(Decoder* decoder, const byte* pc) { + inline BlockTypeImmediate(const WasmFeatures& enabled, Decoder* decoder, + const byte* pc) { uint8_t val = decoder->read_u8(pc + 1, "block type"); if (!decode_local_type(val, &type)) { // Handle multi-value blocks. - if (!VALIDATE(FLAG_experimental_wasm_mv)) { + if (!VALIDATE(enabled.mv)) { decoder->error(pc + 1, "invalid block type"); return; } @@ -661,13 +667,18 @@ struct ControlWithNamedConstructors : public ControlBase { template class WasmDecoder : public Decoder { public: - WasmDecoder(const WasmModule* module, FunctionSig* sig, const byte* start, + WasmDecoder(const WasmModule* module, const WasmFeatures& enabled, + WasmFeatures* detected, FunctionSig* sig, const byte* start, const byte* end, uint32_t buffer_offset = 0) : Decoder(start, end, buffer_offset), module_(module), + enabled_(enabled), + detected_(detected), sig_(sig), local_types_(nullptr) {} const WasmModule* module_; + const WasmFeatures enabled_; + WasmFeatures* detected_; FunctionSig* sig_; ZoneVector* local_types_; @@ -678,7 +689,8 @@ class WasmDecoder : public Decoder { : static_cast(local_types_->size()); } - static bool DecodeLocals(Decoder* decoder, const FunctionSig* sig, + static bool DecodeLocals(const WasmFeatures& enabled, Decoder* decoder, + const FunctionSig* sig, ZoneVector* type_list) { DCHECK_NOT_NULL(type_list); DCHECK_EQ(0, type_list->size()); @@ -718,14 +730,14 @@ class WasmDecoder : public Decoder { type = kWasmF64; break; case kLocalAnyRef: - if (FLAG_experimental_wasm_anyref) { + if (enabled.anyref) { type = kWasmAnyRef; break; } decoder->error(decoder->pc() - 1, "invalid local type"); return false; case kLocalS128: - if (FLAG_experimental_wasm_simd) { + if (enabled.simd) { type = kWasmS128; break; } @@ -1008,7 +1020,7 @@ class WasmDecoder : public Decoder { case kExprIf: // fall through case kExprLoop: case kExprBlock: { - BlockTypeImmediate imm(decoder, pc); + BlockTypeImmediate imm(kAllWasmFeatures, decoder, pc); return 1 + imm.length; } @@ -1215,9 +1227,10 @@ class WasmFullDecoder : public WasmDecoder { public: template WasmFullDecoder(Zone* zone, const WasmModule* module, + const WasmFeatures& enabled, WasmFeatures* detected, const FunctionBody& body, InterfaceArgs&&... interface_args) - : WasmDecoder(module, body.sig, body.start, body.end, - body.offset), + : WasmDecoder(module, enabled, detected, body.sig, body.start, + body.end, body.offset), zone_(zone), interface_(std::forward(interface_args)...), local_type_vec_(zone), @@ -1245,7 +1258,8 @@ class WasmFullDecoder : public WasmDecoder { } DCHECK_EQ(0, this->local_types_->size()); - WasmDecoder::DecodeLocals(this, this->sig_, this->local_types_); + WasmDecoder::DecodeLocals(this->enabled_, this, this->sig_, + this->local_types_); CALL_INTERFACE(StartFunction); DecodeFunctionBody(); if (!this->failed()) CALL_INTERFACE(FinishFunction); @@ -1433,7 +1447,7 @@ class WasmFullDecoder : public WasmDecoder { case kExprNop: break; case kExprBlock: { - BlockTypeImmediate imm(this, this->pc_); + BlockTypeImmediate imm(this->enabled_, this, this->pc_); if (!this->Validate(imm)) break; PopArgs(imm.sig); auto* block = PushBlock(); @@ -1462,7 +1476,7 @@ class WasmFullDecoder : public WasmDecoder { } case kExprTry: { CHECK_PROTOTYPE_OPCODE(eh); - BlockTypeImmediate imm(this, this->pc_); + BlockTypeImmediate imm(this->enabled_, this, this->pc_); if (!this->Validate(imm)) break; PopArgs(imm.sig); auto* try_block = PushTry(); @@ -1515,7 +1529,7 @@ class WasmFullDecoder : public WasmDecoder { break; } case kExprLoop: { - BlockTypeImmediate imm(this, this->pc_); + BlockTypeImmediate imm(this->enabled_, this, this->pc_); if (!this->Validate(imm)) break; PopArgs(imm.sig); auto* block = PushLoop(); @@ -1526,7 +1540,7 @@ class WasmFullDecoder : public WasmDecoder { break; } case kExprIf: { - BlockTypeImmediate imm(this, this->pc_); + BlockTypeImmediate imm(this->enabled_, this, this->pc_); if (!this->Validate(imm)) break; auto cond = Pop(0, kWasmI32); PopArgs(imm.sig); diff --git a/src/wasm/function-body-decoder.cc b/src/wasm/function-body-decoder.cc index 4b8a23ae25..beb8716d9a 100644 --- a/src/wasm/function-body-decoder.cc +++ b/src/wasm/function-body-decoder.cc @@ -809,10 +809,10 @@ class WasmGraphBuildingInterface { } // namespace -bool DecodeLocalDecls(BodyLocalDecls* decls, const byte* start, - const byte* end) { +bool DecodeLocalDecls(const WasmFeatures& enabled, BodyLocalDecls* decls, + const byte* start, const byte* end) { Decoder decoder(start, end); - if (WasmDecoder::DecodeLocals(&decoder, nullptr, + if (WasmDecoder::DecodeLocals(enabled, &decoder, nullptr, &decls->type_list)) { DCHECK(decoder.ok()); decls->encoded_size = decoder.pc_offset(); @@ -825,7 +825,7 @@ BytecodeIterator::BytecodeIterator(const byte* start, const byte* end, BodyLocalDecls* decls) : Decoder(start, end) { if (decls != nullptr) { - if (DecodeLocalDecls(decls, start, end)) { + if (DecodeLocalDecls(kAllWasmFeatures, decls, start, end)) { pc_ += decls->encoded_size; if (pc_ > end_) pc_ = end_; } @@ -833,20 +833,24 @@ BytecodeIterator::BytecodeIterator(const byte* start, const byte* end, } DecodeResult VerifyWasmCode(AccountingAllocator* allocator, - const WasmModule* module, FunctionBody& body) { + const WasmFeatures& enabled, + const WasmModule* module, WasmFeatures* detected, + FunctionBody& body) { Zone zone(allocator, ZONE_NAME); - WasmFullDecoder decoder(&zone, module, - body); + WasmFullDecoder decoder( + &zone, module, enabled, detected, body); decoder.Decode(); return decoder.toResult(nullptr); } -DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder, - FunctionBody& body, +DecodeResult BuildTFGraph(AccountingAllocator* allocator, + const WasmFeatures& enabled, + const wasm::WasmModule* module, TFBuilder* builder, + WasmFeatures* detected, FunctionBody& body, compiler::NodeOriginTable* node_origins) { Zone zone(allocator, ZONE_NAME); WasmFullDecoder decoder( - &zone, builder->module(), body, builder); + &zone, module, enabled, detected, body, builder); if (node_origins) { builder->AddBytecodePositionDecorator(node_origins, &decoder); } @@ -865,7 +869,9 @@ unsigned OpcodeLength(const byte* pc, const byte* end) { std::pair StackEffect(const WasmModule* module, FunctionSig* sig, const byte* pc, const byte* end) { - WasmDecoder decoder(module, sig, pc, end); + WasmFeatures unused_detected_features; + WasmDecoder decoder( + module, kAllWasmFeatures, &unused_detected_features, sig, pc, end); return decoder.StackEffect(pc); } @@ -900,8 +906,10 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body, const WasmModule* module, PrintLocals print_locals, std::ostream& os, std::vector* line_numbers) { Zone zone(allocator, ZONE_NAME); - WasmDecoder decoder(module, body.sig, body.start, - body.end); + WasmFeatures unused_detected_features; + WasmDecoder decoder(module, kAllWasmFeatures, + &unused_detected_features, body.sig, + body.start, body.end); int line_nr = 0; constexpr int kNoByteCode = -1; @@ -999,7 +1007,8 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body, case kExprIf: case kExprBlock: case kExprTry: { - BlockTypeImmediate imm(&i, i.pc()); + BlockTypeImmediate imm(kAllWasmFeatures, &i, + i.pc()); os << " // @" << i.pc_offset(); if (decoder.Complete(imm)) { for (unsigned i = 0; i < imm.out_arity(); i++) { diff --git a/src/wasm/function-body-decoder.h b/src/wasm/function-body-decoder.h index abfdca24ba..13a3ae2d0c 100644 --- a/src/wasm/function-body-decoder.h +++ b/src/wasm/function-body-decoder.h @@ -25,8 +25,10 @@ class WasmGraphBuilder; namespace wasm { -typedef compiler::WasmGraphBuilder TFBuilder; struct WasmModule; // forward declaration of module interface. +struct WasmFeatures; + +typedef compiler::WasmGraphBuilder TFBuilder; // A wrapper around the signature and bytes of a function. struct FunctionBody { @@ -41,10 +43,14 @@ struct FunctionBody { }; V8_EXPORT_PRIVATE DecodeResult VerifyWasmCode(AccountingAllocator* allocator, + const WasmFeatures& enabled, const WasmModule* module, + WasmFeatures* detected, FunctionBody& body); -DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder, +DecodeResult BuildTFGraph(AccountingAllocator* allocator, + const WasmFeatures& enabled, const WasmModule* module, + TFBuilder* builder, WasmFeatures* detected, FunctionBody& body, compiler::NodeOriginTable* node_origins); enum PrintLocals { kPrintLocals, kOmitLocals }; @@ -61,20 +67,6 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body, // A simplified form of AST printing, e.g. from a debugger. void PrintRawWasmCode(const byte* start, const byte* end); -inline DecodeResult VerifyWasmCode(AccountingAllocator* allocator, - const WasmModule* module, FunctionSig* sig, - const byte* start, const byte* end) { - FunctionBody body(sig, 0, start, end); - return VerifyWasmCode(allocator, module, body); -} - -inline DecodeResult BuildTFGraph(AccountingAllocator* allocator, - TFBuilder* builder, FunctionSig* sig, - const byte* start, const byte* end) { - FunctionBody body(sig, 0, start, end); - return BuildTFGraph(allocator, builder, body, nullptr); -} - struct BodyLocalDecls { // The size of the encoded declarations. uint32_t encoded_size = 0; // size of encoded declarations @@ -84,7 +76,8 @@ struct BodyLocalDecls { explicit BodyLocalDecls(Zone* zone) : type_list(zone) {} }; -V8_EXPORT_PRIVATE bool DecodeLocalDecls(BodyLocalDecls* decls, +V8_EXPORT_PRIVATE bool DecodeLocalDecls(const WasmFeatures& enabled, + BodyLocalDecls* decls, const byte* start, const byte* end); V8_EXPORT_PRIVATE BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, diff --git a/src/wasm/module-compiler.cc b/src/wasm/module-compiler.cc index 37b01a7db2..1543756cf1 100644 --- a/src/wasm/module-compiler.cc +++ b/src/wasm/module-compiler.cc @@ -223,6 +223,7 @@ class InstanceBuilder { }; Isolate* isolate_; + const WasmFeatures enabled_; const WasmModule* const module_; ErrorThrower* thrower_; Handle module_object_; @@ -688,7 +689,10 @@ void ValidateSequentially(Isolate* isolate, NativeModule* native_module, wasm_decode, function_time); TimedHistogramScope wasm_decode_function_time_scope(time_counter); - result = VerifyWasmCode(isolate->allocator(), module, body); + WasmFeatures detected; + result = VerifyWasmCode(isolate->allocator(), + native_module->enabled_features(), module, + &detected, body); } if (result.failed()) { TruncatedUserString<> name(wire_bytes.GetName(&func, module)); @@ -840,7 +844,7 @@ class BackgroundCompileTask : public CancelableTask { } // namespace MaybeHandle CompileToModuleObject( - Isolate* isolate, ErrorThrower* thrower, + Isolate* isolate, const WasmFeatures& enabled, ErrorThrower* thrower, std::shared_ptr module, const ModuleWireBytes& wire_bytes, Handle