00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "../common/consts.h"
00022 #include "../common/types.h"
00023 #include "vm.h"
00024 #include <string.h>
00025
00033
00034
00036 #define GET_BIT(v, b) (((v) >> (b)) & 0x1)
00037
00038 #define BIT_SET(v, b) ((v) |= (1 << (b)))
00039
00040 #define BIT_CLR(v, b) ((v) &= (~(1 << (b))))
00041
00042 void AsebaVMSendExecutionStateChanged(AsebaVMState *vm);
00043
00044 void AsebaVMInit(AsebaVMState *vm)
00045 {
00046 vm->pc = 0;
00047 vm->flags = 0;
00048 vm->breakpointsCount = 0;
00049
00050
00051 vm->bytecode[0] = 0;
00052 memset(vm->variables, 0, vm->variablesSize*sizeof(sint16));
00053 }
00054
00055 uint16 AsebaVMGetEventAddress(AsebaVMState *vm, uint16 event)
00056 {
00057 uint16 eventVectorSize = vm->bytecode[0];
00058 uint16 i;
00059
00060
00061 for (i = 1; i < eventVectorSize; i += 2)
00062 if (vm->bytecode[i] == event)
00063 return vm->bytecode[i + 1];
00064 return 0;
00065 }
00066
00067
00068 uint16 AsebaVMSetupEvent(AsebaVMState *vm, uint16 event)
00069 {
00070 uint16 address = AsebaVMGetEventAddress(vm, event);
00071 if (address)
00072 {
00073
00074 if (AsebaMaskIsSet(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK))
00075 {
00076 AsebaSendMessageWords(vm, ASEBA_MESSAGE_EVENT_EXECUTION_KILLED, &vm->pc, 1);
00077 }
00078
00079 vm->pc = address;
00080 vm->sp = -1;
00081 AsebaMaskSet(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK);
00082
00083
00084 if (AsebaMaskIsSet(vm->flags, ASEBA_VM_STEP_BY_STEP_MASK))
00085 AsebaVMSendExecutionStateChanged(vm);
00086 }
00087 return address;
00088 }
00089
00090 static sint16 AsebaVMDoBinaryOperation(AsebaVMState *vm, sint16 valueOne, sint16 valueTwo, uint16 op)
00091 {
00092 switch (op)
00093 {
00094 case ASEBA_OP_SHIFT_LEFT: return valueOne << valueTwo;
00095 case ASEBA_OP_SHIFT_RIGHT: return valueOne >> valueTwo;
00096 case ASEBA_OP_ADD: return valueOne + valueTwo;
00097 case ASEBA_OP_SUB: return valueOne - valueTwo;
00098 case ASEBA_OP_MULT: return valueOne * valueTwo;
00099 case ASEBA_OP_DIV:
00100
00101 if (valueTwo == 0)
00102 {
00103 if(AsebaVMErrorCB)
00104 AsebaVMErrorCB(vm,NULL);
00105 vm->flags = ASEBA_VM_STEP_BY_STEP_MASK;
00106 AsebaSendMessageWords(vm, ASEBA_MESSAGE_DIVISION_BY_ZERO, &vm->pc, 1);
00107 return 0;
00108 }
00109 else
00110 {
00111 return valueOne / valueTwo;
00112 }
00113 case ASEBA_OP_MOD: return valueOne % valueTwo;
00114
00115 case ASEBA_OP_BIT_OR: return valueOne | valueTwo;
00116 case ASEBA_OP_BIT_XOR: return valueOne ^ valueTwo;
00117 case ASEBA_OP_BIT_AND: return valueOne & valueTwo;
00118
00119 case ASEBA_OP_EQUAL: return valueOne == valueTwo;
00120 case ASEBA_OP_NOT_EQUAL: return valueOne != valueTwo;
00121 case ASEBA_OP_BIGGER_THAN: return valueOne > valueTwo;
00122 case ASEBA_OP_BIGGER_EQUAL_THAN: return valueOne >= valueTwo;
00123 case ASEBA_OP_SMALLER_THAN: return valueOne < valueTwo;
00124 case ASEBA_OP_SMALLER_EQUAL_THAN: return valueOne <= valueTwo;
00125
00126 case ASEBA_OP_OR: return valueOne || valueTwo;
00127 case ASEBA_OP_AND: return valueOne && valueTwo;
00128
00129 default:
00130 #ifdef ASEBA_ASSERT
00131 AsebaAssert(vm, ASEBA_ASSERT_UNKNOWN_BINARY_OPERATOR);
00132 #endif
00133 return 0;
00134 }
00135 }
00136
00137 static sint16 AsebaVMDoUnaryOperation(AsebaVMState *vm, sint16 value, uint16 op)
00138 {
00139 switch (op)
00140 {
00141 case ASEBA_UNARY_OP_SUB: return -value;
00142 case ASEBA_UNARY_OP_ABS: return value >= 0 ? value : -value;
00143 case ASEBA_UNARY_OP_BIT_NOT: return ~value;
00144
00145 default:
00146 #ifdef ASEBA_ASSERT
00147 AsebaAssert(vm, ASEBA_ASSERT_UNKNOWN_UNARY_OPERATOR);
00148 #endif
00149 return 0;
00150 }
00151 }
00152
00155 void AsebaVMStep(AsebaVMState *vm)
00156 {
00157 uint16 bytecode = vm->bytecode[vm->pc];
00158
00159 #ifdef ASEBA_ASSERT
00160 if (AsebaMaskIsClear(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK))
00161 AsebaAssert(vm, ASEBA_ASSERT_STEP_OUT_OF_RUN);
00162 #endif
00163
00164 switch (bytecode >> 12)
00165 {
00166
00167 case ASEBA_BYTECODE_STOP:
00168 {
00169 AsebaMaskClear(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK);
00170 }
00171 break;
00172
00173
00174 case ASEBA_BYTECODE_SMALL_IMMEDIATE:
00175 {
00176 sint16 value = ((sint16)(bytecode << 4)) >> 4;
00177
00178
00179 #ifdef ASEBA_ASSERT
00180 if (vm->sp + 1 >= vm->stackSize)
00181 AsebaAssert(vm, ASEBA_ASSERT_STACK_OVERFLOW);
00182 #endif
00183
00184
00185 vm->stack[++vm->sp] = value;
00186
00187
00188 vm->pc ++;
00189 }
00190 break;
00191
00192
00193 case ASEBA_BYTECODE_LARGE_IMMEDIATE:
00194 {
00195
00196 #ifdef ASEBA_ASSERT
00197 if (vm->sp + 1 >= vm->stackSize)
00198 AsebaAssert(vm, ASEBA_ASSERT_STACK_OVERFLOW);
00199 #endif
00200
00201
00202 vm->stack[++vm->sp] = vm->bytecode[vm->pc + 1];
00203
00204
00205 vm->pc += 2;
00206 }
00207 break;
00208
00209
00210 case ASEBA_BYTECODE_LOAD:
00211 {
00212 uint16 variableIndex = bytecode & 0x0fff;
00213
00214
00215 #ifdef ASEBA_ASSERT
00216 if (vm->sp + 1 >= vm->stackSize)
00217 AsebaAssert(vm, ASEBA_ASSERT_STACK_OVERFLOW);
00218 if (variableIndex >= vm->variablesSize)
00219 AsebaAssert(vm, ASEBA_ASSERT_OUT_OF_VARIABLES_BOUNDS);
00220 #endif
00221
00222
00223 vm->stack[++vm->sp] = vm->variables[variableIndex];
00224
00225
00226 vm->pc ++;
00227 }
00228 break;
00229
00230
00231 case ASEBA_BYTECODE_STORE:
00232 {
00233 uint16 variableIndex = bytecode & 0x0fff;
00234
00235
00236 #ifdef ASEBA_ASSERT
00237 if (vm->sp < 0)
00238 AsebaAssert(vm, ASEBA_ASSERT_STACK_UNDERFLOW);
00239 if (variableIndex >= vm->variablesSize)
00240 AsebaAssert(vm, ASEBA_ASSERT_OUT_OF_VARIABLES_BOUNDS);
00241 #endif
00242
00243
00244 vm->variables[variableIndex] = vm->stack[vm->sp--];
00245
00246
00247 vm->pc ++;
00248 }
00249 break;
00250
00251
00252 case ASEBA_BYTECODE_LOAD_INDIRECT:
00253 {
00254 uint16 arrayIndex;
00255 uint16 arraySize;
00256 uint16 variableIndex;
00257
00258
00259 #ifdef ASEBA_ASSERT
00260 if (vm->sp < 0)
00261 AsebaAssert(vm, ASEBA_ASSERT_STACK_UNDERFLOW);
00262 #endif
00263
00264
00265 arrayIndex = bytecode & 0x0fff;
00266 arraySize = vm->bytecode[vm->pc + 1];
00267 variableIndex = vm->stack[vm->sp];
00268
00269
00270 if (variableIndex >= arraySize)
00271 {
00272 uint16 buffer[3];
00273 buffer[0] = vm->pc;
00274 buffer[1] = arraySize;
00275 buffer[2] = variableIndex;
00276 vm->flags = ASEBA_VM_STEP_BY_STEP_MASK;
00277 AsebaSendMessageWords(vm, ASEBA_MESSAGE_ARRAY_ACCESS_OUT_OF_BOUNDS, buffer, 3);
00278 if(AsebaVMErrorCB)
00279 AsebaVMErrorCB(vm,NULL);
00280 break;
00281 }
00282
00283
00284 vm->stack[vm->sp] = vm->variables[arrayIndex + variableIndex];
00285
00286
00287 vm->pc += 2;
00288 }
00289 break;
00290
00291
00292 case ASEBA_BYTECODE_STORE_INDIRECT:
00293 {
00294 uint16 arrayIndex;
00295 uint16 arraySize;
00296 uint16 variableIndex;
00297 sint16 variableValue;
00298
00299
00300 #ifdef ASEBA_ASSERT
00301 if (vm->sp < 1)
00302 AsebaAssert(vm, ASEBA_ASSERT_STACK_UNDERFLOW);
00303 #endif
00304
00305
00306 arrayIndex = bytecode & 0x0fff;
00307 arraySize = vm->bytecode[vm->pc + 1];
00308 variableValue = vm->stack[vm->sp - 1];
00309 variableIndex = (uint16)vm->stack[vm->sp];
00310
00311
00312 if (variableIndex >= arraySize)
00313 {
00314 uint16 buffer[3];
00315 buffer[0] = vm->pc;
00316 buffer[1] = arraySize;
00317 buffer[2] = variableIndex;
00318 vm->flags = ASEBA_VM_STEP_BY_STEP_MASK;
00319 AsebaSendMessageWords(vm, ASEBA_MESSAGE_ARRAY_ACCESS_OUT_OF_BOUNDS, buffer, 3);
00320 if(AsebaVMErrorCB)
00321 AsebaVMErrorCB(vm,NULL);
00322 break;
00323 }
00324
00325
00326 vm->variables[arrayIndex + variableIndex] = variableValue;
00327 vm->sp -= 2;
00328
00329
00330 vm->pc += 2;
00331 }
00332 break;
00333
00334
00335 case ASEBA_BYTECODE_UNARY_ARITHMETIC:
00336 {
00337 sint16 value, opResult;
00338
00339
00340 #ifdef ASEBA_ASSERT
00341 if (vm->sp < 0)
00342 AsebaAssert(vm, ASEBA_ASSERT_STACK_UNDERFLOW);
00343 #endif
00344
00345
00346 value = vm->stack[vm->sp];
00347
00348
00349 opResult = AsebaVMDoUnaryOperation(vm, value, bytecode & ASEBA_UNARY_OPERATOR_MASK);
00350
00351
00352 vm->stack[vm->sp] = opResult;
00353
00354
00355 vm->pc ++;
00356 }
00357 break;
00358
00359
00360 case ASEBA_BYTECODE_BINARY_ARITHMETIC:
00361 {
00362 sint16 valueOne, valueTwo, opResult;
00363
00364
00365 #ifdef ASEBA_ASSERT
00366 if (vm->sp < 1)
00367 AsebaAssert(vm, ASEBA_ASSERT_STACK_UNDERFLOW);
00368 #endif
00369
00370
00371 valueOne = vm->stack[vm->sp - 1];
00372 valueTwo = vm->stack[vm->sp];
00373
00374
00375 opResult = AsebaVMDoBinaryOperation(vm, valueOne, valueTwo, bytecode & ASEBA_BINARY_OPERATOR_MASK);
00376
00377
00378 vm->sp--;
00379 vm->stack[vm->sp] = opResult;
00380
00381
00382 vm->pc ++;
00383 }
00384 break;
00385
00386
00387 case ASEBA_BYTECODE_JUMP:
00388 {
00389 sint16 disp = ((sint16)(bytecode << 4)) >> 4;
00390
00391
00392 #ifdef ASEBA_ASSERT
00393 if ((vm->pc + disp < 0) || (vm->pc + disp >= vm->bytecodeSize))
00394 AsebaAssert(vm, ASEBA_ASSERT_OUT_OF_BYTECODE_BOUNDS);
00395 #endif
00396
00397
00398 vm->pc += disp;
00399 }
00400 break;
00401
00402
00403 case ASEBA_BYTECODE_CONDITIONAL_BRANCH:
00404 {
00405 sint16 conditionResult;
00406 sint16 valueOne, valueTwo;
00407 sint16 disp;
00408
00409
00410 #ifdef ASEBA_ASSERT
00411 if (vm->sp < 1)
00412 AsebaAssert(vm, ASEBA_ASSERT_STACK_OVERFLOW);
00413 #endif
00414
00415
00416 valueOne = vm->stack[vm->sp - 1];
00417 valueTwo = vm->stack[vm->sp];
00418 conditionResult = AsebaVMDoBinaryOperation(vm, valueOne, valueTwo, bytecode & ASEBA_BINARY_OPERATOR_MASK);
00419 vm->sp -= 2;
00420
00421
00422 if (conditionResult && !(GET_BIT(bytecode, ASEBA_IF_IS_WHEN_BIT) && GET_BIT(bytecode, ASEBA_IF_WAS_TRUE_BIT)))
00423 {
00424
00425 disp = 2;
00426 }
00427 else
00428 {
00429
00430 disp = (sint16)vm->bytecode[vm->pc + 1];
00431 }
00432
00433
00434 if (conditionResult)
00435 BIT_SET(vm->bytecode[vm->pc], ASEBA_IF_WAS_TRUE_BIT);
00436 else
00437 BIT_CLR(vm->bytecode[vm->pc], ASEBA_IF_WAS_TRUE_BIT);
00438
00439
00440 #ifdef ASEBA_ASSERT
00441 if ((vm->pc + disp < 0) || (vm->pc + disp >= vm->bytecodeSize))
00442 AsebaAssert(vm, ASEBA_ASSERT_OUT_OF_BYTECODE_BOUNDS);
00443 #endif
00444
00445
00446 vm->pc += disp;
00447 }
00448 break;
00449
00450
00451 case ASEBA_BYTECODE_EMIT:
00452 {
00453
00454 uint16 start = vm->bytecode[vm->pc + 1];
00455 uint16 length = vm->bytecode[vm->pc + 2];
00456
00457 #ifdef ASEBA_ASSERT
00458 if (length > ASEBA_MAX_EVENT_ARG_SIZE)
00459 AsebaAssert(vm, ASEBA_ASSERT_EMIT_BUFFER_TOO_LONG);
00460 #endif
00461 AsebaSendMessageWords(vm, bytecode & 0x0fff, vm->variables + start, length);
00462
00463
00464 vm->pc += 3;
00465 }
00466 break;
00467
00468
00469 case ASEBA_BYTECODE_NATIVE_CALL:
00470 {
00471
00472 AsebaNativeFunction(vm, bytecode & 0x0fff);
00473
00474
00475 vm->pc ++;
00476 }
00477 break;
00478
00479
00480 case ASEBA_BYTECODE_SUB_CALL:
00481 {
00482 uint16 dest = bytecode & 0x0fff;
00483
00484
00485 vm->stack[++vm->sp] = vm->pc + 1;
00486
00487
00488 vm->pc = dest;
00489 }
00490 break;
00491
00492
00493 case ASEBA_BYTECODE_SUB_RET:
00494 {
00495
00496 vm->pc = vm->stack[vm->sp--];
00497 }
00498 break;
00499
00500 default:
00501 #ifdef ASEBA_ASSERT
00502 AsebaAssert(vm, ASEBA_ASSERT_UNKNOWN_BYTECODE);
00503 #endif
00504 break;
00505 }
00506 }
00507
00508 void AsebaVMEmitNodeSpecificError(AsebaVMState *vm, const char* message)
00509 {
00510 uint16 msgLen = strlen(message);
00511 #if defined(__GNUC__)
00512 uint8 buffer[msgLen+3];
00513 #elif defined(_MSC_VER)
00514 uint8 * buffer = _alloca(msgLen+3);
00515 #else
00516 #error "Please provide a stack memory allocator for your compiler"
00517 #endif
00518
00519 if (AsebaVMErrorCB)
00520 AsebaVMErrorCB(vm, message);
00521
00522 vm->flags = ASEBA_VM_STEP_BY_STEP_MASK;
00523
00524 ((uint16*)buffer)[0] = bswap16(vm->pc);
00525 buffer[2] = (uint8)msgLen;
00526 memcpy(buffer+3, message, msgLen);
00527
00528 AsebaSendMessage(vm, ASEBA_MESSAGE_NODE_SPECIFIC_ERROR, buffer, msgLen+3);
00529 }
00530
00534 uint16 AsebaVMCheckBreakpoint(AsebaVMState *vm)
00535 {
00536 uint16 i;
00537 for (i = 0; i < vm->breakpointsCount; i++)
00538 {
00539 if (vm->breakpoints[i] == vm->pc)
00540 {
00541 AsebaMaskSet(vm->flags, ASEBA_VM_STEP_BY_STEP_MASK);
00542 return 1;
00543 }
00544 }
00545
00546 return 0;
00547 }
00548
00551 void AsebaDebugBareRun(AsebaVMState *vm, uint16 stepsLimit)
00552 {
00553 AsebaMaskSet(vm->flags, ASEBA_VM_EVENT_RUNNING_MASK);
00554
00555 if (stepsLimit > 0)
00556 {
00557
00558 while (AsebaMaskIsSet(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK) &&
00559 AsebaMaskIsSet(vm->flags, ASEBA_VM_EVENT_RUNNING_MASK) &&
00560 stepsLimit
00561 )
00562 {
00563 AsebaVMStep(vm);
00564 stepsLimit--;
00565
00566 }
00567 }
00568 else
00569 {
00570
00571 while (AsebaMaskIsSet(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK) &&
00572 AsebaMaskIsSet(vm->flags, ASEBA_VM_EVENT_RUNNING_MASK)
00573 )
00574 AsebaVMStep(vm);
00575 }
00576
00577 AsebaMaskClear(vm->flags, ASEBA_VM_EVENT_RUNNING_MASK);
00578 }
00579
00582 void AsebaDebugBreakpointRun(AsebaVMState *vm, uint16 stepsLimit)
00583 {
00584 AsebaMaskSet(vm->flags, ASEBA_VM_EVENT_RUNNING_MASK);
00585
00586 if (stepsLimit > 0)
00587 {
00588
00589 while (AsebaMaskIsSet(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK) &&
00590 AsebaMaskIsSet(vm->flags, ASEBA_VM_EVENT_RUNNING_MASK) &&
00591 stepsLimit
00592 )
00593 {
00594 if (AsebaVMCheckBreakpoint(vm) != 0)
00595 {
00596 AsebaMaskSet(vm->flags, ASEBA_VM_STEP_BY_STEP_MASK);
00597 AsebaVMSendExecutionStateChanged(vm);
00598 return;
00599 }
00600 AsebaVMStep(vm);
00601 stepsLimit--;
00602
00603 }
00604 }
00605 else
00606 {
00607
00608 while (AsebaMaskIsSet(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK) &&
00609 AsebaMaskIsSet(vm->flags, ASEBA_VM_EVENT_RUNNING_MASK)
00610 )
00611 {
00612 if (AsebaVMCheckBreakpoint(vm) != 0)
00613 {
00614 AsebaMaskSet(vm->flags, ASEBA_VM_STEP_BY_STEP_MASK);
00615 AsebaVMSendExecutionStateChanged(vm);
00616 return;
00617 }
00618 AsebaVMStep(vm);
00619 }
00620 }
00621
00622 AsebaMaskClear(vm->flags, ASEBA_VM_EVENT_RUNNING_MASK);
00623 }
00624
00625 uint16 AsebaVMRun(AsebaVMState *vm, uint16 stepsLimit)
00626 {
00627
00628 if (AsebaMaskIsClear(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK))
00629 return 0;
00630
00631
00632 if (AsebaMaskIsSet(vm->flags, ASEBA_VM_STEP_BY_STEP_MASK))
00633 return 0;
00634
00635
00636 if (vm->breakpointsCount)
00637 AsebaDebugBreakpointRun(vm, stepsLimit);
00638 else
00639 AsebaDebugBareRun(vm, stepsLimit);
00640
00641 return 1;
00642 }
00643
00644
00646 uint8 AsebaVMSetBreakpoint(AsebaVMState *vm, uint16 pc)
00647 {
00648 #ifdef ASEBA_ASSERT
00649 if (pc >= vm->bytecodeSize)
00650 AsebaAssert(vm, ASEBA_ASSERT_BREAKPOINT_OUT_OF_BYTECODE_BOUNDS);
00651 #endif
00652
00653 if (vm->breakpointsCount < ASEBA_MAX_BREAKPOINTS)
00654 {
00655 vm->breakpoints[vm->breakpointsCount++] = pc;
00656 return 1;
00657 }
00658 else
00659 return 0;
00660 }
00661
00663 uint16 AsebaVMClearBreakpoint(AsebaVMState *vm, uint16 pc)
00664 {
00665 uint16 i;
00666 for (i = 0; i < vm->breakpointsCount; i++)
00667 {
00668 if (vm->breakpoints[i] == pc)
00669 {
00670 uint16 j;
00671
00672 vm->breakpointsCount--;
00673 for (j = i; j < vm->breakpointsCount; j++)
00674 vm->breakpoints[j] = vm->breakpoints[j+1];
00675 return 1;
00676 }
00677 }
00678 return 0;
00679 }
00680
00682 void AsebaVMClearBreakpoints(AsebaVMState *vm)
00683 {
00684 vm->breakpointsCount = 0;
00685 }
00686
00688 void AsebaVMSendExecutionStateChanged(AsebaVMState *vm)
00689 {
00690 uint16 buffer[2];
00691 buffer[0] = vm->pc;
00692 buffer[1] = vm->flags;
00693 AsebaSendMessageWords(vm, ASEBA_MESSAGE_EXECUTION_STATE_CHANGED, buffer, 2);
00694 }
00695
00696 void AsebaVMDebugMessage(AsebaVMState *vm, uint16 id, uint16 *data, uint16 dataLength)
00697 {
00698
00699
00700 if (id == ASEBA_MESSAGE_GET_DESCRIPTION)
00701 {
00702 AsebaSendDescription(vm);
00703 return;
00704 }
00705
00706
00707 if (bswap16(data[0]) != vm->nodeId)
00708 return;
00709
00710 data++;
00711 dataLength--;
00712
00713 switch (id)
00714 {
00715 case ASEBA_MESSAGE_SET_BYTECODE:
00716 {
00717 uint16 start = bswap16(data[0]);
00718 uint16 length = dataLength - 1;
00719 uint16 i;
00720 #ifdef ASEBA_ASSERT
00721 if (start + length > vm->bytecodeSize)
00722 AsebaAssert(vm, ASEBA_ASSERT_OUT_OF_BYTECODE_BOUNDS);
00723 #endif
00724 for (i = 0; i < length; i++)
00725 vm->bytecode[start+i] = bswap16(data[i+1]);
00726 }
00727
00728
00729 case ASEBA_MESSAGE_RESET:
00730 vm->flags = ASEBA_VM_STEP_BY_STEP_MASK;
00731
00732 if (AsebaVMSetupEvent(vm, ASEBA_EVENT_INIT) == 0)
00733 AsebaVMSendExecutionStateChanged(vm);
00734 break;
00735
00736 case ASEBA_MESSAGE_RUN:
00737 AsebaMaskClear(vm->flags, ASEBA_VM_STEP_BY_STEP_MASK);
00738 AsebaVMSendExecutionStateChanged(vm);
00739 if(AsebaVMRunCB)
00740 AsebaVMRunCB(vm);
00741 break;
00742
00743 case ASEBA_MESSAGE_PAUSE:
00744 AsebaMaskSet(vm->flags, ASEBA_VM_STEP_BY_STEP_MASK);
00745 AsebaVMSendExecutionStateChanged(vm);
00746 break;
00747
00748 case ASEBA_MESSAGE_STEP:
00749 if (AsebaMaskIsSet(vm->flags, ASEBA_VM_EVENT_ACTIVE_MASK))
00750 {
00751 AsebaVMStep(vm);
00752 AsebaVMSendExecutionStateChanged(vm);
00753 }
00754 break;
00755
00756 case ASEBA_MESSAGE_STOP:
00757 vm->flags = ASEBA_VM_STEP_BY_STEP_MASK;
00758 AsebaVMSendExecutionStateChanged(vm);
00759 break;
00760
00761 case ASEBA_MESSAGE_GET_EXECUTION_STATE:
00762 AsebaVMSendExecutionStateChanged(vm);
00763 break;
00764
00765 case ASEBA_MESSAGE_BREAKPOINT_SET:
00766 {
00767 uint16 buffer[2];
00768 buffer[0] = bswap16(data[0]);
00769 buffer[1] = AsebaVMSetBreakpoint(vm, buffer[0]);
00770 AsebaSendMessageWords(vm, ASEBA_MESSAGE_BREAKPOINT_SET_RESULT, buffer, 2);
00771 }
00772 break;
00773
00774 case ASEBA_MESSAGE_BREAKPOINT_CLEAR:
00775 AsebaVMClearBreakpoint(vm, bswap16(data[0]));
00776 break;
00777
00778 case ASEBA_MESSAGE_BREAKPOINT_CLEAR_ALL:
00779 AsebaVMClearBreakpoints(vm);
00780 break;
00781
00782 case ASEBA_MESSAGE_GET_VARIABLES:
00783 {
00784 uint16 start = bswap16(data[0]);
00785 uint16 length = bswap16(data[1]);
00786 #ifdef ASEBA_ASSERT
00787 if (start + length > vm->variablesSize)
00788 AsebaAssert(vm, ASEBA_ASSERT_OUT_OF_VARIABLES_BOUNDS);
00789 #endif
00790 AsebaSendVariables(vm, start, length);
00791 }
00792 break;
00793
00794 case ASEBA_MESSAGE_SET_VARIABLES:
00795 {
00796 uint16 start = bswap16(data[0]);
00797 uint16 length = dataLength - 1;
00798 uint16 i;
00799 #ifdef ASEBA_ASSERT
00800 if (start + length > vm->variablesSize)
00801 AsebaAssert(vm, ASEBA_ASSERT_OUT_OF_VARIABLES_BOUNDS);
00802 #endif
00803 for (i = 0; i < length; i++)
00804 vm->variables[start+i] = bswap16(data[i+1]);
00805 }
00806 break;
00807
00808 case ASEBA_MESSAGE_WRITE_BYTECODE:
00809 AsebaWriteBytecode(vm);
00810 break;
00811
00812 case ASEBA_MESSAGE_REBOOT:
00813 AsebaResetIntoBootloader(vm);
00814 break;
00815
00816 case ASEBA_MESSAGE_SUSPEND_TO_RAM:
00817 AsebaPutVmToSleep(vm);
00818 break;
00819
00820 default:
00821 break;
00822 }
00823 }
00824
00825 uint16 AsebaVMShouldDropPacket(AsebaVMState *vm, uint16 source, const uint8* data)
00826 {
00827 uint16 type = bswap16(((const uint16*)data)[0]);
00828 if (type < 0x8000)
00829 {
00830
00831 return !AsebaVMGetEventAddress(vm, type);
00832 }
00833 else if (type >= 0xA000)
00834 {
00835
00836 uint16 dest = bswap16(((const uint16*)data)[1]);
00837 if (type == ASEBA_MESSAGE_GET_DESCRIPTION)
00838 return 0;
00839
00840
00841 return dest != vm->nodeId;
00842 }
00843 return 1;
00844 }
00845