#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
#include <iosfwd>
#include <string>
#include "src/base/small-vector.h"
#include "src/common/globals.h"
#include "src/wasm/wasm-feature-flags.h"
#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(imported_strings) \
V(typed_funcref) \
V(multi_memory) \
V(multi_value) \
V(memory64) \
V(bulk_memory) \
V(mutable_globals) \
V(non_trapping_float_to_int) \
V(sign_extension_ops) \
V(jspi)
#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
};
class WasmEnabledFeatures : public base::EnumSet<WasmEnabledFeature> {
public:
constexpr WasmEnabledFeatures() = default;
explicit constexpr WasmEnabledFeatures(
std::initializer_list<WasmEnabledFeature> features)
: EnumSet(features) {}
#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 {}; }
static V8_EXPORT_PRIVATE WasmEnabledFeatures FromFlags();
static V8_EXPORT_PRIVATE WasmEnabledFeatures FromIsolate(Isolate*);
static V8_EXPORT_PRIVATE WasmEnabledFeatures
FromContext(Isolate*, DirectHandle<NativeContext>);
};
class WasmDetectedFeatures
: public base::EnumSet<WasmDetectedFeature, uint64_t> {
public:
constexpr WasmDetectedFeatures() = default;
constexpr WasmDetectedFeatures(
base::EnumSet<WasmDetectedFeature, uint64_t> features)
: base::EnumSet<WasmDetectedFeature, uint64_t>(features) {}
#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,
kJsPrototypes,
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;
}
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_;
};
}
#endif