WasmContext.h (3599B)
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: 3 * 4 * Copyright 2020 Mozilla Foundation 5 * 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 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 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. 17 */ 18 19 #ifndef wasm_context_h 20 #define wasm_context_h 21 22 #ifdef ENABLE_WASM_JSPI 23 # include "gc/Barrier.h" 24 #endif // ENABLE_WASM_JSPI 25 26 #include "js/NativeStackLimits.h" 27 28 #ifdef _WIN32 29 struct _NT_TIB; 30 #endif 31 32 namespace js::wasm { 33 34 #ifdef ENABLE_WASM_JSPI 35 class SuspenderObject; 36 using SuspenderObjectSet = 37 HashSet<SuspenderObject*, PointerHasher<SuspenderObject*>, 38 SystemAllocPolicy>; 39 #endif // ENABLE_WASM_JSPI 40 41 // wasm::Context lives in JSContext and contains the wasm-related per-context 42 // state. 43 44 class Context { 45 public: 46 Context(); 47 ~Context(); 48 49 static constexpr size_t offsetOfStackLimit() { 50 return offsetof(Context, stackLimit); 51 } 52 static constexpr size_t offsetOfMainStackLimit() { 53 return offsetof(Context, mainStackLimit); 54 } 55 56 void initStackLimit(JSContext* cx); 57 58 #ifdef ENABLE_WASM_JSPI 59 static constexpr size_t offsetOfActiveSuspender() { 60 return offsetof(Context, activeSuspender_); 61 } 62 # ifdef _WIN32 63 static constexpr size_t offsetOfTib() { return offsetof(Context, tib_); } 64 static constexpr size_t offsetOfTibStackBase() { 65 return offsetof(Context, tibStackBase_); 66 } 67 static constexpr size_t offsetOfTibStackLimit() { 68 return offsetof(Context, tibStackLimit_); 69 } 70 # endif 71 72 SuspenderObject* activeSuspender() { return activeSuspender_; } 73 bool onSuspendableStack() const { return activeSuspender_ != nullptr; } 74 75 void enterSuspendableStack(JSContext* cx, SuspenderObject* suspender); 76 void leaveSuspendableStack(JSContext* cx); 77 78 SuspenderObject* findSuspenderForStackAddress(const void* stackAddress); 79 80 void trace(JSTracer* trc); 81 void traceRoots(JSTracer* trc); 82 #endif 83 84 // Used by wasm::EnsureThreadSignalHandlers(cx) to install thread signal 85 // handlers once per JSContext/thread. 86 bool triedToInstallSignalHandlers; 87 bool haveSignalHandlers; 88 89 // Like JSContext::jitStackLimit but used for wasm code. Wasm code doesn't 90 // use the stack limit for interrupts, but it does update it for stack 91 // switching. 92 JS::NativeStackLimit stackLimit; 93 // The original stack limit before any stack switches. Cached for easy 94 // restoration. 95 JS::NativeStackLimit mainStackLimit; 96 97 #ifdef ENABLE_WASM_JSPI 98 # if defined(_WIN32) 99 // On WIN64, the Thread Information Block stack limits must be updated on 100 // stack switches to avoid failures on SP checks during vectored exeption 101 // handling for traps. We store the original limits and the TIB here for 102 // easy restoration. 103 _NT_TIB* tib_ = nullptr; 104 void* tibStackBase_ = nullptr; 105 void* tibStackLimit_ = nullptr; 106 # endif 107 108 // The currently active suspender object. Null if we're executing on the 109 // system stack, otherwise we're on a wasm suspendable stack. 110 HeapPtr<SuspenderObject*> activeSuspender_; 111 112 // All of the allocated suspender objects. 113 SuspenderObjectSet suspenders_; 114 #endif 115 }; 116 117 } // namespace js::wasm 118 119 #endif // wasm_context_h