IRGen: Add implementation for dynamically replaceable functions

A dynamically replaceable function calls through a global variable that
holds the function pointer.

struct ChainEntry {
   void *(funPtr)();
   struct ChainEntry *next;
}

ChainEntry dynamicallyReplaceableVar;

void dynamicallyReplaceableFunction() {
  dynamicallyReplaceableVar.funPtr()
}

dynamic replacements will be chainable so the global variable also
functions as the root entry in the chain of replacements.

A dynamic replacement functions can call the previous implementation by
going through its chain entry.

ChainEntry chainEntryOf_dynamic_replacement_for_foo;

void dynamic_replacement_for_foo() {
   // call the previous (original) implementation.
   chainEntryOf_dynamic_replacement_for_foo.funPtr();
}
This commit is contained in:
Arnold Schwaighofer
2018-08-24 07:07:09 -07:00
parent 5f4e183302
commit ebbe3aed1c
14 changed files with 343 additions and 41 deletions

View File

@@ -458,6 +458,16 @@ IRGenModule::IRGenModule(IRGenerator &irgen,
IsSwiftErrorInRegister =
clang::CodeGen::swiftcall::isSwiftErrorLoweredInRegister(
ClangCodeGen->CGM());
DynamicReplacementLinkEntryTy =
llvm::StructType::create(getLLVMContext(), "swift.dyn_repl_link_entry");
DynamicReplacementLinkEntryPtrTy =
DynamicReplacementLinkEntryTy->getPointerTo(DefaultAS);
llvm::Type *linkEntryFields[] = {
Int8PtrTy, // function pointer.
DynamicReplacementLinkEntryPtrTy // next.
};
DynamicReplacementLinkEntryTy->setBody(linkEntryFields);
}
IRGenModule::~IRGenModule() {