2 +----------------------------------------------------------------------+
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 ///////////////////////////////////////////////////////////////////////////////
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();
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>;
107 * The table passed to s_callMap's constructor describes helpers calls
108 * used by translated code. Each row consists of the following values:
111 * The opcode that uses the call
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.
120 * DSSA - The helper returns a single-register value
121 * DNone - The helper does not return a value
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
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
,
140 {ConvDblToArr
, convCellToArrHelper
, DSSA
, SNone
,
142 {ConvIntToArr
, convCellToArrHelper
, DSSA
, SNone
,
144 {ConvObjToArr
, convCellToArrHelper
, DSSA
, SSync
,
146 {ConvStrToArr
, convCellToArrHelper
, DSSA
, SNone
,
148 {ConvFuncToArr
, convCellToArrHelper
, DSSA
, SNone
,
150 {ConvVecToArr
, convVecToArrHelper
, DSSA
, SNone
,
152 // These two need to sync because of Hack array compat notices
153 {ConvDictToArr
, convDictToArrHelper
, DSSA
, SSync
,
155 {ConvKeysetToArr
, convKeysetToArrHelper
, DSSA
, SSync
,
157 {ConvCellToArr
, convCellToArrHelper
, DSSA
, SSync
,
159 {ConvArrToNonDVArr
, convArrToNonDVArrHelper
, DSSA
, SSync
,
161 // ConvClsMethTo##T to sync due to clsmeth conversion notices
162 {ConvClsMethToArr
, convClsMethToArrHealper
, DSSA
, SSync
,
164 {ConvClsMethToVArr
, convClsMethToVArrHealper
, DSSA
, SSync
,
166 {ConvClsMethToDArr
, convClsMethToDArrHealper
, DSSA
, SSync
,
169 {ConvArrToVec
, convArrToVecHelper
, DSSA
, SSync
,
171 {ConvDictToVec
, convDictToVecHelper
, DSSA
, SSync
,
173 {ConvKeysetToVec
, convKeysetToVecHelper
, DSSA
, SSync
,
175 {ConvClsMethToVec
, convClsMethToVecHealper
, DSSA
, SSync
,
177 {ConvObjToVec
, convObjToVecHelper
, DSSA
, SSync
,
180 {ConvArrToDict
, convArrToDictHelper
, DSSA
, SSync
,
182 {ConvVecToDict
, convVecToDictHelper
, DSSA
, SSync
,
184 {ConvKeysetToDict
, convKeysetToDictHelper
, DSSA
, SSync
,
186 {ConvClsMethToDict
, convClsMethToDictHealper
, DSSA
, SSync
,
188 {ConvObjToDict
, convObjToDictHelper
, DSSA
, SSync
,
191 {ConvArrToKeyset
, convArrToKeysetHelper
, DSSA
, SSync
,
193 {ConvVecToKeyset
, convVecToKeysetHelper
, DSSA
, SSync
,
195 {ConvDictToKeyset
, convDictToKeysetHelper
, DSSA
, SSync
,
197 {ConvClsMethToKeyset
, convClsMethToKeysetHealper
, DSSA
, SSync
,
199 {ConvObjToKeyset
, convObjToKeysetHelper
, DSSA
, SSync
,
202 {ConvCellToBool
, cellToBool
, DSSA
, SSync
,
205 {ConvArrToDbl
, convArrToDblHelper
, DSSA
, SNone
,
207 {ConvObjToDbl
, convObjToDblHelper
, DSSA
, SSync
,
209 {ConvStrToDbl
, convStrToDblHelper
, DSSA
, SSync
,
211 {ConvResToDbl
, convResToDblHelper
, DSSA
, SNone
,
213 {ConvCellToDbl
, convCellToDblHelper
, DSSA
, SSync
,
216 {ConvObjToInt
, &ObjectData::toInt64
, DSSA
, SSync
,
218 {ConvStrToInt
, &StringData::toInt64
, DSSA
, SNone
,
219 {{SSA
, 0}, immed(10)}},
220 {ConvResToInt
, &ResourceHdr::getId
, DSSA
, SNone
,
222 {ConvCellToInt
, cellToInt
, DSSA
, SSync
,
225 {ConvDblToStr
, convDblToStrHelper
, DSSA
, SNone
,
227 {ConvIntToStr
, convIntToStrHelper
, DSSA
, SNone
,
229 {ConvObjToStr
, convObjToStrHelper
, DSSA
, SSync
,
231 {ConvResToStr
, convResToStrHelper
, DSSA
, SSync
,
233 {ConvCellToStr
, cellCastToStringData
, DSSA
, SSync
,
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
,
257 {FuncCred
, &FunctionCredential::newInstance
, DSSA
, SNone
,
259 {AllocObj
, ObjectData::newInstance
<true>, DSSA
, SSync
,
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},
291 {VerifyRetRecDesc
, VerifyRetRecDescImpl
, DNone
, SSync
,
292 {extra(&ParamData::paramId
), {SSA
, 0}, {SSA
, 1},
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
,
307 extra(&ThrowArrayIndexExceptionData::isInOut
)}},
308 {ThrowArrayKeyException
,
309 throwArrayKeyException
, DNone
, SSync
,
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
,
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
,
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
,
345 extra(&CheckInOutsData::firstBit
),
346 extra(&CheckInOutsData::mask
),
347 extra(&CheckInOutsData::vals
)}},
348 {HasToString
, &ObjectData::hasToString
, DSSA
, SSync
,
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}}},
473 {LdGblAddrDef
, ldGblAddrDefHelper
, DSSA
, SNone
,
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}}},
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}}},
504 {CreateAGWH
, &c_AsyncGeneratorWaitHandle::Create
, DSSA
, SNone
,
505 {{SSA
, 0}, {SSA
, 1}, {SSA
, 2}, {SSA
, 3}}},
506 {CreateSSWH
, &c_StaticWaitHandle::CreateSucceeded
, DSSA
, SNone
,
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
,
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
,
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}}},
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
,
582 {{extra(&ClassData::cls
)}, {SSA
, 0}}},
583 {CheckFunReifiedGenericMismatch
, checkFunReifiedGenericMismatch
,
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());
612 ///////////////////////////////////////////////////////////////////////////////
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
) {
626 argGroup
.ssa(arg
.ival
);
629 argGroup
.typedValue(arg
.ival
);
631 case ArgType::ExtraImm
:
632 argGroup
.imm(arg
.extraFunc(inst
));
635 argGroup
.imm(arg
.ival
);
642 ///////////////////////////////////////////////////////////////////////////////