HyperDbg Debugger
Loading...
Searching...
No Matches
script-engine.c File Reference

Script engine parser and codegen. More...

#include "pch.h"
#include "platform/user/header/platform-lib-calls.h"

Functions

VOID ShowMessages (const char *Fmt,...)
 Show messages.
UINT64 ScriptEngineConvertNameToAddress (const char *FunctionOrVariableName, PBOOLEAN WasFound)
 Converts name to address.
UINT32 ScriptEngineLoadFileSymbol (UINT64 BaseAddress, const char *PdbFileName, const char *CustomModuleName)
VOID ScriptEngineSetTextMessageCallback (PVOID Handler)
 Set the message handler as an alternative to printf.
UINT32 ScriptEngineUnloadAllSymbols ()
 Unload all the previously loaded symbols.
UINT32 ScriptEngineUnloadModuleSymbol (char *ModuleName)
 Unload a special pdb.
UINT32 ScriptEngineSearchSymbolForMask (const char *SearchMask)
 Search for a special mask.
BOOLEAN ScriptEngineGetFieldOffset (CHAR *TypeName, CHAR *FieldName, UINT32 *FieldOffset)
 Get offset of a field from the structure.
BOOLEAN ScriptEngineGetDataTypeSize (CHAR *TypeName, UINT64 *TypeSize)
 Get size of a data type (structure).
BOOLEAN ScriptEngineCreateSymbolTableForDisassembler (void *CallbackFunction)
 Create symbol table for disassembler.
BOOLEAN ScriptEngineConvertFileToPdbPath (const char *LocalFilePath, char *ResultPath, SIZE_T ResultPathSize)
 Convert local file to pdb path.
BOOLEAN ScriptEngineSymbolInitLoad (PVOID BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const char *SymbolPath, BOOLEAN IsSilentLoad)
 Initial load of the symbols.
BOOLEAN ScriptEngineShowDataBasedOnSymbolTypes (const char *TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, const char *AdditionalParameters)
 Show data based on symbol types.
VOID ScriptEngineSymbolAbortLoading ()
 Cancel loading.
BOOLEAN ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails (const char *LocalFilePath, char *PdbFilePath, char *GuidAndAgeDetails, BOOLEAN Is32BitModule)
 Convert file to pdb attributes for symbols.
BOOLEAN ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetails (const BYTE *LoadedImageBytes, SIZE_T LoadedImageSize, const char *LocalFilePath, char *PdbFilePath, char *GuidAndAgeDetails, BOOLEAN Is32BitModule)
 Convert loaded module bytes to pdb attributes for symbols.
PVOID ScriptEngineParse (char *str)
 The entry point of script engine.
void CodeGen (PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRIPT_ENGINE_TOKEN Operator, PSCRIPT_ENGINE_ERROR_TYPE Error, char **ScriptSource)
 Script Engine code generator.
UINT64 BooleanExpressionExtractEnd (char *str, BOOL *WaitForWaitStatementBooleanExpression, PSCRIPT_ENGINE_TOKEN CurrentIn)
 Computes the boolean expression length starting from the current input position.
void ScriptEngineBooleanExpresssionParse (UINT64 BooleanExpressionSize, PSCRIPT_ENGINE_TOKEN FirstToken, PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, char *str, char *c, PSCRIPT_ENGINE_ERROR_TYPE Error)
 LALR parser used for parsing boolean expression.
PSYMBOL NewSymbol (void)
 Allocates a new SYMBOL and returns the reference to it.
PSYMBOL NewStringSymbol (PSCRIPT_ENGINE_TOKEN Token)
 Allocates a new SYMBOL with string type and returns the reference to it.
PSYMBOL NewWstringSymbol (PSCRIPT_ENGINE_TOKEN Token)
 Allocates a new SYMBOL with wstring type and returns the reference to it.
unsigned int GetSymbolHeapSize (PSYMBOL Symbol)
 Returns the number of SYMBOL objects (24 bytes) allocated by string or wstring sybmol.
void RemoveSymbol (PSYMBOL *Symbol)
 Frees the memory allocate by this Symbol.
void PrintSymbol (PVOID Symbol)
 Prints symbol.
PSYMBOL ToSymbol (PSCRIPT_ENGINE_TOKEN Token, PSCRIPT_ENGINE_ERROR_TYPE Error)
 Converts Token to Symbol and returns the reference to it.
PSYMBOL_BUFFER NewSymbolBuffer (void)
 allocates a new Symbol Buffer and returns the reference to it
void RemoveSymbolBuffer (PVOID SymbolBuffer)
 Frees the memory allocated by SymbolBuffer.
PSYMBOL_BUFFER PushSymbol (PSYMBOL_BUFFER SymbolBuffer, const PSYMBOL Symbol)
 Gets a symbol and push it into the symbol buffer.
void PrintSymbolBuffer (const PVOID SymbolBuffer)
 Prints a symbol buffer.
unsigned long long int RegisterToInt (char *str)
 Converts register string to integer.
unsigned long long int PseudoRegToInt (char *str)
 Converts pseudo register string to integer.
unsigned long long int SemanticRuleToInt (char *str)
 Converts a sematinc rule token to integer.
char * HandleError (PSCRIPT_ENGINE_ERROR_TYPE Error, char *str)
 Prints some information about the error.
int GetGlobalIdentifierVal (PSCRIPT_ENGINE_TOKEN Token)
 Returns the integer assigned to global variable.
int GetLocalIdentifierVal (PSCRIPT_ENGINE_TOKEN Token)
 Returns the integer assigned to local variable.
int NewGlobalIdentifier (PSCRIPT_ENGINE_TOKEN Token)
 Allocates a new global variable and returns the integer assigned to it.
VOID SetGlobalIdentifierVariableType (PSCRIPT_ENGINE_TOKEN Token, VARIABLE_TYPE *VariableType)
VARIABLE_TYPEGetGlobalIdentifierVariableType (PSCRIPT_ENGINE_TOKEN Token)
unsigned long long NewLocalIdentifier (PSCRIPT_ENGINE_TOKEN Token, unsigned int VariableSize)
 Allocates a new local variable and returns the integer assigned to it.
VOID SetLocalIdentifierVariableType (PSCRIPT_ENGINE_TOKEN Token, VARIABLE_TYPE *VariableType)
VARIABLE_TYPEGetLocalIdentifierVariableType (PSCRIPT_ENGINE_TOKEN Token)
int NewFunctionParameterIdentifier (PSCRIPT_ENGINE_TOKEN Token)
int GetFunctionParameterIdentifier (PSCRIPT_ENGINE_TOKEN Token)
PUSER_DEFINED_FUNCTION_NODE GetUserDefinedFunctionNode (PSCRIPT_ENGINE_TOKEN Token)
int LalrGetRhsSize (int RuleId)
 Returns the size of Right Hand Side (RHS) of a rule.
BOOL LalrIsOperandType (PSCRIPT_ENGINE_TOKEN Token)
 Returns TRUE if the Token can be the operand of an operator.
BOOLEAN ScriptEngineSetHwdbgInstanceInfo (HWDBG_INSTANCE_INFORMATION *InstancInfo)
 Set hwdbg instance info for the script engine.
BOOLEAN FuncGetNumberOfOperands (UINT64 FuncType, UINT32 *NumberOfGetOperands, UINT32 *NumberOfSetOperands)
 Script Engine get number of operands.

Variables

HWDBG_INSTANCE_INFORMATION g_HwdbgInstanceInfo
 Instance information of the current hwdbg debuggee.
BOOLEAN g_HwdbgInstanceInfoIsValid
 Shows whether the instance info is valid (received) or not.
PVOID g_MessageHandler
 The handler for ShowMessages function this is because the user might choose not to use printf and instead use his/her handler for showing messages.

Detailed Description

Script engine parser and codegen.

Author
M.H. Gholamrezaei (mh@hy.nosp@m.perd.nosp@m.bg.or.nosp@m.g)
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2020-10-22

Function Documentation

◆ BooleanExpressionExtractEnd()

UINT64 BooleanExpressionExtractEnd ( char * str,
BOOL * WaitForWaitStatementBooleanExpression,
PSCRIPT_ENGINE_TOKEN CurrentIn )

Computes the boolean expression length starting from the current input position.

Parameters
str
WaitForWaitStatementBooleanExpression
CurrentIn
Returns
UINT64
3440{
3441 UINT64 BooleanExpressionSize = 0;
3442 if (*WaitForWaitStatementBooleanExpression)
3443 {
3444 while (str[InputIdx + BooleanExpressionSize - 1] != ';')
3445 {
3446 BooleanExpressionSize += 1;
3447 }
3448 *WaitForWaitStatementBooleanExpression = FALSE;
3449 return InputIdx + BooleanExpressionSize - 1;
3450 }
3451 else
3452 {
3453 int OpenParanthesesCount = 1;
3454 if (!strcmp(CurrentIn->Value, "("))
3455 {
3456 OpenParanthesesCount++;
3457 }
3458 while (str[InputIdx + BooleanExpressionSize - 1] != '\0')
3459 {
3460 if (str[InputIdx + BooleanExpressionSize - 1] == ')')
3461 {
3462 OpenParanthesesCount--;
3463 if (OpenParanthesesCount == 0)
3464 {
3465 return InputIdx + BooleanExpressionSize - 1;
3466 }
3467 }
3468 else if (str[InputIdx + BooleanExpressionSize - 1] == '(')
3469 {
3470 OpenParanthesesCount++;
3471 }
3472 BooleanExpressionSize++;
3473 }
3474 }
3475 return -1;
3476}
#define FALSE
Definition BasicTypes.h:113
unsigned int InputIdx
number of read characters from input
Definition globals.c:18
char * Value
Definition common.h:73

◆ CodeGen()

void CodeGen ( PSCRIPT_ENGINE_TOKEN_LIST MatchedStack,
PSYMBOL_BUFFER CodeBuffer,
PSCRIPT_ENGINE_TOKEN Operator,
PSCRIPT_ENGINE_ERROR_TYPE Error,
char ** ScriptSource )

Script Engine code generator.

