[pkg-d-commits] [ldc] 86/149: Prepare DtoCallFunction() for runtime function calls (#1238)

Matthias Klumpp mak at moszumanska.debian.org
Sun Apr 23 22:37:01 UTC 2017


This is an automated email from the git hooks/post-receive script.

mak pushed a commit to annotated tag v1.2.0
in repository ldc.

commit 87bfcc71082b1b9ad63ba0699830043f61ebac5a
Author: kinke <kinke at users.noreply.github.com>
Date:   Mon Feb 6 16:59:13 2017 +0100

    Prepare DtoCallFunction() for runtime function calls (#1238)
    
    By also accepting DValue args, not just Expressions.
---
 gen/llvmhelpers.h |   3 ++
 gen/tocall.cpp    | 139 ++++++++++++++++++++++++++++++++----------------------
 2 files changed, 85 insertions(+), 57 deletions(-)

diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h
index dd7bb82..bb3b244 100644
--- a/gen/llvmhelpers.h
+++ b/gen/llvmhelpers.h
@@ -216,6 +216,9 @@ bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e,
 ///
 DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
                         Expressions *arguments, LLValue *sretPointer = nullptr);
+DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
+                        const std::vector<DValue *> &argvals,
+                        LLValue *sretPointer = nullptr);
 
 Type *stripModifiers(Type *type, bool transitive = false);
 
