blob: 520281f3808f49a0b043e8e6956513d1d6d94806 [file] [log] [blame]
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_WASM_FEATURES_H_
#define V8_WASM_WASM_FEATURES_H_
#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
#endif // !V8_ENABLE_WEBASSEMBLY
#include <iosfwd>
#include <string>
#include "src/base/small-vector.h"
#include "src/common/globals.h"
// The feature flags are declared in their own header.
#include "src/wasm/wasm-feature-flags.h"
// Features that are always enabled and do not have a flag.
#define FOREACH_WASM_NON_FLAG_FEATURE(V) \
V(shared_memory) \
V(reftypes) \
V(simd) \
V(threads) \
V(return_call) \
V(extended_const) \
V(relaxed_simd) \
V(gc) \
V(typed_funcref) \
V(js_inlining) \
V(multi_memory) \
V(memory64)
// All features, including features that do not have flags.
#define FOREACH_WASM_FEATURE(V) \
FOREACH_WASM_FEATURE_FLAG(V) \
FOREACH_WASM_NON_FLAG_FEATURE(V)
namespace v8::internal::wasm {
enum class WasmEnabledFeature {
#define DECL_FEATURE_ENUM(feat, ...) feat,
FOREACH_WASM_FEATURE_FLAG(DECL_FEATURE_ENUM)
#undef DECL_FEATURE_ENUM
};
enum class WasmDetectedFeature {
#define DECL_FEATURE_ENUM(feat, ...) feat,
FOREACH_WASM_FEATURE(DECL_FEATURE_ENUM)
#undef DECL_FEATURE_ENUM
};
// Set of enabled features. This only includes features that have a flag.
class WasmEnabledFeatures : public base::EnumSet<WasmEnabledFeature> {
public:
constexpr WasmEnabledFeatures() = default;
explicit constexpr WasmEnabledFeatures(
std::initializer_list<WasmEnabledFeature> features)
: EnumSet(features) {}
// Simplified getters. Use {has_foo()} instead of
// {contains(WasmEnabledFeature::foo)}.
#define DECL_FEATURE_GETTER(feat, ...) \
constexpr bool has_##feat() const { \
return contains(WasmEnabledFeature::feat); \
}
FOREACH_WASM_FEATURE_FLAG(DECL_FEATURE_GETTER)
#undef DECL_FEATURE_GETTER
static inline constexpr WasmEnabledFeatures All() {
#define LIST_FEATURE(feat, ...) WasmEnabledFeature::feat,
return WasmEnabledFeatures({FOREACH_WASM_FEATURE_FLAG(LIST_FEATURE)});
#undef LIST_FEATURE
}
static inline constexpr WasmEnabledFeatures None() { return {}; }
static inline constexpr WasmEnabledFeatures ForAsmjs() { return {}; }
// Retuns optional features that are enabled by flags, plus features that are
// not enabled by a flag and are always on.
static V8_EXPORT_PRIVATE WasmEnabledFeatures FromFlags();
static V8_EXPORT_PRIVATE WasmEnabledFeatures FromIsolate(Isolate*);
static V8_EXPORT_PRIVATE WasmEnabledFeatures
FromContext(Isolate*, DirectHandle<NativeContext>);
};
// Set of detected features. This includes features that have a flag plus
// features in FOREACH_WASM_NON_FLAG_FEATURE.
class WasmDetectedFeatures : public base::EnumSet<WasmDetectedFeature> {
public:
constexpr WasmDetectedFeatures() = default;
// Construct from an enum set.
// NOLINTNEXTLINE(runtime/explicit)
constexpr WasmDetectedFeatures(base::EnumSet<WasmDetectedFeature> features)
: base::EnumSet<WasmDetectedFeature>(features) {}
// Simplified getters and setters. Use {add_foo()} and {has_foo()} instead of
// {Add(WasmDetectedFeature::foo)} or {contains(WasmDetectedFeature::foo)}.
#define DECL_FEATURE_GETTER(feat, ...) \
constexpr void add_##feat() { Add(WasmDetectedFeature::feat); } \
constexpr bool has_##feat() const { \
return contains(WasmDetectedFeature::feat); \
}
FOREACH_WASM_FEATURE(DECL_FEATURE_GETTER)
#undef DECL_FEATURE_GETTER
};
inline constexpr const char* name(WasmEnabledFeature feature) {
switch (feature) {
#define NAME(feat, ...) \
case WasmEnabledFeature::feat: \
return #feat;
FOREACH_WASM_FEATURE_FLAG(NAME)
}
#undef NAME
}
inline std::ostream& operator<<(std::ostream& os, WasmEnabledFeature feature) {
return os << name(feature);
}
inline constexpr const char* name(WasmDetectedFeature feature) {
switch (feature) {
#define NAME(feat, ...) \
case WasmDetectedFeature::feat: \
return #feat;
FOREACH_WASM_FEATURE(NAME)
}
#undef NAME
}
inline std::ostream& operator<<(std::ostream& os, WasmDetectedFeature feature) {
return os << name(feature);
}
enum class CompileTimeImport {
kJsString,
kStringConstants,
kTextEncoder,
kTextDecoder,
// Not really an import, but needs the same handling as compile-time imports.
kDisableDenormalFloats,
};
inline std::ostream& operator<<(std::ostream& os, CompileTimeImport imp) {
return os << static_cast<int>(imp);
}
using CompileTimeImportFlags = base::EnumSet<CompileTimeImport, int>;
class CompileTimeImports {
public:
CompileTimeImports() = default;
CompileTimeImports(const CompileTimeImports& other) V8_NOEXCEPT = default;
CompileTimeImports& operator=(const CompileTimeImports& other)
V8_NOEXCEPT = default;
CompileTimeImports(CompileTimeImports&& other) V8_NOEXCEPT {
*this = std::move(other);
}
CompileTimeImports& operator=(CompileTimeImports&& other) V8_NOEXCEPT {
bits_ = other.bits_;
constants_module_ = std::move(other.constants_module_);
return *this;
}
static CompileTimeImports FromSerialized(
CompileTimeImportFlags::StorageType flags,
base::Vector<const char> constants_module) {
CompileTimeImports result;
result.bits_ = CompileTimeImportFlags::FromIntegral(flags);
result.constants_module_.assign(constants_module.begin(),
constants_module.end());
return result;
}
bool empty() const { return bits_.empty(); }
bool has_string_constants(base::Vector<const uint8_t> name) const {
return bits_.contains(CompileTimeImport::kStringConstants) &&
constants_module_.size() == name.size() &&
std::equal(name.begin(), name.end(), constants_module_.begin());
}
bool contains(CompileTimeImport imp) const { return bits_.contains(imp); }
int compare(const CompileTimeImports& other) const {
if (bits_.ToIntegral() < other.bits_.ToIntegral()) return -1;
if (bits_.ToIntegral() > other.bits_.ToIntegral()) return 1;
return constants_module_.compare(other.constants_module_);
}
void Add(CompileTimeImport imp) { bits_.Add(imp); }
std::string& constants_module() { return constants_module_; }
const std::string& constants_module() const { return constants_module_; }
CompileTimeImportFlags flags() const { return bits_; }
private:
CompileTimeImportFlags bits_;
std::string constants_module_;
};
} // namespace v8::internal::wasm
#endif // V8_WASM_WASM_FEATURES_H_