#ifndef V8_COMPILER_WASM_COMPILER_H_
#define V8_COMPILER_WASM_COMPILER_H_
#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
#endif
#include <memory>
#include <utility>
#include "src/base/small-vector.h"
#include "src/codegen/compiler.h"
#include "src/compiler/wasm-compiler-definitions.h"
#include "src/runtime/runtime.h"
#include "src/wasm/function-body-decoder.h"
#include "src/wasm/function-compiler.h"
#include "src/wasm/module-instantiate.h"
#include "src/wasm/wasm-features.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-opcodes.h"
#include "src/wasm/wasm-result.h"
#include "src/zone/zone.h"
namespace v8 {
class CFunctionInfo;
namespace internal {
enum class AbortReason : uint8_t;
struct AssemblerOptions;
enum class BranchHint : uint8_t;
class TurbofanCompilationJob;
namespace compiler {
class CallDescriptor;
class TFGraph;
class MachineGraph;
class Node;
class NodeOriginTable;
class Operator;
class SourcePositionTable;
struct WasmCompilationData;
class WasmDecorator;
class WasmGraphAssembler;
enum class TrapId : int32_t;
struct Int64LoweringSpecialCase;
template <size_t VarCount>
class GraphAssemblerLabel;
struct WasmTypeCheckConfig;
}
namespace wasm {
struct DecodeStruct;
class WasmCode;
class WireBytesStorage;
enum class LoadTransformationKind : uint8_t;
enum Suspend : int;
enum CallOrigin { kCalledFromWasm, kCalledFromJS };
}
namespace compiler {
V8_EXPORT_PRIVATE wasm::WasmCompilationResult CompileWasmImportCallWrapper(
wasm::ImportCallKind, const wasm::CanonicalSig*, int expected_arity,
wasm::Suspend);
V8_EXPORT_PRIVATE wasm::WasmCompilationResult CompileWasmStackEntryWrapper();
wasm::WasmCompilationResult CompileWasmCapiCallWrapper(
const wasm::CanonicalSig*);
wasm::WasmCompilationResult CompileWasmJSFastCallWrapper(
const wasm::CanonicalSig*, DirectHandle<JSReceiver> callable);
std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob(
Isolate* isolate, const wasm::CanonicalSig* sig,
bool receiver_is_first_param);
enum CWasmEntryParameters {
kCodeEntry,
kObjectRef,
kArgumentsBuffer,
kCEntryFp,
kNumParameters
};
V8_EXPORT_PRIVATE Handle<Code> CompileCWasmEntry(Isolate*,
const wasm::CanonicalSig*);
struct WasmLoopInfo {
Node* header;
uint32_t nesting_depth;
bool can_be_innermost;
WasmLoopInfo(Node* header, uint32_t nesting_depth, bool can_be_innermost)
: header(header),
nesting_depth(nesting_depth),
can_be_innermost(can_be_innermost) {}
};
struct WasmCompilationData {
explicit WasmCompilationData(const wasm::FunctionBody& func_body)
: func_body(func_body) {}
size_t body_size() { return func_body.end - func_body.start; }
const wasm::FunctionBody& func_body;
const wasm::WireBytesStorage* wire_bytes_storage;
NodeOriginTable* node_origins{nullptr};
std::vector<WasmLoopInfo>* loop_infos{nullptr};
std::unique_ptr<wasm::AssumptionsJournal> assumptions{};
SourcePositionTable* source_positions{nullptr};
int func_index;
};
class WasmGraphBuilder {
public:
enum ParameterMode {
kInstanceParameterMode,
kWasmImportDataMode,
kJSFunctionAbiMode,
kNoSpecialParameterMode
};
V8_EXPORT_PRIVATE WasmGraphBuilder(
wasm::CompilationEnv* env, Zone* zone, MachineGraph* mcgraph,
const wasm::FunctionSig* sig, compiler::SourcePositionTable* spt,
ParameterMode parameter_mode, Isolate* isolate,
wasm::WasmEnabledFeatures enabled_features,
const wasm::CanonicalSig* wrapper_sig = nullptr);
V8_EXPORT_PRIVATE ~WasmGraphBuilder();
bool TryWasmInlining(int fct_index, wasm::NativeModule* native_module,
int inlining_id);
void Start(unsigned params);
Node* Param(int index, const char* debug_name = nullptr);
void TerminateThrow(Node* effect, Node* control);
Node* Int32Constant(int32_t value);
Node* Return(base::Vector<Node*> nodes);
template <typename... Nodes>
Node* Return(Node* fst, Nodes*... more) {
Node* arr[] = {fst, more...};
return Return(base::ArrayVector(arr));
}
Node* effect();
Node* control();
Node* SetEffect(Node* node);
Node* SetControl(Node* node);
void SetEffectControl(Node* effect, Node* control);
Node* SetEffectControl(Node* effect_and_control) {
SetEffectControl(effect_and_control, effect_and_control);
return effect_and_control;
}
Node* SetType(Node* node, wasm::ValueType type);
V8_EXPORT_PRIVATE void LowerInt64(Signature<MachineRepresentation>* sig);
V8_EXPORT_PRIVATE void LowerInt64(wasm::CallOrigin origin);
void SetSourcePosition(Node* node, wasm::WasmCodePosition position);
Node* IsNull(Node* object, wasm::ValueType type);
Node* TypeGuard(Node* value, wasm::ValueType type);
bool has_simd() const { return has_simd_; }
MachineGraph* mcgraph() { return mcgraph_; }
TFGraph* graph();
Zone* graph_zone();
protected:
Node* NoContextConstant();
Node* BuildLoadIsolateRoot();
Node* UndefinedValue();
const Operator* GetSafeLoadOperator(int offset, wasm::ValueTypeBase type);
Node* BuildSafeStore(int offset, wasm::ValueTypeBase type, Node* arg_buffer,
Node* value, Node* effect, Node* control);
Node* BuildCallNode(size_t param_count, base::Vector<Node*> args,
wasm::WasmCodePosition position, Node* instance_node,
const Operator* op, Node* frame_state = nullptr);
template <typename T>
Node* BuildWasmCall(const Signature<T>* sig, base::Vector<Node*> args,
base::Vector<Node*> rets, wasm::WasmCodePosition position,
Node* implicit_first_arg, bool indirect,
Node* frame_state = nullptr);
Node* BuildCallToRuntime(Runtime::FunctionId f, Node** parameters,
int parameter_count);
Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, Node* js_context,
Node** parameters, int parameter_count);
TrapId GetTrapIdForTrap(wasm::TrapReason reason);
Node* BuildChangeInt64ToBigInt(Node* input, StubCallMode stub_mode);
void Assert(Node* condition, AbortReason abort_reason);
std::unique_ptr<WasmGraphAssembler> gasm_;
Zone* const zone_;
MachineGraph* const mcgraph_;
wasm::CompilationEnv* const env_;
wasm::WasmEnabledFeatures enabled_features_;
Node** parameters_;
SetOncePointer<Node> stack_check_code_node_;
SetOncePointer<const Operator> stack_check_call_operator_;
bool has_simd_ = false;
bool needs_stack_check_ = false;
const wasm::FunctionSig* const function_sig_;
const wasm::CanonicalSig* const wrapper_sig_{nullptr};
compiler::WasmDecorator* decorator_ = nullptr;
compiler::SourcePositionTable* const source_position_table_ = nullptr;
int inlining_id_ = -1;
const ParameterMode parameter_mode_;
Isolate* const isolate_;
SetOncePointer<Node> instance_data_node_;
NullCheckStrategy null_check_strategy_;
static constexpr int kNoCachedMemoryIndex = -1;
int cached_memory_index_ = kNoCachedMemoryIndex;
};
V8_EXPORT_PRIVATE void BuildInlinedJSToWasmWrapper(
Zone* zone, MachineGraph* mcgraph, const wasm::CanonicalSig* signature,
Isolate* isolate, compiler::SourcePositionTable* spt, Node* frame_state,
bool set_in_wasm_flag);
AssemblerOptions WasmAssemblerOptions();
AssemblerOptions WasmStubAssemblerOptions();
template <typename T>
Signature<MachineRepresentation>* CreateMachineSignature(
Zone* zone, const Signature<T>* sig, wasm::CallOrigin origin);
}
}
}
#endif