Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "vm-buffer.h"
00022 #include "../../common/consts.h"
00023 #include "../../common/types.h"
00024 #include <string.h>
00025 #include <assert.h>
00026
00027 static unsigned char buffer[ASEBA_MAX_INNER_PACKET_SIZE];
00028 static unsigned buffer_pos;
00029
00030 static void buffer_add(const uint8* data, const uint16 len)
00031 {
00032 uint16 i = 0;
00033 while (i < len)
00034 {
00035
00036
00037
00038
00039
00040
00041 buffer[buffer_pos++] = data[i++];
00042 }
00043 }
00044
00045 static void buffer_add_uint8(const uint8 value)
00046 {
00047 buffer_add(&value, 1);
00048 }
00049
00050 static void buffer_add_uint16(const uint16 value)
00051 {
00052 const uint16 temp = bswap16(value);
00053 buffer_add((const unsigned char *) &temp, 2);
00054 }
00055
00056 static void buffer_add_sint16(const sint16 value)
00057 {
00058 const uint16 temp = bswap16(value);
00059 buffer_add((const unsigned char *) &temp, 2);
00060 }
00061
00062 static void buffer_add_string(const char* s)
00063 {
00064 uint16 len = strlen(s);
00065 buffer_add_uint8((uint8)len);
00066 while (*s)
00067 buffer_add_uint8(*s++);
00068 }
00069
00070
00071
00072 void AsebaSendMessage(AsebaVMState *vm, uint16 type, const void *data, uint16 size)
00073 {
00074 uint16 i;
00075
00076 buffer_pos = 0;
00077 buffer_add_uint16(type);
00078 for (i = 0; i < size; i++)
00079 buffer_add_uint8(((const unsigned char*)data)[i]);
00080
00081 AsebaSendBuffer(vm, buffer, buffer_pos);
00082 }
00083
00084 #ifdef __BIG_ENDIAN__
00085 void AsebaSendMessageWords(AsebaVMState *vm, uint16 type, const uint16* data, uint16 count)
00086 {
00087 uint16 i;
00088
00089 buffer_pos = 0;
00090 buffer_add_uint16(type);
00091 for (i = 0; i < count; i++)
00092 buffer_add_uint16(data[i]);
00093
00094 AsebaSendBuffer(vm, buffer, buffer_pos);
00095 }
00096 #endif
00097
00098 void AsebaSendVariables(AsebaVMState *vm, uint16 start, uint16 length)
00099 {
00100 uint16 i;
00101
00102 buffer_pos = 0;
00103 buffer_add_uint16(ASEBA_MESSAGE_VARIABLES);
00104 buffer_add_uint16(start);
00105 for (i = start; i < start + length; i++)
00106 buffer_add_uint16(vm->variables[i]);
00107
00108 AsebaSendBuffer(vm, buffer, buffer_pos);
00109 }
00110
00111 void AsebaSendDescription(AsebaVMState *vm)
00112 {
00113 const AsebaVMDescription *vmDescription = AsebaGetVMDescription(vm);
00114 const AsebaVariableDescription* namedVariables = vmDescription->variables;
00115 const AsebaNativeFunctionDescription* const * nativeFunctionsDescription = AsebaGetNativeFunctionsDescriptions(vm);
00116 const AsebaLocalEventDescription* localEvents = AsebaGetLocalEventsDescriptions(vm);
00117
00118 uint16 i = 0;
00119 buffer_pos = 0;
00120
00121 buffer_add_uint16(ASEBA_MESSAGE_DESCRIPTION);
00122
00123 buffer_add_string(vmDescription->name);
00124
00125 buffer_add_uint16(ASEBA_PROTOCOL_VERSION);
00126
00127 buffer_add_uint16(vm->bytecodeSize);
00128 buffer_add_uint16(vm->stackSize);
00129 buffer_add_uint16(vm->variablesSize);
00130
00131
00132 for (i = 0; namedVariables[i].size; i++)
00133 ;
00134 buffer_add_uint16(i);
00135
00136
00137 for (i = 0; localEvents[i].name; i++)
00138 ;
00139 buffer_add_uint16(i);
00140
00141
00142 for (i = 0; nativeFunctionsDescription[i]; i++)
00143 ;
00144 buffer_add_uint16(i);
00145
00146
00147 AsebaSendBuffer(vm, buffer, buffer_pos);
00148
00149
00150 for (i = 0; namedVariables[i].name; i++)
00151 {
00152 buffer_pos = 0;
00153
00154 buffer_add_uint16(ASEBA_MESSAGE_NAMED_VARIABLE_DESCRIPTION);
00155
00156 buffer_add_uint16(namedVariables[i].size);
00157 buffer_add_string(namedVariables[i].name);
00158
00159
00160 AsebaSendBuffer(vm, buffer, buffer_pos);
00161 }
00162
00163
00164 for (i = 0; localEvents[i].name; i++)
00165 {
00166 buffer_pos = 0;
00167
00168 buffer_add_uint16(ASEBA_MESSAGE_LOCAL_EVENT_DESCRIPTION);
00169
00170 buffer_add_string(localEvents[i].name);
00171 buffer_add_string(localEvents[i].doc);
00172
00173
00174 AsebaSendBuffer(vm, buffer, buffer_pos);
00175 }
00176
00177
00178 for (i = 0; nativeFunctionsDescription[i]; i++)
00179 {
00180 uint16 j;
00181
00182 buffer_pos = 0;
00183
00184 buffer_add_uint16(ASEBA_MESSAGE_NATIVE_FUNCTION_DESCRIPTION);
00185
00186
00187 buffer_add_string(nativeFunctionsDescription[i]->name);
00188 buffer_add_string(nativeFunctionsDescription[i]->doc);
00189 for (j = 0; nativeFunctionsDescription[i]->arguments[j].size; j++)
00190 ;
00191 buffer_add_uint16(j);
00192 for (j = 0; nativeFunctionsDescription[i]->arguments[j].size; j++)
00193 {
00194 buffer_add_sint16(nativeFunctionsDescription[i]->arguments[j].size);
00195 buffer_add_string(nativeFunctionsDescription[i]->arguments[j].name);
00196 }
00197
00198
00199 AsebaSendBuffer(vm, buffer, buffer_pos);
00200 }
00201 }
00202
00203 void AsebaProcessIncomingEvents(AsebaVMState *vm)
00204 {
00205 uint16 source;
00206 const AsebaVMDescription *desc = AsebaGetVMDescription(vm);
00207
00208 uint16 amount = AsebaGetBuffer(vm, buffer, ASEBA_MAX_INNER_PACKET_SIZE, &source);
00209
00210 if (amount > 0)
00211 {
00212 uint16 type = bswap16(((uint16*)buffer)[0]);
00213 uint16* payload = (uint16*)(buffer+2);
00214 uint16 payloadSize = (amount-2)/2;
00215 if (type < 0x8000)
00216 {
00217
00218 if (AsebaMaskIsClear(vm->flags, ASEBA_VM_STEP_BY_STEP_MASK) || AsebaMaskIsClear(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK))
00219 {
00220
00221
00222 uint16 argPos = desc->variables[1].size;
00223 uint16 argsSize = desc->variables[2].size;
00224 uint16 i;
00225 vm->variables[argPos++] = source;
00226 for (i = 0; (i < argsSize) && (i < payloadSize); i++)
00227 vm->variables[argPos + i] = bswap16(payload[i]);
00228 AsebaVMSetupEvent(vm, type);
00229 }
00230 }
00231 else
00232 {
00233
00234 AsebaVMDebugMessage(vm, type, payload, payloadSize);
00235 }
00236 }
00237 }
00238