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"
27 #include "gc/Barrier.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"
41 class SharedArrayRawBuffer
;
42 class WasmBreakpointSite
;
44 class WasmStructObject
;
45 class WasmArrayObject
;
53 using mozilla::Atomic
;
56 struct FuncImportInstanceData
;
58 struct MemoryInstanceData
;
61 struct TableInstanceData
;
63 struct TagInstanceData
;
64 struct TypeDefInstanceData
;
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
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
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
98 void* debugTrapHandler_
;
100 // The containing JS::Realm.
103 // The containing JSContext.
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_
;
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;
143 // When compiling with tiering, the jumpTable has one entry for each
144 // baseline-compiled function.
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
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_
;
204 const void* addressOfGCZealModeBits_
;
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
210 MOZ_ALIGNED_DECL(16, char data_
);
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
,
227 Instance(JSContext
* cx
, Handle
<WasmInstanceObject
*> object
,
228 const SharedCode
& code
, SharedTableVector
&& tables
,
229 UniqueDebugState maybeDebug
);
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
,
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_
);
318 static constexpr size_t offsetOfAddressOfGCZealModeBits() {
319 return offsetof(Instance
, addressOfGCZealModeBits_
);
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.
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
,
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
411 // Signature for onFunc:
413 // (uint32_t index, void* code, Instance* instance) -> bool
415 template <typename F
>
416 [[nodiscard
]] bool iterElemsFunctions(const ModuleElemSegment
& seg
,
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
,
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;
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
,
461 static int32_t memCopyShared_m32(Instance
* instance
, uint32_t dstByteOffset
,
462 uint32_t srcByteOffset
, uint32_t len
,
464 static int32_t memCopy_m64(Instance
* instance
, uint64_t dstByteOffset
,
465 uint64_t srcByteOffset
, uint64_t len
,
467 static int32_t memCopyShared_m64(Instance
* instance
, uint64_t dstByteOffset
,
468 uint64_t srcByteOffset
, uint64_t len
,
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
,
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
,
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
,
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
,
552 static void* arrayNewElem(Instance
* instance
, uint32_t srcOffset
,
553 uint32_t numElements
,
554 TypeDefInstanceData
* typeDefData
,
556 static int32_t arrayInitData(Instance
* instance
, void* array
, uint32_t index
,
557 uint32_t segByteOffset
, uint32_t numElements
,
558 TypeDefInstanceData
* typeDefData
,
560 static int32_t arrayInitElem(Instance
* instance
, void* array
, uint32_t index
,
561 uint32_t segOffset
, uint32_t numElements
,
562 TypeDefInstanceData
* typeDefData
,
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
,
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
,
585 static int32_t stringCodePointAt(Instance
* instance
, void* stringArg
,
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
);
613 #endif // wasm_instance_h