Parameters
MatchedStack
CodeBuffer
Operator
Error
ScriptSourcethe script source string
Returns
VOID
710{
715
716 PSYMBOL OperatorSymbol = NULL;
717 PSYMBOL Op0Symbol = NULL;
718 PSYMBOL Op1Symbol = NULL;
719 PSYMBOL Op2Symbol = NULL;
720 PSYMBOL TempSymbol = NULL;
721 VARIABLE_TYPE * VariableType = NULL;
722 VARIABLE_TYPE * PointerVariableType = NULL;
723
724 //
725 // It is in user-defined function if CurrentFunctionSymbol is not null
726 //
727 OperatorSymbol = ToSymbol(Operator, Error);
728
729#ifdef _SCRIPT_ENGINE_CODEGEN_DBG_EN
730 //
731 // Print Debug Info
732 //
733 printf("Operator :\n");
734 PrintToken(Operator);
735 printf("\n");
736
737 printf("Semantic Stack:\n");
738 PrintTokenList(MatchedStack);
739 printf("\n");
740
741 printf("Code Buffer:\n");
742 PrintSymbolBuffer((PVOID)CodeBuffer);
743 printf(".\n.\n.\n\n");
744#endif
745
746 while (TRUE)
747 {
748 if (!strcmp(Operator->Value, "@INCLUDE"))
749 {
750 char * IncludeFilePath;
751 char FullPath[MAX_PATH_LEN];
752 char * IncludeFileBuffer;
753 BOOLEAN IncludedPath = FALSE;
754
755 Temp = Pop(MatchedStack);
756 IncludeFilePath = Temp->Value;
757
758 ResolveIncludePath(IncludeFilePath, FullPath);
759
760 if (!FileExists(FullPath))
761 {
763 break;
764 }
765
766 if (!ParseIncludeFile(FullPath, &IncludeFileBuffer))
767 {
769 break;
770 }
771
772 if (!IncludeHead)
773 {
774 IncludeHead = calloc(sizeof(INCLUDE_NODE), 1);
775 IncludeHead->FilePath = PlatformStrDup(FullPath);
776 }
777 else
778 {
779 PINCLUDE_NODE Node, PrevNode = NULL;
780
781 for (Node = IncludeHead; Node; PrevNode = Node, Node = Node->NextNode)
782 {
783 if (!strcmp(Node->FilePath, FullPath))
784 {
785 IncludedPath = TRUE;
786 break;
787 }
788 }
789
790 if (!IncludedPath && PrevNode)
791 {
792 PrevNode->NextNode = calloc(sizeof(INCLUDE_NODE), 1);
793 PrevNode->NextNode->FilePath = PlatformStrDup(FullPath);
794 }
795 }
796
797 if (!IncludedPath)
798 {
799 *ScriptSource = InsertStrNew(*ScriptSource, InputIdx, IncludeFileBuffer);
800 }
801 }
802
803 else if (!strcmp(Operator->Value, "@START_OF_USER_DEFINED_FUNCTION"))
804 {
805 Op0 = Pop(MatchedStack);
806 VariableType = HandleType(MatchedStack);
807
808 if (VariableType->Kind == TY_UNKNOWN)
809 {
811 break;
812 }
813
814 //
815 // Add jmp instruction to Code Buffer
816 //
817 PSYMBOL JumpInstruction = NewSymbol();
818 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
819 JumpInstruction->Value = FUNC_JMP;
820 PushSymbol(CodeBuffer, JumpInstruction);
821 RemoveSymbol(&JumpInstruction);
822
823 //
824 // Push jump address
825 //
826
827 PSYMBOL JumpAddressSymbol = NewSymbol();
828 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
829 JumpAddressSymbol->Value = 0xffffffffffffffff;
830 PushSymbol(CodeBuffer, JumpAddressSymbol);
831 RemoveSymbol(&JumpAddressSymbol);
832
834 while (Node->NextNode)
835 {
836 Node = Node->NextNode;
837 }
838 Node->NextNode = malloc(sizeof(USER_DEFINED_FUNCTION_NODE));
841
843 CurrentUserDefinedFunction->Address = CodeBuffer->Pointer; // CurrentPointer
844 CurrentUserDefinedFunction->VariableType = (long long unsigned)VariableType;
845 CurrentUserDefinedFunction->IdTable = (unsigned long long)NewTokenList();
846 CurrentUserDefinedFunction->FunctionParameterIdTable = (unsigned long long)NewTokenList();
847 CurrentUserDefinedFunction->TempMap = calloc(MAX_TEMP_COUNT, 1);
848
849 //
850 // push stack base index
851 //
852 TempSymbol = NewSymbol();
853 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
854 TempSymbol->Value = FUNC_PUSH;
855 PushSymbol(CodeBuffer, TempSymbol);
856 RemoveSymbol(&TempSymbol);
857
858 TempSymbol = NewSymbol();
860 TempSymbol->Value = 0;
861 PushSymbol(CodeBuffer, TempSymbol);
862 RemoveSymbol(&TempSymbol);
863
864 //
865 // move stack index to stack base index
866 //
867 TempSymbol = NewSymbol();
868 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
869 TempSymbol->Value = FUNC_MOV;
870 PushSymbol(CodeBuffer, TempSymbol);
871 RemoveSymbol(&TempSymbol);
872
873 TempSymbol = NewSymbol();
874 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
875 TempSymbol->Value = 0;
876 PushSymbol(CodeBuffer, TempSymbol);
877 RemoveSymbol(&TempSymbol);
878
879 TempSymbol = NewSymbol();
881 TempSymbol->Value = 0;
882 PushSymbol(CodeBuffer, TempSymbol);
883 RemoveSymbol(&TempSymbol);
884
885 //
886 // add stack index
887 //
888 TempSymbol = NewSymbol();
889 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
890 TempSymbol->Value = FUNC_ADD;
891 PushSymbol(CodeBuffer, TempSymbol);
892 RemoveSymbol(&TempSymbol);
893
894 TempSymbol = NewSymbol();
895 TempSymbol->Type = SYMBOL_NUM_TYPE;
896 TempSymbol->Value = 0xffffffffffffffff;
897 PushSymbol(CodeBuffer, TempSymbol);
898 RemoveSymbol(&TempSymbol);
899
900 TempSymbol = NewSymbol();
901 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
902 TempSymbol->Value = 0;
903 PushSymbol(CodeBuffer, TempSymbol);
904 RemoveSymbol(&TempSymbol);
905
906 TempSymbol = NewSymbol();
907 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
908 TempSymbol->Value = 0;
909 PushSymbol(CodeBuffer, TempSymbol);
910 RemoveSymbol(&TempSymbol);
911 }
912 else if (!strcmp(Operator->Value, "@FUNCTION_PARAMETER"))
913 {
914 Op0 = Pop(MatchedStack);
915 VariableType = HandleType(MatchedStack);
916
917 if (VariableType->Kind == TY_UNKNOWN)
918 {
920 break;
921 }
922
924 CurrentUserDefinedFunction->ParameterNumber++;
925 }
926 else if (!strcmp(Operator->Value, "@END_OF_USER_DEFINED_FUNCTION"))
927 {
928 UINT64 CurrentPointer = CodeBuffer->Pointer;
929 PSYMBOL Symbol = NULL;
930
932 {
934 break;
935 }
936
937 //
938 // change local id to stack temp
939 //
940 for (UINT64 i = CurrentUserDefinedFunction->Address; i < CurrentPointer; i++)
941 {
942 Symbol = CodeBuffer->Head + i;
943 if (Symbol->Type == SYMBOL_LOCAL_ID_TYPE)
944 {
945 Symbol->Type = SYMBOL_TEMP_TYPE;
946 Symbol->Value += CurrentUserDefinedFunction->MaxTempNumber;
947 }
948
949 else if (Symbol->Type == SYMBOL_VARIABLE_COUNT_TYPE)
950 {
951 UINT64 VariableCount = Symbol->Value;
952 for (UINT64 j = 0; j < VariableCount; j++)
953 {
954 Symbol = CodeBuffer->Head + i + j + 1;
955 if ((Symbol->Type & 0x7fffffff) == SYMBOL_LOCAL_ID_TYPE)
956 {
957 Symbol->Type = SYMBOL_TEMP_TYPE | (Symbol->Type & 0xffffffff00000000);
958 Symbol->Value += CurrentUserDefinedFunction->MaxTempNumber;
959 }
960 }
961 i += VariableCount;
962 }
963 }
964
965 //
966 // set memory size for stack buffer
967 //
968 Symbol = CodeBuffer->Head + CurrentUserDefinedFunction->Address + 6;
969 Symbol->Value = CurrentUserDefinedFunction->MaxTempNumber + CurrentUserDefinedFunction->LocalVariableNumber;
970
971 //
972 // modify jump address
973 //
974 for (UINT64 i = CurrentUserDefinedFunction->Address; i < CurrentPointer; i++)
975 {
976 Symbol = CodeBuffer->Head + i;
977 if (Symbol->Type == SYMBOL_SEMANTIC_RULE_TYPE && Symbol->Value == FUNC_JMP && (CodeBuffer->Head + i + 1)->Value == 0xfffffffffffffff0)
978 {
979 (CodeBuffer->Head + i + 1)->Value = CurrentPointer;
980 i++;
981 }
982 }
983
984 //
985 // move stack base index to stack index
986 //
987 TempSymbol = NewSymbol();
988 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
989 TempSymbol->Value = FUNC_MOV;
990 PushSymbol(CodeBuffer, TempSymbol);
991 RemoveSymbol(&TempSymbol);
992
993 TempSymbol = NewSymbol();
995 TempSymbol->Value = 0;
996 PushSymbol(CodeBuffer, TempSymbol);
997 RemoveSymbol(&TempSymbol);
998
999 TempSymbol = NewSymbol();
1000 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
1001 TempSymbol->Value = 0;
1002 PushSymbol(CodeBuffer, TempSymbol);
1003 RemoveSymbol(&TempSymbol);
1004
1005 //
1006 // pop stack base index
1007 //
1008 TempSymbol = NewSymbol();
1009 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1010 TempSymbol->Value = FUNC_POP;
1011 PushSymbol(CodeBuffer, TempSymbol);
1012 RemoveSymbol(&TempSymbol);
1013
1014 TempSymbol = NewSymbol();
1015 TempSymbol->Type = SYMBOL_STACK_BASE_INDEX_TYPE;
1016 TempSymbol->Value = 0;
1017 PushSymbol(CodeBuffer, TempSymbol);
1018 RemoveSymbol(&TempSymbol);
1019
1020 TempSymbol = NewSymbol();
1021 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1022 TempSymbol->Value = FUNC_RET;
1023 PushSymbol(CodeBuffer, TempSymbol);
1024 RemoveSymbol(&TempSymbol);
1025
1026 Symbol = CodeBuffer->Head + CurrentUserDefinedFunction->Address - 1;
1027 Symbol->Value = CodeBuffer->Pointer;
1028
1030 }
1031 else if (!strcmp(Operator->Value, "@RETURN_OF_USER_DEFINED_FUNCTION_WITHOUT_VALUE"))
1032 {
1034 {
1036 break;
1037 }
1038 if (((VARIABLE_TYPE *)CurrentUserDefinedFunction->VariableType)->Kind != TY_VOID)
1039 {
1041 break;
1042 }
1043
1044 //
1045 // Jump to ret code
1046 //
1047 PSYMBOL Symbol = NewSymbol();
1049 Symbol->Value = FUNC_JMP;
1050 PushSymbol(CodeBuffer, Symbol);
1051 RemoveSymbol(&Symbol);
1052
1053 Symbol = NewSymbol();
1054 Symbol->Type = SYMBOL_NUM_TYPE;
1055 Symbol->Value = 0xfffffffffffffff0;
1056 PushSymbol(CodeBuffer, Symbol);
1057 RemoveSymbol(&Symbol);
1058 }
1059 else if (!strcmp(Operator->Value, "@RETURN_OF_USER_DEFINED_FUNCTION_WITH_VALUE"))
1060 {
1062 {
1064 break;
1065 }
1066 if (((VARIABLE_TYPE *)CurrentUserDefinedFunction->VariableType)->Kind == TY_VOID)
1067 {
1069 break;
1070 }
1071
1072 //
1073 // Store return value
1074 //
1075 PSYMBOL Symbol = NewSymbol();
1077 Symbol->Value = FUNC_MOV;
1078 PushSymbol(CodeBuffer, Symbol);
1079 RemoveSymbol(&Symbol);
1080
1081 Op0 = Pop(MatchedStack);
1082 Op0Symbol = ToSymbol(Op0, Error);
1083 PushSymbol(CodeBuffer, Op0Symbol);
1084 FreeTemp(Op0);
1085
1086 Symbol = NewSymbol();
1088 Symbol->Value = 0;
1089 PushSymbol(CodeBuffer, Symbol);
1090 RemoveSymbol(&Symbol);
1091
1092 //
1093 // Jump to ret code
1094 //
1095 Symbol = NewSymbol();
1097 Symbol->Value = FUNC_JMP;
1098 PushSymbol(CodeBuffer, Symbol);
1099 RemoveSymbol(&Symbol);
1100
1101 Symbol = NewSymbol();
1102 Symbol->Type = SYMBOL_NUM_TYPE;
1103 Symbol->Value = 0xfffffffffffffff0;
1104 PushSymbol(CodeBuffer, Symbol);
1105 RemoveSymbol(&Symbol);
1106
1107 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1108 {
1109 break;
1110 }
1111 }
1112 else if (!strcmp(Operator->Value, "@END_OF_CALLING_USER_DEFINED_FUNCTION_WITHOUT_RETURNING_VALUE") || !strcmp(Operator->Value, "@END_OF_CALLING_USER_DEFINED_FUNCTION_WITH_RETURNING_VALUE"))
1113 {
1114 PSYMBOL Symbol = NULL;
1115 PSYMBOL TempSymbol = NULL;
1116 int VariableNum = 0;
1117 PSCRIPT_ENGINE_TOKEN FunctionToken = NULL;
1118
1119 while (MatchedStack->Pointer > 0)
1120 {
1121 FunctionToken = Pop(MatchedStack);
1122
1123 if (FunctionToken->Type == FUNCTION_ID)
1124 {
1125 break;
1126 }
1127 else
1128 {
1129 VariableNum++;
1130 Symbol = NewSymbol();
1132 Symbol->Value = FUNC_PUSH;
1133 PushSymbol(CodeBuffer, Symbol);
1134 RemoveSymbol(&Symbol);
1135
1136 Symbol = ToSymbol(FunctionToken, Error);
1137 PushSymbol(CodeBuffer, Symbol);
1138 RemoveSymbol(&Symbol);
1139 RemoveToken(&FunctionToken);
1140 }
1141 }
1142
1144
1145 if (!Node)
1146 {
1148 break;
1149 }
1150
1151 if (VariableNum != Node->ParameterNumber)
1152 {
1154 break;
1155 }
1156
1157 Symbol = NewSymbol();
1159 Symbol->Value = FUNC_CALL;
1160 PushSymbol(CodeBuffer, Symbol);
1161 RemoveSymbol(&Symbol);
1162
1163 Symbol = NewSymbol();
1164 Symbol->Type = SYMBOL_NUM_TYPE;
1165 Symbol->Value = Node->Address;
1166 PushSymbol(CodeBuffer, Symbol);
1167 RemoveSymbol(&Symbol);
1168
1169 Symbol = NewSymbol();
1171 Symbol->Value = FUNC_SUB;
1172 PushSymbol(CodeBuffer, Symbol);
1173 RemoveSymbol(&Symbol);
1174
1175 Symbol = NewSymbol();
1176 Symbol->Type = SYMBOL_NUM_TYPE;
1177 Symbol->Value = Node->ParameterNumber;
1178 PushSymbol(CodeBuffer, Symbol);
1179 RemoveSymbol(&Symbol);
1180
1181 Symbol = NewSymbol();
1182 Symbol->Type = SYMBOL_STACK_INDEX_TYPE;
1183 PushSymbol(CodeBuffer, Symbol);
1184 RemoveSymbol(&Symbol);
1185
1186 Symbol = NewSymbol();
1187 Symbol->Type = SYMBOL_STACK_INDEX_TYPE;
1188 PushSymbol(CodeBuffer, Symbol);
1189 RemoveSymbol(&Symbol);
1190
1191 if (!strcmp(Operator->Value, "@END_OF_CALLING_USER_DEFINED_FUNCTION_WITH_RETURNING_VALUE"))
1192 {
1193 if (((VARIABLE_TYPE *)Node->VariableType)->Kind == TY_VOID)
1194 {
1196 break;
1197 }
1198
1199 //
1200 // Add return variable symbol
1201 //
1202 Temp = NewTemp(Error);
1203 Push(MatchedStack, Temp);
1204
1205 Symbol = NewSymbol();
1207 Symbol->Value = FUNC_MOV;
1208 PushSymbol(CodeBuffer, Symbol);
1209 RemoveSymbol(&Symbol);
1210
1211 Symbol = NewSymbol();
1213 Symbol->Value = 0;
1214 PushSymbol(CodeBuffer, Symbol);
1215 RemoveSymbol(&Symbol);
1216
1217 TempSymbol = ToSymbol(Temp, Error);
1218 PushSymbol(CodeBuffer, TempSymbol);
1219 RemoveSymbol(&TempSymbol);
1220
1221 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1222 {
1223 break;
1224 }
1225 }
1226
1227 RemoveToken(&FunctionToken);
1228 }
1229 else if (!strcmp(Operator->Value, "@MULTIPLE_ASSIGNMENT"))
1230 {
1231 int Op1Capacity = 8;
1232 int Op1Count = 0;
1233 PSCRIPT_ENGINE_TOKEN * Op1Array = (PSCRIPT_ENGINE_TOKEN *)malloc(sizeof(PSCRIPT_ENGINE_TOKEN) * Op1Capacity);
1234 PSYMBOL Symbol = NewSymbol();
1236 Symbol->Value = FUNC_MOV;
1237
1238 Op0 = Pop(MatchedStack);
1239 Op0Symbol = ToSymbol(Op0, Error);
1240
1241 for (int i = MatchedStack->Pointer; i > 0; i--)
1242 {
1243 Op1 = Top(MatchedStack);
1244
1245 if (Op1Count >= Op1Capacity)
1246 {
1247 Op1Capacity *= 2;
1248 Op1Array = (PSCRIPT_ENGINE_TOKEN *)realloc(Op1Array, sizeof(PSCRIPT_ENGINE_TOKEN) * Op1Capacity);
1249 }
1250 Op1Array[Op1Count++] = Op1;
1251
1252 if (Op1->Type == TEMP || Op1->Type == HEX || Op1->Type == OCTAL || Op1->Type == BINARY || Op1->Type == PSEUDO_REGISTER)
1253 {
1255 Pop(MatchedStack);
1256 break;
1257 }
1258 else if (Op1->Type == GLOBAL_UNRESOLVED_ID)
1259 {
1260 PushSymbol(CodeBuffer, Symbol);
1261 PushSymbol(CodeBuffer, Op0Symbol);
1262
1263 Op1Symbol = NewSymbol();
1264 free((void *)Op1Symbol->Value);
1265 Op1Symbol->Value = NewGlobalIdentifier(Op1);
1266 SetType(&Op1Symbol->Type, SYMBOL_GLOBAL_ID_TYPE);
1267 Pop(MatchedStack);
1268 PushSymbol(CodeBuffer, Op1Symbol);
1269 }
1270 else if (Op1->Type == LOCAL_UNRESOLVED_ID)
1271 {
1272 PushSymbol(CodeBuffer, Symbol);
1273 PushSymbol(CodeBuffer, Op0Symbol);
1274
1275 Op1Symbol = NewSymbol();
1276 free((void *)Op1Symbol->Value);
1277 Op1Symbol->Value = NewLocalIdentifier(Op1, 8);
1278 SetType(&Op1Symbol->Type, SYMBOL_LOCAL_ID_TYPE);
1279 Pop(MatchedStack);
1280 PushSymbol(CodeBuffer, Op1Symbol);
1281 RemoveSymbol(&Op1Symbol);
1282 }
1283 else if (Op1->Type == LOCAL_ID || Op1->Type == GLOBAL_ID || Op1->Type == FUNCTION_PARAMETER_ID || Op1->Type == REGISTER)
1284 {
1285 PushSymbol(CodeBuffer, Symbol);
1286 PushSymbol(CodeBuffer, Op0Symbol);
1287
1288 Op1Symbol = ToSymbol(Op1, Error);
1289 PushSymbol(CodeBuffer, Op1Symbol);
1290 Pop(MatchedStack);
1291 RemoveSymbol(&Op1Symbol);
1292 }
1293 else
1294 {
1295 break;
1296 }
1297 }
1298
1299 RemoveSymbol(&Symbol);
1300 Op1 = 0;
1301
1302 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1303 {
1304 FreeTemp(Op0);
1305 break;
1306 }
1307
1308 if (MatchedStack->Pointer > 0)
1309 {
1310 if (Top(MatchedStack)->Type == SCRIPT_VARIABLE_TYPE)
1311 {
1312 VariableType = HandleType(MatchedStack);
1313
1314 if (VariableType->Kind == TY_UNKNOWN)
1315 {
1317 break;
1318 }
1319
1320 for (int i = 0; i < Op1Count; i++)
1321 {
1322 Op1 = Op1Array[i];
1323 if (Op1->Type == LOCAL_UNRESOLVED_ID || Op1->Type == LOCAL_ID)
1324 {
1325 SetLocalIdentifierVariableType(Op1, VariableType);
1326 }
1327 else if (Op1->Type == GLOBAL_UNRESOLVED_ID || Op1->Type == GLOBAL_ID)
1328 {
1329 SetGlobalIdentifierVariableType(Op1, VariableType);
1330 }
1331 }
1332
1333 Op1 = 0;
1334 }
1335 }
1336
1337 //
1338 // Free the operand if it is a temp value
1339 //
1340 FreeTemp(Op0);
1341 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1342 {
1343 break;
1344 }
1345
1346 free(Op1Array);
1347 }
1348 else if (!strcmp(Operator->Value, "@ARRAY_INDEX_READ") || !strcmp(Operator->Value, "@ARRAY_INDEX_WRITE"))
1349 {
1350 int ArrayCapacity = 8;
1351 int TokenCount = 0;
1352 PSCRIPT_ENGINE_TOKEN * TokenArray = (PSCRIPT_ENGINE_TOKEN *)malloc(sizeof(PSCRIPT_ENGINE_TOKEN) * ArrayCapacity);
1353 PSCRIPT_ENGINE_TOKEN IdToken;
1354 PSYMBOL IdSymbol;
1355 int ElementOffset = 0;
1356 PSYMBOL Symbol;
1357 PSCRIPT_ENGINE_TOKEN OffsetToken;
1358 PSYMBOL OffsetSymbol;
1359
1360 while (MatchedStack->Pointer)
1361 {
1362 if (TokenCount >= ArrayCapacity)
1363 {
1364 TokenCount *= 2;
1365 TokenArray = (PSCRIPT_ENGINE_TOKEN *)realloc(TokenArray, sizeof(PSCRIPT_ENGINE_TOKEN) * ArrayCapacity);
1366 }
1367
1368 Temp = Top(MatchedStack);
1369 if (!strcmp(Top(MatchedStack)->Value, "@ARRAY_DIM_NUMBER"))
1370 {
1371 Pop(MatchedStack);
1372 TokenArray[TokenCount] = Pop(MatchedStack);
1373 TokenCount++;
1374 }
1375 else
1376 {
1377 break;
1378 }
1379 }
1380
1381 IdToken = Pop(MatchedStack);
1382 IdSymbol = ToSymbol(IdToken, Error);
1383
1384 if (IdToken->Type == LOCAL_UNRESOLVED_ID)
1385 {
1387 break;
1388 }
1389
1390 for (int i = 0; i < TokenCount / 2; i++)
1391 {
1392 PSCRIPT_ENGINE_TOKEN tmp = TokenArray[i];
1393 TokenArray[i] = TokenArray[TokenCount - i - 1];
1394 TokenArray[TokenCount - i - 1] = tmp;
1395 }
1396
1397 VariableType = (VARIABLE_TYPE *)IdToken->VariableType;
1398 Temp = NewTemp(Error);
1399 TempSymbol = ToSymbol(Temp, Error);
1400 OffsetToken = NewTemp(Error);
1401 OffsetSymbol = ToSymbol(OffsetToken, Error);
1402
1403 Symbol = NewSymbol();
1405 Symbol->Value = FUNC_MOV;
1406 PushSymbol(CodeBuffer, Symbol);
1407
1408 Symbol = NewSymbol();
1409 Symbol->Type = SYMBOL_NUM_TYPE;
1410 Symbol->Value = 0;
1411 PushSymbol(CodeBuffer, Symbol);
1412
1413 PushSymbol(CodeBuffer, OffsetSymbol);
1414
1415 for (int i = 0; i < TokenCount; i++)
1416 {
1417 if (!VariableType->Base)
1418 {
1420 break;
1421 }
1422
1423 Symbol = NewSymbol();
1425 Symbol->Value = FUNC_MUL;
1426 PushSymbol(CodeBuffer, Symbol);
1427
1428 Symbol = NewSymbol();
1429 Symbol->Type = SYMBOL_NUM_TYPE;
1430 Symbol->Value = VariableType->Base->Size;
1431 PushSymbol(CodeBuffer, Symbol);
1432
1433 Symbol = ToSymbol(TokenArray[i], Error);
1434 PushSymbol(CodeBuffer, Symbol);
1435
1436 PushSymbol(CodeBuffer, TempSymbol);
1437
1438 Symbol = NewSymbol();
1440 Symbol->Value = FUNC_ADD;
1441 PushSymbol(CodeBuffer, Symbol);
1442
1443 PushSymbol(CodeBuffer, TempSymbol);
1444 PushSymbol(CodeBuffer, OffsetSymbol);
1445 PushSymbol(CodeBuffer, OffsetSymbol);
1446
1447 VariableType = VariableType->Base;
1448 }
1449
1450 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1451 {
1452 break;
1453 }
1454
1455 Symbol = NewSymbol();
1457 Symbol->Value = FUNC_ADD;
1458 PushSymbol(CodeBuffer, Symbol);
1459
1460 PushSymbol(CodeBuffer, IdSymbol);
1461 PushSymbol(CodeBuffer, OffsetSymbol);
1462 PushSymbol(CodeBuffer, OffsetSymbol);
1463
1464 if (!strcmp(Operator->Value, "@ARRAY_INDEX_READ"))
1465 {
1466 Symbol = NewSymbol();
1468 Symbol->Value = FUNC_POI;
1469 PushSymbol(CodeBuffer, Symbol);
1470
1471 PushSymbol(CodeBuffer, OffsetSymbol);
1472 PushSymbol(CodeBuffer, OffsetSymbol);
1473 }
1474 else if (!strcmp(Operator->Value, "@ARRAY_INDEX_WRITE"))
1475 {
1476 OffsetToken->Type = DEFERENCE_TEMP;
1477 }
1478
1479 Push(MatchedStack, OffsetToken);
1480
1481 FreeTemp(Temp);
1482 }
1483 else if (!strcmp(Operator->Value, "@MOV"))
1484 {
1485 PushSymbol(CodeBuffer, OperatorSymbol);
1486 Op0 = Pop(MatchedStack);
1487 Op0Symbol = ToSymbol(Op0, Error);
1488
1489 Op1 = Pop(MatchedStack);
1490 if (Op1->Type == GLOBAL_UNRESOLVED_ID)
1491 {
1492 Op1Symbol = NewSymbol();
1493 free((void *)Op1Symbol->Value);
1494 Op1Symbol->Value = NewGlobalIdentifier(Op1);
1495 SetType(&Op1Symbol->Type, SYMBOL_GLOBAL_ID_TYPE);
1496 }
1497 else if (Op1->Type == LOCAL_UNRESOLVED_ID)
1498 {
1499 Op1Symbol = NewSymbol();
1500 free((void *)Op1Symbol->Value);
1501 Op1Symbol->Value = NewLocalIdentifier(Op1, 8);
1502 SetType(&Op1Symbol->Type, SYMBOL_LOCAL_ID_TYPE);
1503 }
1504 else
1505 {
1506 Op1Symbol = ToSymbol(Op1, Error);
1507 }
1508
1509 if (MatchedStack->Pointer > 0)
1510 {
1511 if (!strcmp(Top(MatchedStack)->Value, "@DECLARE_POINTER_TYPE") || Top(MatchedStack)->Type == SCRIPT_VARIABLE_TYPE)
1512 {
1513 if (!strcmp(Top(MatchedStack)->Value, "@DECLARE_POINTER_TYPE"))
1514 {
1515 PointerVariableType = calloc(1, sizeof(VARIABLE_TYPE));
1516 PointerVariableType->Kind = TY_PTR;
1517 PointerVariableType->Size = 8;
1518 PointerVariableType->Align = 8;
1519 PointerVariableType->IsUnsigned = TRUE;
1520 Pop(MatchedStack);
1521 }
1522
1523 VariableType = HandleType(MatchedStack);
1524
1525 if (VariableType->Kind == TY_UNKNOWN)
1526 {
1528 break;
1529 }
1530
1531 if (PointerVariableType)
1532 {
1533 PointerVariableType->Base = VariableType;
1534 VariableType = PointerVariableType;
1535 }
1536
1537 if (Op1->Type == LOCAL_UNRESOLVED_ID || Op1->Type == LOCAL_ID)
1538 {
1539 SetLocalIdentifierVariableType(Op1, VariableType);
1540 }
1541 else if (Op1->Type == GLOBAL_UNRESOLVED_ID || Op1->Type == GLOBAL_ID)
1542 {
1543 SetGlobalIdentifierVariableType(Op1, VariableType);
1544 }
1545 }
1546 }
1547
1548 PushSymbol(CodeBuffer, Op0Symbol);
1549 PushSymbol(CodeBuffer, Op1Symbol);
1550
1551 //
1552 // Free the operand if it is a temp value
1553 //
1554 FreeTemp(Op0);
1555 FreeTemp(Op1);
1556 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1557 {
1558 break;
1559 }
1560 }
1561 else if (!strcmp(Operator->Value, "@DECLARE_POINTER_TYPE"))
1562 {
1563 Push(MatchedStack, CopyToken(Operator));
1564 }
1565 else if (!strcmp(Operator->Value, "@ARRAY_DIM_NUMBER") || !strcmp(Operator->Value, "@ARRAY_LEFT_BRACKET") || !strcmp(Operator->Value, "@ARRAY_L_VALUE"))
1566 {
1567 Push(MatchedStack, CopyToken(Operator));
1568 }
1569 else if (!strcmp(Operator->Value, "@DEREFERENCE"))
1570 {
1571 PSYMBOL Symbol;
1572
1573 Op0 = Pop(MatchedStack);
1574 Op1 = Pop(MatchedStack);
1575
1576 if (Op1->Type == LOCAL_UNRESOLVED_ID)
1577 {
1579 break;
1580 }
1581
1582 if (((VARIABLE_TYPE *)Op1->VariableType)->Size == 4)
1583 {
1584 Symbol = NewSymbol();
1586 Symbol->Value = FUNC_ED;
1587
1588 Op0Symbol = ToSymbol(Op0, Error);
1589 Op1Symbol = ToSymbol(Op1, Error);
1590
1591 Temp = NewTemp(Error);
1592 TempSymbol = ToSymbol(Temp, Error);
1593
1594 PushSymbol(CodeBuffer, Symbol);
1595 PushSymbol(CodeBuffer, Op0Symbol);
1596 PushSymbol(CodeBuffer, Op1Symbol);
1597 PushSymbol(CodeBuffer, TempSymbol);
1598 FreeTemp(Temp);
1599 }
1600 else if (((VARIABLE_TYPE *)Op1->VariableType)->Size == 8)
1601 {
1602 Symbol = NewSymbol();
1604 Symbol->Value = FUNC_EQ;
1605
1606 Op0Symbol = ToSymbol(Op0, Error);
1607 Op1Symbol = ToSymbol(Op1, Error);
1608
1609 Temp = NewTemp(Error);
1610 TempSymbol = ToSymbol(Temp, Error);
1611
1612 PushSymbol(CodeBuffer, Symbol);
1613 PushSymbol(CodeBuffer, Op0Symbol);
1614 PushSymbol(CodeBuffer, Op1Symbol);
1615 PushSymbol(CodeBuffer, TempSymbol);
1616 FreeTemp(Temp);
1617 }
1618
1619 else if (((VARIABLE_TYPE *)Op1->VariableType)->Size == 1)
1620 {
1621 Symbol = NewSymbol();
1623 Symbol->Value = FUNC_EB;
1624
1625 Op0Symbol = ToSymbol(Op0, Error);
1626 Op1Symbol = ToSymbol(Op1, Error);
1627
1628 Temp = NewTemp(Error);
1629 TempSymbol = ToSymbol(Temp, Error);
1630
1631 PushSymbol(CodeBuffer, Symbol);
1632 PushSymbol(CodeBuffer, Op0Symbol);
1633 PushSymbol(CodeBuffer, Op1Symbol);
1634 PushSymbol(CodeBuffer, TempSymbol);
1635 FreeTemp(Temp);
1636 }
1637 }
1638 else if (!strcmp(Operator->Value, "@ARRAY_DECLARITION"))
1639 {
1640 int TokenCapacity = 8;
1641 int TokenCount = 0;
1642 PSCRIPT_ENGINE_TOKEN * TokenArray = (PSCRIPT_ENGINE_TOKEN *)malloc(sizeof(PSCRIPT_ENGINE_TOKEN) * TokenCapacity);
1643 PSCRIPT_ENGINE_TOKEN IdToken = NULL;
1644 PSYMBOL IdSymbol = NewSymbol();
1645 ;
1646 VARIABLE_TYPE * VariableType2 = NULL;
1647 int Last_ARRAY_DIM_NUMBER_Idx = 0;
1648 int ArrayElementCount = 0;
1649 PSYMBOL Symbol = NULL;
1650 int BaseTypeSize = 0;
1651
1652 for (int i = MatchedStack->Pointer; i > 0; i--)
1653 {
1654 Temp = Pop(MatchedStack);
1655 if (!strcmp(Temp->Value, "@ARRAY_L_VALUE"))
1656 {
1657 break;
1658 }
1659
1660 if (TokenCount >= TokenCapacity)
1661 {
1662 TokenCapacity *= 2;
1663 TokenArray = (PSCRIPT_ENGINE_TOKEN *)realloc(TokenArray, sizeof(PSCRIPT_ENGINE_TOKEN) * TokenCapacity);
1664 }
1665 TokenArray[TokenCount++] = Temp;
1666 }
1667
1668 for (SIZE_T i = 0; i < TokenCount / 2; i++)
1669 {
1670 PSCRIPT_ENGINE_TOKEN tmp = TokenArray[i];
1671 TokenArray[i] = TokenArray[TokenCount - i - 1];
1672 TokenArray[TokenCount - i - 1] = tmp;
1673 }
1674
1675 IdToken = Pop(MatchedStack);
1676
1677 if (MatchedStack->Pointer > 0)
1678 {
1679 if (Top(MatchedStack)->Type == SCRIPT_VARIABLE_TYPE)
1680 {
1681 VariableType = HandleType(MatchedStack);
1682
1683 if (VariableType->Kind == TY_UNKNOWN)
1684 {
1686 break;
1687 }
1688 }
1689 }
1690
1691 if (!VariableType)
1692 {
1693 VariableType = VARIABLE_TYPE_LONG;
1694 }
1695
1696 BaseTypeSize = VariableType->Size;
1697
1698 for (int i = TokenCount - 1; i >= 0; i--)
1699 {
1700 if (!strcmp(TokenArray[i]->Value, "@ARRAY_DIM_NUMBER"))
1701 {
1702 Last_ARRAY_DIM_NUMBER_Idx = i;
1703 break;
1704 }
1705 }
1706
1707 for (int i = Last_ARRAY_DIM_NUMBER_Idx; i >= 0; i--)
1708 {
1709 if (!strcmp(TokenArray[i]->Value, "@ARRAY_DIM_NUMBER"))
1710 {
1711 VariableType2 = calloc(1, sizeof(VARIABLE_TYPE));
1712 VariableType2->Kind = TY_ARRAY;
1713 VariableType2->Size = VariableType->Size * atoi(TokenArray[i - 1]->Value);
1714 VariableType2->Align = VariableType->Align;
1715 VariableType2->Base = VariableType;
1716 VariableType2->ArrayLen = atoi(TokenArray[i - 1]->Value);
1717 VariableType = VariableType2;
1718 i--;
1719 }
1720 }
1721
1722 if (IdToken->Type == LOCAL_UNRESOLVED_ID)
1723 {
1724 IdSymbol->Value = NewLocalIdentifier(IdToken, VariableType->Size);
1726 SetLocalIdentifierVariableType(IdToken, VariableType);
1727 }
1728
1729 for (int i = Last_ARRAY_DIM_NUMBER_Idx + 1; i < TokenCount; i++)
1730 {
1731 if (TokenArray[i]->Type != SEMANTIC_RULE)
1732 {
1733 if ((ArrayElementCount * BaseTypeSize) > VariableType->Size)
1734 {
1736 break;
1737 }
1738
1739 Symbol = NewSymbol();
1741 Symbol->Value = FUNC_MUL;
1742 PushSymbol(CodeBuffer, Symbol);
1743
1744 Symbol = NewSymbol();
1745 Symbol->Type = SYMBOL_NUM_TYPE;
1746 Symbol->Value = BaseTypeSize;
1747 PushSymbol(CodeBuffer, Symbol);
1748
1749 Symbol = NewSymbol();
1750 Symbol->Type = SYMBOL_NUM_TYPE;
1751 Symbol->Value = ArrayElementCount;
1752 PushSymbol(CodeBuffer, Symbol);
1753
1754 Temp = NewTemp(Error);
1755 TempSymbol = ToSymbol(Temp, Error);
1756 PushSymbol(CodeBuffer, TempSymbol);
1757
1758 Symbol = NewSymbol();
1760 Symbol->Value = FUNC_ADD;
1761
1762 PushSymbol(CodeBuffer, Symbol);
1763 PushSymbol(CodeBuffer, IdSymbol);
1764 PushSymbol(CodeBuffer, TempSymbol);
1765 PushSymbol(CodeBuffer, TempSymbol);
1766
1767 Symbol = NewSymbol();
1769
1770 if (BaseTypeSize == 4)
1771 {
1772 Symbol->Value = FUNC_ED;
1773 }
1774 else if (BaseTypeSize == 8)
1775 {
1776 Symbol->Value = FUNC_EQ;
1777 }
1778 else if (BaseTypeSize == 1)
1779 {
1780 Symbol->Value = FUNC_EB;
1781 }
1782
1783 PushSymbol(CodeBuffer, Symbol);
1784
1785 Symbol = ToSymbol(TokenArray[i], Error);
1786 PushSymbol(CodeBuffer, Symbol);
1787
1788 PushSymbol(CodeBuffer, TempSymbol);
1789
1790 PushSymbol(CodeBuffer, TempSymbol);
1791
1792 FreeTemp(Temp);
1793
1794 ArrayElementCount++;
1795 }
1796 }
1797
1798 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1799 {
1800 break;
1801 }
1802
1803 while ((ArrayElementCount * BaseTypeSize) < VariableType->Size)
1804 {
1805 Symbol = NewSymbol();
1807 Symbol->Value = FUNC_MUL;
1808 PushSymbol(CodeBuffer, Symbol);
1809
1810 Symbol = NewSymbol();
1811 Symbol->Type = SYMBOL_NUM_TYPE;
1812 Symbol->Value = BaseTypeSize;
1813 PushSymbol(CodeBuffer, Symbol);
1814
1815 Symbol = NewSymbol();
1816 Symbol->Type = SYMBOL_NUM_TYPE;
1817 Symbol->Value = ArrayElementCount;
1818 PushSymbol(CodeBuffer, Symbol);
1819
1820 Temp = NewTemp(Error);
1821 TempSymbol = ToSymbol(Temp, Error);
1822 PushSymbol(CodeBuffer, TempSymbol);
1823
1824 Symbol = NewSymbol();
1826 Symbol->Value = FUNC_ADD;
1827
1828 PushSymbol(CodeBuffer, Symbol);
1829 PushSymbol(CodeBuffer, IdSymbol);
1830 PushSymbol(CodeBuffer, TempSymbol);
1831 PushSymbol(CodeBuffer, TempSymbol);
1832
1833 Symbol = NewSymbol();
1835
1836 if (BaseTypeSize == 4)
1837 {
1838 Symbol->Value = FUNC_ED;
1839 }
1840 else if (BaseTypeSize == 8)
1841 {
1842 Symbol->Value = FUNC_EQ;
1843 }
1844 else if (BaseTypeSize == 1)
1845 {
1846 Symbol->Value = FUNC_EB;
1847 }
1848
1849 PushSymbol(CodeBuffer, Symbol);
1850
1851 Symbol = Symbol = NewSymbol();
1852 Symbol->Type = SYMBOL_NUM_TYPE;
1853 Symbol->Value = 0;
1854 PushSymbol(CodeBuffer, Symbol);
1855
1856 PushSymbol(CodeBuffer, TempSymbol);
1857
1858 PushSymbol(CodeBuffer, TempSymbol);
1859
1860 FreeTemp(Temp);
1861
1862 ArrayElementCount++;
1863 }
1864 }
1865 else if (IsType2Func(Operator))
1866 {
1867 PushSymbol(CodeBuffer, OperatorSymbol);
1868 Op0 = Pop(MatchedStack);
1869 Op0Symbol = ToSymbol(Op0, Error);
1870
1871 PushSymbol(CodeBuffer, Op0Symbol);
1872 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1873 {
1874 break;
1875 }
1876 }
1877 else if (IsType1Func(Operator))
1878 {
1879 PushSymbol(CodeBuffer, OperatorSymbol);
1880 Op0 = Pop(MatchedStack);
1881 VariableType = (VARIABLE_TYPE *)Op0->VariableType;
1882 Op0Symbol = ToSymbol(Op0, Error);
1883
1884 Temp = NewTemp(Error);
1885 Push(MatchedStack, Temp);
1886 TempSymbol = ToSymbol(Temp, Error);
1887
1888 PushSymbol(CodeBuffer, Op0Symbol);
1889 PushSymbol(CodeBuffer, TempSymbol);
1890
1891 FreeTemp(Op0);
1892 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1893 {
1894 break;
1895 }
1896 }
1897 else if (IsType4Func(Operator))
1898 {
1899 PushSymbol(CodeBuffer, OperatorSymbol);
1900 PSYMBOL_BUFFER TempStack = NewSymbolBuffer();
1901 UINT32 OperandCount = 0;
1902 do
1903 {
1904 if (Op1)
1905 {
1906 RemoveToken(&Op1);
1907 }
1908 Op1 = Pop(MatchedStack);
1909 if (Op1->Type != SEMANTIC_RULE)
1910 {
1911 Op1Symbol = ToSymbol(Op1, Error);
1912
1913 FreeTemp(Op1);
1914 PushSymbol(TempStack, Op1Symbol);
1915 RemoveSymbol(&Op1Symbol);
1916
1917 OperandCount++;
1918 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1919 {
1920 RemoveSymbolBuffer((PVOID)TempStack);
1921 break;
1922 }
1923 }
1924
1925 } while (!(Op1->Type == SEMANTIC_RULE && !strcmp(Op1->Value, "@VARGSTART")));
1926
1927 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1928 {
1929 break;
1930 }
1931 Op0 = Pop(MatchedStack);
1932 Op0Symbol = ToSymbol(Op0, Error);
1933 FreeTemp(Op0);
1934
1935 char * Format = Op0->Value;
1936
1937 PSYMBOL OperandCountSymbol = NewSymbol();
1938 OperandCountSymbol->Type = SYMBOL_VARIABLE_COUNT_TYPE;
1939 OperandCountSymbol->Value = OperandCount;
1940
1941 PushSymbol(CodeBuffer, Op0Symbol);
1942 PushSymbol(CodeBuffer, OperandCountSymbol);
1943
1944 RemoveSymbol(&OperandCountSymbol);
1945 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1946 {
1947 RemoveSymbolBuffer((PVOID)TempStack);
1948 break;
1949 }
1950
1951 unsigned int FirstArgPointer = CodeBuffer->Pointer;
1952
1953 PSYMBOL Symbol;
1954 unsigned int ArgCount = TempStack->Pointer;
1955 for (int i = TempStack->Pointer - 1; i >= 0; i--)
1956 {
1957 Symbol = TempStack->Head + i;
1958 PushSymbol(CodeBuffer, Symbol);
1959 }
1960 PSYMBOL FirstArg = (PSYMBOL)((unsigned long long)CodeBuffer->Head +
1961 (unsigned long long)(FirstArgPointer * sizeof(SYMBOL)));
1962 RemoveSymbolBuffer((PVOID)TempStack);
1963
1964 UINT32 i = 0;
1965 char * Str = Format;
1966 do
1967 {
1968 //
1969 // Not the best way but some how for optimization
1970 //
1971 if (*Str == '%')
1972 {
1973 CHAR Temp = *(Str + 1);
1974
1975 if (Temp == 'd' || Temp == 'i' || Temp == 'u' || Temp == 'o' ||
1976 Temp == 'x' || Temp == 'c' || Temp == 'p' || Temp == 's' ||
1977
1978 !strncmp(Str, "%ws", 3) || !strncmp(Str, "%ls", 3) ||
1979
1980 !strncmp(Str, "%ld", 3) || !strncmp(Str, "%li", 3) ||
1981 !strncmp(Str, "%lu", 3) || !strncmp(Str, "%lo", 3) ||
1982 !strncmp(Str, "%lx", 3) ||
1983
1984 !strncmp(Str, "%hd", 3) || !strncmp(Str, "%hi", 3) ||
1985 !strncmp(Str, "%hu", 3) || !strncmp(Str, "%ho", 3) ||
1986 !strncmp(Str, "%hx", 3) ||
1987
1988 !strncmp(Str, "%lld", 4) || !strncmp(Str, "%lli", 4) ||
1989 !strncmp(Str, "%llu", 4) || !strncmp(Str, "%llo", 4) ||
1990 !strncmp(Str, "%llx", 4)
1991
1992 )
1993 {
1994 if (i < ArgCount)
1995 {
1996 Symbol = FirstArg + i;
1997 }
1998 else
1999 {
2001 break;
2002 }
2003 Symbol->Type &= 0xffffffff;
2004 Symbol->Type |= (UINT64)(Str - Format - 1) << 32;
2005 i++;
2006 }
2007 }
2008 Str++;
2009 } while (*Str);
2010 if (i != ArgCount)
2011 {
2013 }
2014
2015 if (*Error == SCRIPT_ENGINE_ERROR_SYNTAX)
2016 {
2017 break;
2018 }
2019 }
2020 else if (IsType5Func(Operator))
2021 {
2022 PushSymbol(CodeBuffer, OperatorSymbol);
2023 }
2024 else if (IsType16Func(Operator))
2025 {
2026 PushSymbol(CodeBuffer, OperatorSymbol);
2027
2028 Temp = NewTemp(Error);
2029 Push(MatchedStack, Temp);
2030 TempSymbol = ToSymbol(Temp, Error);
2031
2032 PushSymbol(CodeBuffer, TempSymbol);
2033
2034 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2035 {
2036 break;
2037 }
2038 }
2039 else if (!strcmp(Operator->Value, "@IGNORE_LVALUE"))
2040 {
2041 Op0 = Pop(MatchedStack);
2042 }
2043 else if (IsType6Func(Operator))
2044 {
2045 PushSymbol(CodeBuffer, OperatorSymbol);
2046 Op0 = Pop(MatchedStack);
2047 Op0Symbol = ToSymbol(Op0, Error);
2048
2049 Op1 = Pop(MatchedStack);
2050 Op1Symbol = ToSymbol(Op1, Error);
2051
2052 PushSymbol(CodeBuffer, Op0Symbol);
2053 PushSymbol(CodeBuffer, Op1Symbol);
2054 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2055 {
2056 break;
2057 }
2058
2059 Temp = NewTemp(Error);
2060 Push(MatchedStack, Temp);
2061 TempSymbol = ToSymbol(Temp, Error);
2062 PushSymbol(CodeBuffer, TempSymbol);
2063
2064 //
2065 // Free the operand if it is a temp value
2066 //
2067 FreeTemp(Op0);
2068 FreeTemp(Op1);
2069 }
2070 else if (IsType7Func(Operator))
2071 {
2072 PushSymbol(CodeBuffer, OperatorSymbol);
2073 Op0 = Pop(MatchedStack);
2074 Op0Symbol = ToSymbol(Op0, Error);
2075
2076 Op1 = Pop(MatchedStack);
2077 Op1Symbol = ToSymbol(Op1, Error);
2078
2079 PushSymbol(CodeBuffer, Op0Symbol);
2080 PushSymbol(CodeBuffer, Op1Symbol);
2081 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2082 {
2083 break;
2084 }
2085 //
2086 // Free the operand if it is a temp value
2087 //
2088 FreeTemp(Op0);
2089 FreeTemp(Op1);
2090 }
2091 else if (IsType8Func(Operator))
2092 {
2093 PushSymbol(CodeBuffer, OperatorSymbol);
2094 Op0 = Pop(MatchedStack);
2095 Op0Symbol = ToSymbol(Op0, Error);
2096
2097 Op1 = Pop(MatchedStack);
2098 Op1Symbol = ToSymbol(Op1, Error);
2099
2100 Op2 = Pop(MatchedStack);
2101 Op2Symbol = ToSymbol(Op2, Error);
2102
2103 PushSymbol(CodeBuffer, Op0Symbol);
2104 PushSymbol(CodeBuffer, Op1Symbol);
2105 PushSymbol(CodeBuffer, Op2Symbol);
2106
2107 Temp = NewTemp(Error);
2108 Push(MatchedStack, Temp);
2109 TempSymbol = ToSymbol(Temp, Error);
2110 PushSymbol(CodeBuffer, TempSymbol);
2111
2112 FreeTemp(Op2);
2113
2114 //
2115 // Free the operand if it is a temp value
2116 //
2117 FreeTemp(Op0);
2118 FreeTemp(Op1);
2119 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2120 {
2121 break;
2122 }
2123 }
2124 else if (IsType14Func(Operator))
2125 {
2126 PushSymbol(CodeBuffer, OperatorSymbol);
2127 Op0 = Pop(MatchedStack);
2128 Op0Symbol = ToSymbol(Op0, Error);
2129
2130 Op1 = Pop(MatchedStack);
2131 Op1Symbol = ToSymbol(Op1, Error);
2132
2133 Op2 = Pop(MatchedStack);
2134 Op2Symbol = ToSymbol(Op2, Error);
2135
2136 PushSymbol(CodeBuffer, Op0Symbol);
2137 PushSymbol(CodeBuffer, Op1Symbol);
2138 PushSymbol(CodeBuffer, Op2Symbol);
2139 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2140 {
2141 break;
2142 }
2143 //
2144 // Free the operand if it is a temp value
2145 //
2146 FreeTemp(Op0);
2147 FreeTemp(Op1);
2148 FreeTemp(Op2);
2149 }
2150 else if (IsAssignmentOperator(Operator))
2151 {
2152 BOOL Handled = FALSE;
2153 Op1 = TopIndexed(MatchedStack, 1);
2154
2155 if (((VARIABLE_TYPE *)Op1->VariableType)->Kind == TY_PTR)
2156 {
2157 if (!strcmp(Operator->Value, "@ADD_ASSIGNMENT"))
2158 {
2159 PSYMBOL Symbol = NULL;
2160
2161 Symbol = NewSymbol();
2163 Symbol->Value = FUNC_MUL;
2164 PushSymbol(CodeBuffer, Symbol);
2165
2166 Symbol = NewSymbol();
2167 Symbol->Type = SYMBOL_NUM_TYPE;
2168 Symbol->Value = ((VARIABLE_TYPE *)Op1->VariableType)->Base->Size;
2169 PushSymbol(CodeBuffer, Symbol);
2170
2171 Op0 = Pop(MatchedStack);
2172 Op0Symbol = ToSymbol(Op0, Error);
2173 PushSymbol(CodeBuffer, Op0Symbol);
2174
2175 Temp = NewTemp(Error);
2176 TempSymbol = ToSymbol(Temp, Error);
2177 PushSymbol(CodeBuffer, TempSymbol);
2178
2179 Symbol = NewSymbol();
2181 Symbol->Value = FUNC_ADD;
2182 PushSymbol(CodeBuffer, Symbol);
2183
2184 PushSymbol(CodeBuffer, TempSymbol);
2185
2186 Op1 = Pop(MatchedStack);
2187 Op1Symbol = ToSymbol(Op1, Error);
2188 PushSymbol(CodeBuffer, Op1Symbol);
2189 PushSymbol(CodeBuffer, Op1Symbol);
2190
2191 FreeTemp(Op0);
2192 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2193 {
2194 break;
2195 }
2196 }
2197 else if (!strcmp(Operator->Value, "@SUB_ASSIGNMENT"))
2198 {
2199 PSYMBOL Symbol = NULL;
2200
2201 Symbol = NewSymbol();
2203 Symbol->Value = FUNC_MUL;
2204 PushSymbol(CodeBuffer, Symbol);
2205
2206 Symbol = NewSymbol();
2207 Symbol->Type = SYMBOL_NUM_TYPE;
2208 Symbol->Value = ((VARIABLE_TYPE *)Op1->VariableType)->Base->Size;
2209 PushSymbol(CodeBuffer, Symbol);
2210
2211 Op0 = Pop(MatchedStack);
2212 Op0Symbol = ToSymbol(Op0, Error);
2213 PushSymbol(CodeBuffer, Op0Symbol);
2214
2215 Temp = NewTemp(Error);
2216 TempSymbol = ToSymbol(Temp, Error);
2217 PushSymbol(CodeBuffer, TempSymbol);
2218
2219 Symbol = NewSymbol();
2221 Symbol->Value = FUNC_SUB;
2222 PushSymbol(CodeBuffer, Symbol);
2223
2224 PushSymbol(CodeBuffer, TempSymbol);
2225
2226 Op1 = Pop(MatchedStack);
2227 Op1Symbol = ToSymbol(Op1, Error);
2228 PushSymbol(CodeBuffer, Op1Symbol);
2229 PushSymbol(CodeBuffer, Op1Symbol);
2230
2231 FreeTemp(Op0);
2232 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2233 {
2234 break;
2235 }
2236 }
2237 else
2238 {
2240 Op0 = Pop(MatchedStack);
2241 Op1 = Pop(MatchedStack);
2242 }
2243 Handled = TRUE;
2244 }
2245
2246 if (!Handled)
2247 {
2248 PushSymbol(CodeBuffer, OperatorSymbol);
2249 Op0 = Pop(MatchedStack);
2250 Op0Symbol = ToSymbol(Op0, Error);
2251
2252 Op1 = Pop(MatchedStack);
2253 Op1Symbol = ToSymbol(Op1, Error);
2254
2255 PushSymbol(CodeBuffer, Op0Symbol);
2256 PushSymbol(CodeBuffer, Op1Symbol);
2257 PushSymbol(CodeBuffer, Op1Symbol);
2258
2259 //
2260 // Free the operand if it is a temp value
2261 //
2262 FreeTemp(Op0);
2263 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2264 {
2265 break;
2266 }
2267 }
2268 }
2269 else if (IsTwoOperandOperator(Operator))
2270 {
2271 BOOL Handled = FALSE;
2272 Op0 = TopIndexed(MatchedStack, 0);
2273 Op1 = TopIndexed(MatchedStack, 1);
2274
2275 if (!strcmp(Operator->Value, "@ADD") || !strcmp(Operator->Value, "@SUB"))
2276 {
2277 if (((VARIABLE_TYPE *)Op0->VariableType)->Kind == TY_PTR && ((VARIABLE_TYPE *)Op1->VariableType)->Kind == TY_PTR)
2278 {
2280 Op0 = Pop(MatchedStack);
2281 Op1 = Pop(MatchedStack);
2282 Handled = TRUE;
2283 }
2284 else if (((VARIABLE_TYPE *)Op0->VariableType)->Kind == TY_PTR && ((VARIABLE_TYPE *)Op1->VariableType)->Kind != TY_PTR)
2285 {
2286 if (!strcmp(Operator->Value, "@SUB"))
2287 {
2289 Op0 = Pop(MatchedStack);
2290 Op1 = Pop(MatchedStack);
2291 }
2292 else
2293 {
2294 PSYMBOL Symbol = NULL;
2295
2296 Op0 = Pop(MatchedStack);
2297 Op1 = Pop(MatchedStack);
2298 Op0Symbol = ToSymbol(Op0, Error);
2299 Op1Symbol = ToSymbol(Op1, Error);
2300
2301 Symbol = NewSymbol();
2303 Symbol->Value = FUNC_MUL;
2304 PushSymbol(CodeBuffer, Symbol);
2305
2306 Symbol = NewSymbol();
2307 Symbol->Type = SYMBOL_NUM_TYPE;
2308 Symbol->Value = ((VARIABLE_TYPE *)Op0->VariableType)->Base->Size;
2309 PushSymbol(CodeBuffer, Symbol);
2310
2311 Op1Symbol = ToSymbol(Op1, Error);
2312 PushSymbol(CodeBuffer, Op1Symbol);
2313
2314 Temp = NewTemp(Error);
2315 TempSymbol = ToSymbol(Temp, Error);
2316 PushSymbol(CodeBuffer, TempSymbol);
2317
2318 PushSymbol(CodeBuffer, OperatorSymbol);
2319 Op0Symbol = ToSymbol(Op0, Error);
2320 PushSymbol(CodeBuffer, Op0Symbol);
2321 PushSymbol(CodeBuffer, TempSymbol);
2322 PushSymbol(CodeBuffer, TempSymbol);
2323
2324 Push(MatchedStack, Temp);
2325
2326 //
2327 // Free the operand if it is a temp value
2328 //
2329 FreeTemp(Op0);
2330 FreeTemp(Op1);
2331 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2332 {
2333 break;
2334 }
2335 }
2336 Handled = TRUE;
2337 }
2338 else if (((VARIABLE_TYPE *)Op0->VariableType)->Kind != TY_PTR && ((VARIABLE_TYPE *)Op1->VariableType)->Kind == TY_PTR)
2339 {
2340 PSYMBOL Symbol = NULL;
2341
2342 Op0 = Pop(MatchedStack);
2343 Op1 = Pop(MatchedStack);
2344 Op0Symbol = ToSymbol(Op0, Error);
2345 Op1Symbol = ToSymbol(Op1, Error);
2346
2347 Symbol = NewSymbol();
2349 Symbol->Value = FUNC_MUL;
2350 PushSymbol(CodeBuffer, Symbol);
2351
2352 Symbol = NewSymbol();
2353 Symbol->Type = SYMBOL_NUM_TYPE;
2354 Symbol->Value = ((VARIABLE_TYPE *)Op1->VariableType)->Base->Size;
2355 PushSymbol(CodeBuffer, Symbol);
2356
2357 PushSymbol(CodeBuffer, Op0Symbol);
2358
2359 Temp = NewTemp(Error);
2360 TempSymbol = ToSymbol(Temp, Error);
2361 PushSymbol(CodeBuffer, TempSymbol);
2362
2363 PushSymbol(CodeBuffer, OperatorSymbol);
2364 PushSymbol(CodeBuffer, TempSymbol);
2365 PushSymbol(CodeBuffer, Op1Symbol);
2366 PushSymbol(CodeBuffer, TempSymbol);
2367
2368 Push(MatchedStack, Temp);
2369
2370 //
2371 // Free the operand if it is a temp value
2372 //
2373 FreeTemp(Op0);
2374 FreeTemp(Op1);
2375 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2376 {
2377 break;
2378 }
2379
2380 Handled = TRUE;
2381 }
2382
2383 else if (((VARIABLE_TYPE *)Op0->VariableType)->Kind == TY_ARRAY && ((VARIABLE_TYPE *)Op1->VariableType)->Kind == TY_ARRAY)
2384 {
2386 Op0 = Pop(MatchedStack);
2387 Op1 = Pop(MatchedStack);
2388 Handled = TRUE;
2389 }
2390 else if (((VARIABLE_TYPE *)Op0->VariableType)->Kind == TY_ARRAY && ((VARIABLE_TYPE *)Op1->VariableType)->Kind != TY_ARRAY)
2391 {
2392 if (!strcmp(Operator->Value, "@SUB"))
2393 {
2395 Op0 = Pop(MatchedStack);
2396 Op1 = Pop(MatchedStack);
2397 }
2398 else
2399 {
2400 PSYMBOL Symbol = NULL;
2401 int VariableBaseSize = 0;
2402 VariableType = (VARIABLE_TYPE *)Op0->VariableType;
2403 while (VariableType->Base)
2404 {
2405 VariableType = VariableType->Base;
2406 }
2407 VariableBaseSize = VariableType->Size;
2408
2409 Op0 = Pop(MatchedStack);
2410 Op1 = Pop(MatchedStack);
2411 Op0Symbol = ToSymbol(Op0, Error);
2412 Op1Symbol = ToSymbol(Op1, Error);
2413
2414 Symbol = NewSymbol();
2416 Symbol->Value = FUNC_MUL;
2417 PushSymbol(CodeBuffer, Symbol);
2418
2419 Symbol = NewSymbol();
2420 Symbol->Type = SYMBOL_NUM_TYPE;
2421 Symbol->Value = VariableBaseSize;
2422 PushSymbol(CodeBuffer, Symbol);
2423
2424 Op1Symbol = ToSymbol(Op1, Error);
2425 PushSymbol(CodeBuffer, Op1Symbol);
2426
2427 Temp = NewTemp(Error);
2428 TempSymbol = ToSymbol(Temp, Error);
2429 PushSymbol(CodeBuffer, TempSymbol);
2430
2431 PushSymbol(CodeBuffer, OperatorSymbol);
2432 Op0Symbol = ToSymbol(Op0, Error);
2433 PushSymbol(CodeBuffer, Op0Symbol);
2434 PushSymbol(CodeBuffer, TempSymbol);
2435 PushSymbol(CodeBuffer, TempSymbol);
2436
2437 Push(MatchedStack, Temp);
2438
2439 //
2440 // Free the operand if it is a temp value
2441 //
2442 FreeTemp(Op0);
2443 FreeTemp(Op1);
2444 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2445 {
2446 break;
2447 }
2448 }
2449 Handled = TRUE;
2450 }
2451 else if (((VARIABLE_TYPE *)Op0->VariableType)->Kind != TY_ARRAY && ((VARIABLE_TYPE *)Op1->VariableType)->Kind == TY_ARRAY)
2452 {
2453 PSYMBOL Symbol = NULL;
2454 int VariableBaseSize = 0;
2455 VariableType = (VARIABLE_TYPE *)Op1->VariableType;
2456 while (VariableType->Base)
2457 {
2458 VariableType = VariableType->Base;
2459 }
2460 VariableBaseSize = VariableType->Size;
2461
2462 Op0 = Pop(MatchedStack);
2463 Op1 = Pop(MatchedStack);
2464 Op0Symbol = ToSymbol(Op0, Error);
2465 Op1Symbol = ToSymbol(Op1, Error);
2466
2467 Symbol = NewSymbol();
2469 Symbol->Value = FUNC_MUL;
2470 PushSymbol(CodeBuffer, Symbol);
2471
2472 Symbol = NewSymbol();
2473 Symbol->Type = SYMBOL_NUM_TYPE;
2474 Symbol->Value = VariableBaseSize;
2475 PushSymbol(CodeBuffer, Symbol);
2476
2477 PushSymbol(CodeBuffer, Op0Symbol);
2478
2479 Temp = NewTemp(Error);
2480 TempSymbol = ToSymbol(Temp, Error);
2481 PushSymbol(CodeBuffer, TempSymbol);
2482
2483 PushSymbol(CodeBuffer, OperatorSymbol);
2484 PushSymbol(CodeBuffer, TempSymbol);
2485 PushSymbol(CodeBuffer, Op1Symbol);
2486 PushSymbol(CodeBuffer, TempSymbol);
2487
2488 Push(MatchedStack, Temp);
2489
2490 //
2491 // Free the operand if it is a temp value
2492 //
2493 FreeTemp(Op0);
2494 FreeTemp(Op1);
2495 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2496 {
2497 break;
2498 }
2499
2500 Handled = TRUE;
2501 }
2502 }
2503
2504 if (!Handled)
2505 {
2506 PushSymbol(CodeBuffer, OperatorSymbol);
2507 Op0 = Pop(MatchedStack);
2508 Op0Symbol = ToSymbol(Op0, Error);
2509
2510 Op1 = Pop(MatchedStack);
2511 Op1Symbol = ToSymbol(Op1, Error);
2512
2513 Temp = NewTemp(Error);
2515 Push(MatchedStack, Temp);
2516 TempSymbol = ToSymbol(Temp, Error);
2517
2518 PushSymbol(CodeBuffer, Op0Symbol);
2519 PushSymbol(CodeBuffer, Op1Symbol);
2520 PushSymbol(CodeBuffer, TempSymbol);
2521
2522 //
2523 // Free the operand if it is a temp value
2524 //
2525 FreeTemp(Op0);
2526 FreeTemp(Op1);
2527 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2528 {
2529 break;
2530 }
2531 }
2532 }
2533 else if (IsOneOperandOperator(Operator))
2534 {
2535 BOOL Handled = FALSE;
2536 Op0 = Top(MatchedStack);
2537
2538 if (((VARIABLE_TYPE *)Op0->VariableType)->Kind == TY_PTR)
2539 {
2540 if (!strcmp(Operator->Value, "@INC"))
2541 {
2542 PSYMBOL Symbol = NULL;
2543
2544 Symbol = NewSymbol();
2546 Symbol->Value = FUNC_ADD;
2547 PushSymbol(CodeBuffer, Symbol);
2548
2549 Symbol = NewSymbol();
2550 Symbol->Type = SYMBOL_NUM_TYPE;
2551 Symbol->Value = ((VARIABLE_TYPE *)Op0->VariableType)->Base->Size;
2552 PushSymbol(CodeBuffer, Symbol);
2553
2554 Op0 = Pop(MatchedStack);
2555 Op0Symbol = ToSymbol(Op0, Error);
2556 PushSymbol(CodeBuffer, Op0Symbol);
2557 PushSymbol(CodeBuffer, Op0Symbol);
2558
2559 FreeTemp(Op0);
2560 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2561 {
2562 break;
2563 }
2564 Handled = TRUE;
2565 }
2566
2567 else if (!strcmp(Operator->Value, "@DEC"))
2568 {
2569 PSYMBOL Symbol = NULL;
2570
2571 Symbol = NewSymbol();
2573 Symbol->Value = FUNC_SUB;
2574 PushSymbol(CodeBuffer, Symbol);
2575
2576 Symbol = NewSymbol();
2577 Symbol->Type = SYMBOL_NUM_TYPE;
2578 Symbol->Value = ((VARIABLE_TYPE *)Op0->VariableType)->Base->Size;
2579 PushSymbol(CodeBuffer, Symbol);
2580
2581 Op0 = Pop(MatchedStack);
2582 Op0Symbol = ToSymbol(Op0, Error);
2583 PushSymbol(CodeBuffer, Op0Symbol);
2584 PushSymbol(CodeBuffer, Op0Symbol);
2585
2586 FreeTemp(Op0);
2587 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2588 {
2589 break;
2590 }
2591 Handled = TRUE;
2592 }
2593 }
2594
2595 if (!Handled)
2596 {
2597 PushSymbol(CodeBuffer, OperatorSymbol);
2598 Op0 = Pop(MatchedStack);
2599 Op0Symbol = ToSymbol(Op0, Error);
2600
2601 PushSymbol(CodeBuffer, Op0Symbol);
2602
2603 //
2604 // Free the operand if it is a temp value
2605 //
2606 FreeTemp(Op0);
2607 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2608 {
2609 break;
2610 }
2611 }
2612 }
2613 else if (!strcmp(Operator->Value, "@VARGSTART"))
2614 {
2615 PSCRIPT_ENGINE_TOKEN OperatorCopy = CopyToken(Operator);
2616 Push(MatchedStack, OperatorCopy);
2617 }
2618 else if (!strcmp(Operator->Value, "@START_OF_IF"))
2619 {
2620 PSCRIPT_ENGINE_TOKEN OperatorCopy = CopyToken(Operator);
2621 Push(MatchedStack, OperatorCopy);
2622 }
2623 else if (!strcmp(Operator->Value, "@JZ"))
2624 {
2625 // UINT64 CurrentPointer = CodeBuffer->Pointer;
2626 PushSymbol(CodeBuffer, OperatorSymbol);
2627
2628 PSYMBOL JumpAddressSymbol = NewSymbol();
2629 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
2630 JumpAddressSymbol->Value = 0xffffffffffffffff;
2631 PushSymbol(CodeBuffer, JumpAddressSymbol);
2632 RemoveSymbol(&JumpAddressSymbol);
2633
2634 Op0 = Pop(MatchedStack);
2635 Op0Symbol = ToSymbol(Op0, Error);
2636
2637 PushSymbol(CodeBuffer, Op0Symbol);
2638
2639 char str[20] = {0};
2640 sprintf(str, "%llu", (UINT64)CodeBuffer->Pointer);
2641 PSCRIPT_ENGINE_TOKEN CurrentAddressToken = NewToken(DECIMAL, str);
2642 Push(MatchedStack, CurrentAddressToken);
2643
2644 FreeTemp(Op0);
2645 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2646 {
2647 break;
2648 }
2649 }
2650 else if (!strcmp(Operator->Value, "@JMP_TO_END_AND_JZCOMPLETED"))
2651 {
2652 //
2653 // Set JZ jump address
2654 //
2655 UINT64 CurrentPointer = CodeBuffer->Pointer;
2656 PSCRIPT_ENGINE_TOKEN JumpSemanticAddressToken = Pop(MatchedStack);
2657 UINT64 JumpSemanticAddress = DecimalToInt(JumpSemanticAddressToken->Value);
2658 PSYMBOL JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpSemanticAddress - 2);
2659 JumpAddressSymbol->Value = CurrentPointer + 2;
2660 RemoveToken(&JumpSemanticAddressToken);
2661
2662 //
2663 // Add jmp instruction to Code Buffer
2664 //
2665 PSYMBOL JumpInstruction = NewSymbol();
2666 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
2667 JumpInstruction->Value = FUNC_JMP;
2668 PushSymbol(CodeBuffer, JumpInstruction);
2669 RemoveSymbol(&JumpInstruction);
2670
2671 //
2672 // Add -1 decimal code to jump address
2673 //
2674 JumpAddressSymbol = NewSymbol();
2675 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
2676 JumpAddressSymbol->Value = 0xffffffffffffffff;
2677 PushSymbol(CodeBuffer, JumpAddressSymbol);
2678 RemoveSymbol(&JumpAddressSymbol);
2679
2680 //
2681 // push current pointer to stack
2682 //
2683 char str[20] = {0};
2684 sprintf(str, "%llu", CurrentPointer);
2685 PSCRIPT_ENGINE_TOKEN CurrentAddressToken = NewToken(DECIMAL, str);
2686 Push(MatchedStack, CurrentAddressToken);
2687 }
2688 else if (!strcmp(Operator->Value, "@END_OF_IF"))
2689 {
2690 UINT64 CurrentPointer = CodeBuffer->Pointer;
2691 PSCRIPT_ENGINE_TOKEN JumpSemanticAddressToken = Pop(MatchedStack);
2692 PSYMBOL JumpAddressSymbol;
2693 while (strcmp(JumpSemanticAddressToken->Value, "@START_OF_IF"))
2694 {
2695 UINT64 JumpSemanticAddress = DecimalToInt(JumpSemanticAddressToken->Value);
2696 JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpSemanticAddress + 1);
2697 JumpAddressSymbol->Value = CurrentPointer;
2698
2699 RemoveToken(&JumpSemanticAddressToken);
2700 JumpSemanticAddressToken = Pop(MatchedStack);
2701 }
2702 RemoveToken(&JumpSemanticAddressToken);
2703 }
2704 else if (!strcmp(Operator->Value, "@START_OF_WHILE"))
2705 {
2706 //
2707 // Push @START_OF_WHILE token into matched stack
2708 //
2709 PSCRIPT_ENGINE_TOKEN OperatorCopy = CopyToken(Operator);
2710 Push(MatchedStack, OperatorCopy);
2711
2712 char str[20] = {0};
2713 sprintf(str, "%llu", (UINT64)CodeBuffer->Pointer);
2714 PSCRIPT_ENGINE_TOKEN CurrentAddressToken = NewToken(DECIMAL, str);
2715 Push(MatchedStack, CurrentAddressToken);
2716 }
2717 else if (!strcmp(Operator->Value, "@START_OF_WHILE_COMMANDS"))
2718 {
2719 UINT64 CurrentPointer = CodeBuffer->Pointer;
2721
2722 RemoveSymbol(&OperatorSymbol);
2723 OperatorSymbol = ToSymbol(JzToken, Error);
2724 RemoveToken(&JzToken);
2725
2726 PSYMBOL JumpAddressSymbol = NewSymbol();
2727 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
2728 JumpAddressSymbol->Value = 0xffffffffffffffff;
2729
2730 Op0 = Pop(MatchedStack);
2731 Op0Symbol = ToSymbol(Op0, Error);
2732
2733 PSCRIPT_ENGINE_TOKEN StartOfWhileToken = Pop(MatchedStack);
2734
2735 char str[20];
2736 sprintf(str, "%llu", CurrentPointer + 1);
2737 PSCRIPT_ENGINE_TOKEN CurrentAddressToken = NewToken(DECIMAL, str);
2738 Push(MatchedStack, CurrentAddressToken);
2739 Push(MatchedStack, StartOfWhileToken);
2740
2741 PushSymbol(CodeBuffer, OperatorSymbol);
2742 PushSymbol(CodeBuffer, JumpAddressSymbol);
2743
2744 PushSymbol(CodeBuffer, Op0Symbol);
2745
2746 RemoveSymbol(&JumpAddressSymbol);
2747
2748 FreeTemp(Op0);
2749 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2750 {
2751 break;
2752 }
2753 }
2754 else if (!strcmp(Operator->Value, "@END_OF_WHILE"))
2755 {
2756 //
2757 // Add jmp instruction to Code Buffer
2758 //
2759 PSYMBOL JumpInstruction = NewSymbol();
2760 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
2761 JumpInstruction->Value = FUNC_JMP;
2762 PushSymbol(CodeBuffer, JumpInstruction);
2763 RemoveSymbol(&JumpInstruction);
2764
2765 //
2766 // Add jmp address to Code buffer
2767 //
2768 PSCRIPT_ENGINE_TOKEN JumpAddressToken = Pop(MatchedStack);
2769 UINT64 JumpAddress = DecimalToInt(JumpAddressToken->Value);
2770 PSYMBOL JumpAddressSymbol = ToSymbol(JumpAddressToken, Error);
2771
2772 PushSymbol(CodeBuffer, JumpAddressSymbol);
2773 RemoveSymbol(&JumpAddressSymbol);
2774 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2775 {
2776 break;
2777 }
2778
2779 //
2780 // Set jumps addresses
2781 //
2782
2783 UINT64 CurrentPointer = CodeBuffer->Pointer;
2784
2785 do
2786 {
2787 RemoveToken(&JumpAddressToken);
2788 JumpAddressToken = Pop(MatchedStack);
2789 if (!strcmp(JumpAddressToken->Value, "@START_OF_WHILE"))
2790 {
2791 break;
2792 }
2793 JumpAddress = DecimalToInt(JumpAddressToken->Value);
2794 JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpAddress);
2795 JumpAddressSymbol->Value = CurrentPointer;
2796
2797 } while (TRUE);
2798 RemoveToken(&JumpAddressToken);
2799 }
2800 else if (!strcmp(Operator->Value, "@START_OF_DO_WHILE"))
2801 {
2802 //
2803 // Push @START_OF_DO_WHILE token into matched stack
2804 //
2805 PSCRIPT_ENGINE_TOKEN OperatorCopy = CopyToken(Operator);
2806 Push(MatchedStack, OperatorCopy);
2807
2808 char str[20];
2809 sprintf(str, "%llu", (UINT64)CodeBuffer->Pointer);
2810 PSCRIPT_ENGINE_TOKEN CurrentAddressToken = NewToken(DECIMAL, str);
2811 Push(MatchedStack, CurrentAddressToken);
2812 }
2813 else if (!strcmp(Operator->Value, "@END_OF_DO_WHILE"))
2814 {
2815 //
2816 // Add jmp instruction to Code Buffer
2817 //
2818 PSYMBOL JumpInstruction = NewSymbol();
2819 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
2820 JumpInstruction->Value = FUNC_JNZ;
2821 PushSymbol(CodeBuffer, JumpInstruction);
2822 RemoveSymbol(&JumpInstruction);
2823
2824 //
2825 // Add Op0 to CodeBuffer
2826 //
2827 Op0 = Pop(MatchedStack);
2828 Op0Symbol = ToSymbol(Op0, Error);
2829
2830 //
2831 // Add jmp address to Code buffer
2832 //
2833 PSCRIPT_ENGINE_TOKEN JumpAddressToken = Pop(MatchedStack);
2834 UINT64 JumpAddress = DecimalToInt(JumpAddressToken->Value);
2835
2836 PSYMBOL JumpAddressSymbol = ToSymbol(JumpAddressToken, Error);
2837
2838 PushSymbol(CodeBuffer, JumpAddressSymbol);
2839 PushSymbol(CodeBuffer, Op0Symbol);
2840
2841 RemoveSymbol(&JumpAddressSymbol);
2842
2843 FreeTemp(Op0);
2844
2845 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2846 {
2847 break;
2848 }
2849
2850 //
2851 // Set jumps addresses
2852 //
2853
2854 UINT64 CurrentPointer = CodeBuffer->Pointer;
2855
2856 do
2857 {
2858 RemoveToken(&JumpAddressToken);
2859 JumpAddressToken = Pop(MatchedStack);
2860 if (!strcmp(JumpAddressToken->Value, "@START_OF_DO_WHILE"))
2861 {
2862 break;
2863 }
2864 JumpAddress = DecimalToInt(JumpAddressToken->Value);
2865
2866#ifdef _SCRIPT_ENGINE_LL1_DBG_EN
2867 printf("Jz Jump Address = %lld\n", JumpAddress);
2868#endif
2869 JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpAddress);
2870 JumpAddressSymbol->Value = CurrentPointer;
2871
2872 } while (TRUE);
2873 RemoveToken(&JumpAddressToken);
2874 }
2875 else if (!strcmp(Operator->Value, "@START_OF_FOR"))
2876 {
2877 //
2878 // Push @START_OF_FOR token into matched stack
2879 //
2880 PSCRIPT_ENGINE_TOKEN OperatorCopy = CopyToken(Operator);
2881 Push(MatchedStack, OperatorCopy);
2882
2883 //
2884 // Push current pointer into matched stack
2885 //
2886 char str[20] = {0};
2887 sprintf(str, "%llu", (UINT64)CodeBuffer->Pointer);
2888 PSCRIPT_ENGINE_TOKEN CurrentAddressToken = NewToken(DECIMAL, str);
2889 Push(MatchedStack, CurrentAddressToken);
2890 }
2891 else if (!strcmp(Operator->Value, "@FOR_INC_DEC"))
2892 {
2893 //
2894 // JZ
2895 //
2896
2897 //
2898 // Add jz instruction to Code Buffer
2899 //
2900 PSYMBOL JnzInstruction = NewSymbol();
2901 JnzInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
2902 JnzInstruction->Value = FUNC_JZ;
2903 PushSymbol(CodeBuffer, JnzInstruction);
2904 RemoveSymbol(&JnzInstruction);
2905
2906 //
2907 // Add JZ address to Code CodeBuffer
2908 //
2909 PSYMBOL JnzAddressSymbol = NewSymbol();
2910 JnzAddressSymbol->Type = SYMBOL_NUM_TYPE;
2911 JnzAddressSymbol->Value = 0xffffffffffffffff;
2912 PushSymbol(CodeBuffer, JnzAddressSymbol);
2913 RemoveSymbol(&JnzAddressSymbol);
2914
2915 //
2916 // Add Op0 to CodeBuffer
2917 //
2918 Op0 = Pop(MatchedStack);
2919 Op0Symbol = ToSymbol(Op0, Error);
2920
2921 PushSymbol(CodeBuffer, Op0Symbol);
2922 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2923 {
2924 break;
2925 }
2926 //
2927 // JMP
2928 //
2929
2930 //
2931 // Add jmp instruction to Code Buffer
2932 //
2933 PSYMBOL JumpInstruction = NewSymbol();
2934 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
2935 JumpInstruction->Value = FUNC_JMP;
2936 PushSymbol(CodeBuffer, JumpInstruction);
2937 RemoveSymbol(&JumpInstruction);
2938
2939 //
2940 // Add jmp address to Code CodeBuffer
2941 //
2942 PSYMBOL JumpAddressSymbol = NewSymbol();
2943 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
2944 JumpAddressSymbol->Value = 0xffffffffffffffff;
2945 PushSymbol(CodeBuffer, JumpAddressSymbol);
2946 RemoveSymbol(&JumpAddressSymbol);
2947
2948 //
2949 // Pop start_of_for address
2950 //
2951 PSCRIPT_ENGINE_TOKEN StartOfForAddressToken = Pop(MatchedStack);
2952
2953 //
2954 // Push current pointer into matched stack
2955 //
2956 char str[20] = {0};
2957 sprintf(str, "%llu", (UINT64)CodeBuffer->Pointer);
2958 PSCRIPT_ENGINE_TOKEN CurrentAddressToken = NewToken(DECIMAL, str);
2959 Push(MatchedStack, CurrentAddressToken);
2960
2961 //
2962 // Push start_of_for address to matched stack
2963 //
2964 Push(MatchedStack, StartOfForAddressToken);
2965 }
2966 else if (!strcmp(Operator->Value, "@START_OF_FOR_COMMANDS"))
2967 {
2968 //
2969 // JMP
2970 //
2971
2972 //
2973 // Add jmp instruction to Code Buffer
2974 //
2975 PSYMBOL JumpInstruction = NewSymbol();
2976 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
2977 JumpInstruction->Value = FUNC_JMP;
2978 PushSymbol(CodeBuffer, JumpInstruction);
2979 RemoveSymbol(&JumpInstruction);
2980
2981 //
2982 // Add jmp address to Code buffer
2983 //
2984 PSCRIPT_ENGINE_TOKEN JumpAddressToken = Pop(MatchedStack);
2985 UINT64 JumpAddress = DecimalToInt(JumpAddressToken->Value);
2986
2987 PSYMBOL JumpAddressSymbol = ToSymbol(JumpAddressToken, Error);
2988
2989 PushSymbol(CodeBuffer, JumpAddressSymbol);
2990 RemoveToken(&JumpAddressToken);
2991 RemoveSymbol(&JumpAddressSymbol);
2992 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2993 {
2994 break;
2995 }
2996
2997 //
2998 // Set jmp address
2999 //
3000 UINT64 CurrentPointer = CodeBuffer->Pointer;
3001 JumpAddressToken = Pop(MatchedStack);
3002 JumpAddress = DecimalToInt(JumpAddressToken->Value);
3003
3004 JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpAddress - 1);
3005 JumpAddressSymbol->Value = CurrentPointer;
3006
3007 //
3008 // Push address of jz address to stack
3009 //
3010 char str[20] = {0};
3011 sprintf(str, "%llu", JumpAddress - 4);
3012 PSCRIPT_ENGINE_TOKEN JzAddressToken = NewToken(DECIMAL, str);
3013 Push(MatchedStack, JzAddressToken);
3014
3015 //
3016 // Push @INC_DEC token to matched stack
3017 //
3018 PSCRIPT_ENGINE_TOKEN IncDecToken = NewToken(SEMANTIC_RULE, "@INC_DEC");
3019 Push(MatchedStack, IncDecToken);
3020
3021 //
3022 // Push start of inc_dec address to matched stack
3023 //
3024 Push(MatchedStack, JumpAddressToken);
3025 }
3026 else if (!strcmp(Operator->Value, "@END_OF_FOR"))
3027 {
3028 //
3029 // Jmp
3030 //
3031
3032 //
3033 // Add jmp instruction to Code Buffer
3034 //
3035 PSYMBOL JumpInstruction = NewSymbol();
3036 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
3037 JumpInstruction->Value = FUNC_JMP;
3038 PushSymbol(CodeBuffer, JumpInstruction);
3039 RemoveSymbol(&JumpInstruction);
3040
3041 //
3042 // Add jmp address to Code buffer
3043 //
3044 PSCRIPT_ENGINE_TOKEN JumpAddressToken = Pop(MatchedStack);
3045 UINT64 JumpAddress = DecimalToInt(JumpAddressToken->Value);
3046
3047 PSYMBOL JumpAddressSymbol = ToSymbol(JumpAddressToken, Error);
3048
3049 PushSymbol(CodeBuffer, JumpAddressSymbol);
3050 RemoveSymbol(&JumpAddressSymbol);
3051 RemoveToken(&JumpAddressToken);
3052
3053 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
3054 {
3055 break;
3056 }
3057
3058 JumpAddressToken = Pop(MatchedStack);
3059
3060 //
3061 // Set jumps addresses
3062 //
3063
3064 UINT64 CurrentPointer = CodeBuffer->Pointer;
3065
3066 do
3067 {
3068 RemoveToken(&JumpAddressToken);
3069 JumpAddressToken = Pop(MatchedStack);
3070 if (!strcmp(JumpAddressToken->Value, "@START_OF_FOR"))
3071 {
3072 break;
3073 }
3074 else
3075 {
3076 JumpAddress = DecimalToInt(JumpAddressToken->Value);
3077
3078 JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpAddress);
3079 JumpAddressSymbol->Value = CurrentPointer;
3080 }
3081
3082 } while (TRUE);
3083 RemoveToken(&JumpAddressToken);
3084 }
3085 else if (!strcmp(Operator->Value, "@BREAK"))
3086 {
3087 //
3088 // Pop Objects from stack while reaching @START_OF_*
3089 //
3090
3092 PSCRIPT_ENGINE_TOKEN TempToken;
3093 do
3094 {
3095 TempToken = Pop(MatchedStack);
3096
3097 if ((!strcmp(TempToken->Value, "@START_OF_FOR")) ||
3098 (!strcmp(TempToken->Value, "@START_OF_WHILE")) ||
3099 (!strcmp(TempToken->Value, "@START_OF_DO_WHILE")))
3100 {
3101 //
3102 // Push back START_OF_*
3103 //
3104 Push(MatchedStack, TempToken);
3105
3106 //
3107 // Push current pointer into matched stack
3108 //
3109
3110 UINT64 CurrentPointer = CodeBuffer->Pointer + 1;
3111 char str[20];
3112 sprintf(str, "%llu", CurrentPointer);
3113 PSCRIPT_ENGINE_TOKEN CurrentAddressToken = NewToken(DECIMAL, str);
3114 Push(MatchedStack, CurrentAddressToken);
3115
3116 //
3117 // JMP
3118 //
3119
3120 //
3121 // Add jmp instruction to Code Buffer
3122 //
3123 PSYMBOL JumpInstruction = NewSymbol();
3124 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
3125 JumpInstruction->Value = FUNC_JMP;
3126 PushSymbol(CodeBuffer, JumpInstruction);
3127 RemoveSymbol(&JumpInstruction);
3128
3129 //
3130 // Add jmp address to Code buffer
3131 //
3132 PSYMBOL JumpAddressSymbol = NewSymbol();
3133 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
3134 JumpAddressSymbol->Value = 0xffffffffffffffff;
3135 PushSymbol(CodeBuffer, JumpAddressSymbol);
3136 RemoveSymbol(&JumpAddressSymbol);
3137
3138 //
3139 //
3140 //
3141 do
3142 {
3143 TempToken = Pop(TempStack);
3144 Push(MatchedStack, TempToken);
3145
3146 } while (TempStack->Pointer != 0);
3147 break;
3148 }
3149 else if (MatchedStack->Pointer == 0)
3150 {
3152 RemoveToken(&TempToken);
3153 break;
3154 }
3155 else
3156 {
3157 Push(TempStack, TempToken);
3158 }
3159
3160 } while (TRUE);
3161 RemoveTokenList(TempStack);
3162 }
3163 else if (!strcmp(Operator->Value, "@CONTINUE"))
3164 {
3165 //
3166 // Pop Objects from stack while reaching @INC_DEC
3167 //
3169 PSCRIPT_ENGINE_TOKEN TempToken;
3170 do
3171 {
3172 TempToken = Pop(MatchedStack);
3173
3174 if (!strcmp(TempToken->Value, "@INC_DEC"))
3175 {
3176 //
3177 // Push back INC_DEC
3178 //
3179 Push(MatchedStack, TempToken);
3180
3181 //
3182 // Add jmp instruction to Code Buffer
3183 //
3184 PSYMBOL JumpInstruction = NewSymbol();
3185 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
3186 JumpInstruction->Value = FUNC_JMP;
3187 PushSymbol(CodeBuffer, JumpInstruction);
3188 RemoveSymbol(&JumpInstruction);
3189
3190 //
3191 // Add jmp address to Code buffer
3192 //
3193 TempToken = Pop(TempStack);
3194 Push(MatchedStack, TempToken);
3195
3196 PSYMBOL JumpAddressSymbol = NewSymbol();
3197 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
3198 JumpAddressSymbol->Value = DecimalToInt(TempToken->Value);
3199 PushSymbol(CodeBuffer, JumpAddressSymbol);
3200 RemoveSymbol(&JumpAddressSymbol);
3201
3202 //
3203 //
3204 //
3205 do
3206 {
3207 TempToken = Pop(TempStack);
3208 Push(MatchedStack, TempToken);
3209
3210 } while (TempStack->Pointer != 0);
3211 break;
3212 }
3213 else if (MatchedStack->Pointer == 0)
3214 {
3216 break;
3217 }
3218 else
3219 {
3220 Push(TempStack, TempToken);
3221 }
3222
3223 } while (TRUE);
3224
3225 RemoveTokenList(TempStack);
3226 }
3227 else if (IsType9Func(Operator))
3228 {
3229 PushSymbol(CodeBuffer, OperatorSymbol);
3230 Op0 = Pop(MatchedStack);
3231 Op0Symbol = ToSymbol(Op0, Error);
3232
3233 Temp = NewTemp(Error);
3234 Push(MatchedStack, Temp);
3235 TempSymbol = ToSymbol(Temp, Error);
3236
3237 PushSymbol(CodeBuffer, Op0Symbol);
3238 PushSymbol(CodeBuffer, TempSymbol);
3239
3240 FreeTemp(Op0);
3241 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
3242 {
3243 break;
3244 }
3245 }
3246 else if (IsType10Func(Operator))
3247 {
3248 PushSymbol(CodeBuffer, OperatorSymbol);
3249 Op0 = Pop(MatchedStack);
3250 Op0Symbol = ToSymbol(Op0, Error);
3251
3252 Op1 = Pop(MatchedStack);
3253 Op1Symbol = ToSymbol(Op1, Error);
3254
3255 PushSymbol(CodeBuffer, Op0Symbol);
3256 PushSymbol(CodeBuffer, Op1Symbol);
3257 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
3258 {
3259 break;
3260 }
3261
3262 Temp = NewTemp(Error);
3263 Push(MatchedStack, Temp);
3264 TempSymbol = ToSymbol(Temp, Error);
3265 PushSymbol(CodeBuffer, TempSymbol);
3266
3267 //
3268 // Free the operand if it is a temp value
3269 //
3270 FreeTemp(Op0);
3271 FreeTemp(Op1);
3272 }
3273 else if (IsType11Func(Operator))
3274 {
3275 PushSymbol(CodeBuffer, OperatorSymbol);
3276 Op0 = Pop(MatchedStack);
3277 Op0Symbol = ToSymbol(Op0, Error);
3278
3279 Op1 = Pop(MatchedStack);
3280 Op1Symbol = ToSymbol(Op1, Error);
3281
3282 Op2 = Pop(MatchedStack);
3283 Op2Symbol = ToSymbol(Op2, Error);
3284
3285 PushSymbol(CodeBuffer, Op0Symbol);
3286 PushSymbol(CodeBuffer, Op1Symbol);
3287 PushSymbol(CodeBuffer, Op2Symbol);
3288
3289 Temp = NewTemp(Error);
3290 Push(MatchedStack, Temp);
3291 TempSymbol = ToSymbol(Temp, Error);
3292 PushSymbol(CodeBuffer, TempSymbol);
3293
3294 //
3295 // Free the operand if it is a temp value
3296 //
3297 FreeTemp(Op0);
3298 FreeTemp(Op1);
3299 FreeTemp(Op2);
3300 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
3301 {
3302 break;
3303 }
3304 }
3305 else if (IsType12Func(Operator))
3306 {
3307 PushSymbol(CodeBuffer, OperatorSymbol);
3308 Op0 = Pop(MatchedStack);
3309 Op0Symbol = ToSymbol(Op0, Error);
3310
3311 Temp = NewTemp(Error);
3312 Push(MatchedStack, Temp);
3313 TempSymbol = ToSymbol(Temp, Error);
3314
3315 PushSymbol(CodeBuffer, Op0Symbol);
3316 PushSymbol(CodeBuffer, TempSymbol);
3317
3318 FreeTemp(Op0);
3319 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
3320 {
3321 break;
3322 }
3323 }
3324 else if (IsType13Func(Operator))
3325 {
3326 PushSymbol(CodeBuffer, OperatorSymbol);
3327 Op0 = Pop(MatchedStack);
3328 Op0Symbol = ToSymbol(Op0, Error);
3329
3330 Op1 = Pop(MatchedStack);
3331 Op1Symbol = ToSymbol(Op1, Error);
3332
3333 PushSymbol(CodeBuffer, Op0Symbol);
3334 PushSymbol(CodeBuffer, Op1Symbol);
3335 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
3336 {
3337 break;
3338 }
3339
3340 Temp = NewTemp(Error);
3341 Push(MatchedStack, Temp);
3342 TempSymbol = ToSymbol(Temp, Error);
3343 PushSymbol(CodeBuffer, TempSymbol);
3344
3345 //
3346 // Free the operand if it is a temp value
3347 //
3348 FreeTemp(Op0);
3349 FreeTemp(Op1);
3350 }
3351
3352 else if (IsType15Func(Operator))
3353 {
3354 PushSymbol(CodeBuffer, OperatorSymbol);
3355 Op0 = Pop(MatchedStack);
3356 Op0Symbol = ToSymbol(Op0, Error);
3357
3358 Op1 = Pop(MatchedStack);
3359 Op1Symbol = ToSymbol(Op1, Error);
3360
3361 Op2 = Pop(MatchedStack);
3362 Op2Symbol = ToSymbol(Op2, Error);
3363
3364 PushSymbol(CodeBuffer, Op0Symbol);
3365 PushSymbol(CodeBuffer, Op1Symbol);
3366 PushSymbol(CodeBuffer, Op2Symbol);
3367
3368 Temp = NewTemp(Error);
3369 Push(MatchedStack, Temp);
3370 TempSymbol = ToSymbol(Temp, Error);
3371 PushSymbol(CodeBuffer, TempSymbol);
3372
3373 //
3374 // Free the operand if it is a temp value
3375 //
3376 FreeTemp(Op0);
3377 FreeTemp(Op1);
3378 FreeTemp(Op2);
3379 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
3380 {
3381 break;
3382 }
3383 }
3384 else
3385 {
3387 }
3388 break;
3389 }
3390
3391#ifdef _SCRIPT_ENGINE_CODEGEN_DBG_EN
3392 //
3393 // Print Debug Info
3394 //
3395 printf("Semantic Stack:\n");
3396 PrintTokenList(MatchedStack);
3397 printf("\n");
3398
3399 printf("Code Buffer:\n");
3400 PrintSymbolBuffer((PVOID)CodeBuffer);
3401 printf("------------------------------------------\n\n");
3402#endif
3403
3404 if (Op0)
3405 RemoveToken(&Op0);
3406
3407 if (Op1)
3408 RemoveToken(&Op1);
3409
3410 if (Op2)
3411 RemoveToken(&Op2);
3412
3413 RemoveSymbol(&OperatorSymbol);
3414
3415 if (Op0Symbol)
3416 RemoveSymbol(&Op0Symbol);
3417
3418 if (Op1Symbol)
3419 RemoveSymbol(&Op1Symbol);
3420
3421 if (Op2Symbol)
3422 RemoveSymbol(&Op2Symbol);
3423
3424 if (TempSymbol)
3425 RemoveSymbol(&TempSymbol);
3426
3427 return;
3428}
VOID PlatformZeroMemory(PVOID Destination, SIZE_T Size)
Zeros a memory block.
Definition PlatformMem.c:155
int BOOL
Definition BasicTypes.h:25
UCHAR BOOLEAN
Definition BasicTypes.h:35
void * PVOID
Definition BasicTypes.h:56
#define TRUE
Definition BasicTypes.h:114
unsigned int UINT32
Definition BasicTypes.h:54
char CHAR
Definition BasicTypes.h:33
#define SYMBOL_STACK_INDEX_TYPE
Definition ScriptEngineCommonDefinitions.h:58
#define FUNC_EQ
Definition ScriptEngineCommonDefinitions.h:187
#define FUNC_MUL
Definition ScriptEngineCommonDefinitions.h:108
#define SYMBOL_TEMP_TYPE
Definition ScriptEngineCommonDefinitions.h:50
#define FUNC_CALL
Definition ScriptEngineCommonDefinitions.h:131
#define SYMBOL_GLOBAL_ID_TYPE
Definition ScriptEngineCommonDefinitions.h:44
#define SYMBOL_LOCAL_ID_TYPE
Definition ScriptEngineCommonDefinitions.h:45
struct SYMBOL * PSYMBOL
#define FUNC_JMP
Definition ScriptEngineCommonDefinitions.h:117
#define FUNC_MOV
Definition ScriptEngineCommonDefinitions.h:120
#define SYMBOL_REFERENCE_LOCAL_ID_TYPE
Definition ScriptEngineCommonDefinitions.h:61
#define FUNC_SUB
Definition ScriptEngineCommonDefinitions.h:107
#define FUNC_POP
Definition ScriptEngineCommonDefinitions.h:130
#define SYMBOL_STACK_BASE_INDEX_TYPE
Definition ScriptEngineCommonDefinitions.h:59
#define SYMBOL_VARIABLE_COUNT_TYPE
Definition ScriptEngineCommonDefinitions.h:52
struct SYMBOL_BUFFER * PSYMBOL_BUFFER
#define FUNC_RET
Definition ScriptEngineCommonDefinitions.h:132
#define FUNC_POI
Definition ScriptEngineCommonDefinitions.h:160
#define FUNC_PUSH
Definition ScriptEngineCommonDefinitions.h:129
#define FUNC_ADD
Definition ScriptEngineCommonDefinitions.h:106
#define FUNC_JZ
Definition ScriptEngineCommonDefinitions.h:118
#define SYMBOL_SEMANTIC_RULE_TYPE
Definition ScriptEngineCommonDefinitions.h:49
#define FUNC_ED
Definition ScriptEngineCommonDefinitions.h:185
#define SYMBOL_RETURN_VALUE_TYPE
Definition ScriptEngineCommonDefinitions.h:60
#define SYMBOL_NUM_TYPE
Definition ScriptEngineCommonDefinitions.h:46
#define FUNC_EB
Definition ScriptEngineCommonDefinitions.h:186
#define FUNC_JNZ
Definition ScriptEngineCommonDefinitions.h:119
printf("ho")
PINCLUDE_NODE IncludeHead
Definition globals.c:17
PUSER_DEFINED_FUNCTION_NODE UserDefinedFunctionHead
Definition globals.c:15
PUSER_DEFINED_FUNCTION_NODE CurrentUserDefinedFunction
Definition globals.c:16
RequestedActionOfThePacket Value(0x1) 00000000
NULL()
Definition test-case-generator.py:530
char * PlatformStrDup(const char *Str)
Platform independent wrapper for _strdup / strdup.
Definition platform-lib-calls.c:51
char IsType9Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is OneOpFunc3.
Definition common.c:889
char IsType4Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is VarArgFunc1.
Definition common.c:789
PSCRIPT_ENGINE_TOKEN Top(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
Returns last Token of a TokenList.
Definition common.c:523
char IsType2Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is OneOpFunc2.
Definition common.c:729
char IsType6Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is TwoOpFunc1.
Definition common.c:829
char IsType1Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is OneOpFunc1.
Definition common.c:709
PSCRIPT_ENGINE_TOKEN CopyToken(PSCRIPT_ENGINE_TOKEN Token)
Copies a PTOKEN.
Definition common.c:326
char IsType12Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is OneOpFunc4.
Definition common.c:949
char IsType14Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is ThreeOpFunc2.
Definition common.c:989
PSCRIPT_ENGINE_TOKEN TopIndexed(PSCRIPT_ENGINE_TOKEN_LIST TokenList, int Index)
Returns the token at a specific index from the top of the token list.
Definition common.c:543
PSCRIPT_ENGINE_TOKEN NewTemp(PSCRIPT_ENGINE_ERROR_TYPE Error)
Allocates a new temporary variable and returns it.
Definition common.c:655
char IsAssignmentOperator(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is assignment operator.
Definition common.c:1049
char IsType10Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is TwoOpFunc3.
Definition common.c:909
char IsType16Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is ZeroOpFunc2.
Definition common.c:1029
PSCRIPT_ENGINE_TOKEN_LIST Push(PSCRIPT_ENGINE_TOKEN_LIST TokenList, PSCRIPT_ENGINE_TOKEN Token)
Adds Token to the last empty position of TokenList.
Definition common.c:441
char IsType15Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is ThreeOpFunc4.
Definition common.c:1009
void RemoveTokenList(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
Removes allocated memory of a SCRIPT_ENGINE_TOKEN_LIST.
Definition common.c:402
void SetType(unsigned long long *Val, unsigned char Type)
Set the Type object.
Definition common.c:1392
char IsTwoOperandOperator(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is OperatorsTwoOperandList.
Definition common.c:749
void RemoveToken(PSCRIPT_ENGINE_TOKEN *Token)
Removes allocated memory of a token.
Definition common.c:116
PSCRIPT_ENGINE_TOKEN NewToken(SCRIPT_ENGINE_TOKEN_TYPE Type, char *Value)
Allocates a new token with given type and value.
Definition common.c:69
char IsType7Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is TwoOpFunc2.
Definition common.c:849
PSCRIPT_ENGINE_TOKEN Pop(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
Removes last Token of a TokenList and returns it.
Definition common.c:502
PSCRIPT_ENGINE_TOKEN_LIST NewTokenList(void)
Allocates a new SCRIPT_ENGINE_TOKEN_LIST.
Definition common.c:364
char IsType13Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is TwoOpFunc4.
Definition common.c:969
VOID FreeTemp(PSCRIPT_ENGINE_TOKEN Temp)
Frees the memory allocated by Temp.
Definition common.c:693
unsigned long long DecimalToInt(char *str)
Converts an decimal string to a integer.
Definition common.c:1404
void PrintToken(PSCRIPT_ENGINE_TOKEN Token)
Prints token.
Definition common.c:132
char IsOneOperandOperator(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is OperatorsOneOperandList.
Definition common.c:769
char IsType11Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is ThreeOpFunc3.
Definition common.c:929
char IsType8Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is ThreeOpFunc1.
Definition common.c:869
void PrintTokenList(PSCRIPT_ENGINE_TOKEN_LIST TokenList)
Prints each Token inside a TokenList.
Definition common.c:423
char IsType5Func(PSCRIPT_ENGINE_TOKEN Operator)
Checks whether this Token type is ZeroOpFunc1.
Definition common.c:809
struct _SCRIPT_ENGINE_TOKEN * PSCRIPT_ENGINE_TOKEN
struct _INCLUDE_NODE INCLUDE_NODE
Include file linked list node.
struct _SCRIPT_ENGINE_TOKEN_LIST * PSCRIPT_ENGINE_TOKEN_LIST
struct _INCLUDE_NODE * PINCLUDE_NODE
@ DEFERENCE_TEMP
Definition common.h:63
@ TEMP
Definition common.h:57
@ LOCAL_UNRESOLVED_ID
Definition common.h:39
@ SCRIPT_VARIABLE_TYPE
Definition common.h:62
@ SEMANTIC_RULE
Definition common.h:54
@ LOCAL_ID
Definition common.h:38
@ PSEUDO_REGISTER
Definition common.h:52
@ GLOBAL_UNRESOLVED_ID
Definition common.h:41
@ REGISTER
Definition common.h:51
@ FUNCTION_ID
Definition common.h:60
@ OCTAL
Definition common.h:45
@ HEX
Definition common.h:44
@ GLOBAL_ID
Definition common.h:40
@ FUNCTION_PARAMETER_ID
Definition common.h:61
@ BINARY
Definition common.h:46
@ DECIMAL
Definition common.h:42
struct _USER_DEFINED_FUNCTION_NODE USER_DEFINED_FUNCTION_NODE
User-defined function linked list node.
struct _USER_DEFINED_FUNCTION_NODE * PUSER_DEFINED_FUNCTION_NODE
#define MAX_TEMP_COUNT
Definition globals.h:16
PUSER_DEFINED_FUNCTION_NODE GetUserDefinedFunctionNode(PSCRIPT_ENGINE_TOKEN Token)
Definition script-engine.c:4549
VOID SetLocalIdentifierVariableType(PSCRIPT_ENGINE_TOKEN Token, VARIABLE_TYPE *VariableType)
Definition script-engine.c:4473
int NewFunctionParameterIdentifier(PSCRIPT_ENGINE_TOKEN Token)
Definition script-engine.c:4514
PSYMBOL_BUFFER PushSymbol(PSYMBOL_BUFFER SymbolBuffer, const PSYMBOL Symbol)
Gets a symbol and push it into the symbol buffer.
Definition script-engine.c:3966
void PrintSymbolBuffer(const PVOID SymbolBuffer)
Prints a symbol buffer.
Definition script-engine.c:4083
PSYMBOL NewSymbol(void)
Allocates a new SYMBOL and returns the reference to it.
Definition script-engine.c:3666
unsigned long long NewLocalIdentifier(PSCRIPT_ENGINE_TOKEN Token, unsigned int VariableSize)
Allocates a new local variable and returns the integer assigned to it.
Definition script-engine.c:4457
VOID SetGlobalIdentifierVariableType(PSCRIPT_ENGINE_TOKEN Token, VARIABLE_TYPE *VariableType)
Definition script-engine.c:4417
PSYMBOL ToSymbol(PSCRIPT_ENGINE_TOKEN Token, PSCRIPT_ENGINE_ERROR_TYPE Error)
Converts Token to Symbol and returns the reference to it.
Definition script-engine.c:3815
void RemoveSymbolBuffer(PVOID SymbolBuffer)
Frees the memory allocated by SymbolBuffer.
Definition script-engine.c:3949
int NewGlobalIdentifier(PSCRIPT_ENGINE_TOKEN Token)
Allocates a new global variable and returns the integer assigned to it.
Definition script-engine.c:4404
void RemoveSymbol(PSYMBOL *Symbol)
Frees the memory allocate by this Symbol.
Definition script-engine.c:3764
PSYMBOL_BUFFER NewSymbolBuffer(void)
allocates a new Symbol Buffer and returns the reference to it
Definition script-engine.c:3923
BOOLEAN FileExists(const char *Path)
Checks whether a file exists at the given path.
Definition script_include.c:152
VOID ResolveIncludePath(const char *IncludeFilePath, char *OutPath)
Resolves an include file path to a full absolute path.
Definition script_include.c:121
char * InsertStrNew(char *Str, int InputIdx, const char *Buf)
Inserts a string into another string at a given index.
Definition script_include.c:73
BOOLEAN ParseIncludeFile(char *IncludeFile, char **Buffer)
Reads and parses an include file into a buffer.
Definition script_include.c:173
#define MAX_PATH_LEN
Definition script_include.h:15
struct _INCLUDE_NODE * NextNode
Definition common.h:296
char * FilePath
Definition common.h:295
unsigned int Pointer
Definition common.h:86
SCRIPT_ENGINE_TOKEN_TYPE Type
Definition common.h:72
VARIABLE_TYPE * VariableType
Definition common.h:76
long long unsigned Address
Definition common.h:279
long long unsigned VariableType
Definition common.h:280
struct _USER_DEFINED_FUNCTION_NODE * NextNode
Definition common.h:287
long long unsigned ParameterNumber
Definition common.h:281
struct _VARIABLE_TYPE * Base
Definition type.h:45
int Size
Definition type.h:42
int Align
Definition type.h:43
int ArrayLen
Definition type.h:46
VARIABLE_TYPE_KIND Kind
Definition type.h:41
BOOLEAN IsUnsigned
Definition type.h:44
unsigned int Pointer
Definition ScriptEngineCommonDefinitions.h:24
PSYMBOL Head
Definition ScriptEngineCommonDefinitions.h:23
Definition ScriptEngineCommonDefinitions.h:6
long long unsigned Value
Definition ScriptEngineCommonDefinitions.h:9
long long unsigned Type
Definition ScriptEngineCommonDefinitions.h:7
VARIABLE_TYPE * VARIABLE_TYPE_LONG
Definition type.c:23
VARIABLE_TYPE * HandleType(PSCRIPT_ENGINE_TOKEN_LIST PtokenStack)
Return a variable type based on the token stack.
Definition type.c:41
VARIABLE_TYPE * GetCommonVariableType(VARIABLE_TYPE *Ty1, VARIABLE_TYPE *Ty2)
Returns the common variable type between two types.
Definition type.c:188
@ TY_PTR
Definition type.h:31
@ TY_VOID
Definition type.h:21
@ TY_ARRAY
Definition type.h:33
@ TY_UNKNOWN
Definition type.h:20
@ SCRIPT_ENGINE_ERROR_UNDEFINED_FUNCTION
Definition type.h:76
@ SCRIPT_ENGINE_ERROR_NON_VOID_FUNCTION_NOT_RETURNING_VALUE
Definition type.h:79
@ SCRIPT_ENGINE_ERROR_UNHANDLED_SEMANTIC_RULE
Definition type.h:74
@ SCRIPT_ENGINE_ERROR_UNDEFINED_VARIABLE_TYPE
Definition type.h:77
@ SCRIPT_ENGINE_ERROR_VOID_FUNCTION_RETURNING_VALUE
Definition type.h:78
@ SCRIPT_ENGINE_ERROR_SYNTAX
Definition type.h:71
@ SCRIPT_ENGINE_ERROR_FREE
Definition type.h:70
struct _VARIABLE_TYPE VARIABLE_TYPE

◆ FuncGetNumberOfOperands()

BOOLEAN FuncGetNumberOfOperands ( UINT64 FuncType,
UINT32 * NumberOfGetOperands,
UINT32 * NumberOfSetOperands )

Script Engine get number of operands.

Parameters
FuncType
NumberOfGetOperands
NumberOfSetOperands
BOOLEANWhether the function is defined or not
4689{
4690 BOOLEAN Result = FALSE;
4691
4692 switch (FuncType)
4693 {
4694 case FUNC_INC:
4695
4696 *NumberOfGetOperands = 1;
4697 *NumberOfSetOperands = 1;
4698 Result = TRUE;
4699
4700 break;
4701
4702 case FUNC_DEC:
4703
4704 *NumberOfGetOperands = 2;
4705 *NumberOfSetOperands = 1;
4706 Result = TRUE;
4707
4708 break;
4709
4710 case FUNC_OR:
4711
4712 *NumberOfGetOperands = 2;
4713 *NumberOfSetOperands = 1;
4714 Result = TRUE;
4715
4716 break;
4717
4718 case FUNC_XOR:
4719
4720 *NumberOfGetOperands = 2;
4721 *NumberOfSetOperands = 1;
4722 Result = TRUE;
4723
4724 break;
4725
4726 case FUNC_AND:
4727
4728 *NumberOfGetOperands = 2;
4729 *NumberOfSetOperands = 1;
4730 Result = TRUE;
4731
4732 break;
4733
4734 case FUNC_ASL:
4735
4736 *NumberOfGetOperands = 2;
4737 *NumberOfSetOperands = 1;
4738 Result = TRUE;
4739
4740 break;
4741
4742 case FUNC_ADD:
4743
4744 *NumberOfGetOperands = 2;
4745 *NumberOfSetOperands = 1;
4746 Result = TRUE;
4747
4748 break;
4749
4750 case FUNC_SUB:
4751
4752 *NumberOfGetOperands = 2;
4753 *NumberOfSetOperands = 1;
4754 Result = TRUE;
4755
4756 break;
4757
4758 case FUNC_MUL:
4759
4760 *NumberOfGetOperands = 2;
4761 *NumberOfSetOperands = 1;
4762 Result = TRUE;
4763
4764 break;
4765
4766 case FUNC_DIV:
4767
4768 *NumberOfGetOperands = 2;
4769 *NumberOfSetOperands = 1;
4770 Result = TRUE;
4771
4772 break;
4773
4774 case FUNC_MOD:
4775
4776 *NumberOfGetOperands = 2;
4777 *NumberOfSetOperands = 1;
4778 Result = TRUE;
4779
4780 break;
4781
4782 case FUNC_GT:
4783
4784 *NumberOfGetOperands = 2;
4785 *NumberOfSetOperands = 1;
4786 Result = TRUE;
4787
4788 break;
4789
4790 case FUNC_LT:
4791
4792 *NumberOfGetOperands = 2;
4793 *NumberOfSetOperands = 1;
4794 Result = TRUE;
4795
4796 break;
4797
4798 case FUNC_EGT:
4799
4800 *NumberOfGetOperands = 2;
4801 *NumberOfSetOperands = 1;
4802 Result = TRUE;
4803
4804 break;
4805
4806 case FUNC_ELT:
4807
4808 *NumberOfGetOperands = 2;
4809 *NumberOfSetOperands = 1;
4810 Result = TRUE;
4811
4812 break;
4813
4814 case FUNC_EQUAL:
4815
4816 *NumberOfGetOperands = 2;
4817 *NumberOfSetOperands = 1;
4818 Result = TRUE;
4819
4820 break;
4821
4822 case FUNC_NEQ:
4823
4824 *NumberOfGetOperands = 2;
4825 *NumberOfSetOperands = 1;
4826 Result = TRUE;
4827
4828 break;
4829
4830 case FUNC_JMP:
4831
4832 *NumberOfGetOperands = 1;
4833 *NumberOfSetOperands = 0;
4834 Result = TRUE;
4835
4836 break;
4837
4838 case FUNC_JZ:
4839
4840 *NumberOfGetOperands = 2;
4841 *NumberOfSetOperands = 0;
4842 Result = TRUE;
4843
4844 break;
4845
4846 case FUNC_JNZ:
4847
4848 *NumberOfGetOperands = 2;
4849 *NumberOfSetOperands = 0;
4850 Result = TRUE;
4851
4852 break;
4853
4854 case FUNC_MOV:
4855
4856 *NumberOfGetOperands = 1;
4857 *NumberOfSetOperands = 1;
4858 Result = TRUE;
4859
4860 break;
4861
4862 default:
4863 //
4864 // Not defined
4865 //
4866 Result = FALSE;
4867 break;
4868 }
4869
4870 return Result;
4871}
#define FUNC_GT
Definition ScriptEngineCommonDefinitions.h:111
#define FUNC_EGT
Definition ScriptEngineCommonDefinitions.h:113
#define FUNC_INC
Definition ScriptEngineCommonDefinitions.h:98
#define FUNC_ASL
Definition ScriptEngineCommonDefinitions.h:105
#define FUNC_ELT
Definition ScriptEngineCommonDefinitions.h:114
#define FUNC_OR
Definition ScriptEngineCommonDefinitions.h:101
#define FUNC_XOR
Definition ScriptEngineCommonDefinitions.h:102
#define FUNC_NEQ
Definition ScriptEngineCommonDefinitions.h:116
#define FUNC_EQUAL
Definition ScriptEngineCommonDefinitions.h:115
#define FUNC_LT
Definition ScriptEngineCommonDefinitions.h:112
#define FUNC_DIV
Definition ScriptEngineCommonDefinitions.h:109
#define FUNC_AND
Definition ScriptEngineCommonDefinitions.h:103
#define FUNC_DEC
Definition ScriptEngineCommonDefinitions.h:99
#define FUNC_MOD
Definition ScriptEngineCommonDefinitions.h:110

◆ GetFunctionParameterIdentifier()

int GetFunctionParameterIdentifier ( PSCRIPT_ENGINE_TOKEN Token)
Parameters
Token
Returns
int
4529{
4530 PSCRIPT_ENGINE_TOKEN CurrentToken;
4531 for (uintptr_t i = 0; i < ((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->FunctionParameterIdTable)->Pointer; i++)
4532 {
4533 CurrentToken = *(((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->FunctionParameterIdTable)->Head + i);
4534 if (!strcmp(Token->Value, CurrentToken->Value))
4535 {
4536 return (int)i;
4537 }
4538 }
4539 return -1;
4540}

◆ GetGlobalIdentifierVal()

int GetGlobalIdentifierVal ( PSCRIPT_ENGINE_TOKEN Token)

Returns the integer assigned to global variable.

Parameters
Token
Returns
int
4363{
4364 PSCRIPT_ENGINE_TOKEN CurrentToken;
4365 for (uintptr_t i = 0; i < GlobalIdTable->Pointer; i++)
4366 {
4367 CurrentToken = *(GlobalIdTable->Head + i);
4368 if (!strcmp(Token->Value, CurrentToken->Value))
4369 {
4370 return (int)i;
4371 }
4372 }
4373 return -1;
4374}
PSCRIPT_ENGINE_TOKEN_LIST GlobalIdTable
lookup table for storing global Ids
Definition globals.c:14

◆ GetGlobalIdentifierVariableType()

VARIABLE_TYPE * GetGlobalIdentifierVariableType ( PSCRIPT_ENGINE_TOKEN Token)
Parameters
Token
4437{
4438 PSCRIPT_ENGINE_TOKEN CurrentToken;
4439 for (uintptr_t i = 0; i < GlobalIdTable->Pointer; i++)
4440 {
4441 CurrentToken = *(GlobalIdTable->Head + i);
4442 if (!strcmp(Token->Value, CurrentToken->Value))
4443 {
4444 return CurrentToken->VariableType;
4445 }
4446 }
4447 return 0;
4448}

◆ GetLocalIdentifierVal()

int GetLocalIdentifierVal ( PSCRIPT_ENGINE_TOKEN Token)

Returns the integer assigned to local variable.

Parameters
Token
Returns
int
4384{
4385 PSCRIPT_ENGINE_TOKEN CurrentToken;
4386 for (uintptr_t i = 0; i < ((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Pointer; i++)
4387 {
4388 CurrentToken = *(((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Head + i);
4389 if (!strcmp(Token->Value, CurrentToken->Value))
4390 {
4391 return (int)CurrentToken->VariableMemoryIdx;
4392 }
4393 }
4394 return -1;
4395}
unsigned long long VariableMemoryIdx
Definition common.h:77

◆ GetLocalIdentifierVariableType()

VARIABLE_TYPE * GetLocalIdentifierVariableType ( PSCRIPT_ENGINE_TOKEN Token)
Parameters
Token
Returns
VARIABLE_TYPE*
4494{
4495 PSCRIPT_ENGINE_TOKEN CurrentToken;
4496 for (uintptr_t i = 0; i < ((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Pointer; i++)
4497 {
4498 CurrentToken = *(((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Head + i);
4499 if (!strcmp(Token->Value, CurrentToken->Value))
4500 {
4501 return CurrentToken->VariableType;
4502 }
4503 }
4504 return 0;
4505}

◆ GetSymbolHeapSize()

unsigned int GetSymbolHeapSize ( PSYMBOL Symbol)

Returns the number of SYMBOL objects (24 bytes) allocated by string or wstring sybmol.

Returns
PSYMBOL
Parameters
Symbol
Returns
unsigned int
3753{
3754 int Temp = (SIZE_SYMBOL_WITHOUT_LEN + (int)Symbol->Len) / sizeof(SYMBOL) + 1;
3755 return Temp;
3756}
#define SIZE_SYMBOL_WITHOUT_LEN
Definition ScriptEngineCommonDefinitions.h:13
long long unsigned Len
Definition ScriptEngineCommonDefinitions.h:8

◆ GetUserDefinedFunctionNode()

PUSER_DEFINED_FUNCTION_NODE GetUserDefinedFunctionNode ( PSCRIPT_ENGINE_TOKEN Token)
Parameters
Token
Returns
PUSER_DEFINED_FUNCTION_NODE
4550{
4552 while (Node)
4553 {
4554 if (!strcmp((const char *)Token->Value, Node->Name))
4555 {
4556 return Node;
4557 break;
4558 }
4559 Node = Node->NextNode;
4560 }
4561 return 0;
4562}
char * Name
Definition common.h:278

◆ HandleError()

char * HandleError ( PSCRIPT_ENGINE_ERROR_TYPE Error,
char * str )

Prints some information about the error.

Parameters
Error
str
Returns
char*
4253{
4254 //
4255 // calculate position of current line
4256 //
4257 unsigned int LineEnd;
4258 for (int i = InputIdx;; i++)
4259 {
4260 if (str[i] == '\n' || str[i] == '\0')
4261 {
4262 LineEnd = i;
4263 break;
4264 }
4265 }
4266
4267 //
4268 // allocate required memory for message, 16 for line, 100 for error information,
4269 // (CurrentTokenIdx - CurrentLineIdx) for space and,
4270 // (LineEnd - CurrentLineIdx) for input string
4271 //
4272 int MessageSize = 16 + 100 + (CurrentTokenIdx - CurrentLineIdx) + (LineEnd - CurrentLineIdx);
4273 char * Message = (char *)malloc(MessageSize);
4274
4275 if (Message == NULL)
4276 {
4277 printf("err, could not allocate buffer");
4278 return NULL;
4279 }
4280
4281 //
4282 // add line number
4283 //
4284 strcpy(Message, "Line ");
4285 char Line[16] = {0};
4286 sprintf(Line, "%d:\n", CurrentLine);
4287 strcat(Message, Line);
4288
4289 //
4290 // add the line which error happened at
4291 //
4292 strncat(Message, (str + CurrentLineIdx), LineEnd - CurrentLineIdx);
4293
4294 strcat(Message, "\n");
4295
4296 //
4297 // add pointer
4298 //
4299 char Space = ' ';
4300 int n = (CurrentTokenIdx - CurrentLineIdx);
4301 for (int i = 0; i < n; i++)
4302 {
4303 strncat(Message, &Space, 1);
4304 }
4305 strcat(Message, "^\n");
4306
4307 //
4308 // add error cause and details
4309 //
4310 switch (*Error)
4311 {
4313 strcat(Message, "Syntax Error: ");
4314 strcat(Message, "Invalid Syntax");
4315 return Message;
4316
4318 strcat(Message, "Syntax Error: ");
4319 strcat(Message, "Unknown Token");
4320 return Message;
4321
4323 strcat(Message, "Syntax Error: ");
4324 strcat(Message, "Unresolved Variable");
4325 return Message;
4326
4328 strcat(Message, "Syntax Error: ");
4329 strcat(Message, "Unhandled Semantic Rule");
4330 return Message;
4331
4333 strcat(Message, "Internal Error: ");
4334 strcat(Message, "Please split the expression to many smaller expressions.");
4335 return Message;
4336
4338 strcat(Message, "Undefined Function");
4339 return Message;
4341 strcat(Message, "Undefined Variable Type");
4342 return Message;
4344 strcat(Message, "Returning a value in void function");
4345 return Message;
4347 strcat(Message, "Not returning a value in noo-void function");
4348 return Message;
4349 default:
4350 strcat(Message, "Unknown Error: ");
4351 return Message;
4352 }
4353}
unsigned int CurrentTokenIdx
Definition globals.c:21
unsigned int CurrentLine
number of current reading line
Definition globals.c:19
unsigned int CurrentLineIdx
Definition globals.c:20
@ SCRIPT_ENGINE_ERROR_UNRESOLVED_VARIABLE
Definition type.h:73
@ SCRIPT_ENGINE_ERROR_UNKNOWN_TOKEN
Definition type.h:72
@ SCRIPT_ENGINE_ERROR_TEMP_LIST_FULL
Definition type.h:75

◆ LalrGetRhsSize()

int LalrGetRhsSize ( int RuleId)

Returns the size of Right Hand Side (RHS) of a rule.

Parameters
RuleId
Returns
int
4572{
4573 int Counter = 0;
4574 int N = LalrRhsSize[RuleId];
4575 for (int i = 0; i < N; i++)
4576 {
4577 if (LalrRhs[RuleId][i].Type != EPSILON && LalrRhs[RuleId][i].Type != SEMANTIC_RULE)
4578 {
4579 Counter++;
4580 }
4581 }
4582 return Counter;
4583}
const unsigned int LalrRhsSize[RULES_COUNT]
Definition parse-table.c:1946
const struct _SCRIPT_ENGINE_TOKEN LalrRhs[RULES_COUNT][MAX_RHS_LEN]
Definition parse-table.c:1826
@ EPSILON
Definition common.h:56

◆ LalrIsOperandType()

BOOL LalrIsOperandType ( PSCRIPT_ENGINE_TOKEN Token)

Returns TRUE if the Token can be the operand of an operator.

Parameters
Token
Returns
BOOL
4593{
4594 if (Token->Type == GLOBAL_ID)
4595 {
4596 return TRUE;
4597 }
4598 else if (Token->Type == GLOBAL_UNRESOLVED_ID)
4599 {
4600 return TRUE;
4601 }
4602 if (Token->Type == LOCAL_ID)
4603 {
4604 return TRUE;
4605 }
4606 else if (Token->Type == LOCAL_UNRESOLVED_ID)
4607 {
4608 return TRUE;
4609 }
4610 else if (Token->Type == FUNCTION_PARAMETER_ID)
4611 {
4612 return TRUE;
4613 }
4614 else if (Token->Type == FUNCTION_ID)
4615 {
4616 return TRUE;
4617 }
4618 else if (Token->Type == DECIMAL)
4619 {
4620 return TRUE;
4621 }
4622 else if (Token->Type == HEX)
4623 {
4624 return TRUE;
4625 }
4626 else if (Token->Type == OCTAL)
4627 {
4628 return TRUE;
4629 }
4630 else if (Token->Type == BINARY)
4631 {
4632 return TRUE;
4633 }
4634 else if (Token->Type == REGISTER)
4635 {
4636 return TRUE;
4637 }
4638 else if (Token->Type == PSEUDO_REGISTER)
4639 {
4640 return TRUE;
4641 }
4642 else if (Token->Type == TEMP)
4643 {
4644 return TRUE;
4645 }
4646 else if (Token->Type == STRING)
4647 {
4648 return TRUE;
4649 }
4650 else if (Token->Type == WSTRING)
4651 {
4652 return TRUE;
4653 }
4654 return FALSE;
4655}
@ WSTRING
Definition common.h:59
@ STRING
Definition common.h:58

◆ NewFunctionParameterIdentifier()

int NewFunctionParameterIdentifier ( PSCRIPT_ENGINE_TOKEN Token)
Parameters
Token
Returns
int
4515{
4516 PSCRIPT_ENGINE_TOKEN CopiedToken = CopyToken(Token);
4517 Push(((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->FunctionParameterIdTable), CopiedToken);
4518 return ((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->FunctionParameterIdTable)->Pointer - 1;
4519}

◆ NewGlobalIdentifier()

int NewGlobalIdentifier ( PSCRIPT_ENGINE_TOKEN Token)

Allocates a new global variable and returns the integer assigned to it.

Parameters
Token
Returns
int
4405{
4406 PSCRIPT_ENGINE_TOKEN CopiedToken = CopyToken(Token);
4407 GlobalIdTable = Push(GlobalIdTable, CopiedToken);
4408 return GlobalIdTable->Pointer - 1;
4409}

◆ NewLocalIdentifier()

unsigned long long NewLocalIdentifier ( PSCRIPT_ENGINE_TOKEN Token,
unsigned int VariableSize )

Allocates a new local variable and returns the integer assigned to it.

Parameters
Token
Returns
int
4458{
4459 PSCRIPT_ENGINE_TOKEN CopiedToken = CopyToken(Token);
4460 unsigned int VariableNumber = ((VariableSize + 8 - 1) & ~(8 - 1)) / 8;
4461 CopiedToken->VariableMemoryIdx = CurrentUserDefinedFunction->LocalVariableNumber;
4462 CurrentUserDefinedFunction->LocalVariableNumber += VariableNumber;
4464 return CopiedToken->VariableMemoryIdx;
4465}

◆ NewStringSymbol()

PSYMBOL NewStringSymbol ( PSCRIPT_ENGINE_TOKEN Token)

Allocates a new SYMBOL with string type and returns the reference to it.

Parameters
value
Returns
PSYMBOL
3693{
3694 PSYMBOL Symbol;
3695 int BufferSize = (SIZE_SYMBOL_WITHOUT_LEN + Token->Len) / sizeof(SYMBOL) + 1;
3696 Symbol = (PSYMBOL)calloc(sizeof(SYMBOL), BufferSize);
3697
3698 if (Symbol == NULL)
3699 {
3700 //
3701 // There was an error allocating buffer
3702 //
3703 return NULL;
3704 }
3705
3706 memcpy(&Symbol->Value, Token->Value, Token->Len);
3707 SetType(&Symbol->Type, SYMBOL_STRING_TYPE);
3708 Symbol->Len = Token->Len;
3709 return Symbol;
3710}
#define SYMBOL_STRING_TYPE
Definition ScriptEngineCommonDefinitions.h:51
unsigned int Len
Definition common.h:74

◆ NewSymbol()

PSYMBOL NewSymbol ( void )

Allocates a new SYMBOL and returns the reference to it.

Returns
PSYMBOL
3667{
3668 PSYMBOL Symbol;
3669 Symbol = (PSYMBOL)malloc(sizeof(SYMBOL));
3670
3671 if (Symbol == NULL)
3672 {
3673 //
3674 // There was an error allocating buffer
3675 //
3676 return NULL;
3677 }
3678
3679 Symbol->Value = 0;
3680 Symbol->Len = 0;
3681 Symbol->Type = 0;
3682 return Symbol;
3683}

◆ NewSymbolBuffer()

PSYMBOL_BUFFER NewSymbolBuffer ( void )

allocates a new Symbol Buffer and returns the reference to it

Returns
PSYMBOL_BUFFER
3924{
3925 PSYMBOL_BUFFER SymbolBuffer;
3926 SymbolBuffer = (PSYMBOL_BUFFER)malloc(sizeof(*SymbolBuffer));
3927
3928 if (SymbolBuffer == NULL)
3929 {
3930 //
3931 // There was an error allocating buffer
3932 //
3933 return NULL;
3934 }
3935
3936 SymbolBuffer->Pointer = 0;
3937 SymbolBuffer->Size = SYMBOL_BUFFER_INIT_SIZE;
3938 SymbolBuffer->Head = (PSYMBOL)malloc(SymbolBuffer->Size * sizeof(SYMBOL));
3939 SymbolBuffer->Message = NULL;
3940 return SymbolBuffer;
3941}
#define SYMBOL_BUFFER_INIT_SIZE
Definition common.h:21
char * Message
Definition ScriptEngineCommonDefinitions.h:26
unsigned int Size
Definition ScriptEngineCommonDefinitions.h:25

◆ NewWstringSymbol()

PSYMBOL NewWstringSymbol ( PSCRIPT_ENGINE_TOKEN Token)

Allocates a new SYMBOL with wstring type and returns the reference to it.

Parameters
value
Returns
PSYMBOL
3720{
3721 PSYMBOL Symbol;
3722 int BufferSize = (SIZE_SYMBOL_WITHOUT_LEN + Token->Len) / sizeof(SYMBOL) + 1;
3723 Symbol = (PSYMBOL)malloc(BufferSize * sizeof(SYMBOL));
3724
3725 if (Symbol == NULL)
3726 {
3727 //
3728 // There was an error allocating buffer
3729 //
3730 return NULL;
3731 }
3732
3733 memcpy(&Symbol->Value, Token->Value, Token->Len);
3734 SetType(&Symbol->Type, SYMBOL_WSTRING_TYPE);
3735 Symbol->Len = Token->Len;
3736 return Symbol;
3737}
#define SYMBOL_WSTRING_TYPE
Definition ScriptEngineCommonDefinitions.h:54

◆ PrintSymbol()

void PrintSymbol ( PVOID Symbol)

Prints symbol.

Parameters
PVOID
3778{
3779 PSYMBOL Sym = (PSYMBOL)Symbol;
3780
3781 if (Sym->Type & 0xffffffff00000000)
3782 {
3783 printf("Type = @VARGSTART\n");
3784 return;
3785 }
3786
3787 printf("Type = %s, ", SymbolTypeNames[Sym->Type]);
3788
3789 if (Sym->Type == SYMBOL_SEMANTIC_RULE_TYPE)
3790 {
3791 printf("Value = %s\n", FunctionNames[Sym->Value]);
3792 }
3793 else if (Sym->Type == SYMBOL_STRING_TYPE)
3794 {
3795 printf("Value = %s\n", (char *)&Sym->Value);
3796 }
3797 else if (Sym->Type == SYMBOL_WSTRING_TYPE)
3798 {
3799 printf("Value = %ls\n", (wchar_t *)&Sym->Value);
3800 }
3801 else
3802 {
3803 printf("Value = %lld\n", Sym->Value);
3804 }
3805}

◆ PrintSymbolBuffer()

void PrintSymbolBuffer ( const PVOID SymbolBuffer)

Prints a symbol buffer.

Parameters
SymbolBuffer
4084{
4085 PSYMBOL_BUFFER SymBuff = (PSYMBOL_BUFFER)SymbolBuffer;
4086 PSYMBOL Symbol;
4087 printf("CodeBuffer:\n");
4088 for (unsigned int i = 0; i < SymBuff->Pointer;)
4089 {
4090 Symbol = SymBuff->Head + i;
4091 printf("Address = %d, ", i);
4092 PrintSymbol((PVOID)Symbol);
4093 if (Symbol->Type == SYMBOL_STRING_TYPE || Symbol->Type == SYMBOL_WSTRING_TYPE)
4094 {
4095 INT Temp = GetSymbolHeapSize(Symbol);
4096 i += Temp;
4097 }
4098 else
4099 {
4100 i++;
4101 }
4102 }
4103}
int INT
Definition BasicTypes.h:43
void PrintSymbol(PVOID Symbol)
Prints symbol.
Definition script-engine.c:3777
unsigned int GetSymbolHeapSize(PSYMBOL Symbol)
Returns the number of SYMBOL objects (24 bytes) allocated by string or wstring sybmol.
Definition script-engine.c:3752

◆ PseudoRegToInt()

unsigned long long int PseudoRegToInt ( char * str)

Converts pseudo register string to integer.

Parameters
str
Returns
unsigned long long int
4214{
4215 for (int i = 0; i < PSEUDO_REGISTER_MAP_LIST_LENGTH; i++)
4216 {
4217 if (!strcmp(str, PseudoRegisterMapList[i].Name))
4218 {
4219 return PseudoRegisterMapList[i].Type;
4220 }
4221 }
4222 return INVALID;
4223}
#define INVALID
Definition ScriptEngineCommonDefinitions.h:92
const SYMBOL_MAP PseudoRegisterMapList[]
Definition parse-table.c:1676
#define PSEUDO_REGISTER_MAP_LIST_LENGTH
Definition parse-table.h:13

◆ PushSymbol()

PSYMBOL_BUFFER PushSymbol ( PSYMBOL_BUFFER SymbolBuffer,
const PSYMBOL Symbol )

Gets a symbol and push it into the symbol buffer.

Parameters
SymbolBuffer
Symbol
Returns
PSYMBOL_BUFFER
3967{
3968 //
3969 // Calculate address to write new token
3970 //
3971 uintptr_t Head = (uintptr_t)SymbolBuffer->Head;
3972 uintptr_t Pointer = (uintptr_t)SymbolBuffer->Pointer;
3973 PSYMBOL WriteAddr = (PSYMBOL)(Head + Pointer * sizeof(SYMBOL));
3974
3975 if (Symbol->Type == SYMBOL_STRING_TYPE || Symbol->Type == SYMBOL_WSTRING_TYPE)
3976 {
3977 //
3978 // Update Pointer
3979 //
3980 SymbolBuffer->Pointer += GetSymbolHeapSize(Symbol);
3981
3982 //
3983 // Handle Overflow
3984 //
3985 if (SymbolBuffer->Pointer >= SymbolBuffer->Size - 1)
3986 {
3987 //
3988 // Calculate new size for the symbol B
3989 //
3990 unsigned int NewSize = SymbolBuffer->Size;
3991 do
3992 {
3993 NewSize *= 2;
3994 } while (NewSize <= SymbolBuffer->Pointer);
3995
3996 //
3997 // Allocate a new buffer for string list with doubled length
3998 //
3999 PSYMBOL NewHead = (PSYMBOL)malloc(NewSize * sizeof(SYMBOL));
4000
4001 if (NewHead == NULL)
4002 {
4003 printf("err, could not allocate buffer");
4004 return NULL;
4005 }
4006
4007 //
4008 // Copy old buffer to new buffer
4009 //
4010 memcpy(NewHead, SymbolBuffer->Head, SymbolBuffer->Size * sizeof(SYMBOL));
4011
4012 //
4013 // Free old buffer
4014 //
4015 free(SymbolBuffer->Head);
4016
4017 //
4018 // Update Head and size of SymbolBuffer
4019 //
4020 SymbolBuffer->Size = NewSize;
4021 SymbolBuffer->Head = NewHead;
4022 }
4023 WriteAddr = (PSYMBOL)((uintptr_t)SymbolBuffer->Head + (uintptr_t)Pointer * (uintptr_t)sizeof(SYMBOL));
4024 WriteAddr->Type = Symbol->Type;
4025 WriteAddr->Len = Symbol->Len;
4026 memcpy((char *)&WriteAddr->Value, (char *)&Symbol->Value, Symbol->Len);
4027 }
4028 else
4029 {
4030 //
4031 // Write input to the appropriate address in SymbolBuffer
4032 //
4033 *WriteAddr = *Symbol;
4034
4035 //
4036 // Update Pointer
4037 //
4038 SymbolBuffer->Pointer++;
4039
4040 //
4041 // Handle Overflow
4042 //
4043 if (Pointer >= SymbolBuffer->Size - 1)
4044 {
4045 //
4046 // Allocate a new buffer for string list with doubled length
4047 //
4048 PSYMBOL NewHead = (PSYMBOL)malloc(2 * SymbolBuffer->Size * sizeof(SYMBOL));
4049
4050 if (NewHead == NULL)
4051 {
4052 printf("err, could not allocate buffer");
4053 return NULL;
4054 }
4055
4056 //
4057 // Copy old Buffer to new buffer
4058 //
4059 memcpy(NewHead, SymbolBuffer->Head, SymbolBuffer->Size * sizeof(SYMBOL));
4060
4061 //
4062 // Free Old buffer
4063 //
4064 free(SymbolBuffer->Head);
4065
4066 //
4067 // Update Head and size of SymbolBuffer
4068 //
4069 SymbolBuffer->Size *= 2;
4070 SymbolBuffer->Head = NewHead;
4071 }
4072 }
4073
4074 return SymbolBuffer;
4075}

◆ RegisterToInt()

unsigned long long int RegisterToInt ( char * str)

Converts register string to integer.

Parameters
str
Returns
unsigned long long int
4113{
4114 //
4115 // Check for register names
4116 //
4117 for (int i = 0; i < REGISTER_MAP_LIST_LENGTH; i++)
4118 {
4119 if (!strcmp(str, RegisterMapList[i].Name))
4120 {
4121 return RegisterMapList[i].Type;
4122 }
4123 }
4124
4125 //
4126 // Check for hwdbg register names
4127 // Check if the registers start with '@hw_portX' or '@hw_pinX'
4128 //
4130 {
4131 const char * Ptr;
4132 UINT32 Num = 0;
4133
4134 //
4135 // Check for "hw_pin"
4136 //
4137 if (strncmp(str, "hw_pin", 6) == 0)
4138 {
4139 Ptr = str + 6;
4140 if (*Ptr == '\0')
4141 {
4142 return INVALID; // No number present
4143 }
4144 while (*Ptr)
4145 {
4146 if (!isdigit((unsigned char)*Ptr))
4147 {
4148 return INVALID; // Not a valid decimal number
4149 }
4150 Ptr++;
4151 }
4152 Num = atoi(str + 6);
4153
4154 //
4155 // port numbers start after the latest pin number
4156 //
4157 if (Num >= g_HwdbgInstanceInfo.numberOfPins)
4158 {
4159 return INVALID; // Invalid "hw_pinX"
4160 }
4161 else
4162 {
4163 return Num; // Valid "hw_pinX"
4164 }
4165 }
4166
4167 //
4168 // Check for "hw_port"
4169 //
4170 if (strncmp(str, "hw_port", 7) == 0)
4171 {
4172 Ptr = str + 7;
4173 if (*Ptr == '\0')
4174 {
4175 return INVALID; // No number present
4176 }
4177 while (*Ptr)
4178 {
4179 if (!isdigit((unsigned char)*Ptr))
4180 {
4181 return INVALID; // Not a valid decimal number
4182 }
4183
4184 Ptr++;
4185 }
4186
4187 Num = atoi(str + 7);
4188
4189 if (Num >= g_HwdbgInstanceInfo.numberOfPorts)
4190 {
4191 return INVALID; // Invalid "hw_portX"
4192 }
4193 else
4194 {
4195 return Num + g_HwdbgInstanceInfo.numberOfPins; // Valid "hw_portX"
4196 }
4197 }
4198 }
4199
4200 //
4201 // Not a valid register name
4202 //
4203 return INVALID;
4204}
@ Num
Definition commands.h:167
BOOLEAN g_HwdbgInstanceInfoIsValid
Shows whether the instance info is valid (received) or not.
Definition globals.h:697
HWDBG_INSTANCE_INFORMATION g_HwdbgInstanceInfo
Instance information of the current hwdbg debuggee.
Definition globals.h:691
const SYMBOL_MAP RegisterMapList[]
Definition parse-table.c:1554
#define REGISTER_MAP_LIST_LENGTH
Definition parse-table.h:12

◆ RemoveSymbol()

void RemoveSymbol ( PSYMBOL * Symbol)

Frees the memory allocate by this Symbol.

Parameters
Symbol
3765{
3766 free(*Symbol);
3767 *Symbol = NULL;
3768 return;
3769}

◆ RemoveSymbolBuffer()

void RemoveSymbolBuffer ( PVOID SymbolBuffer)

Frees the memory allocated by SymbolBuffer.

Parameters
SymbolBuffer
3950{
3951 PSYMBOL_BUFFER SymBuf = (PSYMBOL_BUFFER)SymbolBuffer;
3952
3953 free(SymBuf->Message);
3954 free(SymBuf->Head);
3955 free(SymBuf);
3956}

◆ ScriptEngineBooleanExpresssionParse()

void ScriptEngineBooleanExpresssionParse ( UINT64 BooleanExpressionSize,
PSCRIPT_ENGINE_TOKEN FirstToken,
PSCRIPT_ENGINE_TOKEN_LIST MatchedStack,
PSYMBOL_BUFFER CodeBuffer,
char * str,
char * c,
PSCRIPT_ENGINE_ERROR_TYPE Error )

LALR parser used for parsing boolean expression.

Parameters
BooleanExpressionSize
FirstToken
MatchedStack
CodeBuffer
str
c
Error
3498{
3500
3502 Push(Stack, State);
3503
3504#ifdef _SCRIPT_ENGINE_LALR_DBG_EN
3505 printf("Boolean Expression: ");
3506 printf("%s", FirstToken->Value);
3507 for (int i = InputIdx - 1; i < BooleanExpressionSize; i++)
3508 {
3509 printf("%c", str[i]);
3510 }
3511 printf("\n\n");
3512#endif
3513
3514 //
3515 // End of File Token
3516 //
3518
3519 PSCRIPT_ENGINE_TOKEN CurrentIn = CopyToken(FirstToken);
3520
3521 PSCRIPT_ENGINE_TOKEN TopToken = NULL;
3524 PSCRIPT_ENGINE_TOKEN Operand = NULL;
3525 PSCRIPT_ENGINE_TOKEN SemanticRule = NULL;
3526
3527 int Action = INVALID;
3528 int StateId = 0;
3529 int Goto = 0;
3530 int InputPointer = 0;
3531 int RhsSize = 0;
3532 unsigned int InputIdxTemp;
3533 CHAR CTemp;
3534
3535 while (1)
3536 {
3537 TopToken = Top(Stack);
3538 int TerminalId = LalrGetTerminalId(CurrentIn);
3539 StateId = (int)DecimalToSignedInt(TopToken->Value);
3540 if (StateId == INVALID || TerminalId < 0)
3541 {
3543 break;
3544 }
3545 Action = LalrActionTable[StateId][TerminalId];
3546
3547#ifdef _SCRIPT_ENGINE_LALR_DBG_EN
3548 printf("Stack :\n");
3549 PrintTokenList(Stack);
3550 printf("Action : %d\n\n", Action);
3551#endif
3552 if (Action == LALR_ACCEPT)
3553 {
3554 *Error = SCRIPT_ENGINE_ERROR_FREE;
3555 break;
3556 }
3557 if (Action == INVALID)
3558 {
3560 break;
3561 }
3562 if (Action == 0)
3563 {
3565 break;
3566 }
3567 else if (Action >= 0) // Shift
3568 {
3569 StateId = Action;
3570 Push(Stack, CurrentIn);
3571
3572 char buffer[20] = {0};
3573 sprintf(buffer, "%d", StateId);
3574 State = NewToken(STATE_ID, buffer);
3575 Push(Stack, State);
3576
3577 InputIdxTemp = InputIdx;
3578 CTemp = *c;
3579
3580 CurrentIn = Scan(str, c);
3581 if (InputIdx - 1 > BooleanExpressionSize)
3582 {
3583 InputIdx = InputIdxTemp;
3584 *c = CTemp;
3585
3586 RemoveToken(&CurrentIn);
3587
3588 CurrentIn = CopyToken(EndToken);
3589 }
3590 }
3591 else if (Action < 0) // Reduce
3592 {
3593 StateId = -Action;
3594 Lhs = (PSCRIPT_ENGINE_TOKEN)&LalrLhs[StateId - 1];
3595 RhsSize = LalrGetRhsSize(StateId - 1);
3596 SemanticRule = (PSCRIPT_ENGINE_TOKEN)&LalrSemanticRules[StateId - 1];
3597
3598 for (int i = 0; i < 2 * RhsSize; i++)
3599 {
3600 Temp = Pop(Stack);
3601 if (SemanticRule->Type == SEMANTIC_RULE && !strcmp(SemanticRule->Value, "@PUSH"))
3602 {
3603 if (LalrIsOperandType(Temp))
3604 {
3605 Operand = Temp;
3606 Push(MatchedStack, Operand);
3607 }
3608 else
3609 {
3610 RemoveToken(&Temp);
3611 }
3612 }
3613 else
3614 {
3615 RemoveToken(&Temp);
3616 }
3617 }
3618 if (SemanticRule->Type == SEMANTIC_RULE)
3619 {
3620 if (!strcmp(SemanticRule->Value, "@PUSH"))
3621 {
3622 }
3623 else
3624 {
3625 CodeGen(MatchedStack, CodeBuffer, SemanticRule, Error, &str);
3626 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
3627 {
3628 break;
3629 }
3630 }
3631 }
3632
3633 Temp = Top(Stack);
3634 StateId = (int)DecimalToSignedInt(Temp->Value);
3635
3636 Goto = LalrGotoTable[StateId][LalrGetNonTerminalId(Lhs)];
3637
3639
3640 char buffer[20] = {0};
3641 sprintf(buffer, "%d", Goto);
3642 State = NewToken(STATE_ID, buffer);
3643 Push(Stack, LhsCopy);
3644 Push(Stack, State);
3645 }
3646 }
3647
3648 if (EndToken)
3649 RemoveToken(&EndToken);
3650
3651 if (Stack)
3652 RemoveTokenList(Stack);
3653
3654 if (CurrentIn)
3655 RemoveToken(&CurrentIn);
3656
3657 return;
3658}
#define LALR_ACCEPT
Definition ScriptEngineCommonDefinitions.h:93
const unsigned int RhsSize[RULES_COUNT]
Definition parse-table.c:576
const int LalrGotoTable[LALR_STATE_COUNT][LALR_NONTERMINAL_COUNT]
Definition parse-table.c:2184
const int LalrActionTable[LALR_STATE_COUNT][LALR_TERMINAL_COUNT]
Definition parse-table.c:2519
const struct _SCRIPT_ENGINE_TOKEN Lhs[RULES_COUNT]
Definition parse-table.c:2
const struct _SCRIPT_ENGINE_TOKEN LalrSemanticRules[RULES_COUNT]
Definition parse-table.c:2854
const struct _SCRIPT_ENGINE_TOKEN LalrLhs[RULES_COUNT]
Definition parse-table.c:1706
PSCRIPT_ENGINE_TOKEN Scan(char *str, char *c)
Perform scanning the script engine.
Definition scanner.c:976
int LalrGetNonTerminalId(PSCRIPT_ENGINE_TOKEN Token)
Gets the Non Terminal Id object.
Definition common.c:1227
int LalrGetTerminalId(PSCRIPT_ENGINE_TOKEN Token)
Gets the Terminal Id object.
Definition common.c:1244
unsigned long long DecimalToSignedInt(char *str)
Converts an decimal string to a signed integer.
Definition common.c:1425
@ END_OF_STACK
Definition common.h:55
@ STATE_ID
Definition common.h:43
int LalrGetRhsSize(int RuleId)
Returns the size of Right Hand Side (RHS) of a rule.
Definition script-engine.c:4571
BOOL LalrIsOperandType(PSCRIPT_ENGINE_TOKEN Token)
Returns TRUE if the Token can be the operand of an operator.
Definition script-engine.c:4592
void CodeGen(PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, PSCRIPT_ENGINE_TOKEN Operator, PSCRIPT_ENGINE_ERROR_TYPE Error, char **ScriptSource)
Script Engine code generator.
Definition script-engine.c:709

◆ ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails()

BOOLEAN ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails ( const char * LocalFilePath,
char * PdbFilePath,
char * GuidAndAgeDetails,
BOOLEAN Is32BitModule )

Convert file to pdb attributes for symbols.

Parameters
LocalFilePath
PdbFilePath
GuidAndAgeDetails
Is32BitModule
Returns
BOOLEAN
297{
298 //
299 // A wrapper for pdb to path file and guid and age detail converter
300 //
301 return SymConvertFileToPdbFileAndGuidAndAgeDetails(LocalFilePath, PdbFilePath, GuidAndAgeDetails, Is32BitModule);
302}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN SymConvertFileToPdbFileAndGuidAndAgeDetails(const CHAR *LocalFilePath, CHAR *PdbFilePath, CHAR *GuidAndAgeDetails, BOOLEAN Is32BitModule)

◆ ScriptEngineConvertFileToPdbPath()

BOOLEAN ScriptEngineConvertFileToPdbPath ( const char * LocalFilePath,
char * ResultPath,
SIZE_T ResultPathSize )

Convert local file to pdb path.

Parameters
LocalFilePath
ResultPath
Returns
BOOLEAN
218{
219 //
220 // A wrapper for pdb to path converter
221 //
222 return SymConvertFileToPdbPath(LocalFilePath, ResultPath, ResultPathSize);
223}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN SymConvertFileToPdbPath(const CHAR *LocalFilePath, CHAR *ResultPath, SIZE_T ResultPathSize)

◆ ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetails()

BOOLEAN ScriptEngineConvertLoadedModuleToPdbFileAndGuidAndAgeDetails ( const BYTE * LoadedImageBytes,
SIZE_T LoadedImageSize,
const char * LocalFilePath,
char * PdbFilePath,
char * GuidAndAgeDetails,
BOOLEAN Is32BitModule )

Convert loaded module bytes to pdb attributes for symbols.

Parameters
LoadedImageBytes
LoadedImageSize
LocalFilePath
PdbFilePath
GuidAndAgeDetails
Is32BitModule
Returns
BOOLEAN
323{
324 //
325 // A wrapper for loaded module pdb to path file and guid and age detail converter
326 //
328 LoadedImageBytes,
329 LoadedImageSize,
330 LocalFilePath,
331 PdbFilePath,
332 GuidAndAgeDetails,
333 Is32BitModule);
334}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN SymConvertLoadedModuleToPdbFileAndGuidAndAgeDetails(const BYTE *LoadedImageBytes, SIZE_T LoadedImageSize, const CHAR *LocalFilePath, CHAR *PdbFilePath, CHAR *GuidAndAgeDetails, BOOLEAN Is32BitModule)

◆ ScriptEngineConvertNameToAddress()

UINT64 ScriptEngineConvertNameToAddress ( const char * FunctionOrVariableName,
PBOOLEAN WasFound )

Converts name to address.

Parameters
FunctionOrVariableName
WasFound
Returns
UINT64
70{
71 //
72 // A wrapper for pdb parser
73 //
74 return SymConvertNameToAddress(FunctionOrVariableName, WasFound);
75}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT64 SymConvertNameToAddress(const CHAR *FunctionOrVariableName, PBOOLEAN WasFound)
Convert function name to address.
Definition symbol-parser.cpp:900

◆ ScriptEngineCreateSymbolTableForDisassembler()

BOOLEAN ScriptEngineCreateSymbolTableForDisassembler ( void * CallbackFunction)

Create symbol table for disassembler.

Parameters
CallbackFunction
Returns
BOOLEAN
202{
203 //
204 // A wrapper for pdb symbol table callback creator
205 //
206 return SymCreateSymbolTableForDisassembler(CallbackFunction);
207}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN SymCreateSymbolTableForDisassembler(PVOID CallbackFunction)
Create symbol table for disassembler.
Definition symbol-parser.cpp:1242

◆ ScriptEngineGetDataTypeSize()

BOOLEAN ScriptEngineGetDataTypeSize ( CHAR * TypeName,
UINT64 * TypeSize )

Get size of a data type (structure).

Parameters
TypeName
TypeSize
Returns
BOOLEAN
187{
188 //
189 // A wrapper for getting size of the structure
190 //
191 return SymGetDataTypeSize(TypeName, TypeSize);
192}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN SymGetDataTypeSize(CHAR *TypeName, UINT64 *TypeSize)
Get the size of structures from the symbols.
Definition symbol-parser.cpp:1126

◆ ScriptEngineGetFieldOffset()

BOOLEAN ScriptEngineGetFieldOffset ( CHAR * TypeName,
CHAR * FieldName,
UINT32 * FieldOffset )

Get offset of a field from the structure.

Parameters
TypeName
FieldName
FieldOffset
Returns
BOOLEAN
171{
172 //
173 // A wrapper for search for fields in the structure
174 //
175 return SymGetFieldOffset(TypeName, FieldName, FieldOffset);
176}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN SymGetFieldOffset(CHAR *TypeName, CHAR *FieldName, UINT32 *FieldOffset)
Search and show symbols.
Definition symbol-parser.cpp:1038

◆ ScriptEngineLoadFileSymbol()

UINT32 ScriptEngineLoadFileSymbol ( UINT64 BaseAddress,
const char * PdbFileName,
const char * CustomModuleName )

Load symbol files

Parameters
BaseAddress
PdbFileName
CustomModuleName
Returns
UINT32
90{
91 //
92 // A wrapper for pdb parser
93 //
94 return SymLoadFileSymbol(BaseAddress, PdbFileName, CustomModuleName);
95}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT32 SymLoadFileSymbol(UINT64 BaseAddress, const CHAR *PdbFileName, const CHAR *CustomModuleName)
load symbol based on a file name and GUID
Definition symbol-parser.cpp:628

◆ ScriptEngineParse()

PVOID ScriptEngineParse ( char * str)

The entry point of script engine.

Parameters
str
Returns
PVOID
344{
345 char * ScriptSource = PlatformStrDup(str);
346
349 PSYMBOL_BUFFER CodeBuffer = NewSymbolBuffer();
350
354 UserDefinedFunctionHead->IdTable = (unsigned long long)NewTokenList();
355 UserDefinedFunctionHead->FunctionParameterIdTable = (unsigned long long)NewTokenList();
356 UserDefinedFunctionHead->TempMap = calloc(MAX_TEMP_COUNT, 1);
357 UserDefinedFunctionHead->VariableType = (unsigned long long)VARIABLE_TYPE_VOID;
358
360
362 char * ErrorMessage = NULL;
363
364 static INT FirstCall = 1;
365 if (FirstCall)
366 {
368 FirstCall = 0;
369 }
370
372
373 int NonTerminalId;
374 int TerminalId;
375 int RuleId;
376 CHAR C;
377 BOOL WaitForWaitStatementBooleanExpression = FALSE;
378
379 //
380 // Initialize Scanner
381 //
382 InputIdx = 0;
383 CurrentLine = 0;
384 CurrentLineIdx = 0;
385
386 //
387 // End of File Token
388 //
390
391 //
392 // Start Token
393 //
395
396 Push(Stack, EndToken);
397 Push(Stack, StartToken);
398
399 C = sgetc(ScriptSource);
400
401 PSCRIPT_ENGINE_TOKEN CurrentIn = Scan(ScriptSource, &C);
402 if (CurrentIn->Type == UNKNOWN)
403 {
405 ErrorMessage = HandleError(&Error, ScriptSource);
406 CodeBuffer->Message = ErrorMessage;
407
408 RemoveTokenList(Stack);
409 RemoveTokenList(MatchedStack);
410 RemoveToken(&CurrentIn);
411 return (PVOID)CodeBuffer;
412 }
413
414 //
415 // add stack index
416 //
417 PSYMBOL TempSymbol = NewSymbol();
418 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
419 TempSymbol->Value = FUNC_ADD;
420 PushSymbol(CodeBuffer, TempSymbol);
421 RemoveSymbol(&TempSymbol);
422
423 TempSymbol = NewSymbol();
424 TempSymbol->Type = SYMBOL_NUM_TYPE;
425 TempSymbol->Value = 0xffffffffffffffff;
426 PushSymbol(CodeBuffer, TempSymbol);
427 RemoveSymbol(&TempSymbol);
428
429 TempSymbol = NewSymbol();
430 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
431 TempSymbol->Value = 0;
432 PushSymbol(CodeBuffer, TempSymbol);
433 RemoveSymbol(&TempSymbol);
434
435 TempSymbol = NewSymbol();
436 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
437 TempSymbol->Value = 0;
438 PushSymbol(CodeBuffer, TempSymbol);
439 RemoveSymbol(&TempSymbol);
440
441 do
442 {
443 RemoveToken(&TopToken);
444 TopToken = Pop(Stack);
445
446#ifdef _SCRIPT_ENGINE_LL1_DBG_EN
447 printf("\nTop Token :\n");
448 PrintToken(TopToken);
449 printf("\nCurrent Input :\n");
450 PrintToken(CurrentIn);
451 printf("\n");
452#endif
453
454 if (TopToken->Type == NON_TERMINAL)
455 {
456 if (!strcmp(TopToken->Value, "BOOLEAN_EXPRESSION"))
457 {
458 UINT64 BooleanExpressionSize = BooleanExpressionExtractEnd(ScriptSource, &WaitForWaitStatementBooleanExpression, CurrentIn);
459
460 ScriptEngineBooleanExpresssionParse(BooleanExpressionSize, CurrentIn, MatchedStack, CodeBuffer, ScriptSource, &C, &Error);
461 if (Error != SCRIPT_ENGINE_ERROR_FREE)
462 {
463 break;
464 }
465
466 RemoveToken(&CurrentIn);
467 CurrentIn = Scan(ScriptSource, &C);
468 if (CurrentIn->Type == UNKNOWN)
469 {
471 break;
472 }
473
474 RemoveToken(&CurrentIn);
475 CurrentIn = Scan(ScriptSource, &C);
476 if (CurrentIn->Type == UNKNOWN)
477 {
479 break;
480 }
481 RemoveToken(&TopToken);
482 TopToken = Pop(Stack);
483 }
484 else
485 {
486 NonTerminalId = GetNonTerminalId(TopToken);
487 if (NonTerminalId == INVALID)
488 {
490 break;
491 }
492
493 TerminalId = GetTerminalId(CurrentIn);
494 if (TerminalId == INVALID)
495 {
497 break;
498 }
499
500 RuleId = ParseTable[NonTerminalId][TerminalId];
501 if (RuleId == INVALID)
502 {
504 break;
505 }
506
507 //
508 // Push RHS Reversely into stack
509 //
510 for (int i = RhsSize[RuleId] - 1; i >= 0; i--)
511 {
512 PSCRIPT_ENGINE_TOKEN Token = (PSCRIPT_ENGINE_TOKEN)&Rhs[RuleId][i];
513
514 if (Token->Type == EPSILON)
515 break;
516
517 PSCRIPT_ENGINE_TOKEN DuplicatedToken = CopyToken(Token);
518 Push(Stack, DuplicatedToken);
519 }
520 }
521 }
522 else if (TopToken->Type == SEMANTIC_RULE)
523 {
524 if (!strcmp(TopToken->Value, "@PUSH"))
525 {
526 RemoveToken(&TopToken);
527 TopToken = Pop(Stack);
528
529 Push(MatchedStack, CurrentIn);
530
531 CurrentIn = Scan(ScriptSource, &C);
532 if (CurrentIn->Type == UNKNOWN)
533 {
535 break;
536 }
537 }
538
539 else
540 {
541 if (!strcmp(TopToken->Value, "@START_OF_FOR"))
542 {
543 WaitForWaitStatementBooleanExpression = TRUE;
544 }
545 CodeGen(MatchedStack, CodeBuffer, TopToken, &Error, &ScriptSource);
546 if (Error != SCRIPT_ENGINE_ERROR_FREE)
547 {
548 break;
549 }
550 }
551 }
552 else
553 {
554 if (!IsEqual(TopToken, CurrentIn))
555 {
557 break;
558 }
559 else
560 {
561 RemoveToken(&CurrentIn);
562 CurrentIn = Scan(ScriptSource, &C);
563
564 if (CurrentIn->Type == UNKNOWN)
565 {
567 break;
568 }
569 }
570 }
571#ifdef _SCRIPT_ENGINE_LL1_DBG_EN
572 printf("Stack: \n");
573 PrintTokenList(Stack);
574 printf("\n");
575#endif
576 } while (TopToken->Type != END_OF_STACK);
577
578 if (Error != SCRIPT_ENGINE_ERROR_FREE)
579 {
580 ErrorMessage = HandleError(&Error, ScriptSource);
581 }
582 else
583 {
584 ErrorMessage = NULL;
585
586 PSYMBOL Symbol;
587 //
588 // change local id to stack temp
589 //
590 for (UINT64 i = 0; i < CodeBuffer->Pointer; i++)
591 {
592 Symbol = CodeBuffer->Head + i;
593 if (Symbol->Type == SYMBOL_LOCAL_ID_TYPE)
594 {
595 Symbol->Type = SYMBOL_TEMP_TYPE;
596 Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
597 }
598 else if (Symbol->Type == SYMBOL_REFERENCE_LOCAL_ID_TYPE)
599 {
601 Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
602 }
603 else if (Symbol->Type == SYMBOL_DEREFERENCE_LOCAL_ID_TYPE)
604 {
606 Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
607 }
608 else if (Symbol->Type == SYMBOL_VARIABLE_COUNT_TYPE)
609 {
610 UINT64 VariableCount = Symbol->Value;
611 for (UINT64 j = 0; j < VariableCount; j++)
612 {
613 Symbol = CodeBuffer->Head + i + j + 1;
614 if ((Symbol->Type & 0x7fffffff) == SYMBOL_LOCAL_ID_TYPE)
615 {
616 Symbol->Type = SYMBOL_TEMP_TYPE | (Symbol->Type & 0xffffffff00000000);
617 Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
618 }
619 else if ((Symbol->Type & 0x7fffffff) == SYMBOL_REFERENCE_LOCAL_ID_TYPE)
620 {
621 Symbol->Type = SYMBOL_REFERENCE_LOCAL_ID_TYPE | (Symbol->Type & 0xffffffff00000000);
622 Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
623 }
624 else if ((Symbol->Type & 0x7fffffff) == SYMBOL_DEREFERENCE_LOCAL_ID_TYPE)
625 {
626 Symbol->Type = SYMBOL_DEREFERENCE_LOCAL_ID_TYPE | (Symbol->Type & 0xffffffff00000000);
627 Symbol->Value += UserDefinedFunctionHead->MaxTempNumber;
628 }
629 }
630 i += VariableCount;
631 }
632 }
633
634 //
635 // set memory size for stack buffer
636 //
637 Symbol = CodeBuffer->Head + 1;
638 Symbol->Value = CurrentUserDefinedFunction->MaxTempNumber + CurrentUserDefinedFunction->LocalVariableNumber;
639 }
640 CodeBuffer->Message = ErrorMessage;
641
642 if (Stack)
643 RemoveTokenList(Stack);
644
645 if (MatchedStack)
646 RemoveTokenList(MatchedStack);
647
649 {
651 while (Node)
652 {
653 if (Node->Name)
654 free(Node->Name);
655
656 if (Node->IdTable)
658
659 if (Node->FunctionParameterIdTable)
661
662 if (Node->TempMap)
663 free(Node->TempMap);
664
665 PUSER_DEFINED_FUNCTION_NODE Temp = Node;
666 Node = Node->NextNode;
667 free(Temp);
668 }
670 }
671
672 if (IncludeHead)
673 {
675 while (Node)
676 {
677 if (Node->FilePath)
678 free(Node->FilePath);
679
680 PINCLUDE_NODE Temp = Node;
681 Node = Node->NextNode;
682 free(Temp);
683 }
684 IncludeHead = 0;
685 }
686
687 if (CurrentIn)
688 RemoveToken(&CurrentIn);
689
690 if (TopToken)
691 RemoveToken(&TopToken);
692
693 free(ScriptSource);
694
695 return (PVOID)CodeBuffer;
696}
#define SYMBOL_REFERENCE_TEMP_TYPE
Definition ScriptEngineCommonDefinitions.h:62
#define SYMBOL_DEREFERENCE_LOCAL_ID_TYPE
Definition ScriptEngineCommonDefinitions.h:63
#define SYMBOL_DEREFERENCE_TEMP_TYPE
Definition ScriptEngineCommonDefinitions.h:64
const int ParseTable[NONETERMINAL_COUNT][TERMINAL_COUNT]
Definition parse-table.c:1060
const struct _SCRIPT_ENGINE_TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]
Definition parse-table.c:289
#define START_VARIABLE
Definition parse-table.h:7
char sgetc(char *str)
Returns the next character in the input string.
Definition scanner.c:1042
char IsEqual(const PSCRIPT_ENGINE_TOKEN Token1, const PSCRIPT_ENGINE_TOKEN Token2)
Checks whether the value and type of Token1 and Token2 are the same.
Definition common.c:1347
int GetTerminalId(PSCRIPT_ENGINE_TOKEN Token)
Gets the Terminal Id object.
Definition common.c:1118
int GetNonTerminalId(PSCRIPT_ENGINE_TOKEN Token)
Gets the Non Terminal Id object.
Definition common.c:1101
PSCRIPT_ENGINE_TOKEN NewUnknownToken()
Allocates a new token.
Definition common.c:20
@ UNKNOWN
Definition common.h:64
@ NON_TERMINAL
Definition common.h:53
UINT64 BooleanExpressionExtractEnd(char *str, BOOL *WaitForWaitStatementBooleanExpression, PSCRIPT_ENGINE_TOKEN CurrentIn)
Computes the boolean expression length starting from the current input position.
Definition script-engine.c:3439
void ScriptEngineBooleanExpresssionParse(UINT64 BooleanExpressionSize, PSCRIPT_ENGINE_TOKEN FirstToken, PSCRIPT_ENGINE_TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, char *str, char *c, PSCRIPT_ENGINE_ERROR_TYPE Error)
LALR parser used for parsing boolean expression.
Definition script-engine.c:3490
char * HandleError(PSCRIPT_ENGINE_ERROR_TYPE Error, char *str)
Prints some information about the error.
Definition script-engine.c:4252
long long unsigned IdTable
Definition common.h:284
char * TempMap
Definition common.h:286
long long unsigned FunctionParameterIdTable
Definition common.h:285
VARIABLE_TYPE * VARIABLE_TYPE_VOID
Definition type.c:17
enum _SCRIPT_ENGINE_ERROR_TYPE SCRIPT_ENGINE_ERROR_TYPE

◆ ScriptEngineSearchSymbolForMask()

UINT32 ScriptEngineSearchSymbolForMask ( const char * SearchMask)

Search for a special mask.

Parameters
SearchMask
Returns
UINT32
154{
155 //
156 // A wrapper for pdb mask searcher
157 //
158 return SymSearchSymbolForMask(SearchMask);
159}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT32 SymSearchSymbolForMask(const CHAR *SearchMask)
Gets the offset from the symbol.
Definition symbol-parser.cpp:1195

◆ ScriptEngineSetHwdbgInstanceInfo()

BOOLEAN ScriptEngineSetHwdbgInstanceInfo ( HWDBG_INSTANCE_INFORMATION * InstancInfo)

Set hwdbg instance info for the script engine.

Parameters
InstancInfo
Returns
BOOLEAN
4665{
4666 //
4667 // Copy the instance info into the global variable
4668 //
4669 memcpy(&g_HwdbgInstanceInfo, InstancInfo, sizeof(HWDBG_INSTANCE_INFORMATION));
4670
4671 //
4672 // Indicate that the instance info is valid
4673 //
4675
4676 return TRUE;
4677}
struct _HWDBG_INSTANCE_INFORMATION HWDBG_INSTANCE_INFORMATION
The structure of script capabilities information in hwdbg.

◆ ScriptEngineSetTextMessageCallback()

VOID ScriptEngineSetTextMessageCallback ( PVOID Handler)

Set the message handler as an alternative to printf.

Parameters
Handler
Returns
VOID
105{
106 //
107 // Set the script engine message handler
108 //
109 g_MessageHandler = Handler;
110
111 //
112 // Call message handler of the symbol parser
113 //
115}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER VOID SymSetTextMessageCallback(PVOID Handler)
Set the function callback that will be called if any message needs to be shown.
Definition symbol-parser.cpp:127
PVOID g_MessageHandler
The handler for ShowMessages function this is because the user might choose not to use printf and ins...
Definition globals.h:460

◆ ScriptEngineShowDataBasedOnSymbolTypes()

BOOLEAN ScriptEngineShowDataBasedOnSymbolTypes ( const char * TypeName,
UINT64 Address,
BOOLEAN IsStruct,
PVOID BufferAddress,
const char * AdditionalParameters )

Show data based on symbol types.

Parameters
TypeName
Address
IsStruct
BufferAddress
AdditionalParameters
Returns
BOOLEAN
264{
265 //
266 // A wrapper for showing types and data within structures
267 //
268 return SymShowDataBasedOnSymbolTypes(TypeName, Address, IsStruct, BufferAddress, AdditionalParameters);
269}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN SymShowDataBasedOnSymbolTypes(const CHAR *TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, const CHAR *AdditionalParameters)

◆ ScriptEngineSymbolAbortLoading()

VOID ScriptEngineSymbolAbortLoading ( )

Cancel loading.

Returns
VOID
278{
279 //
280 // A wrapper for aborting download and reload
281 //
283}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER VOID SymbolAbortLoading()

◆ ScriptEngineSymbolInitLoad()

BOOLEAN ScriptEngineSymbolInitLoad ( PVOID BufferToStoreDetails,
UINT32 StoredLength,
BOOLEAN DownloadIfAvailable,
const char * SymbolPath,
BOOLEAN IsSilentLoad )

Initial load of the symbols.

Parameters
BufferToStoreDetails
StoredLength
DownloadIfAvailable
SymbolPath
IsSilentLoad
Returns
BOOLEAN
241{
242 //
243 // A wrapper for pdb and modules parser
244 //
245 return SymbolInitLoad(BufferToStoreDetails, StoredLength, DownloadIfAvailable, SymbolPath, IsSilentLoad);
246}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER BOOLEAN SymbolInitLoad(PVOID BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const CHAR *SymbolPath, BOOLEAN IsSilentLoad)

◆ ScriptEngineUnloadAllSymbols()

UINT32 ScriptEngineUnloadAllSymbols ( )

Unload all the previously loaded symbols.

Returns
UINT32
124{
125 //
126 // A wrapper for pdb unloader
127 //
128 return SymUnloadAllSymbols();
129}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT32 SymUnloadAllSymbols()
Unload all the symbols.
Definition symbol-parser.cpp:822

◆ ScriptEngineUnloadModuleSymbol()

UINT32 ScriptEngineUnloadModuleSymbol ( char * ModuleName)

Unload a special pdb.

Parameters
ModuleName
Returns
UINT32
139{
140 //
141 // A wrapper for pdb unloader
142 //
143 return SymUnloadModuleSymbol(ModuleName);
144}
IMPORT_EXPORT_HYPERDBG_SYMBOL_PARSER UINT32 SymUnloadModuleSymbol(CHAR *ModuleName)
Unload one module symbol.
Definition symbol-parser.cpp:763

◆ SemanticRuleToInt()

unsigned long long int SemanticRuleToInt ( char * str)

Converts a sematinc rule token to integer.

Parameters
str
Returns
unsigned long long int
4233{
4234 for (int i = 0; i < SEMANTIC_RULES_MAP_LIST_LENGTH; i++)
4235 {
4236 if (!strcmp(str, SemanticRulesMapList[i].Name))
4237 {
4238 return SemanticRulesMapList[i].Type;
4239 }
4240 }
4241 return INVALID;
4242}
const SYMBOL_MAP SemanticRulesMapList[]
Definition parse-table.c:1386
#define SEMANTIC_RULES_MAP_LIST_LENGTH
Definition parse-table.h:16

◆ SetGlobalIdentifierVariableType()

VOID SetGlobalIdentifierVariableType ( PSCRIPT_ENGINE_TOKEN Token,
VARIABLE_TYPE * VariableType )
Parameters
Token
4418{
4419 PSCRIPT_ENGINE_TOKEN CurrentToken;
4420 for (uintptr_t i = 0; i < GlobalIdTable->Pointer; i++)
4421 {
4422 CurrentToken = *(GlobalIdTable->Head + i);
4423 if (!strcmp(Token->Value, CurrentToken->Value))
4424 {
4425 CurrentToken->VariableType = (VARIABLE_TYPE *)VariableType;
4426 }
4427 }
4428}

◆ SetLocalIdentifierVariableType()

VOID SetLocalIdentifierVariableType ( PSCRIPT_ENGINE_TOKEN Token,
VARIABLE_TYPE * VariableType )
Parameters
Token
4474{
4475 PSCRIPT_ENGINE_TOKEN CurrentToken;
4476 for (uintptr_t i = 0; i < ((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Pointer; i++)
4477 {
4478 CurrentToken = *(((PSCRIPT_ENGINE_TOKEN_LIST)CurrentUserDefinedFunction->IdTable)->Head + i);
4479 if (!strcmp(Token->Value, CurrentToken->Value))
4480 {
4481 CurrentToken->VariableType = VariableType;
4482 }
4483 }
4484}

◆ ShowMessages()

VOID ShowMessages ( const char * Fmt,
... )

Show messages.

Parameters
Fmtformat string message
Fmtformat string message
...arguments
Returns
VOID
34{
35 va_list ArgList;
36 va_list Args;
37
38 if (g_MessageHandler == NULL)
39 {
40 va_start(Args, Fmt);
41 vprintf(Fmt, Args);
42 va_end(Args);
43 }
44 else
45 {
47 va_start(ArgList, Fmt);
48 INT SprintfResult = PlatformVsnprintf(TempMessage, COMMUNICATION_BUFFER_SIZE + TCP_END_OF_BUFFER_CHARS_COUNT, Fmt, ArgList);
49 va_end(ArgList);
50
51 if (SprintfResult != -1)
52 {
53 //
54 // There is another handler
55 //
57 }
58 }
59}
#define TCP_END_OF_BUFFER_CHARS_COUNT
count of characters for tcp end of buffer
Definition Constants.h:442
#define COMMUNICATION_BUFFER_SIZE
Packet size for TCP connections.
Definition Constants.h:338
int(* SendMessageWithParamCallback)(const char *Text)
Callback type that can be used to be used as a custom ShowMessages function (by passing message as a ...
Definition DataTypes.h:155
INT PlatformVsnprintf(char *Buffer, SIZE_T BufferSize, const char *Format, va_list ArgList)
Platform independent wrapper for vsprintf_s / vsnprintf.
Definition platform-lib-calls.c:33

◆ ToSymbol()

Converts Token to Symbol and returns the reference to it.

Parameters
Token
Error
Returns
PSYMBOL
3816{
3817 PSYMBOL Symbol = NewSymbol();
3818 switch (Token->Type)
3819 {
3820 case GLOBAL_ID:
3821 Symbol->Value = GetGlobalIdentifierVal(Token);
3823 return Symbol;
3824
3825 case LOCAL_ID:
3826 {
3827 Symbol->Value = GetLocalIdentifierVal(Token);
3828
3829 if (((VARIABLE_TYPE *)Token->VariableType)->Kind == TY_ARRAY)
3830 {
3832 }
3833 else
3834 {
3836 }
3837
3838 return Symbol;
3839 }
3840
3841 case DECIMAL:
3842 Symbol->Value = DecimalToInt(Token->Value);
3843 SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
3844 return Symbol;
3845
3846 case HEX:
3847 Symbol->Value = HexToInt(Token->Value);
3848 SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
3849 return Symbol;
3850
3851 case OCTAL:
3852 Symbol->Value = OctalToInt(Token->Value);
3853 SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
3854 return Symbol;
3855
3856 case BINARY:
3857 Symbol->Value = BinaryToInt(Token->Value);
3858 SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
3859 return Symbol;
3860
3861 case REGISTER:
3862 Symbol->Value = RegisterToInt(Token->Value);
3864 return Symbol;
3865
3866 case PSEUDO_REGISTER:
3867 Symbol->Value = PseudoRegToInt(Token->Value);
3869 return Symbol;
3870
3871 case SEMANTIC_RULE:
3872 Symbol->Value = SemanticRuleToInt(Token->Value);
3874 return Symbol;
3875
3876 case TEMP:
3877
3878 Symbol->Value = DecimalToInt(Token->Value);
3879
3880 if (((VARIABLE_TYPE *)Token->VariableType)->Kind == TY_ARRAY)
3881 {
3883 }
3884 else
3885 {
3886 SetType(&Symbol->Type, SYMBOL_TEMP_TYPE);
3887 }
3888
3889 return Symbol;
3890
3891 case STRING:
3892 RemoveSymbol(&Symbol);
3893 return NewStringSymbol(Token);
3894
3895 case WSTRING:
3896 RemoveSymbol(&Symbol);
3897 return NewWstringSymbol(Token);
3898
3900 Symbol->Value = GetFunctionParameterIdentifier(Token);
3902 return Symbol;
3903
3904 case DEFERENCE_TEMP:
3905 Symbol->Value = DecimalToInt(Token->Value);
3907 return Symbol;
3908
3909 default:
3911 Symbol->Type = INVALID;
3912 Symbol->Value = INVALID;
3913 return Symbol;
3914 }
3915}
#define SYMBOL_REGISTER_TYPE
Definition ScriptEngineCommonDefinitions.h:47
#define SYMBOL_FUNCTION_PARAMETER_ID_TYPE
Definition ScriptEngineCommonDefinitions.h:55
#define SYMBOL_PSEUDO_REG_TYPE
Definition ScriptEngineCommonDefinitions.h:48
unsigned long long OctalToInt(char *str)
Converts an octal string to integer.
Definition common.c:1492
unsigned long long BinaryToInt(char *str)
Converts a binary string to integer.
Definition common.c:1514
unsigned long long HexToInt(char *str)
Converts an hexadecimal string to integer.
Definition common.c:1459
unsigned long long int RegisterToInt(char *str)
Converts register string to integer.
Definition script-engine.c:4112
PSYMBOL NewStringSymbol(PSCRIPT_ENGINE_TOKEN Token)
Allocates a new SYMBOL with string type and returns the reference to it.
Definition script-engine.c:3692
int GetGlobalIdentifierVal(PSCRIPT_ENGINE_TOKEN Token)
Returns the integer assigned to global variable.
Definition script-engine.c:4362
int GetLocalIdentifierVal(PSCRIPT_ENGINE_TOKEN Token)
Returns the integer assigned to local variable.
Definition script-engine.c:4383
unsigned long long int SemanticRuleToInt(char *str)
Converts a sematinc rule token to integer.
Definition script-engine.c:4232
unsigned long long int PseudoRegToInt(char *str)
Converts pseudo register string to integer.
Definition script-engine.c:4213
PSYMBOL NewWstringSymbol(PSCRIPT_ENGINE_TOKEN Token)
Allocates a new SYMBOL with wstring type and returns the reference to it.
Definition script-engine.c:3719
int GetFunctionParameterIdentifier(PSCRIPT_ENGINE_TOKEN Token)
Definition script-engine.c:4528

Variable Documentation

◆ g_HwdbgInstanceInfo

HWDBG_INSTANCE_INFORMATION g_HwdbgInstanceInfo
extern

Instance information of the current hwdbg debuggee.

◆ g_HwdbgInstanceInfoIsValid

BOOLEAN g_HwdbgInstanceInfoIsValid
extern

Shows whether the instance info is valid (received) or not.

◆ g_MessageHandler

PVOID g_MessageHandler
extern

The handler for ShowMessages function this is because the user might choose not to use printf and instead use his/her handler for showing messages.