|
8 | 8 | #include "TimerManager.h"
|
9 | 9 |
|
10 | 10 | #include <cxxreact/SystraceSection.h>
|
| 11 | +#include <react/featureflags/ReactNativeFeatureFlags.h> |
11 | 12 | #include <utility>
|
12 | 13 |
|
13 | 14 | namespace facebook::react {
|
@@ -148,60 +149,64 @@ void TimerManager::callTimer(TimerHandle timerHandle) {
|
148 | 149 | void TimerManager::attachGlobals(jsi::Runtime& runtime) {
|
149 | 150 | // Install host functions for timers.
|
150 | 151 | // TODO (T45786383): Add missing timer functions from JSTimers
|
151 |
| - // TODO (T96212789): Remove when JSVM microtask queue is used everywhere in |
152 |
| - // bridgeless mode. This is being overwritten in JS in that case. |
153 |
| - runtime.global().setProperty( |
154 |
| - runtime, |
155 |
| - "setImmediate", |
156 |
| - jsi::Function::createFromHostFunction( |
157 |
| - runtime, |
158 |
| - jsi::PropNameID::forAscii(runtime, "setImmediate"), |
159 |
| - 2, // Function, ...args |
160 |
| - [this]( |
161 |
| - jsi::Runtime& rt, |
162 |
| - const jsi::Value& thisVal, |
163 |
| - const jsi::Value* args, |
164 |
| - size_t count) { |
165 |
| - if (count == 0) { |
166 |
| - throw jsi::JSError( |
167 |
| - rt, |
168 |
| - "setImmediate must be called with at least one argument (a function to call)"); |
169 |
| - } |
170 |
| - |
171 |
| - if (!args[0].isObject() || !args[0].asObject(rt).isFunction(rt)) { |
172 |
| - throw jsi::JSError( |
173 |
| - rt, "The first argument to setImmediate must be a function."); |
174 |
| - } |
175 |
| - auto callback = args[0].getObject(rt).getFunction(rt); |
176 |
| - |
177 |
| - // Package up the remaining argument values into one place. |
178 |
| - std::vector<jsi::Value> moreArgs; |
179 |
| - for (size_t extraArgNum = 1; extraArgNum < count; extraArgNum++) { |
180 |
| - moreArgs.emplace_back(rt, args[extraArgNum]); |
181 |
| - } |
182 |
| - |
183 |
| - return createReactNativeMicrotask( |
184 |
| - std::move(callback), std::move(moreArgs)); |
185 |
| - })); |
186 | 152 |
|
187 |
| - runtime.global().setProperty( |
188 |
| - runtime, |
189 |
| - "clearImmediate", |
190 |
| - jsi::Function::createFromHostFunction( |
191 |
| - runtime, |
192 |
| - jsi::PropNameID::forAscii(runtime, "clearImmediate"), |
193 |
| - 1, // handle |
194 |
| - [this]( |
195 |
| - jsi::Runtime& rt, |
196 |
| - const jsi::Value& thisVal, |
197 |
| - const jsi::Value* args, |
198 |
| - size_t count) { |
199 |
| - if (count > 0 && args[0].isNumber()) { |
200 |
| - auto handle = (TimerHandle)args[0].asNumber(); |
201 |
| - deleteReactNativeMicrotask(rt, handle); |
202 |
| - } |
203 |
| - return jsi::Value::undefined(); |
204 |
| - })); |
| 153 | + // Ensure that we don't define `setImmediate` and `clearImmediate` if |
| 154 | + // microtasks are enabled (as we polyfill them using `queueMicrotask` then). |
| 155 | + if (!ReactNativeFeatureFlags::enableMicrotasks()) { |
| 156 | + runtime.global().setProperty( |
| 157 | + runtime, |
| 158 | + "setImmediate", |
| 159 | + jsi::Function::createFromHostFunction( |
| 160 | + runtime, |
| 161 | + jsi::PropNameID::forAscii(runtime, "setImmediate"), |
| 162 | + 2, // Function, ...args |
| 163 | + [this]( |
| 164 | + jsi::Runtime& rt, |
| 165 | + const jsi::Value& thisVal, |
| 166 | + const jsi::Value* args, |
| 167 | + size_t count) { |
| 168 | + if (count == 0) { |
| 169 | + throw jsi::JSError( |
| 170 | + rt, |
| 171 | + "setImmediate must be called with at least one argument (a function to call)"); |
| 172 | + } |
| 173 | + |
| 174 | + if (!args[0].isObject() || !args[0].asObject(rt).isFunction(rt)) { |
| 175 | + throw jsi::JSError( |
| 176 | + rt, |
| 177 | + "The first argument to setImmediate must be a function."); |
| 178 | + } |
| 179 | + auto callback = args[0].getObject(rt).getFunction(rt); |
| 180 | + |
| 181 | + // Package up the remaining argument values into one place. |
| 182 | + std::vector<jsi::Value> moreArgs; |
| 183 | + for (size_t extraArgNum = 1; extraArgNum < count; extraArgNum++) { |
| 184 | + moreArgs.emplace_back(rt, args[extraArgNum]); |
| 185 | + } |
| 186 | + |
| 187 | + return createReactNativeMicrotask( |
| 188 | + std::move(callback), std::move(moreArgs)); |
| 189 | + })); |
| 190 | + |
| 191 | + runtime.global().setProperty( |
| 192 | + runtime, |
| 193 | + "clearImmediate", |
| 194 | + jsi::Function::createFromHostFunction( |
| 195 | + runtime, |
| 196 | + jsi::PropNameID::forAscii(runtime, "clearImmediate"), |
| 197 | + 1, // handle |
| 198 | + [this]( |
| 199 | + jsi::Runtime& rt, |
| 200 | + const jsi::Value& thisVal, |
| 201 | + const jsi::Value* args, |
| 202 | + size_t count) { |
| 203 | + if (count > 0 && args[0].isNumber()) { |
| 204 | + auto handle = (TimerHandle)args[0].asNumber(); |
| 205 | + deleteReactNativeMicrotask(rt, handle); |
| 206 | + } |
| 207 | + return jsi::Value::undefined(); |
| 208 | + })); |
| 209 | + } |
205 | 210 |
|
206 | 211 | runtime.global().setProperty(
|
207 | 212 | runtime,
|
|
0 commit comments