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