diff --git a/gen/tocall.cpp b/gen/tocall.cpp
index 2c22d4e..1c8a821 100644
--- a/gen/tocall.cpp
+++ b/gen/tocall.cpp
@@ -208,18 +208,16 @@ static void addExplicitArguments(std::vector<LLValue *> &args, AttrSet &attrs,
 
 ////////////////////////////////////////////////////////////////////////////////
 
-static LLValue *getTypeinfoArrayArgumentForDVarArg(Expressions *arguments,
-                                                   int begin) {
+static LLValue *
+getTypeinfoArrayArgumentForDVarArg(const std::vector<DValue *> &argvals,
+                                   int begin) {
   IF_LOG Logger::println("doing d-style variadic arguments");
   LOG_SCOPE
 
   // number of non variadic args
   IF_LOG Logger::println("num non vararg params = %d", begin);
 
-  // get n args in arguments list
-  size_t n_arguments = arguments ? arguments->dim : 0;
-
-  const size_t numVariadicArgs = n_arguments - begin;
+  const size_t numVariadicArgs = argvals.size() - begin;
 
   // build type info array
   LLType *typeinfotype = DtoType(Type::dtypeinfo->type);
@@ -232,9 +230,9 @@ static LLValue *getTypeinfoArrayArgumentForDVarArg(Expressions *arguments,
   IF_LOG Logger::cout() << "_arguments storage: " << *typeinfomem << '\n';
 
   std::vector<LLConstant *> vtypeinfos;
-  vtypeinfos.reserve(n_arguments);
-  for (size_t i = begin; i < n_arguments; i++) {
-    vtypeinfos.push_back(DtoTypeInfoOf((*arguments)[i]->type));
+  vtypeinfos.reserve(argvals.size());
+  for (size_t i = begin; i < argvals.size(); i++) {
+    vtypeinfos.push_back(DtoTypeInfoOf(argvals[i]->type));
   }
 
   // apply initializer
@@ -634,13 +632,15 @@ public:
 
   ImplicitArgumentsBuilder(std::vector<LLValue *> &args, AttrSet &attrs,
                            Loc &loc, DValue *fnval,
-                           LLFunctionType *llCalleeType, Expressions *arguments,
+                           LLFunctionType *llCalleeType,
+                           const std::vector<DValue *> &argvals,
                            Type *resulttype, LLValue *sretPointer)
-      : args(args), attrs(attrs), loc(loc), fnval(fnval), arguments(arguments),
+      : args(args), attrs(attrs), loc(loc), fnval(fnval), argvals(argvals),
         resulttype(resulttype), sretPointer(sretPointer),
         // computed:
-        calleeType(fnval->type), dfnval(fnval->isFunc()),
-        irFty(DtoIrTypeFunction(fnval)), tf(DtoTypeFunction(fnval)),
+        isDelegateCall(fnval->type->toBasetype()->ty == Tdelegate),
+        dfnval(fnval->isFunc()), irFty(DtoIrTypeFunction(fnval)),
+        tf(DtoTypeFunction(fnval)),
         llArgTypesBegin(llCalleeType->param_begin()) {}
 
   void addImplicitArgs() {
@@ -661,12 +661,12 @@ private:
   AttrSet &attrs;
   Loc &loc;
   DValue *const fnval;
-  Expressions *const arguments;
+  const std::vector<DValue *> &argvals;
   Type *const resulttype;
   LLValue *const sretPointer;
 
   // computed:
-  Type *const calleeType;
+  const bool isDelegateCall;
   DFuncValue *const dfnval;
   IrFuncTy &irFty;
   TypeFunction *const tf;
@@ -700,10 +700,9 @@ private:
   // Adds an optional context/this pointer argument.
   void addContext() {
     bool thiscall = irFty.arg_this;
-    bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate);
     bool nestedcall = irFty.arg_nest;
 
-    if (!thiscall && !delegatecall && !nestedcall)
+    if (!thiscall && !isDelegateCall && !nestedcall)
       return;
 
     size_t index = args.size();
@@ -734,7 +733,7 @@ private:
       // ... or a normal 'this' argument
       LLValue *thisarg = DtoBitCast(dfnval->vthis, llArgType);
       args.push_back(thisarg);
-    } else if (delegatecall) {
+    } else if (isDelegateCall) {
       // ... or a delegate context arg
       LLValue *ctxarg;
       if (fnval->isLVal()) {
@@ -767,7 +766,7 @@ private:
 
     if (irFty.arg_objcSelector && dfnval) {
       if (auto sel = dfnval->func->objc.selector) {
-        LLGlobalVariable* selptr = objc_getMethVarRef(*sel);
+        LLGlobalVariable *selptr = objc_getMethVarRef(*sel);
         args.push_back(DtoBitCast(DtoLoad(selptr), getVoidPtrType()));
         hasObjcSelector = true;
       }
@@ -782,7 +781,7 @@ private:
 
     int numFormalParams = Parameter::dim(tf->parameters);
     LLValue *argumentsArg =
-        getTypeinfoArrayArgumentForDVarArg(arguments, numFormalParams);
+        getTypeinfoArrayArgumentForDVarArg(argvals, numFormalParams);
 
     args.push_back(argumentsArg);
     attrs.add(args.size(), irFty.arg_arguments->attrs);
@@ -791,18 +790,17 @@ private:
 
 ////////////////////////////////////////////////////////////////////////////////
 
-// FIXME: this function is a mess !
-
-DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
-                        Expressions *arguments, LLValue *sretPointer) {
-  IF_LOG Logger::println("DtoCallFunction()");
-  LOG_SCOPE
+namespace {
 
+// FIXME: this function is a mess !
+DValue *DtoCallFunctionImpl(Loc &loc, Type *resulttype, DValue *fnval,
+                            const std::vector<DValue *> &argvals,
+                            LLValue *sretPointer) {
   // make sure the D callee type has been processed
   DtoType(fnval->type);
 
   // get func value if any
-  DFuncValue *dfnval = fnval->isFunc();
+  DFuncValue *const dfnval = fnval->isFunc();
 
   // get function type info
   IrFuncTy &irFty = DtoIrTypeFunction(fnval);
@@ -834,7 +832,7 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
   args.reserve(irFty.args.size());
 
   // handle implicit arguments (sret, context/this, _arguments)
-  ImplicitArgumentsBuilder iab(args, attrs, loc, fnval, callableTy, arguments,
+  ImplicitArgumentsBuilder iab(args, attrs, loc, fnval, callableTy, argvals,
                                resulttype, sretPointer);
   iab.addImplicitArgs();
 
@@ -853,34 +851,6 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
   }
 
   const int numFormalParams = Parameter::dim(tf->parameters); // excl. variadics
-  const size_t n_arguments =
-      arguments ? arguments->dim : 0; // number of explicit arguments
-
-  std::vector<DValue *> argvals(n_arguments, static_cast<DValue *>(nullptr));
-  if (dfnval && dfnval->func && dfnval->func->isArrayOp) {
-    // For array ops, the druntime implementation signatures are crafted
-    // specifically such that the evaluation order is as expected with
-    // the strange DMD reverse parameter passing order. Thus, we need
-    // to actually build the arguments right-to-left for them.
-    for (int i = numFormalParams - 1; i >= 0; --i) {
-      Parameter *fnarg = Parameter::getNth(tf->parameters, i);
-      assert(fnarg);
-      DValue *argval = DtoArgument(fnarg, (*arguments)[i]);
-      argvals[i] = argval;
-    }
-  } else {
-    for (int i = 0; i < numFormalParams; ++i) {
-      Parameter *fnarg = Parameter::getNth(tf->parameters, i);
-      assert(fnarg);
-      DValue *argval = DtoArgument(fnarg, (*arguments)[i]);
-      argvals[i] = argval;
-    }
-  }
-  // add varargs
-  for (size_t i = numFormalParams; i < n_arguments; ++i) {
-    argvals[i] = DtoArgument(nullptr, (*arguments)[i]);
-  }
-
   addExplicitArguments(args, attrs, irFty, callableTy, argvals,
                        numFormalParams);
 
@@ -911,7 +881,8 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
                                                                         : 0);
   LLValue *retllval =
       (irFty.arg_sret ? args[sretArgIndex] : call.getInstruction());
-  bool retValIsLVal = (tf->isref && returnTy != Tvoid) || (irFty.arg_sret != nullptr);
+  bool retValIsLVal =
+      (tf->isref && returnTy != Tvoid) || (irFty.arg_sret != nullptr);
 
   if (!retValIsLVal) {
     // let the ABI transform the return value back
@@ -1044,3 +1015,57 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
 
   return new DImValue(resulttype, retllval);
 }
+
+std::vector<DValue *> evaluateArgExpressions(DValue *fnval,
+                                             Expressions *arguments) {
+  IF_LOG Logger::println("Evaluating argument expressions");
+  LOG_SCOPE
+
+  const auto tf = DtoTypeFunction(fnval);
+
+  const size_t numArguments = arguments ? arguments->dim : 0;
+  std::vector<DValue *> argvals(numArguments);
+
+  // For array ops, the druntime implementation signatures are crafted
+  // specifically such that the evaluation order is as expected with
+  // the strange DMD reverse parameter passing order. Thus, we need
+  // to actually evaluate the arguments right-to-left for them.
+  const auto dfnval = fnval->isFunc();
+  const bool reverse = (dfnval && dfnval->func && dfnval->func->isArrayOp);
+
+  // formal params (excl. variadics)
+  const size_t numFormalParams = Parameter::dim(tf->parameters);
+  for (size_t j = 0; j < numFormalParams; ++j) {
+    size_t i = (!reverse ? j : numFormalParams - 1 - j);
+    Parameter *fnarg = Parameter::getNth(tf->parameters, i);
+    assert(fnarg);
+    argvals[i] = DtoArgument(fnarg, (*arguments)[i]);
+  }
+
+  // append variadics
+  for (size_t i = numFormalParams; i < numArguments; ++i) {
+    argvals[i] = DtoArgument(nullptr, (*arguments)[i]);
+  }
+
+  return argvals;
+}
+
+} // anonymous namespace
+
+DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
+                        const std::vector<DValue *> &argvals,
+                        LLValue *sretPointer) {
+  IF_LOG Logger::println("DtoCallFunction()");
+  LOG_SCOPE
+
+  return DtoCallFunctionImpl(loc, resulttype, fnval, argvals, sretPointer);
+}
+
+DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
+                        Expressions *arguments, llvm::Value *sretPointer) {
+  IF_LOG Logger::println("DtoCallFunction()");
+  LOG_SCOPE
+
+  const auto argvals = evaluateArgExpressions(fnval, arguments);
+  return DtoCallFunctionImpl(loc, resulttype, fnval, argvals, sretPointer);
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git



More information about the pkg-d-commits mailing list