no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / js / src / wasm / WasmInstance.h
blob0e4f9745b7c21872777d642c62efc15ca04e8d5d
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
4 * Copyright 2016 Mozilla Foundation
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 #ifndef wasm_instance_h
20 #define wasm_instance_h
22 #include "mozilla/Atomics.h"
23 #include "mozilla/Maybe.h"
25 #include <functional>
27 #include "gc/Barrier.h"
28 #include "gc/Zone.h"
29 #include "js/Stack.h" // JS::NativeStackLimit
30 #include "js/TypeDecls.h"
31 #include "vm/SharedMem.h"
32 #include "wasm/WasmExprType.h" // for ResultType
33 #include "wasm/WasmLog.h" // for PrintCallback
34 #include "wasm/WasmModuleTypes.h"
35 #include "wasm/WasmShareable.h" // for SeenSet
36 #include "wasm/WasmTypeDecls.h"
37 #include "wasm/WasmValue.h"
39 namespace js {
41 class SharedArrayRawBuffer;
42 class WasmBreakpointSite;
44 class WasmStructObject;
45 class WasmArrayObject;
47 namespace gc {
48 class StoreBuffer;
49 } // namespace gc
51 namespace wasm {
53 using mozilla::Atomic;
55 class FuncImport;
56 struct FuncImportInstanceData;
57 struct MemoryDesc;
58 struct MemoryInstanceData;
59 class GlobalDesc;
60 struct TableDesc;
61 struct TableInstanceData;
62 struct TagDesc;
63 struct TagInstanceData;
64 struct TypeDefInstanceData;
65 class WasmFrameIter;
67 // Instance represents a wasm instance and provides all the support for runtime
68 // execution of code in the instance. Instances share various immutable data
69 // structures with the Module from which they were instantiated and other
70 // instances instantiated from the same Module. However, an Instance has no
71 // direct reference to its source Module which allows a Module to be destroyed
72 // while it still has live Instances.
74 // The instance's code may be shared among multiple instances.
76 // An Instance is also known as a 'TlsData'. They used to be separate objects,
77 // but have now been unified. Extant references to 'TlsData' will be cleaned
78 // up over time.
79 class alignas(16) Instance {
80 // NOTE: The first fields of Instance are reserved for commonly accessed data
81 // from the JIT, such that they have as small an offset as possible. See the
82 // next note for the end of this region.
84 // Pointer to the base of memory 0 (or null if there is no memories). This is
85 // always in sync with the MemoryInstanceData for memory 0.
86 uint8_t* memory0Base_;
88 // Bounds check limit in bytes (or zero if there is no memory) for memory 0
89 // This is 64-bits on 64-bit systems so as to allow for heap lengths up to and
90 // beyond 4GB, and 32-bits on 32-bit systems, where memories are limited to
91 // 2GB.
93 // See "Linear memory addresses and bounds checking" in WasmMemory.cpp.
94 uintptr_t memory0BoundsCheckLimit_;
96 // Null or a pointer to a per-process builtin thunk that will invoke the Debug
97 // Trap Handler.
98 void* debugTrapHandler_;
100 // The containing JS::Realm.
101 JS::Realm* realm_;
103 // The containing JSContext.
104 JSContext* cx_;
106 // The pending exception that was found during stack unwinding after a throw.
108 // - Only non-null while unwinding the control stack from a wasm-exit stub.
109 // until the nearest enclosing Wasm try-catch or try-delegate block.
110 // - Set by wasm::HandleThrow, unset by Instance::consumePendingException.
111 // - If the unwind target is a `try-delegate`, it is unset by the delegated
112 // try-catch block or function body block.
113 GCPtr<AnyRef> pendingException_;
114 // The tag object of the pending exception.
115 GCPtr<AnyRef> pendingExceptionTag_;
117 // Usually equal to cx->stackLimitForJitCode(JS::StackForUntrustedScript),
118 // but can be racily set to trigger immediate trap as an opportunity to
119 // CheckForInterrupt without an additional branch.
120 Atomic<JS::NativeStackLimit, mozilla::Relaxed> stackLimit_;
122 // Set to 1 when wasm should call CheckForInterrupt.
123 Atomic<uint32_t, mozilla::Relaxed> interrupt_;
125 // The address of the realm()->zone()->needsIncrementalBarrier(). This is
126 // specific to this instance and not a process wide field, and so it cannot
127 // be linked into code.
128 const JS::shadow::Zone::BarrierState* addressOfNeedsIncrementalBarrier_;
130 public:
131 // NOTE: All fields commonly accessed by the JIT must be above this method,
132 // and this method adapted for the last field present. This method is used
133 // to assert that we can use compact offsets on x86(-64) for these fields.
134 // We cannot have the assertion here, due to C++ 'offsetof' rules.
135 static constexpr size_t offsetOfLastCommonJitField() {
136 return offsetof(Instance, addressOfNeedsIncrementalBarrier_);
139 // The number of baseline scratch storage words available.
140 static constexpr size_t N_BASELINE_SCRATCH_WORDS = 4;
142 private:
143 // When compiling with tiering, the jumpTable has one entry for each
144 // baseline-compiled function.
145 void** jumpTable_;
147 // 4 words of scratch storage for the baseline compiler, which can't always
148 // use the stack for this.
149 uintptr_t baselineScratchWords_[N_BASELINE_SCRATCH_WORDS];
151 // The class_ of WasmValueBox, this is a per-process value. We could patch
152 // this into code, but the only use-sites are register restricted and cannot
153 // easily use a symbolic address.
154 const JSClass* valueBoxClass_;
156 // Address of the JitRuntime's arguments rectifier trampoline
157 void* jsJitArgsRectifier_;
159 // Address of the JitRuntime's exception handler trampoline
160 void* jsJitExceptionHandler_;
162 // Address of the JitRuntime's object prebarrier trampoline
163 void* preBarrierCode_;
165 // Address of the store buffer for this instance
166 gc::StoreBuffer* storeBuffer_;
168 // Weak pointer to WasmInstanceObject that owns this instance
169 WeakHeapPtr<WasmInstanceObject*> object_;
171 // The wasm::Code for this instance
172 const SharedCode code_;
174 // The tables for this instance, if any
175 const SharedTableVector tables_;
177 // Passive data segments for use with bulk memory instructions
178 DataSegmentVector passiveDataSegments_;
180 // Passive elem segments for use with tables
181 InstanceElemSegmentVector passiveElemSegments_;
183 // The wasm::DebugState for this instance, if any
184 const UniqueDebugState maybeDebug_;
186 // If debugging, this is a per-funcIndex bit table denoting whether debugging
187 // is currently enabled for the function within the instance. The flag is set
188 // if any breakpoint or function entry or exit point needs to be visited. It
189 // is OK to conservatively set this flag, but there is very significant
190 // overhead to taking a breakpoint trap, so managing it precisely is
191 // worthwhile.
192 uint32_t* debugFilter_;
194 // The exclusive maximum index of a global that has been initialized so far.
195 uint32_t maxInitializedGlobalsIndexPlus1_;
197 // Pointer that should be freed (due to padding before the Instance).
198 void* allocatedBase_;
200 // Fields from the JS context for memory allocation, stashed on the instance
201 // so it can be accessed from JIT code.
202 const void* addressOfNurseryPosition_;
203 #ifdef JS_GC_ZEAL
204 const void* addressOfGCZealModeBits_;
205 #endif
207 // The data must be the last field. Globals for the module start here
208 // and are inline in this structure. 16-byte alignment is required for SIMD
209 // data.
210 MOZ_ALIGNED_DECL(16, char data_);
212 // Internal helpers:
213 TypeDefInstanceData* typeDefInstanceData(uint32_t typeIndex) const;
214 const void* addressOfGlobalCell(const GlobalDesc& globalDesc) const;
215 FuncImportInstanceData& funcImportInstanceData(const FuncImport& fi);
216 MemoryInstanceData& memoryInstanceData(uint32_t memoryIndex) const;
217 TableInstanceData& tableInstanceData(uint32_t tableIndex) const;
218 TagInstanceData& tagInstanceData(uint32_t tagIndex) const;
220 // Only WasmInstanceObject can call the private trace function.
221 friend class js::WasmInstanceObject;
222 void tracePrivate(JSTracer* trc);
224 bool callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc,
225 uint64_t* argv);
227 Instance(JSContext* cx, Handle<WasmInstanceObject*> object,
228 const SharedCode& code, SharedTableVector&& tables,
229 UniqueDebugState maybeDebug);
230 ~Instance();
232 public:
233 static Instance* create(JSContext* cx, Handle<WasmInstanceObject*> object,
234 const SharedCode& code, uint32_t instanceDataLength,
235 SharedTableVector&& tables,
236 UniqueDebugState maybeDebug);
237 static void destroy(Instance* instance);
239 bool init(JSContext* cx, const JSObjectVector& funcImports,
240 const ValVector& globalImportValues,
241 Handle<WasmMemoryObjectVector> memories,
242 const WasmGlobalObjectVector& globalObjs,
243 const WasmTagObjectVector& tagObjs,
244 const DataSegmentVector& dataSegments,
245 const ModuleElemSegmentVector& elemSegments);
247 // Trace any GC roots on the stack, for the frame associated with |wfi|,
248 // whose next instruction to execute is |nextPC|.
250 // For consistency checking of StackMap sizes in debug builds, this also
251 // takes |highestByteVisitedInPrevFrame|, which is the address of the
252 // highest byte scanned in the frame below this one on the stack, and in
253 // turn it returns the address of the highest byte scanned in this frame.
254 uintptr_t traceFrame(JSTracer* trc, const wasm::WasmFrameIter& wfi,
255 uint8_t* nextPC,
256 uintptr_t highestByteVisitedInPrevFrame);
257 void updateFrameForMovingGC(const wasm::WasmFrameIter& wfi, uint8_t* nextPC);
259 static constexpr size_t offsetOfMemory0Base() {
260 return offsetof(Instance, memory0Base_);
262 static constexpr size_t offsetOfMemory0BoundsCheckLimit() {
263 return offsetof(Instance, memory0BoundsCheckLimit_);
265 static constexpr size_t offsetOfDebugTrapHandler() {
266 return offsetof(Instance, debugTrapHandler_);
269 static constexpr size_t offsetOfRealm() { return offsetof(Instance, realm_); }
270 static constexpr size_t offsetOfCx() { return offsetof(Instance, cx_); }
271 static constexpr size_t offsetOfValueBoxClass() {
272 return offsetof(Instance, valueBoxClass_);
274 static constexpr size_t offsetOfPendingException() {
275 return offsetof(Instance, pendingException_);
277 static constexpr size_t offsetOfPendingExceptionTag() {
278 return offsetof(Instance, pendingExceptionTag_);
280 static constexpr size_t offsetOfStackLimit() {
281 return offsetof(Instance, stackLimit_);
283 static constexpr size_t offsetOfInterrupt() {
284 return offsetof(Instance, interrupt_);
286 static constexpr size_t offsetOfAddressOfNeedsIncrementalBarrier() {
287 return offsetof(Instance, addressOfNeedsIncrementalBarrier_);
289 static constexpr size_t offsetOfJumpTable() {
290 return offsetof(Instance, jumpTable_);
292 static constexpr size_t offsetOfBaselineScratchWords() {
293 return offsetof(Instance, baselineScratchWords_);
295 static constexpr size_t sizeOfBaselineScratchWords() {
296 return sizeof(baselineScratchWords_);
298 static constexpr size_t offsetOfJSJitArgsRectifier() {
299 return offsetof(Instance, jsJitArgsRectifier_);
301 static constexpr size_t offsetOfJSJitExceptionHandler() {
302 return offsetof(Instance, jsJitExceptionHandler_);
304 static constexpr size_t offsetOfPreBarrierCode() {
305 return offsetof(Instance, preBarrierCode_);
307 static constexpr size_t offsetOfDebugFilter() {
308 return offsetof(Instance, debugFilter_);
310 static constexpr size_t offsetOfData() { return offsetof(Instance, data_); }
311 static constexpr size_t offsetInData(size_t offset) {
312 return offsetOfData() + offset;
314 static constexpr size_t offsetOfAddressOfNurseryPosition() {
315 return offsetof(Instance, addressOfNurseryPosition_);
317 #ifdef JS_GC_ZEAL
318 static constexpr size_t offsetOfAddressOfGCZealModeBits() {
319 return offsetof(Instance, addressOfGCZealModeBits_);
321 #endif
323 JSContext* cx() const { return cx_; }
324 void* debugTrapHandler() const { return debugTrapHandler_; }
325 void setDebugTrapHandler(void* newHandler) { debugTrapHandler_ = newHandler; }
326 JS::Realm* realm() const { return realm_; }
327 bool debugEnabled() const { return !!maybeDebug_; }
328 DebugState& debug() { return *maybeDebug_; }
329 uint8_t* data() const { return (uint8_t*)&data_; }
330 const SharedTableVector& tables() const { return tables_; }
331 SharedMem<uint8_t*> memoryBase(uint32_t memoryIndex) const;
332 WasmMemoryObject* memory(uint32_t memoryIndex) const;
333 size_t memoryMappedSize(uint32_t memoryIndex) const;
334 SharedArrayRawBuffer* sharedMemoryBuffer(
335 uint32_t memoryIndex) const; // never null
336 bool memoryAccessInGuardRegion(const uint8_t* addr, unsigned numBytes) const;
338 // Methods to set, test and clear the interrupt fields. Both interrupt
339 // fields are Relaxed and so no consistency/ordering can be assumed.
341 void setInterrupt();
342 bool isInterrupted() const;
343 void resetInterrupt(JSContext* cx);
345 bool debugFilter(uint32_t funcIndex) const;
346 void setDebugFilter(uint32_t funcIndex, bool value);
348 const Code& code() const { return *code_; }
349 inline const CodeTier& code(Tier t) const;
350 inline uint8_t* codeBase(Tier t) const;
351 inline const MetadataTier& metadata(Tier t) const;
352 inline const Metadata& metadata() const;
353 inline bool isAsmJS() const;
355 // This method returns a pointer to the GC object that owns this Instance.
356 // Instances may be reached via weak edges (e.g., Realm::instances_)
357 // so this perform a read-barrier on the returned object unless the barrier
358 // is explicitly waived.
360 WasmInstanceObject* object() const;
361 WasmInstanceObject* objectUnbarriered() const;
363 // Execute the given export given the JS call arguments, storing the return
364 // value in args.rval.
366 [[nodiscard]] bool callExport(JSContext* cx, uint32_t funcIndex,
367 const CallArgs& args,
368 CoercionLevel level = CoercionLevel::Spec);
370 // Exception handling support
372 void setPendingException(Handle<WasmExceptionObject*> exn);
374 // Constant expression support
376 void constantGlobalGet(uint32_t globalIndex, MutableHandleVal result);
377 [[nodiscard]] bool constantRefFunc(uint32_t funcIndex,
378 MutableHandleFuncRef result);
379 WasmStructObject* constantStructNewDefault(JSContext* cx, uint32_t typeIndex);
380 WasmArrayObject* constantArrayNewDefault(JSContext* cx, uint32_t typeIndex,
381 uint32_t numElements);
383 // Return the name associated with a given function index, or generate one
384 // if none was given by the module.
386 JSAtom* getFuncDisplayAtom(JSContext* cx, uint32_t funcIndex) const;
387 void ensureProfilingLabels(bool profilingEnabled) const;
389 // Called by Wasm(Memory|Table)Object when a moving resize occurs:
391 void onMovingGrowMemory(const WasmMemoryObject* memory);
392 void onMovingGrowTable(const Table* table);
394 bool initSegments(JSContext* cx, const DataSegmentVector& dataSegments,
395 const ModuleElemSegmentVector& elemSegments);
397 // Called to apply a single ElemSegment at a given offset, assuming
398 // that all bounds validation has already been performed.
399 [[nodiscard]] bool initElems(uint32_t tableIndex,
400 const ModuleElemSegment& seg,
401 uint32_t dstOffset);
403 // Iterates through elements of a ModuleElemSegment containing functions.
404 // Unlike iterElemsAnyrefs, this method can get function data (instance and
405 // code pointers) without creating intermediate JSFunctions.
407 // NOTE: This method only works for element segments that use the index
408 // encoding. If the expression encoding is used, you must use
409 // iterElemsAnyrefs.
411 // Signature for onFunc:
413 // (uint32_t index, void* code, Instance* instance) -> bool
415 template <typename F>
416 [[nodiscard]] bool iterElemsFunctions(const ModuleElemSegment& seg,
417 const F& onFunc);
419 // Iterates through elements of a ModuleElemSegment. This method works for any
420 // type of wasm ref and both element segment encodings. As required by AnyRef,
421 // any functions will be wrapped in JSFunction - if possible, you should use
422 // iterElemsFunctions to avoid this.
424 // Signature for onAnyRef:
426 // (uint32_t index, AnyRef ref) -> bool
428 template <typename F>
429 [[nodiscard]] bool iterElemsAnyrefs(const ModuleElemSegment& seg,
430 const F& onAnyRef);
432 // Debugger support:
434 JSString* createDisplayURL(JSContext* cx);
435 WasmBreakpointSite* getOrCreateBreakpointSite(JSContext* cx, uint32_t offset);
436 void destroyBreakpointSite(JS::GCContext* gcx, uint32_t offset);
438 // about:memory reporting:
440 void addSizeOfMisc(MallocSizeOf mallocSizeOf, SeenSet<Metadata>* seenMetadata,
441 SeenSet<Code>* seenCode, SeenSet<Table>* seenTables,
442 size_t* code, size_t* data) const;
444 // Wasm disassembly support
446 void disassembleExport(JSContext* cx, uint32_t funcIndex, Tier tier,
447 PrintCallback printString) const;
449 public:
450 // Functions to be called directly from wasm code.
451 static int32_t callImport_general(Instance*, int32_t, int32_t, uint64_t*);
452 static uint32_t memoryGrow_m32(Instance* instance, uint32_t delta,
453 uint32_t memoryIndex);
454 static uint64_t memoryGrow_m64(Instance* instance, uint64_t delta,
455 uint32_t memoryIndex);
456 static uint32_t memorySize_m32(Instance* instance, uint32_t memoryIndex);
457 static uint64_t memorySize_m64(Instance* instance, uint32_t memoryIndex);
458 static int32_t memCopy_m32(Instance* instance, uint32_t dstByteOffset,
459 uint32_t srcByteOffset, uint32_t len,
460 uint8_t* memBase);
461 static int32_t memCopyShared_m32(Instance* instance, uint32_t dstByteOffset,
462 uint32_t srcByteOffset, uint32_t len,
463 uint8_t* memBase);
464 static int32_t memCopy_m64(Instance* instance, uint64_t dstByteOffset,
465 uint64_t srcByteOffset, uint64_t len,
466 uint8_t* memBase);
467 static int32_t memCopyShared_m64(Instance* instance, uint64_t dstByteOffset,
468 uint64_t srcByteOffset, uint64_t len,
469 uint8_t* memBase);
470 static int32_t memCopy_any(Instance* instance, uint64_t dstByteOffset,
471 uint64_t srcByteOffset, uint64_t len,
472 uint32_t dstMemIndex, uint32_t srcMemIndex);
474 static int32_t memFill_m32(Instance* instance, uint32_t byteOffset,
475 uint32_t value, uint32_t len, uint8_t* memBase);
476 static int32_t memFillShared_m32(Instance* instance, uint32_t byteOffset,
477 uint32_t value, uint32_t len,
478 uint8_t* memBase);
479 static int32_t memFill_m64(Instance* instance, uint64_t byteOffset,
480 uint32_t value, uint64_t len, uint8_t* memBase);
481 static int32_t memFillShared_m64(Instance* instance, uint64_t byteOffset,
482 uint32_t value, uint64_t len,
483 uint8_t* memBase);
484 static int32_t memInit_m32(Instance* instance, uint32_t dstOffset,
485 uint32_t srcOffset, uint32_t len,
486 uint32_t segIndex, uint32_t memIndex);
487 static int32_t memInit_m64(Instance* instance, uint64_t dstOffset,
488 uint32_t srcOffset, uint32_t len,
489 uint32_t segIndex, uint32_t memIndex);
490 static int32_t dataDrop(Instance* instance, uint32_t segIndex);
491 static int32_t tableCopy(Instance* instance, uint32_t dstOffset,
492 uint32_t srcOffset, uint32_t len,
493 uint32_t dstTableIndex, uint32_t srcTableIndex);
494 static int32_t tableFill(Instance* instance, uint32_t start, void* value,
495 uint32_t len, uint32_t tableIndex);
496 static int32_t memDiscard_m32(Instance* instance, uint32_t byteOffset,
497 uint32_t byteLen, uint8_t* memBase);
498 static int32_t memDiscardShared_m32(Instance* instance, uint32_t byteOffset,
499 uint32_t byteLen, uint8_t* memBase);
500 static int32_t memDiscard_m64(Instance* instance, uint64_t byteOffset,
501 uint64_t byteLen, uint8_t* memBase);
502 static int32_t memDiscardShared_m64(Instance* instance, uint64_t byteOffset,
503 uint64_t byteLen, uint8_t* memBase);
504 static void* tableGet(Instance* instance, uint32_t index,
505 uint32_t tableIndex);
506 static uint32_t tableGrow(Instance* instance, void* initValue, uint32_t delta,
507 uint32_t tableIndex);
508 static int32_t tableSet(Instance* instance, uint32_t index, void* value,
509 uint32_t tableIndex);
510 static uint32_t tableSize(Instance* instance, uint32_t tableIndex);
511 static int32_t tableInit(Instance* instance, uint32_t dstOffset,
512 uint32_t srcOffset, uint32_t len, uint32_t segIndex,
513 uint32_t tableIndex);
514 static int32_t elemDrop(Instance* instance, uint32_t segIndex);
515 static int32_t wait_i32_m32(Instance* instance, uint32_t byteOffset,
516 int32_t value, int64_t timeout,
517 uint32_t memoryIndex);
518 static int32_t wait_i32_m64(Instance* instance, uint64_t byteOffset,
519 int32_t value, int64_t timeout,
520 uint32_t memoryIndex);
521 static int32_t wait_i64_m32(Instance* instance, uint32_t byteOffset,
522 int64_t value, int64_t timeout,
523 uint32_t memoryIndex);
524 static int32_t wait_i64_m64(Instance* instance, uint64_t byteOffset,
525 int64_t value, int64_t timeout,
526 uint32_t memoryIndex);
527 static int32_t wake_m32(Instance* instance, uint32_t byteOffset,
528 int32_t count, uint32_t memoryIndex);
529 static int32_t wake_m64(Instance* instance, uint64_t byteOffset,
530 int32_t count, uint32_t memoryIndex);
531 static void* refFunc(Instance* instance, uint32_t funcIndex);
532 static void postBarrier(Instance* instance, void** location);
533 static void postBarrierPrecise(Instance* instance, void** location,
534 void* prev);
535 static void postBarrierPreciseWithOffset(Instance* instance, void** base,
536 uint32_t offset, void* prev);
537 static void* exceptionNew(Instance* instance, void* exceptionArg);
538 static int32_t throwException(Instance* instance, void* exceptionArg);
539 template <bool ZeroFields>
540 static void* structNewIL(Instance* instance,
541 TypeDefInstanceData* typeDefData);
542 template <bool ZeroFields>
543 static void* structNewOOL(Instance* instance,
544 TypeDefInstanceData* typeDefData);
545 template <bool ZeroFields>
546 static void* arrayNew(Instance* instance, uint32_t numElements,
547 TypeDefInstanceData* typeDefData);
548 static void* arrayNewData(Instance* instance, uint32_t segByteOffset,
549 uint32_t numElements,
550 TypeDefInstanceData* typeDefData,
551 uint32_t segIndex);
552 static void* arrayNewElem(Instance* instance, uint32_t srcOffset,
553 uint32_t numElements,
554 TypeDefInstanceData* typeDefData,
555 uint32_t segIndex);
556 static int32_t arrayInitData(Instance* instance, void* array, uint32_t index,
557 uint32_t segByteOffset, uint32_t numElements,
558 TypeDefInstanceData* typeDefData,
559 uint32_t segIndex);
560 static int32_t arrayInitElem(Instance* instance, void* array, uint32_t index,
561 uint32_t segOffset, uint32_t numElements,
562 TypeDefInstanceData* typeDefData,
563 uint32_t segIndex);
564 static int32_t arrayCopy(Instance* instance, void* dstArray,
565 uint32_t dstIndex, void* srcArray, uint32_t srcIndex,
566 uint32_t numElements, uint32_t elementSize);
567 static int32_t arrayFill(Instance* instance, void* array, uint32_t index,
568 uint32_t numElements);
569 static int32_t refTest(Instance* instance, void* refPtr,
570 const wasm::TypeDef* typeDef);
571 static int32_t intrI8VecMul(Instance* instance, uint32_t dest, uint32_t src1,
572 uint32_t src2, uint32_t len, uint8_t* memBase);
574 static int32_t stringTest(Instance* instance, void* stringArg);
575 static void* stringCast(Instance* instance, void* stringArg);
576 static void* stringFromCharCodeArray(Instance* instance, void* arrayArg,
577 uint32_t arrayStart,
578 uint32_t arrayCount);
579 static int32_t stringIntoCharCodeArray(Instance* instance, void* stringArg,
580 void* arrayArg, uint32_t arrayStart);
581 static void* stringFromCharCode(Instance* instance, uint32_t charCode);
582 static void* stringFromCodePoint(Instance* instance, uint32_t codePoint);
583 static int32_t stringCharCodeAt(Instance* instance, void* stringArg,
584 uint32_t index);
585 static int32_t stringCodePointAt(Instance* instance, void* stringArg,
586 uint32_t index);
587 static int32_t stringLength(Instance* instance, void* stringArg);
588 static void* stringConcat(Instance* instance, void* firstStringArg,
589 void* secondStringArg);
590 static void* stringSubstring(Instance* instance, void* stringArg,
591 int32_t startIndex, int32_t endIndex);
592 static int32_t stringEquals(Instance* instance, void* firstStringArg,
593 void* secondStringArg);
594 static int32_t stringCompare(Instance* instance, void* firstStringArg,
595 void* secondStringArg);
598 bool ResultsToJSValue(JSContext* cx, ResultType type, void* registerResultLoc,
599 Maybe<char*> stackResultsLoc, MutableHandleValue rval,
600 CoercionLevel level = CoercionLevel::Spec);
602 // Report an error to `cx` and mark it as a 'trap' so that it cannot be caught
603 // by wasm exception handlers.
604 void ReportTrapError(JSContext* cx, unsigned errorNumber);
606 // Instance is not a GC thing itself but contains GC thing pointers. Ensure they
607 // are traced appropriately.
608 void TraceInstanceEdge(JSTracer* trc, Instance* instance, const char* name);
610 } // namespace wasm
611 } // namespace js
613 #endif // wasm_instance_h