void validate() { #ifdef DEBUG if (onStack()) { return;
}
MOZ_ASSERT(inRegister()); switch (type_.kind()) { case ValType::I32:
MOZ_ASSERT(loc_ == Location::Gpr); break; case ValType::I64:
MOZ_ASSERT(loc_ == Location::Gpr64); break; case ValType::F32: case ValType::F64:
MOZ_ASSERT(loc_ == Location::Fpr); break; case ValType::Ref:
MOZ_ASSERT(loc_ == Location::Gpr); break; case ValType::V128:
MOZ_ASSERT(loc_ == Location::Fpr); break;
} #endif
}
friendclass ABIResultIter;
ABIResult() {}
public: // Sizes of items in the stack area. // // The size values come from the implementations of Push() in // MacroAssembler-x86-shared.cpp and MacroAssembler-arm-shared.cpp, and from // VFPRegister::size() in Architecture-arm.h. // // On ARM unlike on x86 we push a single for float.
// Just as WebAssembly functions can take multiple arguments, they can also // return multiple results. As with a call, a limited number of results will be // located in registers, and the rest will be stored in a stack area. The // |ABIResultIter| computes result locations, given a |ResultType|. // // Recall that a |ResultType| represents a sequence of value types t1..tN, // indexed from 1 to N. In principle it doesn't matter how we decide which // results get to be in registers and which go to the stack. To better // harmonize with WebAssembly's abstract stack machine, whose properties are // taken advantage of by the baseline compiler, our strategy is to start // allocating result locations in "reverse" order: from result N down to 1. // // If a result with index I is in a register, then all results with index J > I // are also in registers. If a result I is on the stack, then all results with // index K < I are also on the stack, farther away from the stack pointer than // result I. // // Currently only a single result is ever stored in a register, though this may // change in the future on register-rich platforms. // // NB: The baseline compiler also uses thie ABI for locations of block // parameters and return values, within individual WebAssembly functions.
// A value that is written into the trap exit frame, which is useful for // cross-checking during garbage collection. static constexpr uintptr_t TrapExitDummyValue = 1337;
// And its offset, in words, down from the highest-addressed word of the trap // exit frame. The value is written into the frame using WasmPush. In the // case where WasmPush allocates more than one word, the value will therefore // be written at the lowest-addressed word. #ifdef JS_CODEGEN_ARM64 static constexpr size_t TrapExitDummyValueOffsetFromTop = 1; #else static constexpr size_t TrapExitDummyValueOffsetFromTop = 0; #endif
// An argument that will end up on the stack according to the system ABI, to be // passed to GenerateDirectCallFromJit. Since the direct JIT call creates its // own frame, it is its responsibility to put stack arguments to their expected // locations; so the caller of GenerateDirectCallFromJit can put them anywhere.
class JitCallStackArg { public: enumclass Tag {
Imm32,
GPR,
FPU,
Address,
Undefined,
};
private:
Tag tag_; union U {
int32_t imm32_;
jit::Register gpr_;
jit::FloatRegister fpu_;
jit::Address addr_;
U() {}
} arg;
using JitCallStackArgVector = Vector<JitCallStackArg, 4, SystemAllocPolicy>;
// Generates an inline wasm call (during jit compilation) to a specific wasm // function (as specifed by the given FuncExport). // This call doesn't go through a wasm entry, but rather creates its own // inlined exit frame. // Assumes: // - all the registers have been preserved by the caller, // - all arguments passed in registers have been set up at the expected // locations, // - all arguments passed on stack slot are alive as defined by a corresponding // JitCallStackArg.
#ifdef ENABLE_WASM_JSPI // Generates a stub that is the frame at the base of a continuation stack. // // A continuation is always entered through the `resume` instruction. `resume` // will need to pass all arguments via the stack (not the call ABI that uses // registers), because the arguments to a continuation can be partially applied // using `cont.bind`. So this stub translates from the `resume` ABI to perform // a `call_ref` to the `funcref` that was passed to `cont.new`. // // When the callee returns, the results are converted again to the `resume` // stack arguments ABI and the stub performs a stack switch to the enclosing // handler. // // There will need to be a unique stub for each function type passed to // `cont.new`. Right now we only support `[] -> []`, so we take no func type. externbool GenerateContBaseFrameStub(jit::MacroAssembler& masm,
Offsets* offsets); #endif
// Clobber all wasm registers before doing a long jmp. This leaves InstanceReg, // and jumpReg. externvoid ClobberWasmRegsForLongJmp(jit::MacroAssembler& masm,
jit::Register jumpReg);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.