#include "config.h"
#include "WasmBinding.h"
#if ENABLE(WEBASSEMBLY)
#include "CCallHelpers.h"
#include "JSCInlines.h"
#include "LinkBuffer.h"
#include "WasmInstance.h"
namespace JSC { namespace Wasm {
using JIT = CCallHelpers;
Expected<MacroAssemblerCodeRef, BindingFailure> wasmToWasm(unsigned importIndex)
{
const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get();
JIT jit;
GPRReg scratch = GPRInfo::nonPreservedNonArgumentGPR;
GPRReg baseMemory = pinnedRegs.baseMemoryPointer;
ASSERT(baseMemory != scratch);
const auto& sizeRegs = pinnedRegs.sizeRegisters;
ASSERT(sizeRegs.size() >= 1);
ASSERT(sizeRegs[0].sizeRegister != baseMemory);
ASSERT(sizeRegs[0].sizeRegister != scratch);
GPRReg sizeRegAsScratch = sizeRegs[0].sizeRegister;
jit.loadWasmContextInstance(sizeRegAsScratch); jit.loadPtr(JIT::Address(sizeRegAsScratch, Instance::offsetOfTargetInstance(importIndex)), baseMemory); jit.loadPtr(JIT::Address(sizeRegAsScratch, Instance::offsetOfWasmEntrypoint(importIndex)), scratch); jit.storeWasmContextInstance(baseMemory);
jit.loadPtr(JIT::Address(sizeRegAsScratch, Instance::offsetOfCachedStackLimit()), sizeRegAsScratch);
jit.storePtr(sizeRegAsScratch, JIT::Address(baseMemory, Instance::offsetOfCachedStackLimit()));
jit.loadPtr(JIT::Address(baseMemory, Instance::offsetOfMemory()), baseMemory); ASSERT(!sizeRegs[0].sizeOffset); jit.loadPtr(CCallHelpers::Address(baseMemory, Memory::offsetOfIndexingMask()), pinnedRegs.indexingMask); jit.loadPtr(JIT::Address(baseMemory, Wasm::Memory::offsetOfSize()), sizeRegs[0].sizeRegister); jit.loadPtr(JIT::Address(baseMemory, Wasm::Memory::offsetOfMemory()), baseMemory); for (unsigned i = 1; i < sizeRegs.size(); ++i) {
ASSERT(sizeRegs[i].sizeRegister != baseMemory);
ASSERT(sizeRegs[i].sizeRegister != scratch);
jit.add64(JIT::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister);
}
jit.loadPtr(scratch, scratch);
jit.jump(scratch);
LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, JITCompilationCanFail);
if (UNLIKELY(patchBuffer.didFailToAllocate()))
return makeUnexpected(BindingFailure::OutOfMemory);
return FINALIZE_CODE(patchBuffer, ("WebAssembly->WebAssembly import[%i]", importIndex));
}
} }
#endif // ENABLE(WEBASSEMBLY)