KSeExpr 6.0.0.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
13namespace KSeExpr {
14int 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
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);
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);
69 node->setData(data);
70 interpreter->s[ptrDataLoc] = reinterpret_cast<char *>(data);
71
72 return outoperand;
73}
74} // namespace KSeExpr
75
76extern "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
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)
Node that calls a function.
Definition ExprNode.h:654
void setData(Data *data) const
associate blind data with this node (subsequently owned by this object)
Definition ExprNode.h:744
const ExprFunc * func() const
Definition ExprNode.h:762
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
base class for custom instance data
Definition ExprNode.h:723