hphp/runtime/vm/jit/native-calls.cpp (407 lines of code) (raw):

/* +----------------------------------------------------------------------+ | HipHop for PHP | +----------------------------------------------------------------------+ | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ */ #include "hphp/runtime/vm/jit/native-calls.h" #include <folly/ClockGettimeWrappers.h> #include "hphp/runtime/base/comparisons.h" #include "hphp/runtime/base/exceptions.h" #include "hphp/runtime/base/rds.h" #include "hphp/runtime/base/stats.h" #include "hphp/runtime/base/timestamp.h" #include "hphp/runtime/base/tv-conversions.h" #include "hphp/runtime/base/vanilla-vec.h" #include "hphp/runtime/vm/class-meth-data-ref.h" #include "hphp/runtime/vm/property-profile.h" #include "hphp/runtime/vm/reified-generics.h" #include "hphp/runtime/vm/runtime.h" #include "hphp/runtime/vm/unit-util.h" #include "hphp/runtime/vm/jit/arg-group.h" #include "hphp/runtime/vm/jit/func-order.h" #include "hphp/runtime/vm/jit/ir-opcode.h" #include "hphp/runtime/vm/jit/irlower.h" #include "hphp/runtime/vm/jit/translator-runtime.h" #include "hphp/runtime/ext/array/ext_array.h" #include "hphp/runtime/ext/asio/asio-blockable.h" #include "hphp/runtime/ext/asio/ext_async-function-wait-handle.h" #include "hphp/runtime/ext/asio/ext_static-wait-handle.h" #include "hphp/runtime/ext/collections/ext_collections-pair.h" #include "hphp/runtime/ext/collections/ext_collections-vector.h" #include "hphp/runtime/ext/collections/ext_collections.h" #include "hphp/runtime/ext/functioncredential/ext_functioncredential.h" #include "hphp/runtime/ext/std/ext_std_errorfunc.h" #include "hphp/util/abi-cxx.h" #include "hphp/util/assertions.h" namespace HPHP::jit { /////////////////////////////////////////////////////////////////////////////// namespace NativeCalls { /////////////////////////////////////////////////////////////////////////////// namespace { constexpr irlower::SyncOptions SNone = irlower::SyncOptions::None; constexpr irlower::SyncOptions SSync = irlower::SyncOptions::Sync; constexpr DestType DSSA = DestType::SSA; constexpr DestType DTV = DestType::TV; constexpr DestType DNone = DestType::None; template<class EDType, class MemberType> Arg extra(MemberType EDType::*ptr) { auto fun = [ptr] (const IRInstruction* inst) { auto const extra = inst->extra<EDType>(); return Type::cns(extra->*ptr).rawVal(); }; return Arg(fun); } Arg immed(intptr_t imm) { return Arg(ArgType::Imm, imm); } auto constexpr SSA = ArgType::SSA; auto constexpr TV = ArgType::TV; using IFaceSupportFn = bool (*)(const StringData*); using StrCmpFn = bool (*)(const StringData*, const StringData*); using ObjCmpFn = bool (*)(const ObjectData*, const ObjectData*); using ResCmpFn = bool (*)(const ResourceHdr*, const ResourceHdr*); using StrCmpFnInt = int64_t (*)(const StringData*, const StringData*); using ObjCmpFnInt = int64_t (*)(const ObjectData*, const ObjectData*); using ResCmpFnInt = int64_t (*)(const ResourceHdr*, const ResourceHdr*); } ////////////////////////////////////////////////////////////////////// /* * The table passed to s_callMap's constructor describes helpers calls * used by translated code. Each row consists of the following values: * * Opcode * The opcode that uses the call * * Func * A value describing the function to call: * <function pointer> - Raw function pointer * <pointer to member> - Dispatch to a C++ member function---the * function must be non-virtual. * * Dest * DSSA - The helper returns a single-register value * DNone - The helper does not return a value * * SyncPoint * SNone - The helper does not need a sync point * SSync - The helper needs a normal sync point * SSyncAdj1 - The helper needs a sync point that skips top of stack on unwind * * Args * A list of tuples describing the arguments to pass to the helper * {SSA, idx} - Pass the value in inst->src(idx) * {TV, idx} - Pass the value in inst->src(idx) as a * TypedValue, in two registers * extra(&EDStruct::member) - extract an immediate from extra data * immed(int64_t) - constant immediate */ static CallMap s_callMap { /* Opcode, Func, Dest, SyncPoint, Args */ {ConvArrLikeToVec, convArrLikeToVecHelper, DSSA, SSync, {{SSA, 0}}}, {ConvObjToVec, convObjToVecHelper, DSSA, SSync, {{SSA, 0}}}, {ConvArrLikeToDict, convArrLikeToDictHelper, DSSA, SSync, {{SSA, 0}}}, {ConvObjToDict, convObjToDictHelper, DSSA, SSync, {{SSA, 0}}}, {ConvArrLikeToKeyset, convArrLikeToKeysetHelper, DSSA, SSync, {{SSA, 0}}}, {ConvObjToKeyset, convObjToKeysetHelper, DSSA, SSync, {{SSA, 0}}}, {ConvTVToBool, tvToBool, DSSA, SSync, {{TV, 0}}}, {ConvObjToDbl, convObjToDblHelper, DSSA, SSync, {{SSA, 0}}}, {ConvStrToDbl, convStrToDblHelper, DSSA, SNone, {{SSA, 0}}}, {ConvResToDbl, convResToDblHelper, DSSA, SNone, {{SSA, 0}}}, {ConvTVToDbl, convTVToDblHelper, DSSA, SSync, {{TV, 0}}}, {ConvObjToInt, &ObjectData::toInt64, DSSA, SSync, {{SSA, 0}}}, {ConvStrToInt, &StringData::toInt64, DSSA, SNone, {{SSA, 0}, immed(10)}}, {ConvResToInt, &ResourceHdr::getId, DSSA, SNone, {{SSA, 0}}}, {ConvTVToInt, tvToInt, DSSA, SSync, {{TV, 0}}}, {ConvDblToStr, convDblToStrHelper, DSSA, SNone, {{SSA, 0}}}, {ConvIntToStr, convIntToStrHelper, DSSA, SNone, {{SSA, 0}}}, {ConvObjToStr, convObjToStrHelper, DSSA, SSync, {{SSA, 0}}}, {ConvTVToStr, static_cast<StringData* (*)( TypedValue, const ConvNoticeLevel, const StringData*)>(tvCastToStringData), DSSA, SSync, {{TV, 0}, extra(&ConvNoticeData::level), extra(&ConvNoticeData::reasonIntVal)}}, {ConcatStrStr, concat_ss, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {ConcatStrInt, concat_si, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {ConcatIntStr, concat_is, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {ConcatStr3, concat_s3, DSSA, SSync, {{SSA, 0}, {SSA, 1}, {SSA, 2}}}, {ConcatStr4, concat_s4, DSSA, SSync, {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}}, {Clone, &ObjectData::clone, DSSA, SSync, {{SSA, 0}}}, {NewRFunc, RFuncData::newInstance, DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {NewRClsMeth, RClsMethData::create, DSSA, SNone, {{SSA, 0}, {SSA, 1}, {SSA, 2}}}, {NewPair, collections::allocPair, DSSA, SNone, {{TV, 0}, {TV, 1}}}, {FuncCred, &FunctionCredential::newInstance, DSSA, SNone, {{SSA, 0}}}, {AllocObj, ObjectData::newInstance<true>, DSSA, SSync, {{SSA, 0}}}, {AllocObjReified, ObjectData::newInstanceReified<true>, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {InitProps, &Class::initProps, DNone, SSync, {{extra(&ClassData::cls)}}}, {InitSProps, &Class::initSProps, DNone, SSync, {{extra(&ClassData::cls)}}}, {DebugBacktrace, debug_backtrace_jit, DSSA, SSync, {{SSA, 0}}}, {InitThrowableFileAndLine, throwable_init_file_and_line_from_builtin, DNone, debug ? SSync : SNone, {{SSA, 0}}}, {LdClsCtor, loadClassCtor, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {LookupClsMethod, lookupClsMethodHelper, DSSA, SSync, {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}}, {LookupClsCns, lookupClsCns, DTV, SSync, {{SSA, 0}, {SSA, 1}}}, {LookupClsCtxCns, lookupClsCtxCns, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {PrintStr, print_string, DNone, SSync, {{SSA, 0}}}, {PrintInt, print_int, DNone, SSync, {{SSA, 0}}}, {PrintBool, print_boolean, DNone, SSync, {{SSA, 0}}}, {VerifyParamCls, VerifyParamTypeSlow, DNone, SSync, {{SSA, 0}, {SSA, 2}, extra(&FuncParamWithTCData::func), extra(&FuncParamWithTCData::paramId), extra(&FuncParamWithTCData::tcAsInt)}}, {VerifyParamCallable, VerifyParamTypeCallable, DNone, SSync, {{TV, 0}, extra(&FuncParamData::func), extra(&FuncParamData::paramId)}}, {VerifyRetCls, VerifyRetTypeSlow, DNone, SSync, {{SSA, 0}, {SSA, 2}, extra(&FuncParamWithTCData::func), extra(&FuncParamWithTCData::paramId), extra(&FuncParamWithTCData::tcAsInt)}}, {VerifyRetCallable, VerifyRetTypeCallable, DNone, SSync, {{TV, 0}, extra(&FuncParamData::func), extra(&FuncParamData::paramId)}}, {ThrowUninitLoc, throwUndefVariable, DNone, SSync, {{SSA, 0}}}, {RaiseError, raise_error_sd, DNone, SSync, {{SSA, 0}}}, {RaiseWarning, raiseWarning, DNone, SSync, {{SSA, 0}}}, {RaiseNotice, raiseNotice, DNone, SSync, {{SSA, 0}}}, {ThrowCannotModifyReadonlyCollection, throw_cannot_modify_readonly_collection, DNone, SSync, {}}, {ThrowMustBeEnclosedInReadonly, throwMustBeEnclosedInReadonlyException, DNone, SSync, {extra(&ClassData::cls), {SSA, 0}}}, {ThrowMustBeReadonlyException, throwMustBeReadonlyException, DNone, SSync, {extra(&ClassData::cls), {SSA, 0}}}, {ThrowMustBeMutableException, throwMustBeMutableException, DNone, SSync, {extra(&ClassData::cls), {SSA, 0}}}, {ThrowMustBeValueTypeException, throwMustBeValueTypeException, DNone, SSync, {extra(&ClassData::cls), {SSA, 0}}}, {ThrowLocalMustBeValueTypeException, throwOrWarnLocalMustBeValueTypeException, DNone, SSync, {{SSA, 0}}}, {ThrowArrayKeyException, throwArrayKeyException, DNone, SSync, {{SSA, 0}, {SSA, 1}}}, {ThrowUndefPropException, throwUndefPropException, DNone, SSync, {{SSA, 0}, {SSA, 1}}}, {RaiseTooManyArg, raiseTooManyArgumentsPrologue, DNone, SSync, {extra(&FuncData::func), {SSA, 0}}}, {RaiseCoeffectsFunParamTypeViolation, raiseCoeffectsFunParamTypeViolation, DNone, SSync, {{TV, 0}, extra(&ParamData::paramId)}}, {RaiseCoeffectsFunParamCoeffectRulesViolation, raiseCoeffectsFunParamCoeffectRulesViolation, DNone, SSync, {{SSA, 0}}}, {ThrowInvalidOperation, throw_invalid_operation_exception, DNone, SSync, {{SSA, 0}}}, {ThrowCallReifiedFunctionWithoutGenerics, throw_call_reified_func_without_generics, DNone, SSync, {{SSA, 0}}}, {ThrowDivisionByZeroException, throw_division_by_zero_exception, DNone, SSync, {}}, {ThrowHasThisNeedStatic, throw_has_this_need_static, DNone, SSync, {{SSA, 0}}}, {ThrowMissingArg, throwMissingArgument, DNone, SSync, {extra(&FuncArgData::func), extra(&FuncArgData::argNum)}}, {ThrowMissingThis, throw_missing_this, DNone, SSync, {{SSA, 0}}}, {ThrowParameterWrongType, throw_parameter_wrong_type, DNone, SSync, {{TV, 0}, extra(&FuncArgTypeData::func), extra(&FuncArgTypeData::argNum), extra(&FuncArgTypeData::type)}}, {CheckInOutMismatch, checkInOutMismatch, DNone, SSync, {{SSA, 0}, extra(&BoolVecArgsData::numArgs), extra(&BoolVecArgsData::args)}}, {ThrowInOutMismatch, throwParamInOutMismatch, DNone, SSync, {{SSA, 0}, extra(&ParamData::paramId)}}, {CheckReadonlyMismatch, checkReadonlyMismatch, DNone, SSync, {{SSA, 0}, extra(&BoolVecArgsData::numArgs), extra(&BoolVecArgsData::args)}}, {ThrowReadonlyMismatch, throwReadonlyMismatch, DNone, SSync, {{SSA, 0}, extra(&ParamData::paramId)}}, {HasToString, &ObjectData::hasToString, DSSA, SNone, {{SSA, 0}}}, /* Type specialized comparison operators */ {GtStr, static_cast<StrCmpFn>(more), DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {GteStr, static_cast<StrCmpFn>(moreEqual), DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {LtStr, static_cast<StrCmpFn>(less), DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {LteStr, static_cast<StrCmpFn>(lessEqual), DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {EqStr, static_cast<StrCmpFn>(equal), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {NeqStr, static_cast<StrCmpFn>(nequal), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {SameStr, static_cast<StrCmpFn>(same), DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {NSameStr, static_cast<StrCmpFn>(nsame), DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {CmpStr, static_cast<StrCmpFnInt>(compare), DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {GtObj, static_cast<ObjCmpFn>(more), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {GteObj, static_cast<ObjCmpFn>(moreEqual), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {LtObj, static_cast<ObjCmpFn>(less), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {LteObj, static_cast<ObjCmpFn>(lessEqual), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {EqObj, static_cast<ObjCmpFn>(equal), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {NeqObj, static_cast<ObjCmpFn>(nequal), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {CmpObj, static_cast<ObjCmpFnInt>(compare), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {GtArrLike, ArrayData::Gt, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {GteArrLike, ArrayData::Gte, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {LtArrLike, ArrayData::Lt, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {LteArrLike, ArrayData::Lte, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {EqArrLike, ArrayData::Equal, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {NeqArrLike, ArrayData::NotEqual, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {SameArrLike, ArrayData::Same, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {NSameArrLike, ArrayData::NotSame, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {CmpArrLike, ArrayData::Compare, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {GtRes, static_cast<ResCmpFn>(more), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {GteRes, static_cast<ResCmpFn>(moreEqual), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {LtRes, static_cast<ResCmpFn>(less), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {LteRes, static_cast<ResCmpFn>(lessEqual), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {CmpRes, static_cast<ResCmpFnInt>(compare), DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, /* Static prop helpers */ {LdClsPropAddrOrNull, getSPropOrNull, DSSA, SSync, {{extra(&ReadonlyData::op)}, {SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}, {SSA, 4}}}, {LdClsPropAddrOrRaise, getSPropOrRaise, DSSA, SSync, {{extra(&ReadonlyData::op)}, {SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}, {SSA, 4}}}, {ProfileProp, &PropertyProfile::incCount, DNone, SNone, {{SSA, 0}, {SSA, 1}}}, {IncCallCounter, FuncOrder::incCount, DNone, SNone, {{extra(&FuncData::func)}, {SSA, 0}}}, /* Global helpers */ {LdGblAddrDef, ldGblAddrDefHelper, DSSA, SSync, {{SSA, 0}}}, /* Generator support helpers */ {CreateGen, &Generator::Create, DSSA, SNone, {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}}, /* Async generator support helpers */ {CreateAGen, &AsyncGenerator::Create, DSSA, SNone, {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}}, /* Async function support helpers */ {CreateAFWH, &c_AsyncFunctionWaitHandle::Create, DSSA, SNone, {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}, {SSA, 4}}}, {CreateAGWH, &c_AsyncGeneratorWaitHandle::Create, DSSA, SNone, {{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}}, {AFWHPrepareChild, &c_AsyncFunctionWaitHandle::PrepareChild, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, /* SetNewElem helpers */ {SetNewElemDict, setNewElemDict, DSSA, SSync, {{SSA, 0}, {TV, 1}}}, {SetNewElemVec, setNewElemVec, DSSA, SSync, {{SSA, 0}, {TV, 1}}}, {SetNewElem, setNewElem, DSSA, SSync, {{SSA, 0}, {TV, 1}}}, /* AddNewElem helpers */ {AddNewElemKeyset, addNewElemKeyset, DSSA, SSync, {{SSA, 0}, {TV, 1}}}, {AddNewElemVec, addNewElemVec, DSSA, SNone, {{SSA, 0}, {TV, 1}}}, /* MInstrTranslator helpers */ {StringGet, MInstrHelpers::stringGetI, DSSA, SSync, {{SSA, 0}, {SSA, 1}}}, {PairIsset, MInstrHelpers::pairIsset, DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {VectorIsset, MInstrHelpers::vectorIsset, DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {ThrowOutOfBounds, throwOOBException, DNone, SSync, {{TV, 0}, {TV, 1}}}, {ThrowInvalidArrayKey, invalidArrayKeyHelper, DNone, SSync, {{SSA, 0}, {TV, 1}}}, /* instanceof checks */ {ProfileInstanceCheck, &InstanceBits::profile, DNone, SNone, {{SSA, 0}}}, {InstanceOfIface, &Class::ifaceofDirect, DSSA, SNone, {{SSA, 0}, {SSA, 1}}}, {InterfaceSupportsArrLike, IFaceSupportFn{interface_supports_arrlike}, DSSA, SNone, {{SSA, 0}}}, {InterfaceSupportsStr, IFaceSupportFn{interface_supports_string}, DSSA, SNone, {{SSA, 0}}}, {InterfaceSupportsInt, IFaceSupportFn{interface_supports_int}, DSSA, SNone, {{SSA, 0}}}, {InterfaceSupportsDbl, IFaceSupportFn{interface_supports_double}, DSSA, SNone, {{SSA, 0}}}, {OODeclExists, &Class::exists, DSSA, SSync, {{SSA, 0}, {SSA, 1}, extra(&ClassKindData::kind)}}, /* is/as expressions */ {IsTypeStruct, isTypeStructHelper, DSSA, SSync, {{SSA, 0}, {TV, 1}, {extra(&RDSHandleData::handle)}}}, {ThrowAsTypeStructException, throwAsTypeStructExceptionHelper, DNone, SSync, {{SSA, 0}, {TV, 1}}}, /* surprise flag support */ {SuspendHookAwaitEF, &EventHook::onFunctionSuspendAwaitEFJit, DNone, SSync, {{SSA, 0}, {SSA, 1}}}, {SuspendHookAwaitEG, &EventHook::onFunctionSuspendAwaitEGJit, DNone, SSync, {{SSA, 0}}}, {SuspendHookAwaitR, &EventHook::onFunctionSuspendAwaitRJit, DNone, SSync, {{SSA, 0}, {SSA, 1}}}, {SuspendHookCreateCont, &EventHook::onFunctionSuspendCreateContJit, DNone, SSync, {{SSA, 0}, {SSA, 1}}}, {SuspendHookYield, &EventHook::onFunctionSuspendYieldJit, DNone, SSync, {{SSA, 0}}}, {ReturnHook, &EventHook::onFunctionReturnJit, DNone, SSync, {{SSA, 0}, {TV, 1}}}, /* silence operator support */ {ZeroErrorLevel, &zero_error_level, DSSA, SNone, {}}, {RestoreErrorLevel, &restore_error_level, DNone, SNone, {{SSA, 0}}}, /* count($mixed) */ {Count, &countHelper, DSSA, SSync, {{TV, 0}}}, /* microtime(true) */ {GetTime, TimeStamp::CurrentSecond, DSSA, SNone, {}}, /* clock_gettime_ns($clk_id) */ {GetTimeNs, folly::chrono::clock_gettime_ns, DSSA, SNone, {{SSA, 0}}}, /* ClsMethDataRef */ {CheckClsMethFunc, checkClsMethFuncHelper, DNone, SSync, {{SSA, 0}}}, /* reified generics operations */ {CheckClsReifiedGenericMismatch, checkClassReifiedGenericMismatch, DNone, SSync, {{extra(&ClassData::cls)}, {SSA, 0}}}, {CheckFunReifiedGenericMismatch, checkFunReifiedGenericMismatch, DNone, SSync, {{SSA, 0}, {SSA, 1}}}, {VerifyReifiedLocalType, VerifyReifiedLocalTypeImpl, DNone, SSync, {{TV, 0}, {SSA, 1}, {SSA, 2}, extra(&FuncParamData::func), extra(&FuncParamData::paramId)}}, {VerifyReifiedReturnType, VerifyReifiedReturnTypeImpl, DNone, SSync, {{TV, 0}, {SSA, 1}, {SSA, 2}, extra(&FuncData::func)}}, {RecordReifiedGenericsAndGetTSList, recordReifiedGenericsAndGetTSList, DSSA, SSync, {{SSA, 0}}}, {RaiseErrorOnInvalidIsAsExpressionType, errorOnIsAsExpressionInvalidTypesHelper, DSSA, SSync, {{SSA, 0}}}, }; CallMap::CallMap(CallInfoList infos) { for (auto const& info : infos) { m_map[info.op] = info; } } bool CallMap::hasInfo(Opcode op) { return s_callMap.m_map.count(op) != 0; } const CallInfo& CallMap::info(Opcode op) { auto it = s_callMap.m_map.find(op); assertx(it != s_callMap.m_map.end()); return it->second; } /////////////////////////////////////////////////////////////////////////////// } // NativeCalls /////////////////////////////////////////////////////////////////////////////// using namespace NativeCalls; ArgGroup toArgGroup(const CallInfo& info, const StateVector<SSATmp,Vloc>& locs, const IRInstruction* inst) { ArgGroup argGroup{inst, locs}; for (auto const& arg : info.args) { switch (arg.type) { case ArgType::SSA: argGroup.ssa(arg.ival); break; case ArgType::TV: argGroup.typedValue(arg.ival); break; case ArgType::ExtraImm: argGroup.imm(arg.extraFunc(inst)); break; case ArgType::Imm: argGroup.imm(arg.ival); break; } } return argGroup; } /////////////////////////////////////////////////////////////////////////////// }