hphp/runtime/vm/jit/irgen-func-prologue.cpp
/*
 * Initialize parameters.
 *
 * Set un-passed parameters to Uninit and set up the variadic capture parameter
 * as neeeded.
 */
Initialize parameters.
Set un-passed parameters to Uninit and set up the variadic capture parameter
as neeeded.
Initialize parameters . Set un - passed parameters to Uninit and set up the variadic capture parameter as neeeded .
void init_params(IRGS& env, const Func* func, uint32_t argc,
                 SSATmp* callFlags) {
  assertx(!func->hasReifiedGenerics() || !func->isClosureBody());
  auto constexpr kMaxParamsInitUnroll = 5;
  auto const nparams = func->numNonVariadicParams();
  if (func->hasReifiedGenerics()) {
    ifThenElse(
      env,
      [&] (Block* taken) {
        auto constexpr flag = 1 << CallFlags::Flags::HasGenerics;
        auto const hasGenerics = gen(env, AndInt, callFlags, cns(env, flag));
        gen(env, JmpNZero, taken, hasGenerics);
      },
      [&] {
        arrprov::TagOverride ap_override{arrprov::tagFromSK(env.bcState)};
        auto const emptyArr =
          RuntimeOption::EvalHackArrDVArrs ? ArrayData::CreateVec()
                                           : ArrayData::CreateVArray();
        gen(
          env,
          StLoc,
          LocalId{func->numParams()},
          fp(env),
          cns(env, emptyArr));
      },
      [&] {
        if (argc == func->numParams()) return;
        auto const type = RuntimeOption::EvalHackArrDVArrs ? TVec : TVArr;
        auto const generics = [&] {
          if (argc < func->numParams()) {
            gen(env, AssertLoc, type, LocalId{argc}, fp(env));
            return gen(env, LdLoc, type, LocalId{argc}, fp(env));
          } else {
            assertx(!isInlining(env));
            auto const genericsOff = IRSPRelOffsetData(offsetFromIRSP(
              env, BCSPRelOffset{func->numSlotsInFrame() - int32_t(argc) - 1}));
            gen(env, AssertStk, type, genericsOff, sp(env));
            return gen(env, LdStk, type, genericsOff, sp(env));
          }
        }();
        gen(env, StLoc, LocalId{func->numParams()}, fp(env), generics);
      }
    );
  }
  if (argc < nparams) {
    if (nparams - argc <= kMaxParamsInitUnroll || isInlining(env)) {
      for (auto i = argc; i < nparams; ++i) {
        gen(env, StLoc, LocalId{i}, fp(env), cns(env, TUninit));
      }
    } else {
      gen(env, StLocRange, LocalIdRange{argc, nparams},
          fp(env), cns(env, TUninit));
    }
  }
  if (argc <= nparams && func->hasVariadicCaptureParam()) {
    ARRPROV_USE_RUNTIME_LOCATION();
    gen(env, StLoc, LocalId{nparams}, fp(env),
        cns(env, ArrayData::CreateVArray()));
  }
}
void init_params ( IRGS & env , const Func * func , uint32_t argc , SSATmp * callFlags ) { assertx ( ! func -> hasReifiedGenerics ( ) || ! func -> isClosureBody ( ) ) ; auto constexpr kMaxParamsInitUnroll = 5 ; auto const nparams = func -> numNonVariadicParams ( ) ; if ( func -> hasReifiedGenerics ( ) ) { ifThenElse ( env , [ & ] ( Block * taken ) { auto constexpr flag = 1 << CallFlags :: Flags :: HasGenerics ; auto const hasGenerics = gen ( env , AndInt , callFlags , cns ( env , flag ) ) ; gen ( env , JmpNZero , taken , hasGenerics ) ; } , [ & ] { arrprov :: TagOverride ap_override { arrprov :: tagFromSK ( env . bcState ) } ; auto const emptyArr = RuntimeOption :: EvalHackArrDVArrs ? ArrayData :: CreateVec ( ) : ArrayData :: CreateVArray ( ) ; gen ( env , StLoc , LocalId { func -> numParams ( ) } , fp ( env ) , cns ( env , emptyArr ) ) ; } , [ & ] { if ( argc == func -> numParams ( ) ) return ; auto const type = RuntimeOption :: EvalHackArrDVArrs ? TVec : TVArr ; auto const generics = [ & ] { if ( argc < func -> numParams ( ) ) { gen ( env , AssertLoc , type , LocalId { argc } , fp ( env ) ) ; return gen ( env , LdLoc , type , LocalId { argc } , fp ( env ) ) ; } else { assertx ( ! isInlining ( env ) ) ; auto const genericsOff = IRSPRelOffsetData ( offsetFromIRSP ( env , BCSPRelOffset { func -> numSlotsInFrame ( ) - int32_t ( argc ) - 1 } ) ) ; gen ( env , AssertStk , type , genericsOff , sp ( env ) ) ; return gen ( env , LdStk , type , genericsOff , sp ( env ) ) ; } } ( ) ; gen ( env , StLoc , LocalId { func -> numParams ( ) } , fp ( env ) , generics ) ; } ) ; } if ( argc < nparams ) { if ( nparams - argc <= kMaxParamsInitUnroll || isInlining ( env ) ) { for ( auto i = argc ; i < nparams ; ++ i ) { gen ( env , StLoc , LocalId { i } , fp ( env ) , cns ( env , TUninit ) ) ; } } else { gen ( env , StLocRange , LocalIdRange { argc , nparams } , fp ( env ) , cns ( env , TUninit ) ) ; } } if ( argc <= nparams && func -> hasVariadicCaptureParam ( ) ) { ARRPROV_USE_RUNTIME_LOCATION ( ) ; gen ( env , StLoc , LocalId { nparams } , fp ( env ) , cns ( env , ArrayData :: CreateVArray ( ) ) ) ; } }
Initialize parameters.
Initialize parameters .
// Reified generics are not supported on closures yet. // Maximum number of default-value parameter initializations to unroll. // If generics were expected and given, but not enough args were provided, // move generics to the correct slot ($0ReifiedGenerics is the first // non-parameter local). // FIXME: leaks memory if generics were given but not expected. // Generics not given. We will either fail later or raise a warning. // Write empty array so that the local is properly initialized. // Already at the correct slot. // Too few arguments; set everything else to Uninit. // Need to initialize `...$args'.