KSeExpr  4.0.4.0
ExprFuncX.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2019 Disney Enterprises, Inc.
2 // SPDX-License-Identifier: LicenseRef-Apache-2.0
3 // SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 
6 #include <cstdio>
7 
8 #include "ExprFunc.h"
9 #include "ExprFuncX.h"
10 #include "Interpreter.h"
11 #include "ExprNode.h"
12 
13 namespace KSeExpr {
14 int ExprFuncSimple::EvalOp(int *opData, double *fp, char **c, std::vector<int> &callStack) {
15  auto *simple = reinterpret_cast<ExprFuncSimple *>(c[opData[0]]);
16  // ExprFuncNode::Data* simpleData=reinterpret_cast<ExprFuncNode::Data*>(c[opData[1]]);
17  ArgHandle args(opData, fp, c, callStack);
18  simple->eval(args);
19  return 1;
20 }
21 
22 int ExprFuncSimple::buildInterpreter(const ExprFuncNode *node, Interpreter *interpreter) const {
23  std::vector<int> operands;
24  for (int c = 0; c < node->numChildren(); c++) {
25  int operand = node->child(c)->buildInterpreter(interpreter);
26 #if 0
27  // debug
28  std::cerr<<"we are "<<node->promote(c)<<" "<<c<<std::endl;
29 #endif
30  if (node->promote(c) != 0) {
31  interpreter->addOp(getTemplatizedOp<Promote>(node->promote(c)));
32  int promotedOperand = interpreter->allocFP(node->promote(c));
33  interpreter->addOperand(operand);
34  interpreter->addOperand(promotedOperand);
35  operand = promotedOperand;
36  interpreter->endOp();
37  }
38  operands.push_back(operand);
39  }
40  int outoperand = -1;
41  int nargsData = interpreter->allocFP(1);
42  interpreter->d[nargsData] = node->numChildren();
43  if (node->type().isFP())
44  outoperand = interpreter->allocFP(node->type().dim());
45  else if (node->type().isString())
46  outoperand = interpreter->allocPtr();
47  else
48  assert(false);
49 
50  interpreter->addOp(EvalOp);
51  int ptrLoc = interpreter->allocPtr();
52  int ptrDataLoc = interpreter->allocPtr();
53  interpreter->s[ptrLoc] = (char *)this;
54  interpreter->addOperand(ptrLoc);
55  interpreter->addOperand(ptrDataLoc);
56  interpreter->addOperand(outoperand);
57  interpreter->addOperand(nargsData);
58  for (int operand : operands) {
59  interpreter->addOperand(operand);
60  }
61  interpreter->endOp(false); // do not eval because the function may not be evaluatable!
62 
63  // call into interpreter eval
64  int pc = interpreter->nextPC() - 1;
65  int *opCurr = (&interpreter->opData[0]) + interpreter->ops[pc].second;
66 
67  ArgHandle args(opCurr, &interpreter->d[0], &interpreter->s[0], interpreter->callStack);
68  ExprFuncNode::Data* data = evalConstant(node, args);
69  node->setData(data);
70  interpreter->s[ptrDataLoc] = reinterpret_cast<char *>(data);
71 
72  return outoperand;
73 }
74 } // namespace KSeExpr
75 
76 extern "C" {
77 // allocate int[4+number of args];
78 // allocate char*[2];
79 // allocate double[1+ sizeof(ret) + sizeof(args)]
80 //
81 // int[0]= c , 0
82 // int[1]= c , 1
83 // int[2]= f, 0
84 // int[3]= f, 8
85 //
86 // int[4]= f, 8
87 // int[5]= f, 9
88 //
89 //
90 // double[0] = 0
91 // double[1] = 0
92 // double[2] = 0
93 // double[3] = 0
94 // opData indexes either into f or into c.
95 // opdata[0] points to ExprFuncSimple instance
96 // opdata[1] points to the data generated by evalConstant
97 // opdata[2] points to return value
98 // opdata[3] points to number of args
99 // opdata[4] points to beginning of arguments in
100 void KSeExprLLVMEvalCustomFunction(int *opDataArg,
101  double *fpArg,
102  char **strArg,
103  void **funcdata,
104  const KSeExpr::ExprFuncNode *node) {
105  const KSeExpr::ExprFunc *func = node->func();
106  auto *funcX = const_cast<KSeExpr::ExprFuncX *>(func->funcx());
107  auto *funcSimple = static_cast<KSeExpr::ExprFuncSimple *>(funcX);
108 
109  strArg[0] = reinterpret_cast<char *>(funcSimple);
110 
111  std::vector<int> callStack;
112  KSeExpr::ExprFuncSimple::ArgHandle handle(opDataArg, fpArg, strArg, callStack);
113  if (!*funcdata) {
114  handle.data = funcSimple->evalConstant(node, handle);
115  *funcdata = reinterpret_cast<void *>(handle.data);
116  node->setData(handle.data);
117  } else {
118  handle.data = reinterpret_cast<KSeExpr::ExprFuncNode::Data *>(*funcdata);
119  }
120 
121  funcSimple->eval(handle);
122  // for (int i = 0; i < retSize; ++i) result[i] = fp[1 + i];
123 }
124 }
void KSeExprLLVMEvalCustomFunction(int *opDataArg, double *fpArg, char **strArg, void **funcdata, const KSeExpr::ExprFuncNode *node)
Definition: ExprFuncX.cpp:100
Node that calls a function.
Definition: ExprNode.h:654
const ExprFunc * func() const
Definition: ExprNode.h:762
void setData(Data *data) const
associate blind data with this node (subsequently owned by this object)
Definition: ExprNode.h:744
int promote(int i) const
Definition: ExprNode.h:758
ExprFuncNode::Data * data
Definition: ExprFuncX.h:91
static int EvalOp(int *opData, double *fp, char **c, std::vector< int > &callStack)
Definition: ExprFuncX.cpp:14
int buildInterpreter(const ExprFuncNode *node, Interpreter *interpreter) const override
Build an interpreter to evaluate the expression.
Definition: ExprFuncX.cpp:22
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const =0
Extension function spec, used for complicated argument custom functions.
Definition: ExprFuncX.h:23
Function Definition, used in parse tree and func table.
Definition: ExprFunc.h:35
const ExprFuncX * funcx() const
return pointer to the funcx
Definition: ExprFunc.h:177
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
int numChildren() const
Number of children.
Definition: ExprNode.h:108
const ExprType & type() const
The type of the node.
Definition: ExprNode.h:150
const ExprNode * child(size_t i) const
Get 0 indexed child.
Definition: ExprNode.h:114
int dim() const
Definition: ExprType.h:180
bool isString() const
Definition: ExprType.h:210
bool isFP() const
Direct is predicate checks.
Definition: ExprType.h:190
std::vector< std::pair< OpF, int > > ops
Definition: Interpreter.h:46
std::vector< double > d
Double data (constants and evaluated)
Definition: Interpreter.h:33
int addOp(OpF op)
! adds an operator to the program (pointing to the data at the current location)
Definition: Interpreter.h:63
void endOp(bool execute=true)
Definition: Interpreter.h:73
std::vector< int > callStack
Definition: Interpreter.h:47
std::vector< char * > s
constant and evaluated pointer data
Definition: Interpreter.h:35
int allocFP(int n)
! Allocate a floating point set of data of dimension n
Definition: Interpreter.h:94
int nextPC() const
Return the position that the next instruction will be placed at.
Definition: Interpreter.h:60
int allocPtr()
Allocate a pointer location (can be anything, but typically space for char*)
Definition: Interpreter.h:101
std::vector< int > opData
Ooperands to op.
Definition: Interpreter.h:37
int addOperand(int param)
! Adds an operand. Note this should be done after doing the addOp!
Definition: Interpreter.h:86
base class for custom instance data
Definition: ExprNode.h:723