OpenClonk
C4AulScriptFunc.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2016, The OpenClonk Team and contributors
5  *
6  * Distributed under the terms of the ISC license; see accompanying file
7  * "COPYING" for details.
8  *
9  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10  * See accompanying file "TRADEMARK" for details.
11  *
12  * To redistribute this file separately, substitute the full license texts
13  * for the above references.
14  */
15 
16 #ifndef C4AULSCRIPTFUNC_H_
17 #define C4AULSCRIPTFUNC_H_
18 
19 #include "script/C4Value.h"
20 #include "script/C4ValueMap.h"
21 
22 // byte code chunk type
23 // some special script functions defined hard-coded to reduce the exec context
24 enum C4AulBCCType : int
25 {
26  AB_ARRAYA, // array or proplist access
28  AB_PROP, // proplist access with static key
30  AB_ARRAY_SLICE, // array slicing
32  AB_DUP, // duplicate value from stack
33  AB_DUP_CONTEXT, // duplicate value from stack of parent function
34  AB_STACK_SET, // copy top of stack to stack
35  AB_POP_TO, // pop top of stack to stack
36  AB_LOCALN, // a property of this
38  AB_GLOBALN, // a named global
40  AB_PAR, // Par statement
41  AB_THIS, // this()
42  AB_FUNC, // function
43 
44 // prefix
45  AB_Inc, // ++
46  AB_Dec, // --
47  AB_BitNot, // ~
48  AB_Not, // !
49  AB_Neg, // -
50 
51 // postfix
52  AB_Pow, // **
53  AB_Div, // /
54  AB_Mul, // *
55  AB_Mod, // %
56  AB_Sub, // -
57  AB_Sum, // +
58  AB_LeftShift, // <<
64  AB_Equal, // ==
65  AB_NotEqual, // !=
66  AB_BitAnd, // &
67  AB_BitXOr, // ^
68  AB_BitOr, // |
69 
70  AB_CALL, // direct object call
71  AB_CALLFS, // failsafe direct call
72  AB_STACK, // push nulls / pop
73  AB_INT, // constant: int
74  AB_BOOL, // constant: bool
75  AB_STRING, // constant: string
76  AB_CPROPLIST, // constant: proplist
77  AB_CARRAY, // constant: array
78  AB_CFUNCTION, // constant: function
79  AB_NIL, // constant: nil
80  AB_NEW_ARRAY, // semi-constant: array
81  AB_NEW_PROPLIST, // create a new proplist
82  AB_JUMP, // jump
83  AB_JUMPAND, // jump if convertible to false, else pop the stack
84  AB_JUMPOR, // jump if convertible to true, else pop the stack
85  AB_JUMPNNIL, // jump if not nil, else pop the stack
86  AB_CONDN, // conditional jump (negated, pops stack)
87  AB_COND, // conditional jump (pops stack)
88  AB_FOREACH_NEXT, // foreach: next element
89  AB_RETURN, // return statement
90  AB_ERR, // parse error at this position
91  AB_DEBUG, // debug break
92  AB_EOFN, // end of function
93 };
94 
95 // byte code chunk
96 class C4AulBCC
97 {
98 public:
99  C4AulBCCType bccType{AB_EOFN}; // chunk type
100  union
101  {
102  intptr_t X;
103  int32_t i;
104  C4String * s;
105  C4PropList * p;
106  C4ValueArray * a;
107  C4AulFunc * f;
108  } Par; // extra info
109  C4AulBCC() = default;
111  {
112  IncRef();
113  }
114  C4AulBCC(const C4AulBCC & from): C4AulBCC(from.bccType, from.Par.X) { }
115  C4AulBCC & operator = (const C4AulBCC & from)
116  {
117  DecRef();
118  bccType = from.bccType;
119  Par = from.Par;
120  IncRef();
121  return *this;
122  }
123  C4AulBCC(C4AulBCC && from): bccType(from.bccType), Par(from.Par)
124  {
125  from.bccType = AB_EOFN;
126  }
128  {
129  DecRef();
130  bccType = from.bccType;
131  Par = from.Par;
132  from.bccType = AB_EOFN;
133  return *this;
134  }
136  {
137  DecRef();
138  }
139 private:
140  void IncRef()
141  {
142  switch (bccType)
143  {
144  case AB_ERR:
145  if (Par.s)
146  case AB_STRING: case AB_CALL: case AB_CALLFS: case AB_LOCALN: case AB_LOCALN_SET: case AB_PROP: case AB_PROP_SET:
147  Par.s->IncRef();
148  break;
149  case AB_CARRAY:
150  Par.a->IncRef();
151  break;
152  default: break;
153  }
154  }
155  void DecRef()
156  {
157  switch (bccType)
158  {
159  case AB_ERR:
160  if (Par.s)
161  case AB_STRING: case AB_CALL: case AB_CALLFS: case AB_LOCALN: case AB_LOCALN_SET: case AB_PROP: case AB_PROP_SET:
162  Par.s->DecRef();
163  break;
164  case AB_CARRAY:
165  Par.a->DecRef();
166  break;
167  default: break;
168  }
169  }
170 };
171 
172 // script function class
174 {
175 public:
176  C4AulFunc *OwnerOverloaded; // overloaded owner function; if present
177  void SetOverloaded(C4AulFunc *);
178  C4AulScriptFunc *SFunc() override { return this; } // type check func...
179 protected:
180  void AddBCC(C4AulBCCType eType, intptr_t = 0, const char * SPos = nullptr); // add byte code chunk and advance
181  void RemoveLastBCC();
182  void ClearCode();
183  int GetCodePos() const { return Code.size(); }
184  C4AulBCC *GetCodeByPos(int iPos) { return &Code[iPos]; }
185  C4AulBCC *GetLastCode() { return Code.empty() ? nullptr : &Code.back(); }
186  void DumpByteCode();
187  std::vector<C4AulBCC> Code;
188  std::vector<const char *> PosForCode;
189  int ParCount;
190  C4V_Type ParType[C4AUL_MAX_Par]; // parameter types
191 
192 public:
193  const char *Script; // script pos
194  C4ValueMapNames VarNamed; // list of named vars in this function
195  C4ValueMapNames ParNamed; // list of named pars in this function
196  void AddPar(const char * Idtf, C4V_Type type = C4V_Any)
197  {
198  assert(ParCount < C4AUL_MAX_Par);
199  assert(ParCount == ParNamed.iSize);
200  ParNamed.AddName(Idtf);
201  ParType[ParCount] = type;
202  ++ParCount;
203  }
204  C4ScriptHost *pOrgScript; // the orginal script (!= Owner if included or appended)
205 
206  C4AulScriptFunc(C4PropListStatic * Parent, C4ScriptHost *pOrgScript, const char *pName, const char *Script);
207  C4AulScriptFunc(C4PropListStatic * Parent, const C4AulScriptFunc &FromFunc); // copy script/code, etc from given func
208  ~C4AulScriptFunc() override;
209 
210  void ParseDirectExecFunc(C4AulScriptEngine *Engine, C4AulScriptContext* context = nullptr);
211  void ParseDirectExecStatement(C4AulScriptEngine *Engine, C4AulScriptContext* context = nullptr);
212 
213  bool GetPublic() const override { return true; }
214  int GetParCount() const override { return ParCount; }
215  const C4V_Type *GetParType() const override { return ParType; }
216  C4V_Type GetRetType() const override { return C4V_Any; }
217  C4Value Exec(C4PropList * p, C4Value pPars[], bool fPassErrors=false) override; // execute func
218 
219  int GetLineOfCode(C4AulBCC * bcc);
220  C4AulBCC * GetCode();
221 
222  uint32_t tProfileTime; // internally set by profiler
223 
224  friend class C4AulCompiler;
225  friend class C4AulParse;
226  friend class C4ScriptHost;
227 };
228 
229 #endif /* C4AULSCRIPTFUNC_H_ */
#define X(sdl, oc)
#define C4AUL_MAX_Par
Definition: C4AulFunc.h:26
C4AulBCCType
@ AB_Pow
@ AB_BitAnd
@ AB_FOREACH_NEXT
@ AB_LeftShift
@ AB_ARRAY_SLICE_SET
@ AB_THIS
@ AB_Sum
@ AB_GreaterThanEqual
@ AB_Inc
@ AB_DEBUG
@ AB_INT
@ AB_Mul
@ AB_ARRAYA
@ AB_EOFN
@ AB_Sub
@ AB_PAR
@ AB_LessThan
@ AB_LessThanEqual
@ AB_ARRAYA_SET
@ AB_RightShift
@ AB_GreaterThan
@ AB_PROP
@ AB_BitNot
@ AB_CPROPLIST
@ AB_Equal
@ AB_BitOr
@ AB_CALLFS
@ AB_ERR
@ AB_CALL
@ AB_FUNC
@ AB_BOOL
@ AB_POP_TO
@ AB_Mod
@ AB_GLOBALN
@ AB_STRING
@ AB_NIL
@ AB_NotEqual
@ AB_CARRAY
@ AB_STACK_SET
@ AB_Div
@ AB_STACK
@ AB_NEW_ARRAY
@ AB_ARRAY_SLICE
@ AB_LOCALN
@ AB_GLOBALN_SET
@ AB_DUP
@ AB_LOCALN_SET
@ AB_JUMPAND
@ AB_DUP_CONTEXT
@ AB_JUMPNNIL
@ AB_Dec
@ AB_CONDN
@ AB_JUMPOR
@ AB_CFUNCTION
@ AB_Neg
@ AB_COND
@ AB_JUMP
@ AB_Not
@ AB_BitXOr
@ AB_RETURN
@ AB_NEW_PROPLIST
@ AB_PROP_SET
#define s
#define a
C4V_Type
Definition: C4Value.h:24
@ C4V_Any
Definition: C4Value.h:37
C4AulBCC(C4AulBCCType bccType, intptr_t X)
C4AulBCC & operator=(const C4AulBCC &from)
union C4AulBCC::@83 Par
C4AulBCC()=default
C4AulBCC(const C4AulBCC &from)
C4AulBCC(C4AulBCC &&from)
C4AulBCCType bccType
C4PropListStatic * Parent
Definition: C4AulFunc.h:55
std::vector< C4AulBCC > Code
void AddPar(const char *Idtf, C4V_Type type=C4V_Any)
const char * Script
const C4V_Type * GetParType() const override
C4AulFunc * OwnerOverloaded
C4AulScriptFunc(C4PropListStatic *Parent, C4ScriptHost *pOrgScript, const char *pName, const char *Script)
C4V_Type GetRetType() const override
C4Value Exec(C4PropList *p, C4Value pPars[], bool fPassErrors=false) override
std::vector< const char * > PosForCode
void ParseDirectExecStatement(C4AulScriptEngine *Engine, C4AulScriptContext *context=nullptr)
Definition: C4AulParse.cpp:848
C4ValueMapNames VarNamed
void ParseDirectExecFunc(C4AulScriptEngine *Engine, C4AulScriptContext *context=nullptr)
Definition: C4AulParse.cpp:839
C4AulBCC * GetCodeByPos(int iPos)
void AddBCC(C4AulBCCType eType, intptr_t=0, const char *SPos=nullptr)
C4AulBCC * GetCode()
int GetCodePos() const
C4AulScriptFunc * SFunc() override
int GetLineOfCode(C4AulBCC *bcc)
C4V_Type ParType[C4AUL_MAX_Par]
bool GetPublic() const override
C4AulBCC * GetLastCode()
C4ValueMapNames ParNamed
void SetOverloaded(C4AulFunc *)
C4ScriptHost * pOrgScript
int GetParCount() const override
~C4AulScriptFunc() override
int32_t AddName(const char *pnName)
Definition: C4ValueMap.cpp:429