Ejemplo n.º 1
0
ManagedValue SILGenBuilder::createTupleExtract(SILLocation loc,
                                               ManagedValue base,
                                               unsigned index, SILType type) {
  ManagedValue borrowedBase = SGF.emitManagedBeginBorrow(loc, base.getValue());
  SILValue extract =
      createTupleExtract(loc, borrowedBase.getValue(), index, type);
  return ManagedValue::forUnmanaged(extract);
}
Ejemplo n.º 2
0
ManagedValue SILGenBuilder::createStructExtract(SILLocation loc,
                                                ManagedValue base,
                                                VarDecl *decl) {
  ManagedValue borrowedBase = gen.emitManagedBeginBorrow(loc, base.getValue());
  SILValue extract =
      SILBuilder::createStructExtract(loc, borrowedBase.getValue(), decl);
  return ManagedValue::forUnmanaged(extract);
}
Ejemplo n.º 3
0
ManagedValue SILGenBuilder::createLoadBorrow(SILLocation loc,
                                             ManagedValue base) {
  if (SGF.getTypeLowering(base.getType()).isTrivial()) {
    auto *i = createLoad(loc, base.getValue(), LoadOwnershipQualifier::Trivial);
    return ManagedValue::forUnmanaged(i);
  }

  auto *i = createLoadBorrow(loc, base.getValue());
  return SGF.emitManagedBorrowedRValueWithCleanup(base.getValue(), i);
}
Ejemplo n.º 4
0
ManagedValue SILGenBuilder::createFormalAccessLoadBorrow(SILLocation loc,
                                                         ManagedValue base) {
  if (getFunction().getTypeLowering(base.getType()).isTrivial()) {
    auto *i = SILBuilder::createLoad(loc, base.getValue(),
                                     LoadOwnershipQualifier::Trivial);
    return ManagedValue::forUnmanaged(i);
  }

  SILValue baseValue = base.getValue();
  auto *i = SILBuilder::createLoadBorrow(loc, baseValue);
  return gen.emitFormalEvaluationManagedBorrowedRValueWithCleanup(loc,
                                                                  baseValue, i);
}
Ejemplo n.º 5
0
ManagedValue SILGenBuilder::createObjCSuperMethod(SILLocation loc,
                                                  ManagedValue operand,
                                                  SILDeclRef member,
                                                  SILType methodTy) {
  SILValue v = createObjCSuperMethod(loc, operand.getValue(), member, methodTy);
  return ManagedValue::forUnmanaged(v);
}
Ejemplo n.º 6
0
static ManagedValue emitBridgeCollectionToNative(SILGenFunction &gen,
                                                 SILLocation loc,
                                                 SILDeclRef bridgeFnRef,
                                                 ManagedValue collection,
                                                 SILType nativeTy) {
  SILValue bridgeFn = gen.emitGlobalFunctionRef(loc, bridgeFnRef);

  auto collectionTy = nativeTy.getSwiftRValueType()->castTo<BoundGenericType>();
  auto subs = collectionTy->getSubstitutions(gen.SGM.M.getSwiftModule(),
                                             nullptr);
  auto substFnType = bridgeFn.getType().substGenericArgs(gen.SGM.M, subs);

  Type inputType = collection.getType().getSwiftRValueType();
  if (!inputType->getOptionalObjectType()) {
    SILType loweredOptTy = gen.SGM.getLoweredType(OptionalType::get(inputType));
    auto *someDecl = gen.getASTContext().getOptionalSomeDecl();
    auto *enumInst = gen.B.createEnum(loc, collection.getValue(), someDecl,
                                      loweredOptTy);
    collection = ManagedValue(enumInst, collection.getCleanup());
  }

  SILValue result = gen.B.createApply(loc, bridgeFn,
                                      substFnType,
                                      nativeTy,
                                      subs,
                                      { collection.forward(gen) });

  return gen.emitManagedRValueWithCleanup(result);
}
Ejemplo n.º 7
0
/// Perform a foreign error check by testing whether the error was nil.
static void
emitErrorIsNonNilErrorCheck(SILGenFunction &gen, SILLocation loc,
                            ManagedValue errorSlot, bool suppressErrorCheck) {
  // If we're suppressing the check, just don't check.
  if (suppressErrorCheck) return;

  SILValue optionalError = gen.B.createLoad(loc, errorSlot.getValue());

  OptionalTypeKind optKind;
  optionalError->getType().getAnyOptionalObjectType(gen.SGM.M, optKind);

  ASTContext &ctx = gen.getASTContext();

  // Switch on the optional error.
  SILBasicBlock *errorBB = gen.createBasicBlock(FunctionSection::Postmatter);
  SILBasicBlock *contBB = gen.createBasicBlock();
  gen.B.createSwitchEnum(loc, optionalError, /*default*/ nullptr,
                         { { ctx.getOptionalSomeDecl(optKind), errorBB },
                           { ctx.getOptionalNoneDecl(optKind), contBB } });

  // Emit the error block.  Just be lazy and reload the error there.
  gen.emitForeignErrorBlock(loc, errorBB, errorSlot);

  // Return the result.
  gen.B.emitBlock(contBB);
  return;
}
Ejemplo n.º 8
0
ManagedValue SILGenBuilder::createUncheckedTrivialBitCast(SILLocation loc,
                                                          ManagedValue original,
                                                          SILType type) {
  SILValue result =
      SGF.B.createUncheckedTrivialBitCast(loc, original.getValue(), type);
  return ManagedValue::forUnmanaged(result);
}
Ejemplo n.º 9
0
uint16_t SILGenFunction::emitProlog(ArrayRef<ParameterList *> paramLists,
                                    Type resultType, DeclContext *DC,
                                    bool throws) {
  // Create the indirect result parameters.
  auto *genericSig = DC->getGenericSignatureOfContext();
  resultType = resultType->getCanonicalType(genericSig);

  emitIndirectResultParameters(*this, resultType, DC);

  // Emit the argument variables in calling convention order.
  ArgumentInitHelper emitter(*this, F);

  for (ParameterList *paramList : reversed(paramLists)) {
    // Add the SILArguments and use them to initialize the local argument
    // values.
    for (auto &param : *paramList)
      emitter.emitParam(param);
  }

  // Record the ArgNo of the artificial $error inout argument. 
  unsigned ArgNo = emitter.getNumArgs();
  if (throws) {
    RegularLocation Loc = RegularLocation::getAutoGeneratedLocation();
    if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC))
      Loc = AFD->getThrowsLoc();
    else if (auto *ACE = dyn_cast<AbstractClosureExpr>(DC))
      Loc = ACE->getLoc();
    auto NativeErrorTy = SILType::getExceptionType(getASTContext());
    ManagedValue Undef = emitUndef(Loc, NativeErrorTy);
    SILDebugVariable DbgVar("$error", /*Constant*/ false, ++ArgNo);
    B.createDebugValue(Loc, Undef.getValue(), DbgVar);
  }

  return ArgNo;
}
Ejemplo n.º 10
0
ManagedValue
SILGenFunction::emitPreconditionOptionalHasValue(SILLocation loc,
                                                 ManagedValue optional) {
  // Generate code to the optional is present, and if not, abort with a message
  // (provided by the stdlib).
  SILBasicBlock *contBB = createBasicBlock();
  SILBasicBlock *failBB = createBasicBlock();

  bool hadCleanup = optional.hasCleanup();
  bool hadLValue = optional.isLValue();

  auto noneDecl = getASTContext().getOptionalNoneDecl();
  auto someDecl = getASTContext().getOptionalSomeDecl();
  if (optional.getType().isAddress()) {
    // We forward in the creation routine for
    // unchecked_take_enum_data_addr. switch_enum_addr is a +0 operation.
    B.createSwitchEnumAddr(loc, optional.getValue(),
                           /*defaultDest*/ nullptr,
                           {{someDecl, contBB}, {noneDecl, failBB}});
  } else {
    B.createSwitchEnum(loc, optional.forward(*this),
                       /*defaultDest*/ nullptr,
                       {{someDecl, contBB}, {noneDecl, failBB}});
  }
  B.emitBlock(failBB);

  // Call the standard library implementation of _diagnoseUnexpectedNilOptional.
  if (auto diagnoseFailure =
        getASTContext().getDiagnoseUnexpectedNilOptional(nullptr)) {
    ManagedValue args[4];
    emitSourceLocationArgs(*this, loc, args);
    
    emitApplyOfLibraryIntrinsic(loc, diagnoseFailure, SubstitutionMap(), args,
                                SGFContext());
  }

  B.createUnreachable(loc);
  B.clearInsertionPoint();
  B.emitBlock(contBB);

  ManagedValue result;
  SILType payloadType = optional.getType().getAnyOptionalObjectType();

  if (payloadType.isObject()) {
    result = B.createOwnedPHIArgument(payloadType);
  } else {
    result =
        B.createUncheckedTakeEnumDataAddr(loc, optional, someDecl, payloadType);
  }

  if (hadCleanup) {
    return result;
  }

  if (hadLValue) {
    return ManagedValue::forLValue(result.forward(*this));
  }

  return ManagedValue::forUnmanaged(result.forward(*this));
}
Ejemplo n.º 11
0
SILValue RValue::getUnmanagedSingleValue(SILGenFunction &SGF,
                                         SILLocation l) const & {
  assert(isComplete() && "rvalue is not complete");
  ManagedValue mv =
      implodeTupleValues<ImplodeKind::Unmanaged>(values, SGF, type, l);
  return mv.getValue();
}
Ejemplo n.º 12
0
ManagedValue SILGenBuilder::createFormalAccessCopyAddr(
    SILLocation loc, ManagedValue originalAddr, SILValue newAddr,
    IsTake_t isTake, IsInitialization_t isInit) {
  SILBuilder::createCopyAddr(loc, originalAddr.getValue(), newAddr, isTake,
                             isInit);
  return gen.emitFormalAccessManagedBufferWithCleanup(loc, newAddr);
}
Ejemplo n.º 13
0
ManagedValue SILGenBuilder::createOpenExistentialMetatype(SILLocation loc,
                                                          ManagedValue value,
                                                          SILType openedType) {
  SILValue result = SILGenBuilder::createOpenExistentialMetatype(
      loc, value.getValue(), openedType);
  return ManagedValue::forTrivialRValue(result);
}
Ejemplo n.º 14
0
ManagedValue SILGenBuilder::createUncheckedBitCast(SILLocation loc,
                                                   ManagedValue value,
                                                   SILType type) {
  CleanupCloner cloner(*this, value);
  SILValue cast = createUncheckedBitCast(loc, value.getValue(), type);

  // Currently SILBuilder::createUncheckedBitCast only produces these
  // instructions. We assert here to make sure if this changes, this code is
  // updated.
  assert((isa<UncheckedTrivialBitCastInst>(cast) ||
          isa<UncheckedRefCastInst>(cast) ||
          isa<UncheckedBitwiseCastInst>(cast)) &&
         "SILGenBuilder is out of sync with SILBuilder.");

  // If we have a trivial inst, just return early.
  if (isa<UncheckedTrivialBitCastInst>(cast))
    return ManagedValue::forUnmanaged(cast);

  // If we perform an unchecked bitwise case, then we are producing a new RC
  // identity implying that we need a copy of the casted value to be returned so
  // that the inputs/outputs of the case have separate ownership.
  if (isa<UncheckedBitwiseCastInst>(cast)) {
    return ManagedValue::forUnmanaged(cast).copy(SGF, loc);
  }

  // Otherwise, we forward the cleanup of the input value and place the cleanup
  // on the cast value since unchecked_ref_cast is "forwarding".
  value.forward(SGF);
  return cloner.clone(cast);
}
Ejemplo n.º 15
0
ManagedValue SILGenFunction::emitCheckedGetOptionalValueFrom(SILLocation loc,
                                                      ManagedValue src,
                                                      const TypeLowering &optTL,
                                                      SGFContext C) {
  emitPreconditionOptionalHasValue(loc, src.getValue());
  return emitUncheckedGetOptionalValueFrom(loc, src, optTL, C);
}
Ejemplo n.º 16
0
ManagedValue SILGenBuilder::createStructExtract(SILLocation loc,
                                                ManagedValue base,
                                                VarDecl *decl) {
  ManagedValue borrowedBase = base.formalAccessBorrow(SGF, loc);
  SILValue extract = createStructExtract(loc, borrowedBase.getValue(), decl);
  return ManagedValue::forUnmanaged(extract);
}
Ejemplo n.º 17
0
/// Specialized emitter for Builtin.reinterpretCast.
static ManagedValue emitBuiltinReinterpretCast(SILGenFunction &SGF,
                                         SILLocation loc,
                                         SubstitutionMap substitutions,
                                         ArrayRef<ManagedValue> args,
                                         SGFContext C) {
  assert(args.size() == 1 && "reinterpretCast should be given one argument");
  assert(substitutions.getReplacementTypes().size() == 2 &&
         "reinterpretCast should have two subs");
  
  auto &fromTL = SGF.getTypeLowering(substitutions.getReplacementTypes()[0]);
  auto &toTL = SGF.getTypeLowering(substitutions.getReplacementTypes()[1]);
  
  // If casting between address types, cast the address.
  if (fromTL.isAddress() || toTL.isAddress()) {
    SILValue fromAddr;

    // If the from value is not an address, move it to a buffer.
    if (!fromTL.isAddress()) {
      fromAddr = SGF.emitTemporaryAllocation(loc, args[0].getValue()->getType());
      fromTL.emitStore(SGF.B, loc, args[0].getValue(), fromAddr,
                       StoreOwnershipQualifier::Init);
    } else {
      fromAddr = args[0].getValue();
    }
    auto toAddr = SGF.B.createUncheckedAddrCast(loc, fromAddr,
                                      toTL.getLoweredType().getAddressType());
    
    // Load and retain the destination value if it's loadable. Leave the cleanup
    // on the original value since we don't know anything about it's type.
    if (!toTL.isAddress()) {
      return SGF.emitManagedLoadCopy(loc, toAddr, toTL);
    }
    // Leave the cleanup on the original value.
    if (toTL.isTrivial())
      return ManagedValue::forUnmanaged(toAddr);

    // Initialize the +1 result buffer without taking the incoming value. The
    // source and destination cleanups will be independent.
    return SGF.B.bufferForExpr(
        loc, toTL.getLoweredType(), toTL, C,
        [&](SILValue bufferAddr) {
          SGF.B.createCopyAddr(loc, toAddr, bufferAddr, IsNotTake,
                               IsInitialization);
        });
  }
  // Create the appropriate bitcast based on the source and dest types.
  ManagedValue in = args[0];
  SILType resultTy = toTL.getLoweredType();
  if (resultTy.isTrivial(SGF.F))
    return SGF.B.createUncheckedTrivialBitCast(loc, in, resultTy);

  // If we can perform a ref cast, just return.
  if (auto refCast = SGF.B.tryCreateUncheckedRefCast(loc, in, resultTy))
    return refCast;

  // Otherwise leave the original cleanup and retain the cast value.
  SILValue out = SGF.B.createUncheckedBitwiseCast(loc, in.getValue(), resultTy);
  return SGF.emitManagedRetain(loc, out, toTL);
}
Ejemplo n.º 18
0
ManagedValue SILGenBuilder::createTupleElementAddr(SILLocation Loc,
                                                   ManagedValue Base,
                                                   unsigned Index,
                                                   SILType Type) {
  SILValue TupleEltAddr =
      createTupleElementAddr(Loc, Base.getValue(), Index, Type);
  return ManagedValue::forUnmanaged(TupleEltAddr);
}
Ejemplo n.º 19
0
ManagedValue SILGenBuilder::createRefElementAddr(SILLocation loc,
                                                 ManagedValue operand,
                                                 VarDecl *field,
                                                 SILType resultTy) {
  operand = operand.formalAccessBorrow(SGF, loc);
  SILValue result = createRefElementAddr(loc, operand.getValue(), field);
  return ManagedValue::forUnmanaged(result);
}
Ejemplo n.º 20
0
ManagedValue SILGenBuilder::createOpenExistentialBoxValue(SILLocation loc,
                                                          ManagedValue original,
                                                          SILType type) {
  ManagedValue borrowedExistential = original.formalAccessBorrow(SGF, loc);
  SILValue openedExistential =
      createOpenExistentialBoxValue(loc, borrowedExistential.getValue(), type);
  return ManagedValue::forUnmanaged(openedExistential);
}
Ejemplo n.º 21
0
static ManagedValue emitNativeToCBridgedNonoptionalValue(SILGenFunction &gen,
                                                         SILLocation loc,
                                                         ManagedValue v,
                                                         SILType bridgedTy) {
  CanType loweredBridgedTy = bridgedTy.getSwiftRValueType();
  CanType loweredNativeTy = v.getType().getSwiftRValueType();
  if (loweredNativeTy == loweredBridgedTy)
    return v;

  // FIXME: Handle this via an _ObjectiveCBridgeable query rather than
  // hardcoding String -> NSString.
  if (loweredNativeTy == gen.SGM.Types.getStringType()
      && loweredBridgedTy == gen.SGM.Types.getNSStringType()) {
    if (auto result = emitBridgeNativeToObjectiveC(gen, loc, v))
      return *result;

    return gen.emitUndef(loc, bridgedTy);
  }

  // If the input is a native type with a bridged mapping, convert it.
#define BRIDGE_TYPE(BridgedModule,BridgedType, NativeModule,NativeType,Opt) \
  if (loweredNativeTy == gen.SGM.Types.get##NativeType##Type()              \
      && loweredBridgedTy == gen.SGM.Types.get##BridgedType##Type()) {      \
    return emitBridge##NativeType##To##BridgedType(gen, loc, v);            \
  }
#include "swift/SIL/BridgedTypes.def"

  // Bridge thick to Objective-C metatypes.
  if (auto bridgedMetaTy = dyn_cast<AnyMetatypeType>(loweredBridgedTy)) {
    if (bridgedMetaTy->getRepresentation() == MetatypeRepresentation::ObjC) {
      SILValue native = gen.B.emitThickToObjCMetatype(loc, v.getValue(),
                           SILType::getPrimitiveObjectType(loweredBridgedTy));
      return ManagedValue(native, v.getCleanup());
    }
  }

  // Bridge native functions to blocks.
  auto bridgedFTy = dyn_cast<SILFunctionType>(loweredBridgedTy);
  if (bridgedFTy
      && bridgedFTy->getRepresentation() == SILFunctionType::Representation::Block){
    auto nativeFTy = cast<SILFunctionType>(loweredNativeTy);

    if (nativeFTy->getRepresentation() != SILFunctionType::Representation::Block)
      return gen.emitFuncToBlock(loc, v, bridgedFTy);
  }

  // If the native type conforms to _ObjectiveCBridgeable, use its
  // _bridgeToObjectiveC witness.
  if (auto conformance =
          gen.SGM.getConformanceToObjectiveCBridgeable(loc, loweredNativeTy)) {
    if (auto result = emitBridgeNativeToObjectiveC(gen, loc, v, conformance))
      return *result;

    return gen.emitUndef(loc, bridgedTy);
  }

  return v;
}
Ejemplo n.º 22
0
static ManagedValue emitCBridgedToNativeValue(SILGenFunction &gen,
                                              SILLocation loc,
                                              ManagedValue v,
                                              SILType nativeTy) {
  CanType loweredNativeTy = nativeTy.getSwiftRValueType();
  CanType loweredBridgedTy = v.getType().getSwiftRValueType();
  if (loweredNativeTy == loweredBridgedTy)
    return v;

  if (loweredNativeTy.getAnyOptionalObjectType()) {
    return gen.emitOptionalToOptional(loc, v, nativeTy,
                                      emitCBridgedToNativeValue);
  }

  // Bridge Bool to ObjCBool or DarwinBoolean when requested.
  if (loweredNativeTy == gen.SGM.Types.getBoolType()) {
    if (loweredBridgedTy == gen.SGM.Types.getObjCBoolType()) {
      return emitBridgeForeignBoolToBool(gen, loc, v,
                                         gen.SGM.getObjCBoolToBoolFn());
    }
    if (loweredBridgedTy == gen.SGM.Types.getDarwinBooleanType()) {
      return emitBridgeForeignBoolToBool(gen, loc, v,
                                         gen.SGM.getDarwinBooleanToBoolFn());
    }
  }

  // Bridge Objective-C to thick metatypes.
  if (auto bridgedMetaTy = dyn_cast<AnyMetatypeType>(loweredBridgedTy)){
    if (bridgedMetaTy->getRepresentation() == MetatypeRepresentation::ObjC) {
      SILValue native = gen.B.emitObjCToThickMetatype(loc, v.getValue(),
                                        gen.getLoweredType(loweredNativeTy));
      return ManagedValue(native, v.getCleanup());
    }
  }

  // Bridge blocks back into native function types.
  auto bridgedFTy = dyn_cast<SILFunctionType>(loweredBridgedTy);
  if (bridgedFTy
      && bridgedFTy->getRepresentation() == SILFunctionType::Representation::Block){
    auto nativeFTy = cast<SILFunctionType>(loweredNativeTy);

    if (nativeFTy->getRepresentation() != SILFunctionType::Representation::Block)
      return gen.emitBlockToFunc(loc, v, nativeFTy);
  }

  // Bridge via _ObjectiveCBridgeable.
  if (auto conformance =
        gen.SGM.getConformanceToObjectiveCBridgeable(loc, loweredNativeTy)) {
    if (auto result = emitBridgeObjectiveCToNative(gen, loc, v, conformance))
      return *result;

    assert(gen.SGM.getASTContext().Diags.hadAnyError() &&
           "Bridging code should have complained");
    return gen.emitUndef(loc, nativeTy);
  }

  return v;
}
Ejemplo n.º 23
0
/// Bridge a native function to a block with a thunk.
ManagedValue SILGenFunction::emitFuncToBlock(SILLocation loc,
                                             ManagedValue fn,
                                             CanSILFunctionType blockTy) {
  // Build the invoke function signature. The block will capture the original
  // function value.
  auto fnTy = fn.getType().castTo<SILFunctionType>();
  auto storageTy = SILBlockStorageType::get(fnTy);

  // Build the invoke function type.
  SmallVector<SILParameterInfo, 4> params;
  params.push_back(SILParameterInfo(storageTy,
                                 ParameterConvention::Indirect_InoutAliasable));
  std::copy(blockTy->getParameters().begin(),
            blockTy->getParameters().end(),
            std::back_inserter(params));

  auto invokeTy =
    SILFunctionType::get(nullptr,
                     SILFunctionType::ExtInfo()
                       .withRepresentation(SILFunctionType::Representation::
                                           CFunctionPointer),
                     ParameterConvention::Direct_Unowned,
                     params,
                     blockTy->getAllResults(),
                     blockTy->getOptionalErrorResult(),
                     getASTContext());

  // Create the invoke function. Borrow the mangling scheme from reabstraction
  // thunks, which is what we are in spirit.
  auto thunk = SGM.getOrCreateReabstractionThunk(nullptr,
                                                 invokeTy,
                                                 fnTy,
                                                 blockTy,
                                                 F.isFragile());

  // Build it if necessary.
  if (thunk->empty()) {
    SILGenFunction thunkSGF(SGM, *thunk);
    auto loc = RegularLocation::getAutoGeneratedLocation();
    buildFuncToBlockInvokeBody(thunkSGF, loc, blockTy, storageTy, fnTy);
  }

  // Form the block on the stack.
  auto storageAddrTy = SILType::getPrimitiveAddressType(storageTy);
  auto storage = emitTemporaryAllocation(loc, storageAddrTy);
  auto capture = B.createProjectBlockStorage(loc, storage);
  // Store the function to the block without claiming it, so that it still
  // gets cleaned up in scope. Copying the block will create an independent
  // reference.
  B.createStore(loc, fn.getValue(), capture);
  auto invokeFn = B.createFunctionRef(loc, thunk);
  auto stackBlock = B.createInitBlockStorageHeader(loc, storage, invokeFn,
                                      SILType::getPrimitiveObjectType(blockTy));

  // Copy the block so we have an independent heap object we can hand off.
  auto heapBlock = B.createCopyBlock(loc, stackBlock);
  return emitManagedRValueWithCleanup(heapBlock);
}
Ejemplo n.º 24
0
ManagedValue SILGenBuilder::tryCreateUncheckedRefCast(SILLocation loc,
                                                      ManagedValue original,
                                                      SILType type) {
  CleanupCloner cloner(*this, original);
  SILValue result = tryCreateUncheckedRefCast(loc, original.getValue(), type);
  if (!result)
    return ManagedValue();
  original.forward(SGF);
  return cloner.clone(result);
}
Ejemplo n.º 25
0
ManagedValue SILGenBuilder::createCopyUnownedValue(SILLocation loc,
                                                   ManagedValue originalValue) {
  auto unownedType = originalValue.getType().castTo<UnownedStorageType>();
  assert(unownedType->isLoadable(ResilienceExpansion::Maximal));
  (void)unownedType;

  SILValue result =
      SILBuilder::createCopyUnownedValue(loc, originalValue.getValue());
  return gen.emitManagedRValueWithCleanup(result);
}
Ejemplo n.º 26
0
ManagedValue
SILGenBuilder::createUnsafeCopyUnownedValue(SILLocation loc,
                                            ManagedValue originalValue) {
  auto unmanagedType = originalValue.getType().getAs<UnmanagedStorageType>();
  SILValue result = SILBuilder::createUnmanagedToRef(
      loc, originalValue.getValue(),
      SILType::getPrimitiveObjectType(unmanagedType.getReferentType()));
  SILBuilder::createUnmanagedRetainValue(loc, result, getDefaultAtomicity());
  return gen.emitManagedRValueWithCleanup(result);
}
Ejemplo n.º 27
0
static std::pair<ManagedValue, SILDeclRef>
getNextUncurryLevelRef(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk,
                       ManagedValue selfArg, SubstitutionMap curriedSubs) {
  auto *vd = thunk.getDecl();

  // Reference the next uncurrying level of the function.
  SILDeclRef next = SILDeclRef(vd, thunk.kind);
  assert(!next.isCurried);

  auto constantInfo = SGF.SGM.Types.getConstantInfo(next);

  // If the function is natively foreign, reference its foreign entry point.
  if (requiresForeignToNativeThunk(vd))
    return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)),
            next};

  // If the thunk is a curry thunk for a direct method reference, we are
  // doing a direct dispatch (eg, a fragile 'super.foo()' call).
  if (thunk.isDirectReference)
    return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)),
            next};

  if (auto *func = dyn_cast<AbstractFunctionDecl>(vd)) {
    if (getMethodDispatch(func) == MethodDispatch::Class) {
      // Use the dynamic thunk if dynamic.
      if (vd->isObjCDynamic()) {
        return {SGF.emitDynamicMethodRef(loc, next, constantInfo.SILFnType),
                next};
      }

      auto methodTy = SGF.SGM.Types.getConstantOverrideType(next);
      SILValue result =
          SGF.emitClassMethodRef(loc, selfArg.getValue(), next, methodTy);
      return {ManagedValue::forUnmanaged(result),
              next.getOverriddenVTableEntry()};
    }

    // If the fully-uncurried reference is to a generic method, look up the
    // witness.
    if (constantInfo.SILFnType->getRepresentation()
          == SILFunctionTypeRepresentation::WitnessMethod) {
      auto protocol = func->getDeclContext()->getSelfProtocolDecl();
      auto origSelfType = protocol->getSelfInterfaceType()->getCanonicalType();
      auto substSelfType = origSelfType.subst(curriedSubs)->getCanonicalType();
      auto conformance = curriedSubs.lookupConformance(origSelfType, protocol);
      auto result = SGF.B.createWitnessMethod(loc, substSelfType, *conformance,
                                              next, constantInfo.getSILType());
      return {ManagedValue::forUnmanaged(result), next};
    }
  }

  // Otherwise, emit a direct call.
  return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)),
          next};
}
Ejemplo n.º 28
0
ManagedValue SILGenBuilder::createLoadCopy(SILLocation loc, ManagedValue v,
                                           const TypeLowering &lowering) {
  assert(lowering.getLoweredType().getAddressType() == v.getType());
  SILValue result =
      lowering.emitLoadOfCopy(*this, loc, v.getValue(), IsNotTake);
  if (lowering.isTrivial())
    return ManagedValue::forUnmanaged(result);
  assert((!lowering.isAddressOnly()
          || !SGF.silConv.useLoweredAddresses()) &&
         "cannot retain an unloadable type");
  return SGF.emitManagedRValueWithCleanup(result, lowering);
}
Ejemplo n.º 29
0
void SILGenFunction::emitClassMemberDestruction(ManagedValue selfValue,
                                                ClassDecl *cd,
                                                CleanupLocation cleanupLoc) {
  selfValue = selfValue.borrow(*this, cleanupLoc);
  for (VarDecl *vd : cd->getStoredProperties()) {
    const TypeLowering &ti = getTypeLowering(vd->getType());
    if (!ti.isTrivial()) {
      SILValue addr =
          B.createRefElementAddr(cleanupLoc, selfValue.getValue(), vd,
                                 ti.getLoweredType().getAddressType());
      B.createDestroyAddr(cleanupLoc, addr);
    }
  }
}
Ejemplo n.º 30
0
ManagedValue SILGenBuilder::createUncheckedEnumData(SILLocation loc,
                                                    ManagedValue operand,
                                                    EnumElementDecl *element) {
  if (operand.hasCleanup()) {
    SILValue newValue =
        SILBuilder::createUncheckedEnumData(loc, operand.forward(gen), element);
    return gen.emitManagedRValueWithCleanup(newValue);
  }

  ManagedValue borrowedBase = operand.borrow(gen, loc);
  SILValue newValue = SILBuilder::createUncheckedEnumData(
      loc, borrowedBase.getValue(), element);
  return ManagedValue::forUnmanaged(newValue);
}