diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /js/src/wasm/WasmInstance.h | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/wasm/WasmInstance.h')
-rw-r--r-- | js/src/wasm/WasmInstance.h | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/js/src/wasm/WasmInstance.h b/js/src/wasm/WasmInstance.h new file mode 100644 index 0000000000..130bb1cfdb --- /dev/null +++ b/js/src/wasm/WasmInstance.h @@ -0,0 +1,236 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * + * Copyright 2016 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef wasm_instance_h +#define wasm_instance_h + +#include "gc/Barrier.h" +#include "gc/Zone.h" +#include "vm/SharedMem.h" +#include "wasm/TypedObject.h" +#include "wasm/WasmCode.h" +#include "wasm/WasmDebug.h" +#include "wasm/WasmFrameIter.h" // js::wasm::WasmFrameIter +#include "wasm/WasmProcess.h" +#include "wasm/WasmTable.h" + +namespace js { +namespace wasm { + +// Instance represents a wasm instance and provides all the support for runtime +// execution of code in the instance. Instances share various immutable data +// structures with the Module from which they were instantiated and other +// instances instantiated from the same Module. However, an Instance has no +// direct reference to its source Module which allows a Module to be destroyed +// while it still has live Instances. +// +// The instance's code may be shared among multiple instances provided none of +// those instances are being debugged. Instances that are being debugged own +// their code. + +class Instance { + JS::Realm* const realm_; + WeakHeapPtrWasmInstanceObject object_; + void* jsJitArgsRectifier_; + void* jsJitExceptionHandler_; + void* preBarrierCode_; + const SharedCode code_; + const UniqueTlsData tlsData_; + const GCPtrWasmMemoryObject memory_; + const SharedExceptionTagVector exceptionTags_; + const SharedTableVector tables_; + DataSegmentVector passiveDataSegments_; + ElemSegmentVector passiveElemSegments_; + const UniqueDebugState maybeDebug_; + bool hasGcTypes_; + + // Internal helpers: + const void** addressOfTypeId(const TypeIdDesc& typeId) const; + FuncImportTls& funcImportTls(const FuncImport& fi); + TableTls& tableTls(const TableDesc& td) const; + + // Only WasmInstanceObject can call the private trace function. + friend class js::WasmInstanceObject; + void tracePrivate(JSTracer* trc); + + bool callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, + uint64_t* argv); + + public: + Instance(JSContext* cx, HandleWasmInstanceObject object, SharedCode code, + UniqueTlsData tlsData, HandleWasmMemoryObject memory, + SharedExceptionTagVector&& exceptionTags, SharedTableVector&& tables, + UniqueDebugState maybeDebug); + ~Instance(); + bool init(JSContext* cx, const JSFunctionVector& funcImports, + const ValVector& globalImportValues, + const WasmGlobalObjectVector& globalObjs, + const DataSegmentVector& dataSegments, + const ElemSegmentVector& elemSegments); + void trace(JSTracer* trc); + + // Trace any GC roots on the stack, for the frame associated with |wfi|, + // whose next instruction to execute is |nextPC|. + // + // For consistency checking of StackMap sizes in debug builds, this also + // takes |highestByteVisitedInPrevFrame|, which is the address of the + // highest byte scanned in the frame below this one on the stack, and in + // turn it returns the address of the highest byte scanned in this frame. + uintptr_t traceFrame(JSTracer* trc, const wasm::WasmFrameIter& wfi, + uint8_t* nextPC, + uintptr_t highestByteVisitedInPrevFrame); + + JS::Realm* realm() const { return realm_; } + const Code& code() const { return *code_; } + const CodeTier& code(Tier t) const { return code_->codeTier(t); } + bool debugEnabled() const { return !!maybeDebug_; } + DebugState& debug() { return *maybeDebug_; } + const ModuleSegment& moduleSegment(Tier t) const { return code_->segment(t); } + TlsData* tlsData() const { return tlsData_.get(); } + uint8_t* globalData() const { return (uint8_t*)&tlsData_->globalArea; } + uint8_t* codeBase(Tier t) const { return code_->segment(t).base(); } + const MetadataTier& metadata(Tier t) const { return code_->metadata(t); } + const Metadata& metadata() const { return code_->metadata(); } + bool isAsmJS() const { return metadata().isAsmJS(); } + const SharedTableVector& tables() const { return tables_; } + SharedMem<uint8_t*> memoryBase() const; + WasmMemoryObject* memory() const; + size_t memoryMappedSize() const; + SharedArrayRawBuffer* sharedMemoryBuffer() const; // never null + bool memoryAccessInGuardRegion(uint8_t* addr, unsigned numBytes) const; + bool memoryAccessInBounds(uint8_t* addr, unsigned numBytes) const; + const SharedExceptionTagVector& exceptionTags() const { + return exceptionTags_; + } + + static constexpr size_t offsetOfJSJitArgsRectifier() { + return offsetof(Instance, jsJitArgsRectifier_); + } + static constexpr size_t offsetOfJSJitExceptionHandler() { + return offsetof(Instance, jsJitExceptionHandler_); + } + static constexpr size_t offsetOfPreBarrierCode() { + return offsetof(Instance, preBarrierCode_); + } + + // This method returns a pointer to the GC object that owns this Instance. + // Instances may be reached via weak edges (e.g., Realm::instances_) + // so this perform a read-barrier on the returned object unless the barrier + // is explicitly waived. + + WasmInstanceObject* object() const; + WasmInstanceObject* objectUnbarriered() const; + + // Execute the given export given the JS call arguments, storing the return + // value in args.rval. + + [[nodiscard]] bool callExport(JSContext* cx, uint32_t funcIndex, + CallArgs args); + + // Return the name associated with a given function index, or generate one + // if none was given by the module. + + JSAtom* getFuncDisplayAtom(JSContext* cx, uint32_t funcIndex) const; + void ensureProfilingLabels(bool profilingEnabled) const; + + // Called by Wasm(Memory|Table)Object when a moving resize occurs: + + void onMovingGrowMemory(); + void onMovingGrowTable(const Table* theTable); + + // Called to apply a single ElemSegment at a given offset, assuming + // that all bounds validation has already been performed. + + [[nodiscard]] bool initElems(uint32_t tableIndex, const ElemSegment& seg, + uint32_t dstOffset, uint32_t srcOffset, + uint32_t len); + + // Debugger support: + + JSString* createDisplayURL(JSContext* cx); + WasmBreakpointSite* getOrCreateBreakpointSite(JSContext* cx, uint32_t offset); + void destroyBreakpointSite(JSFreeOp* fop, uint32_t offset); + + // about:memory reporting: + + void addSizeOfMisc(MallocSizeOf mallocSizeOf, Metadata::SeenSet* seenMetadata, + Code::SeenSet* seenCode, Table::SeenSet* seenTables, + size_t* code, size_t* data) const; + + // Wasm disassembly support + + void disassembleExport(JSContext* cx, uint32_t funcIndex, Tier tier, + PrintCallback callback) const; + + public: + // Functions to be called directly from wasm code. + static int32_t callImport_general(Instance*, int32_t, int32_t, uint64_t*); + static uint32_t memoryGrow_i32(Instance* instance, uint32_t delta); + static uint32_t memorySize_i32(Instance* instance); + static int32_t wait_i32(Instance* instance, uint32_t byteOffset, + int32_t value, int64_t timeout); + static int32_t wait_i64(Instance* instance, uint32_t byteOffset, + int64_t value, int64_t timeout); + static int32_t wake(Instance* instance, uint32_t byteOffset, int32_t count); + static int32_t memCopy(Instance* instance, uint32_t destByteOffset, + uint32_t srcByteOffset, uint32_t len, + uint8_t* memBase); + static int32_t memCopyShared(Instance* instance, uint32_t destByteOffset, + uint32_t srcByteOffset, uint32_t len, + uint8_t* memBase); + static int32_t dataDrop(Instance* instance, uint32_t segIndex); + static int32_t memFill(Instance* instance, uint32_t byteOffset, + uint32_t value, uint32_t len, uint8_t* memBase); + static int32_t memFillShared(Instance* instance, uint32_t byteOffset, + uint32_t value, uint32_t len, uint8_t* memBase); + static int32_t memInit(Instance* instance, uint32_t dstOffset, + uint32_t srcOffset, uint32_t len, uint32_t segIndex); + static int32_t tableCopy(Instance* instance, uint32_t dstOffset, + uint32_t srcOffset, uint32_t len, + uint32_t dstTableIndex, uint32_t srcTableIndex); + static int32_t elemDrop(Instance* instance, uint32_t segIndex); + static int32_t tableFill(Instance* instance, uint32_t start, void* value, + uint32_t len, uint32_t tableIndex); + static void* tableGet(Instance* instance, uint32_t index, + uint32_t tableIndex); + static uint32_t tableGrow(Instance* instance, void* initValue, uint32_t delta, + uint32_t tableIndex); + static int32_t tableSet(Instance* instance, uint32_t index, void* value, + uint32_t tableIndex); + static uint32_t tableSize(Instance* instance, uint32_t tableIndex); + static int32_t tableInit(Instance* instance, uint32_t dstOffset, + uint32_t srcOffset, uint32_t len, uint32_t segIndex, + uint32_t tableIndex); + static void* refFunc(Instance* instance, uint32_t funcIndex); + static void preBarrierFiltering(Instance* instance, gc::Cell** location); + static void postBarrier(Instance* instance, gc::Cell** location); + static void postBarrierFiltering(Instance* instance, gc::Cell** location); + static void* structNew(Instance* instance, void* structDescr); + static void* structNarrow(Instance* instance, void* outputStructDescr, + void* maybeNullPtr); +}; + +using UniqueInstance = UniquePtr<Instance>; + +bool ResultsToJSValue(JSContext* cx, ResultType type, void* registerResultLoc, + Maybe<char*> stackResultsLoc, MutableHandleValue rval); + +} // namespace wasm +} // namespace js + +#endif // wasm_instance_h |