Remove dead includes in hphp/runtime/vm
[hiphop-php.git] / hphp / runtime / vm / jit / native-calls.cpp
blob6f924e46cedfe2197891d8dce8f1d676ac1ed696
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/native-calls.h"
19 #include <folly/ClockGettimeWrappers.h>
21 #include "hphp/runtime/base/comparisons.h"
22 #include "hphp/runtime/base/exceptions.h"
23 #include "hphp/runtime/base/packed-array.h"
24 #include "hphp/runtime/base/set-array.h"
25 #include "hphp/runtime/base/rds.h"
26 #include "hphp/runtime/base/stats.h"
27 #include "hphp/runtime/base/timestamp.h"
28 #include "hphp/runtime/base/tv-conversions.h"
30 #include "hphp/runtime/vm/property-profile.h"
31 #include "hphp/runtime/vm/reified-generics.h"
32 #include "hphp/runtime/vm/runtime.h"
33 #include "hphp/runtime/vm/unit-util.h"
35 #include "hphp/runtime/vm/jit/arg-group.h"
36 #include "hphp/runtime/vm/jit/ir-opcode.h"
37 #include "hphp/runtime/vm/jit/irlower.h"
38 #include "hphp/runtime/vm/jit/translator-runtime.h"
40 #include "hphp/runtime/ext/array/ext_array.h"
41 #include "hphp/runtime/ext/asio/asio-blockable.h"
42 #include "hphp/runtime/ext/asio/ext_async-function-wait-handle.h"
43 #include "hphp/runtime/ext/asio/ext_static-wait-handle.h"
44 #include "hphp/runtime/ext/collections/ext_collections-pair.h"
45 #include "hphp/runtime/ext/collections/ext_collections-vector.h"
46 #include "hphp/runtime/ext/collections/ext_collections.h"
47 #include "hphp/runtime/ext/functioncredential/ext_functioncredential.h"
48 #include "hphp/runtime/ext/std/ext_std_errorfunc.h"
50 #include "hphp/util/abi-cxx.h"
51 #include "hphp/util/assertions.h"
53 namespace HPHP { namespace jit {
55 ///////////////////////////////////////////////////////////////////////////////
57 namespace NativeCalls {
59 ///////////////////////////////////////////////////////////////////////////////
61 namespace {
63 constexpr irlower::SyncOptions SNone = irlower::SyncOptions::None;
64 constexpr irlower::SyncOptions SSync = irlower::SyncOptions::Sync;
66 constexpr DestType DSSA = DestType::SSA;
67 constexpr DestType DNone = DestType::None;
69 template<class EDType, class MemberType>
70 Arg extra(MemberType EDType::*ptr) {
71 auto fun = [ptr] (const IRInstruction* inst) {
72 auto const extra = inst->extra<EDType>();
73 return Type::cns(extra->*ptr).rawVal();
75 return Arg(fun);
78 Arg immed(intptr_t imm) { return Arg(ArgType::Imm, imm); }
80 auto constexpr SSA = ArgType::SSA;
81 auto constexpr TV = ArgType::TV;
83 using IFaceSupportFn = bool (*)(const StringData*);
85 using StrCmpFn = bool (*)(const StringData*, const StringData*);
86 using ObjCmpFn = bool (*)(const ObjectData*, const ObjectData*);
87 using ResCmpFn = bool (*)(const ResourceHdr*, const ResourceHdr*);
88 using StrIntCmpFn = bool (*)(const StringData*, int64_t);
90 using StrCmpFnInt = int64_t (*)(const StringData*, const StringData*);
91 using ObjCmpFnInt = int64_t (*)(const ObjectData*, const ObjectData*);
92 using ResCmpFnInt = int64_t (*)(const ResourceHdr*, const ResourceHdr*);
93 using StrIntCmpFnInt = int64_t (*)(const StringData*, int64_t);
97 //////////////////////////////////////////////////////////////////////
99 #ifdef MSVC_REQUIRE_AUTO_TEMPLATED_OVERLOAD
100 static auto c_AsyncFunctionWaitHandle_Create_true =
101 &c_AsyncFunctionWaitHandle::Create<true>;
102 static auto c_AsyncFunctionWaitHandle_Create_false =
103 &c_AsyncFunctionWaitHandle::Create<false>;
104 #endif
107 * The table passed to s_callMap's constructor describes helpers calls
108 * used by translated code. Each row consists of the following values:
110 * Opcode
111 * The opcode that uses the call
113 * Func
114 * A value describing the function to call:
115 * <function pointer> - Raw function pointer
116 * <pointer to member> - Dispatch to a C++ member function---the
117 * function must be non-virtual.
119 * Dest
120 * DSSA - The helper returns a single-register value
121 * DNone - The helper does not return a value
123 * SyncPoint
124 * SNone - The helper does not need a sync point
125 * SSync - The helper needs a normal sync point
126 * SSyncAdj1 - The helper needs a sync point that skips top of stack on unwind
128 * Args
129 * A list of tuples describing the arguments to pass to the helper
130 * {SSA, idx} - Pass the value in inst->src(idx)
131 * {TV, idx} - Pass the value in inst->src(idx) as a
132 * TypedValue, in two registers
133 * extra(&EDStruct::member) - extract an immediate from extra data
134 * immed(int64_t) - constant immediate
136 static CallMap s_callMap {
137 /* Opcode, Func, Dest, SyncPoint, Args */
138 {ConvBoolToArr, convCellToArrHelper, DSSA, SNone,
139 {{TV, 0}}},
140 {ConvDblToArr, convCellToArrHelper, DSSA, SNone,
141 {{TV, 0}}},
142 {ConvIntToArr, convCellToArrHelper, DSSA, SNone,
143 {{TV, 0}}},
144 {ConvObjToArr, convCellToArrHelper, DSSA, SSync,
145 {{TV, 0}}},
146 {ConvStrToArr, convCellToArrHelper, DSSA, SNone,
147 {{TV, 0}}},
148 {ConvFuncToArr, convCellToArrHelper, DSSA, SNone,
149 {{TV, 0}}},
150 {ConvVecToArr, convVecToArrHelper, DSSA, SNone,
151 {{SSA, 0}}},
152 // These two need to sync because of Hack array compat notices
153 {ConvDictToArr, convDictToArrHelper, DSSA, SSync,
154 {{SSA, 0}}},
155 {ConvKeysetToArr, convKeysetToArrHelper, DSSA, SSync,
156 {{SSA, 0}}},
157 {ConvCellToArr, convCellToArrHelper, DSSA, SSync,
158 {{TV, 0}}},
159 {ConvArrToNonDVArr, convArrToNonDVArrHelper, DSSA, SSync,
160 {{SSA, 0}}},
161 // ConvClsMethTo##T to sync due to clsmeth conversion notices
162 {ConvClsMethToArr, convClsMethToArrHealper, DSSA, SSync,
163 {{SSA, 0}}},
164 {ConvClsMethToVArr, convClsMethToVArrHealper, DSSA, SSync,
165 {{SSA, 0}}},
166 {ConvClsMethToDArr, convClsMethToDArrHealper, DSSA, SSync,
167 {{SSA, 0}}},
169 {ConvArrToVec, convArrToVecHelper, DSSA, SSync,
170 {{SSA, 0}}},
171 {ConvDictToVec, convDictToVecHelper, DSSA, SSync,
172 {{SSA, 0}}},
173 {ConvKeysetToVec, convKeysetToVecHelper, DSSA, SSync,
174 {{SSA, 0}}},
175 {ConvClsMethToVec, convClsMethToVecHealper, DSSA, SSync,
176 {{SSA, 0}}},
177 {ConvObjToVec, convObjToVecHelper, DSSA, SSync,
178 {{SSA, 0}}},
180 {ConvArrToDict, convArrToDictHelper, DSSA, SSync,
181 {{SSA, 0}}},
182 {ConvVecToDict, convVecToDictHelper, DSSA, SSync,
183 {{SSA, 0}}},
184 {ConvKeysetToDict, convKeysetToDictHelper, DSSA, SSync,
185 {{SSA, 0}}},
186 {ConvClsMethToDict, convClsMethToDictHealper, DSSA, SSync,
187 {{SSA, 0}}},
188 {ConvObjToDict, convObjToDictHelper, DSSA, SSync,
189 {{SSA, 0}}},
191 {ConvArrToKeyset, convArrToKeysetHelper, DSSA, SSync,
192 {{SSA, 0}}},
193 {ConvVecToKeyset, convVecToKeysetHelper, DSSA, SSync,
194 {{SSA, 0}}},
195 {ConvDictToKeyset, convDictToKeysetHelper, DSSA, SSync,
196 {{SSA, 0}}},
197 {ConvClsMethToKeyset, convClsMethToKeysetHealper, DSSA, SSync,
198 {{SSA, 0}}},
199 {ConvObjToKeyset, convObjToKeysetHelper, DSSA, SSync,
200 {{SSA, 0}}},
202 {ConvCellToBool, cellToBool, DSSA, SSync,
203 {{TV, 0}}},
205 {ConvArrToDbl, convArrToDblHelper, DSSA, SNone,
206 {{SSA, 0}}},
207 {ConvObjToDbl, convObjToDblHelper, DSSA, SSync,
208 {{SSA, 0}}},
209 {ConvStrToDbl, convStrToDblHelper, DSSA, SSync,
210 {{SSA, 0}}},
211 {ConvResToDbl, convResToDblHelper, DSSA, SNone,
212 {{SSA, 0}}},
213 {ConvCellToDbl, convCellToDblHelper, DSSA, SSync,
214 {{TV, 0}}},
216 {ConvObjToInt, &ObjectData::toInt64, DSSA, SSync,
217 {{SSA, 0}}},
218 {ConvStrToInt, &StringData::toInt64, DSSA, SNone,
219 {{SSA, 0}, immed(10)}},
220 {ConvResToInt, &ResourceHdr::getId, DSSA, SNone,
221 {{SSA, 0}}},
222 {ConvCellToInt, cellToInt, DSSA, SSync,
223 {{TV, 0}}},
225 {ConvDblToStr, convDblToStrHelper, DSSA, SNone,
226 {{SSA, 0}}},
227 {ConvIntToStr, convIntToStrHelper, DSSA, SNone,
228 {{SSA, 0}}},
229 {ConvObjToStr, convObjToStrHelper, DSSA, SSync,
230 {{SSA, 0}}},
231 {ConvResToStr, convResToStrHelper, DSSA, SSync,
232 {{SSA, 0}}},
233 {ConvCellToStr, cellCastToStringData, DSSA, SSync,
234 {{TV, 0}}},
236 {ConcatStrStr, concat_ss, DSSA, SSync, {{SSA, 0}, {SSA, 1}}},
237 {ConcatStrInt, concat_si, DSSA, SSync, {{SSA, 0}, {SSA, 1}}},
238 {ConcatIntStr, concat_is, DSSA, SSync, {{SSA, 0}, {SSA, 1}}},
239 {ConcatStr3, concat_s3, DSSA, SSync,
240 {{SSA, 0}, {SSA, 1}, {SSA, 2}}},
241 {ConcatStr4, concat_s4, DSSA, SSync,
242 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}},
244 {AddElemIntKey, addElemIntKeyHelper, DSSA, SSync,
245 {{SSA, 0}, {SSA, 1}, {TV, 2}}},
246 {AddNewElem, addNewElemHelper, DSSA, SSync,
247 {{SSA, 0}, {TV, 1}}},
248 {DictAddElemStrKey, dictAddElemStringKeyHelper, DSSA, SSync,
249 {{SSA, 0}, {SSA, 1}, {TV, 2}}},
250 {DictAddElemIntKey, dictAddElemIntKeyHelper, DSSA, SSync,
251 {{SSA, 0}, {SSA, 1}, {TV, 2}}},
253 {ArrayAdd, arrayAdd, DSSA, SSync, {{SSA, 0}, {SSA, 1}}},
254 {Clone, &ObjectData::clone, DSSA, SSync, {{SSA, 0}}},
255 {NewPair, collections::allocPair, DSSA, SNone,
256 {{TV, 0}, {TV, 1}}},
257 {FuncCred, &FunctionCredential::newInstance, DSSA, SNone,
258 {{SSA, 0}}},
259 {AllocObj, ObjectData::newInstance<true>, DSSA, SSync,
260 {{SSA, 0}}},
261 {AllocObjReified, ObjectData::newInstanceReified<true>, DSSA, SSync,
262 {{SSA, 0}, {SSA, 1}}},
263 {InitProps, &Class::initProps, DNone, SSync,
264 {{extra(&ClassData::cls)}}},
265 {InitSProps, &Class::initSProps, DNone, SSync,
266 {{extra(&ClassData::cls)}}},
267 {DebugBacktrace, debug_backtrace_jit, DSSA, SSync, {{SSA, 0}}},
268 {DebugBacktraceFast, debug_backtrace_fast, DSSA, SSync, {}},
269 {InitThrowableFileAndLine,
270 throwable_init_file_and_line_from_builtin,
271 DNone, debug ? SSync : SNone, {{SSA, 0}}},
272 {LdClsCtor, loadClassCtor, DSSA, SSync,
273 {{SSA, 0}, {SSA, 1}}},
274 {LookupClsMethod, lookupClsMethodHelper, DSSA, SSync,
275 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}},
276 {LookupClsRDS, lookupClsRDS, DSSA, SNone, {{SSA, 0}}},
277 {PrintStr, print_string, DNone, SSync, {{SSA, 0}}},
278 {PrintInt, print_int, DNone, SSync, {{SSA, 0}}},
279 {PrintBool, print_boolean, DNone, SSync, {{SSA, 0}}},
280 {VerifyParamCls, VerifyParamTypeSlow, DNone, SSync,
281 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}},
282 {VerifyParamRecDesc, VerifyParamRecDescImpl, DNone, SSync,
283 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}},
284 {VerifyParamCallable, VerifyParamTypeCallable, DNone, SSync,
285 {{TV, 0}, {SSA, 1}}},
286 {VerifyParamFail, VerifyParamTypeFail, DNone, SSync, {{SSA, 0}}},
287 {VerifyParamFailHard,VerifyParamTypeFail, DNone, SSync, {{SSA, 0}}},
288 {VerifyRetCls, VerifyRetTypeSlow, DNone, SSync,
289 {extra(&ParamData::paramId), {SSA, 0}, {SSA, 1},
290 {SSA, 2}, {TV, 3}}},
291 {VerifyRetRecDesc, VerifyRetRecDescImpl, DNone, SSync,
292 {extra(&ParamData::paramId), {SSA, 0}, {SSA, 1},
293 {SSA, 2}, {TV, 3}}},
294 {VerifyRetCallable, VerifyRetTypeCallable, DNone, SSync,
295 {extra(&ParamData::paramId), {TV, 0}}},
296 {VerifyRetFail, VerifyRetTypeFail, DNone, SSync,
297 {extra(&ParamData::paramId), {SSA, 0}}},
298 {VerifyRetFailHard, VerifyRetTypeFail, DNone, SSync,
299 {extra(&ParamData::paramId), {SSA, 0}}},
300 {RaiseUninitLoc, raiseUndefVariable, DNone, SSync, {{SSA, 0}}},
301 {RaiseError, raise_error_sd, DNone, SSync, {{SSA, 0}}},
302 {RaiseWarning, raiseWarning, DNone, SSync, {{SSA, 0}}},
303 {RaiseNotice, raiseNotice, DNone, SSync, {{SSA, 0}}},
304 {ThrowArrayIndexException,
305 throwArrayIndexException, DNone, SSync,
306 {{SSA, 0},
307 extra(&ThrowArrayIndexExceptionData::isInOut)}},
308 {ThrowArrayKeyException,
309 throwArrayKeyException, DNone, SSync,
310 {{SSA, 0},
311 extra(&ThrowArrayKeyExceptionData::isInOut)}},
312 {RaiseUndefProp, raiseUndefProp, DNone, SSync,
313 {{SSA, 0}, {SSA, 1}}},
314 {RaiseTooManyArg, raiseTooManyArgumentsPrologue, DNone, SSync,
315 {extra(&FuncData::func), {SSA, 0}}},
316 {RaiseRxCallViolation, raiseRxCallViolation,
317 DNone, SSync, {{SSA, 0}, {SSA, 1}}},
318 {ThrowInvalidOperation, throw_invalid_operation_exception,
319 DNone, SSync, {{SSA, 0}}},
320 {ThrowArithmeticError, throw_arithmetic_error,
321 DNone, SSync, {{SSA, 0}}},
322 {ThrowCallReifiedFunctionWithoutGenerics,
323 throw_call_reified_func_without_generics,
324 DNone, SSync, {{SSA, 0}}},
325 {ThrowDivisionByZeroError, throw_division_by_zero_error,
326 DNone, SSync, {{SSA, 0}}},
327 {ThrowDivisionByZeroException, throw_division_by_zero_exception,
328 DNone, SSync, {}},
329 {ThrowHasThisNeedStatic, throw_has_this_need_static,
330 DNone, SSync, {{SSA, 0}}},
331 {ThrowMissingArg, throwMissingArgument, DNone, SSync,
332 {extra(&FuncArgData::func),
333 extra(&FuncArgData::argNum)}},
334 {ThrowMissingThis, throw_missing_this,
335 DNone, SSync, {{SSA, 0}}},
336 {ThrowParameterWrongType, throw_parameter_wrong_type, DNone, SSync,
337 {{TV, 0},
338 extra(&FuncArgTypeData::func),
339 extra(&FuncArgTypeData::argNum),
340 extra(&FuncArgTypeData::type)}},
341 {ThrowParamInOutMismatch, throwParamInOutMismatch, DNone, SSync,
342 {{SSA, 0}, extra(&ParamData::paramId)}},
343 {ThrowParamInOutMismatchRange, throwParamInOutMismatchRange, DNone, SSync,
344 {{SSA, 0},
345 extra(&CheckInOutsData::firstBit),
346 extra(&CheckInOutsData::mask),
347 extra(&CheckInOutsData::vals)}},
348 {HasToString, &ObjectData::hasToString, DSSA, SSync,
349 {{SSA, 0}}},
351 /* Type specialized comparison operators */
352 {GtStr, static_cast<StrCmpFn>(more), DSSA, SSync,
353 {{SSA, 0}, {SSA, 1}}},
354 {GteStr, static_cast<StrCmpFn>(moreEqual), DSSA, SSync,
355 {{SSA, 0}, {SSA, 1}}},
356 {LtStr, static_cast<StrCmpFn>(less), DSSA, SSync,
357 {{SSA, 0}, {SSA, 1}}},
358 {LteStr, static_cast<StrCmpFn>(lessEqual), DSSA, SSync,
359 {{SSA, 0}, {SSA, 1}}},
360 {EqStr, static_cast<StrCmpFn>(equal), DSSA, SSync,
361 {{SSA, 0}, {SSA, 1}}},
362 {NeqStr, static_cast<StrCmpFn>(nequal), DSSA, SSync,
363 {{SSA, 0}, {SSA, 1}}},
364 {SameStr, static_cast<StrCmpFn>(same), DSSA, SSync,
365 {{SSA, 0}, {SSA, 1}}},
366 {NSameStr, static_cast<StrCmpFn>(nsame), DSSA, SSync,
367 {{SSA, 0}, {SSA, 1}}},
368 {CmpStr, static_cast<StrCmpFnInt>(compare), DSSA, SSync,
369 {{SSA, 0}, {SSA, 1}}},
370 {GtStrInt, static_cast<StrIntCmpFn>(more), DSSA, SSync,
371 {{SSA, 0}, {SSA, 1}}},
372 {GteStrInt, static_cast<StrIntCmpFn>(moreEqual), DSSA, SSync,
373 {{SSA, 0}, {SSA, 1}}},
374 {LtStrInt, static_cast<StrIntCmpFn>(less), DSSA, SSync,
375 {{SSA, 0}, {SSA, 1}}},
376 {LteStrInt, static_cast<StrIntCmpFn>(lessEqual), DSSA, SSync,
377 {{SSA, 0}, {SSA, 1}}},
378 {EqStrInt, static_cast<StrIntCmpFn>(equal), DSSA, SSync,
379 {{SSA, 0}, {SSA, 1}}},
380 {NeqStrInt, static_cast<StrIntCmpFn>(nequal), DSSA, SSync,
381 {{SSA, 0}, {SSA, 1}}},
382 {CmpStrInt, static_cast<StrIntCmpFnInt>(compare), DSSA, SSync,
383 {{SSA, 0}, {SSA, 1}}},
384 {GtObj, static_cast<ObjCmpFn>(more), DSSA, SSync,
385 {{SSA, 0}, {SSA, 1}}},
386 {GteObj, static_cast<ObjCmpFn>(moreEqual), DSSA, SSync,
387 {{SSA, 0}, {SSA, 1}}},
388 {LtObj, static_cast<ObjCmpFn>(less), DSSA, SSync,
389 {{SSA, 0}, {SSA, 1}}},
390 {LteObj, static_cast<ObjCmpFn>(lessEqual), DSSA, SSync,
391 {{SSA, 0}, {SSA, 1}}},
392 {EqObj, static_cast<ObjCmpFn>(equal), DSSA, SSync,
393 {{SSA, 0}, {SSA, 1}}},
394 {NeqObj, static_cast<ObjCmpFn>(nequal), DSSA, SSync,
395 {{SSA, 0}, {SSA, 1}}},
396 {CmpObj, static_cast<ObjCmpFnInt>(compare), DSSA, SSync,
397 {{SSA, 0}, {SSA, 1}}},
398 {GtArr, ArrayData::Gt, DSSA, SSync,
399 {{SSA, 0}, {SSA, 1}}},
400 {GteArr, ArrayData::Gte, DSSA, SSync,
401 {{SSA, 0}, {SSA, 1}}},
402 {LtArr, ArrayData::Lt, DSSA, SSync,
403 {{SSA, 0}, {SSA, 1}}},
404 {LteArr, ArrayData::Lte, DSSA, SSync,
405 {{SSA, 0}, {SSA, 1}}},
406 {EqArr, ArrayData::Equal, DSSA, SSync,
407 {{SSA, 0}, {SSA, 1}}},
408 {NeqArr, ArrayData::NotEqual, DSSA, SSync,
409 {{SSA, 0}, {SSA, 1}}},
410 {SameArr, ArrayData::Same, DSSA, SSync,
411 {{SSA, 0}, {SSA, 1}}},
412 {NSameArr, ArrayData::NotSame, DSSA, SSync,
413 {{SSA, 0}, {SSA, 1}}},
414 {CmpArr, ArrayData::Compare, DSSA, SSync,
415 {{SSA, 0}, {SSA, 1}}},
416 {GtVec, PackedArray::VecGt, DSSA, SSync,
417 {{SSA, 0}, {SSA, 1}}},
418 {GteVec, PackedArray::VecGte, DSSA, SSync,
419 {{SSA, 0}, {SSA, 1}}},
420 {LtVec, PackedArray::VecLt, DSSA, SSync,
421 {{SSA, 0}, {SSA, 1}}},
422 {LteVec, PackedArray::VecLte, DSSA, SSync,
423 {{SSA, 0}, {SSA, 1}}},
424 {EqVec, PackedArray::VecEqual, DSSA, SSync,
425 {{SSA, 0}, {SSA, 1}}},
426 {NeqVec, PackedArray::VecNotEqual, DSSA, SSync,
427 {{SSA, 0}, {SSA, 1}}},
428 {SameVec, PackedArray::VecSame, DSSA, SSync,
429 {{SSA, 0}, {SSA, 1}}},
430 {NSameVec, PackedArray::VecNotSame, DSSA, SSync,
431 {{SSA, 0}, {SSA, 1}}},
432 {CmpVec, PackedArray::VecCmp, DSSA, SSync,
433 {{SSA, 0}, {SSA, 1}}},
434 {EqDict, MixedArray::DictEqual, DSSA, SSync,
435 {{SSA, 0}, {SSA, 1}}},
436 {NeqDict, MixedArray::DictNotEqual, DSSA, SSync,
437 {{SSA, 0}, {SSA, 1}}},
438 {SameDict, MixedArray::DictSame, DSSA, SSync,
439 {{SSA, 0}, {SSA, 1}}},
440 {NSameDict, MixedArray::DictNotSame, DSSA, SSync,
441 {{SSA, 0}, {SSA, 1}}},
442 {EqKeyset, SetArray::Equal, DSSA, SSync,
443 {{SSA, 0}, {SSA, 1}}},
444 {NeqKeyset, SetArray::NotEqual, DSSA, SSync,
445 {{SSA, 0}, {SSA, 1}}},
446 {SameKeyset, SetArray::Same, DSSA, SSync,
447 {{SSA, 0}, {SSA, 1}}},
448 {NSameKeyset, SetArray::NotSame, DSSA, SSync,
449 {{SSA, 0}, {SSA, 1}}},
450 {GtRes, static_cast<ResCmpFn>(more), DSSA, SSync,
451 {{SSA, 0}, {SSA, 1}}},
452 {GteRes, static_cast<ResCmpFn>(moreEqual), DSSA, SSync,
453 {{SSA, 0}, {SSA, 1}}},
454 {LtRes, static_cast<ResCmpFn>(less), DSSA, SSync,
455 {{SSA, 0}, {SSA, 1}}},
456 {LteRes, static_cast<ResCmpFn>(lessEqual), DSSA, SSync,
457 {{SSA, 0}, {SSA, 1}}},
458 {CmpRes, static_cast<ResCmpFnInt>(compare), DSSA, SSync,
459 {{SSA, 0}, {SSA, 1}}},
461 /* Static prop helpers */
462 {LdClsPropAddrOrNull,
463 getSPropOrNull, DSSA, SSync,
464 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}, {SSA, 4}}},
465 {LdClsPropAddrOrRaise,
466 getSPropOrRaise, DSSA, SSync,
467 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}, {SSA, 4}}},
469 {ProfileProp, &PropertyProfile::incCount, DNone, SNone,
470 {{SSA, 0}, {SSA, 1}}},
472 /* Global helpers */
473 {LdGblAddrDef, ldGblAddrDefHelper, DSSA, SNone,
474 {{SSA, 0}}},
476 /* Switch helpers */
477 {LdSwitchDblIndex, switchDoubleHelper, DSSA, SSync,
478 {{SSA, 0}, {SSA, 1}, {SSA, 2}}},
479 {LdSwitchStrIndex, switchStringHelper, DSSA, SSync,
480 {{SSA, 0}, {SSA, 1}, {SSA, 2}}},
481 {LdSwitchObjIndex, switchObjHelper, DSSA, SSync,
482 {{SSA, 0}, {SSA, 1}, {SSA, 2}}},
484 /* Generator support helpers */
485 {CreateGen, &Generator::Create, DSSA, SNone,
486 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}},
488 /* Async generator support helpers */
489 {CreateAGen, &AsyncGenerator::Create, DSSA, SNone,
490 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}},
492 /* Async function support helpers */
493 #ifdef MSVC_REQUIRE_AUTO_TEMPLATED_OVERLOAD
494 {CreateAFWH, c_AsyncFunctionWaitHandle_Create_true, DSSA, SNone,
495 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}, {SSA, 4}}},
496 {CreateAFWHNoVV, c_AsyncFunctionWaitHandle_Create_false, DSSA, SNone,
497 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}, {SSA, 4}}},
498 #else
499 {CreateAFWH, &c_AsyncFunctionWaitHandle::Create<true>, DSSA, SNone,
500 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}, {SSA, 4}}},
501 {CreateAFWHNoVV, &c_AsyncFunctionWaitHandle::Create<false>, DSSA, SNone,
502 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}, {SSA, 4}}},
503 #endif
504 {CreateAGWH, &c_AsyncGeneratorWaitHandle::Create, DSSA, SNone,
505 {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}},
506 {CreateSSWH, &c_StaticWaitHandle::CreateSucceeded, DSSA, SNone,
507 {{TV, 0}}},
508 {AFWHPrepareChild, &c_AsyncFunctionWaitHandle::PrepareChild, DSSA, SSync,
509 {{SSA, 0}, {SSA, 1}}},
511 /* MInstrTranslator helpers */
512 {SetNewElemArray, MInstrHelpers::setNewElemArray, DNone, SSync,
513 {{SSA, 0}, {TV, 1}}},
514 {StringGet, MInstrHelpers::stringGetI, DSSA, SSync, {{SSA, 0}, {SSA, 1}}},
516 {PairIsset, MInstrHelpers::pairIsset, DSSA, SSync, {{SSA, 0}, {SSA, 1}}},
517 {VectorIsset, MInstrHelpers::vectorIsset, DSSA, SSync,
518 {{SSA, 0}, {SSA, 1}}},
519 {ElemVecU, MInstrHelpers::elemVecIU, DSSA, SSync, {{SSA, 0}, {SSA, 1}}},
520 {ThrowOutOfBounds, throwOOBException, DNone, SSync, {{TV, 0}, {TV, 1}}},
521 {ThrowInvalidArrayKey, invalidArrayKeyHelper, DNone, SSync,
522 {{SSA, 0}, {TV, 1}}},
524 /* instanceof checks */
525 {ProfileInstanceCheck, &InstanceBits::profile, DNone, SNone, {{SSA, 0}}},
526 {InstanceOfIface, &Class::ifaceofDirect, DSSA,
527 SNone, {{SSA, 0}, {SSA, 1}}},
528 {InterfaceSupportsArr, IFaceSupportFn{interface_supports_array},
529 DSSA, SNone, {{SSA, 0}}},
530 {InterfaceSupportsVec, IFaceSupportFn{interface_supports_vec},
531 DSSA, SNone, {{SSA, 0}}},
532 {InterfaceSupportsDict, IFaceSupportFn{interface_supports_dict},
533 DSSA, SNone, {{SSA, 0}}},
534 {InterfaceSupportsKeyset, IFaceSupportFn{interface_supports_keyset},
535 DSSA, SNone, {{SSA, 0}}},
536 {InterfaceSupportsStr, IFaceSupportFn{interface_supports_string},
537 DSSA, SNone, {{SSA, 0}}},
538 {InterfaceSupportsInt, IFaceSupportFn{interface_supports_int},
539 DSSA, SNone, {{SSA, 0}}},
540 {InterfaceSupportsDbl, IFaceSupportFn{interface_supports_double},
541 DSSA, SNone, {{SSA, 0}}},
542 {OODeclExists, &Unit::classExists, DSSA, SSync,
543 {{SSA, 0}, {SSA, 1}, extra(&ClassKindData::kind)}},
545 /* is/as expressions */
546 {IsTypeStruct, isTypeStructHelper, DSSA, SSync, {{SSA, 0}, {TV, 1}}},
547 {ThrowAsTypeStructException, throwAsTypeStructExceptionHelper, DNone, SSync,
548 {{SSA, 0}, {TV, 1}}},
550 /* surprise flag support */
551 {SuspendHookAwaitEF, &EventHook::onFunctionSuspendAwaitEF, DNone,
552 SSync, {{SSA, 0}, {SSA, 1}}},
553 {SuspendHookAwaitEG, &EventHook::onFunctionSuspendAwaitEG, DNone,
554 SSync, {{SSA, 0}}},
555 {SuspendHookAwaitR, &EventHook::onFunctionSuspendAwaitR, DNone,
556 SSync, {{SSA, 0}, {SSA, 1}}},
557 {SuspendHookCreateCont, &EventHook::onFunctionSuspendCreateCont, DNone,
558 SSync, {{SSA, 0}, {SSA, 1}}},
559 {SuspendHookYield, &EventHook::onFunctionSuspendYield, DNone,
560 SSync, {{SSA, 0}}},
561 {ReturnHook, &EventHook::onFunctionReturn, DNone,
562 SSync, {{SSA, 0}, {TV, 1}}},
564 /* silence operator support */
565 {ZeroErrorLevel, &zero_error_level, DSSA, SNone, {}},
566 {RestoreErrorLevel, &restore_error_level, DNone, SNone, {{SSA, 0}}},
568 /* count($mixed) */
569 {Count, &countHelper, DSSA, SSync, {{TV, 0}}},
571 /* method_exists($obj, $meth) */
572 {MethodExists, methodExistsHelper, DSSA, SNone, {{SSA, 0}, {SSA, 1}}},
574 /* microtime(true) */
575 {GetTime, TimeStamp::CurrentSecond, DSSA, SNone, {}},
576 /* clock_gettime_ns($clk_id) */
577 {GetTimeNs, folly::chrono::clock_gettime_ns, DSSA, SNone, {{SSA, 0}}},
579 /* reified generics operations */
580 {CheckClsReifiedGenericMismatch, checkClassReifiedGenericMismatch,
581 DNone, SSync,
582 {{extra(&ClassData::cls)}, {SSA, 0}}},
583 {CheckFunReifiedGenericMismatch, checkFunReifiedGenericMismatch,
584 DNone, SSync,
585 {{extra(&FuncData::func)}, {SSA, 0}}},
586 {VerifyReifiedLocalType, VerifyReifiedLocalTypeImpl, DNone, SSync,
587 {{extra(&ParamData::paramId)}, {SSA, 0}}},
588 {VerifyReifiedReturnType, VerifyReifiedReturnTypeImpl, DNone, SSync,
589 {{TV, 0}, {SSA, 1}}},
590 {RecordReifiedGenericsAndGetTSList, recordReifiedGenericsAndGetTSList,
591 DSSA, SSync, {{SSA, 0}}},
592 {RaiseErrorOnInvalidIsAsExpressionType,
593 errorOnIsAsExpressionInvalidTypesHelper, DSSA, SSync, {{SSA, 0}}},
596 CallMap::CallMap(CallInfoList infos) {
597 for (auto const& info : infos) {
598 m_map[info.op] = info;
602 bool CallMap::hasInfo(Opcode op) {
603 return s_callMap.m_map.count(op) != 0;
606 const CallInfo& CallMap::info(Opcode op) {
607 auto it = s_callMap.m_map.find(op);
608 assertx(it != s_callMap.m_map.end());
609 return it->second;
612 ///////////////////////////////////////////////////////////////////////////////
614 } // NativeCalls
616 ///////////////////////////////////////////////////////////////////////////////
618 using namespace NativeCalls;
619 ArgGroup toArgGroup(const CallInfo& info,
620 const StateVector<SSATmp,Vloc>& locs,
621 const IRInstruction* inst) {
622 ArgGroup argGroup{inst, locs};
623 for (auto const& arg : info.args) {
624 switch (arg.type) {
625 case ArgType::SSA:
626 argGroup.ssa(arg.ival);
627 break;
628 case ArgType::TV:
629 argGroup.typedValue(arg.ival);
630 break;
631 case ArgType::ExtraImm:
632 argGroup.imm(arg.extraFunc(inst));
633 break;
634 case ArgType::Imm:
635 argGroup.imm(arg.ival);
636 break;
639 return argGroup;
642 ///////////////////////////////////////////////////////////////////////////////