1 /* 2 AngelCode Scripting Library 3 Copyright (c) 2003-2017 Andreas Jonsson 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any 7 damages arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any 10 purpose, including commercial applications, and to alter it and 11 redistribute it freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you 14 must not claim that you wrote the original software. If you use 15 this software in a product, an acknowledgment in the product 16 documentation would be appreciated but is not required. 17 18 2. Altered source versions must be plainly marked as such, and 19 must not be misrepresented as being the original software. 20 21 3. This notice may not be removed or altered from any source 22 distribution. 23 24 The original version of this library can be located at: 25 http://www.angelcode.com/angelscript/ 26 27 Andreas Jonsson 28 andreas@angelcode.com 29 */ 30 31 32 // 33 // as_scriptfunction.h 34 // 35 // A container for a compiled script function 36 // 37 38 39 40 #ifndef AS_SCRIPTFUNCTION_H 41 #define AS_SCRIPTFUNCTION_H 42 43 #include "as_config.h" 44 #include "as_string.h" 45 #include "as_array.h" 46 #include "as_datatype.h" 47 #include "as_atomic.h" 48 49 BEGIN_AS_NAMESPACE 50 51 class asCScriptEngine; 52 class asCModule; 53 class asCConfigGroup; 54 class asCGlobalProperty; 55 class asCScriptNode; 56 class asCFuncdefType; 57 struct asSNameSpace; 58 59 struct asSScriptVariable 60 { 61 asCString name; 62 asCDataType type; 63 int stackOffset; 64 asUINT declaredAtProgramPos; 65 }; 66 67 enum asEListPatternNodeType 68 { 69 asLPT_REPEAT, 70 asLPT_REPEAT_SAME, 71 asLPT_START, 72 asLPT_END, 73 asLPT_TYPE 74 }; 75 76 struct asSListPatternNode 77 { asSListPatternNodeasSListPatternNode78 asSListPatternNode(asEListPatternNodeType t) : type(t), next(0) {} ~asSListPatternNodeasSListPatternNode79 virtual ~asSListPatternNode() {}; DuplicateasSListPatternNode80 virtual asSListPatternNode *Duplicate() { return asNEW(asSListPatternNode)(type); } 81 asEListPatternNodeType type; 82 asSListPatternNode *next; 83 }; 84 85 struct asSListPatternDataTypeNode : public asSListPatternNode 86 { asSListPatternDataTypeNodeasSListPatternDataTypeNode87 asSListPatternDataTypeNode(const asCDataType &dt) : asSListPatternNode(asLPT_TYPE), dataType(dt) {} DuplicateasSListPatternDataTypeNode88 asSListPatternNode *Duplicate() { return asNEW(asSListPatternDataTypeNode)(dataType); } 89 asCDataType dataType; 90 }; 91 92 enum asEObjVarInfoOption 93 { 94 asOBJ_UNINIT, 95 asOBJ_INIT, 96 asBLOCK_BEGIN, 97 asBLOCK_END 98 }; 99 100 enum asEFuncTrait 101 { 102 asTRAIT_CONSTRUCTOR = 1, 103 asTRAIT_DESTRUCTOR = 2, 104 asTRAIT_CONST = 4, 105 asTRAIT_PRIVATE = 8, 106 asTRAIT_PROTECTED = 16, 107 asTRAIT_FINAL = 32, 108 asTRAIT_OVERRIDE = 64, 109 asTRAIT_SHARED = 128, 110 asTRAIT_EXTERNAL = 256 111 }; 112 113 struct asSFunctionTraits 114 { asSFunctionTraitsasSFunctionTraits115 asSFunctionTraits() : traits(0) {} SetTraitasSFunctionTraits116 void SetTrait(asEFuncTrait trait, bool set) { if (set) traits |= trait; else traits &= ~trait; } GetTraitasSFunctionTraits117 bool GetTrait(asEFuncTrait trait) const { return (traits & trait) ? true : false; } 118 protected: 119 asDWORD traits; 120 }; 121 122 struct asSObjectVariableInfo 123 { 124 asUINT programPos; 125 int variableOffset; 126 asEObjVarInfoOption option; 127 }; 128 129 struct asSSystemFunctionInterface; 130 131 // TODO: Might be interesting to allow enumeration of accessed global variables, and 132 // also functions/methods that are being called. This could be used to build a 133 // code database with call graphs, etc. 134 135 void RegisterScriptFunction(asCScriptEngine *engine); 136 137 class asCScriptFunction : public asIScriptFunction 138 { 139 public: 140 // From asIScriptFunction 141 asIScriptEngine *GetEngine() const; 142 143 // Memory management 144 int AddRef() const; 145 int Release() const; 146 147 // Miscellaneous 148 int GetId() const; 149 asEFuncType GetFuncType() const; 150 const char *GetModuleName() const; 151 asIScriptModule *GetModule() const; 152 const char *GetScriptSectionName() const; 153 const char *GetConfigGroup() const; 154 asDWORD GetAccessMask() const; 155 void *GetAuxiliary() const; 156 157 // Function signature 158 asITypeInfo *GetObjectType() const; 159 const char *GetObjectName() const; 160 const char *GetName() const; 161 const char *GetNamespace() const; 162 const char *GetDeclaration(bool includeObjectName = true, bool includeNamespace = false, bool includeParamNames = false) const; 163 bool IsReadOnly() const; 164 bool IsPrivate() const; 165 bool IsProtected() const; 166 bool IsFinal() const; 167 bool IsOverride() const; 168 bool IsShared() const; 169 asUINT GetParamCount() const; 170 int GetParam(asUINT index, int *typeId, asDWORD *flags = 0, const char **name = 0, const char **defaultArg = 0) const; 171 int GetReturnTypeId(asDWORD *flags = 0) const; 172 173 // Type id for function pointers 174 int GetTypeId() const; 175 bool IsCompatibleWithTypeId(int typeId) const; 176 177 // Delegates 178 void *GetDelegateObject() const; 179 asITypeInfo *GetDelegateObjectType() const; 180 asIScriptFunction *GetDelegateFunction() const; 181 182 // Debug information 183 asUINT GetVarCount() const; 184 int GetVar(asUINT index, const char **name, int *typeId = 0) const; 185 const char * GetVarDecl(asUINT index, bool includeNamespace = false) const; 186 int FindNextLineWithCode(int line) const; 187 188 // For JIT compilation 189 asDWORD *GetByteCode(asUINT *length = 0); 190 191 // User data 192 void *SetUserData(void *userData, asPWORD type); 193 void *GetUserData(asPWORD type) const; 194 195 public: 196 //----------------------------------- 197 // Internal methods 198 SetShared(bool set)199 void SetShared(bool set) {traits.SetTrait(asTRAIT_SHARED, set);} SetReadOnly(bool set)200 void SetReadOnly(bool set) { traits.SetTrait(asTRAIT_CONST, set); } SetFinal(bool set)201 void SetFinal(bool set) { traits.SetTrait(asTRAIT_FINAL, set); } SetOverride(bool set)202 void SetOverride(bool set) { traits.SetTrait(asTRAIT_OVERRIDE, set); } SetProtected(bool set)203 void SetProtected(bool set) { traits.SetTrait(asTRAIT_PROTECTED, set); } SetPrivate(bool set)204 void SetPrivate(bool set) { traits.SetTrait(asTRAIT_PRIVATE, set); } 205 206 asCScriptFunction(asCScriptEngine *engine, asCModule *mod, asEFuncType funcType); 207 ~asCScriptFunction(); 208 209 // Keep an internal reference counter to separate references coming from 210 // application or script objects and references coming from the script code 211 int AddRefInternal(); 212 int ReleaseInternal(); 213 214 void DestroyHalfCreated(); 215 216 // TODO: operator== 217 // TODO: The asIScriptFunction should provide operator== and operator!= that should do a 218 // a value comparison. Two delegate objects that point to the same object and class method should compare as equal 219 // TODO: The operator== should also be provided in script as opEquals to allow the same comparison in script 220 // To do this we'll need some way to adapt the argtype for opEquals for each funcdef, preferrably without instantiating lots of different methods 221 // Perhaps reusing 'auto' to mean the same type as the object 222 //bool operator==(const asCScriptFunction &other) const; 223 224 void DestroyInternal(); 225 226 void AddVariable(asCString &name, asCDataType &type, int stackOffset); 227 228 int GetSpaceNeededForArguments(); 229 int GetSpaceNeededForReturnValue(); 230 asCString GetDeclarationStr(bool includeObjectName = true, bool includeNamespace = false, bool includeParamNames = false) const; 231 int GetLineNumber(int programPosition, int *sectionIdx); 232 void ComputeSignatureId(); 233 bool IsSignatureEqual(const asCScriptFunction *func) const; 234 bool IsSignatureExceptNameEqual(const asCScriptFunction *func) const; 235 bool IsSignatureExceptNameEqual(const asCDataType &retType, const asCArray<asCDataType> ¶mTypes, const asCArray<asETypeModifiers> &inOutFlags, const asCObjectType *type, bool isReadOnly) const; 236 bool IsSignatureExceptNameAndReturnTypeEqual(const asCScriptFunction *fun) const; 237 bool IsSignatureExceptNameAndReturnTypeEqual(const asCArray<asCDataType> ¶mTypes, const asCArray<asETypeModifiers> &inOutFlags, const asCObjectType *type, bool isReadOnly) const; 238 bool IsSignatureExceptNameAndObjectTypeEqual(const asCScriptFunction *func) const; 239 240 asCTypeInfo *GetTypeInfoOfLocalVar(short varOffset); 241 242 void MakeDelegate(asCScriptFunction *func, void *obj); 243 244 int RegisterListPattern(const char *decl, asCScriptNode *listPattern); 245 int ParseListPattern(asSListPatternNode *&target, const char *decl, asCScriptNode *listPattern); 246 247 bool DoesReturnOnStack() const; 248 249 void JITCompile(); 250 251 void AddReferences(); 252 void ReleaseReferences(); 253 254 void AllocateScriptFunctionData(); 255 void DeallocateScriptFunctionData(); 256 257 asCGlobalProperty *GetPropertyByGlobalVarPtr(void *gvarPtr); 258 259 // GC methods (for delegates) 260 int GetRefCount(); 261 void SetFlag(); 262 bool GetFlag(); 263 void EnumReferences(asIScriptEngine *engine); 264 void ReleaseAllHandles(asIScriptEngine *engine); 265 266 public: 267 //----------------------------------- 268 // Properties 269 270 mutable asCAtomic externalRefCount; // Used for external referneces 271 asCAtomic internalRefCount; // Used for internal references 272 mutable bool gcFlag; 273 asCScriptEngine *engine; 274 asCModule *module; 275 276 asCArray<asPWORD> userData; 277 278 // Function signature 279 asCString name; 280 asCDataType returnType; 281 asCArray<asCDataType> parameterTypes; 282 asCArray<asCString> parameterNames; 283 asCArray<asETypeModifiers> inOutFlags; 284 asCArray<asCString *> defaultArgs; 285 asSFunctionTraits traits; 286 asCObjectType *objectType; 287 int signatureId; 288 289 int id; 290 291 asEFuncType funcType; 292 asDWORD accessMask; 293 294 // Namespace will be null for funcdefs that are declared as child funcdefs 295 // of a class. In this case the namespace shall be taken from the parentClass 296 // in the funcdefType 297 asSNameSpace *nameSpace; 298 299 asCFuncdefType *funcdefType; // Doesn't increase refCount 300 301 // Used by asFUNC_DELEGATE 302 void *objForDelegate; 303 asCScriptFunction *funcForDelegate; 304 305 // Used by list factory behaviour 306 asSListPatternNode *listPattern; 307 308 // Used by asFUNC_SCRIPT 309 struct ScriptFunctionData 310 { 311 // Bytecode for the script function 312 asCArray<asDWORD> byteCode; 313 314 // The stack space needed for the local variables 315 asDWORD variableSpace; 316 317 // These hold information on objects and function pointers, including temporary 318 // variables used by exception handler and when saving bytecode 319 asCArray<asCTypeInfo*> objVariableTypes; 320 asCArray<int> objVariablePos; 321 322 // The first variables in above array are allocated on the heap, the rest on the stack. 323 // This variable shows how many are on the heap. 324 asUINT objVariablesOnHeap; 325 326 // Holds information on scope for object variables on the stack 327 asCArray<asSObjectVariableInfo> objVariableInfo; 328 329 // The stack needed to execute the function 330 int stackNeeded; 331 332 // JIT compiled code of this function 333 asJITFunction jitFunction; 334 335 // Holds debug information on explicitly declared variables 336 asCArray<asSScriptVariable*> variables; 337 // Store position, line number pairs for debug information 338 asCArray<int> lineNumbers; 339 // Store the script section where the code was declared 340 int scriptSectionIdx; 341 // Store the location where the function was declared (row in the lower 20 bits, and column in the upper 12) 342 int declaredAt; 343 // Store position/index pairs if the bytecode is compiled from multiple script sections 344 asCArray<int> sectionIdxs; 345 }; 346 ScriptFunctionData *scriptData; 347 348 // Stub functions and delegates don't own the object and parameters 349 bool dontCleanUpOnException; 350 351 // Used by asFUNC_VIRTUAL 352 int vfTableIdx; 353 354 // Used by asFUNC_SYSTEM 355 asSSystemFunctionInterface *sysFuncIntf; 356 }; 357 358 const char * const DELEGATE_FACTORY = "$dlgte"; 359 asCScriptFunction *CreateDelegate(asCScriptFunction *func, void *obj); 360 361 END_AS_NAMESPACE 362 363 #endif 364