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 "compiler.h"
00022 #include "../common/consts.h"
00023 #include <cassert>
00024 #include <iostream>
00025
00026 namespace Aseba
00027 {
00030
00032 bool Compiler::verifyStackCalls(PreLinkBytecode& preLinkBytecode)
00033 {
00034
00035 for (PreLinkBytecode::EventsBytecode::iterator it = preLinkBytecode.events.begin(); it != preLinkBytecode.events.end(); ++it)
00036 {
00037 if (it->second.maxStackDepth > targetDescription->stackSize)
00038 return false;
00039
00040 const BytecodeVector& bytecode = it->second;
00041 for (size_t pc = 0; pc < bytecode.size();)
00042 {
00043 switch (bytecode[pc] >> 12)
00044 {
00045 case ASEBA_BYTECODE_SUB_CALL:
00046 {
00047 unsigned id = bytecode[pc] & 0x0fff;
00048 PreLinkBytecode::SubroutinesBytecode::iterator destIt = preLinkBytecode.subroutines.find(id);
00049 assert(destIt != preLinkBytecode.subroutines.end());
00050 destIt->second.callDepth = 1;
00051 pc += 1;
00052 }
00053 break;
00054
00055 case ASEBA_BYTECODE_LARGE_IMMEDIATE:
00056 case ASEBA_BYTECODE_LOAD_INDIRECT:
00057 case ASEBA_BYTECODE_STORE_INDIRECT:
00058 case ASEBA_BYTECODE_CONDITIONAL_BRANCH:
00059 pc += 2;
00060 break;
00061
00062 case ASEBA_BYTECODE_EMIT:
00063 pc += 3;
00064 break;
00065
00066 default:
00067 pc += 1;
00068 break;
00069 }
00070 }
00071 }
00072
00073
00074 bool wasActivity;
00075 do
00076 {
00077 wasActivity = false;
00078 for (PreLinkBytecode::SubroutinesBytecode::iterator it = preLinkBytecode.subroutines.begin(); it != preLinkBytecode.subroutines.end(); ++it)
00079 {
00080 unsigned myDepth = it->second.callDepth;
00081 if (myDepth + it->second.maxStackDepth > targetDescription->stackSize)
00082 {
00083 return false;
00084 }
00085
00086 const BytecodeVector& bytecode = it->second;
00087 for (size_t pc = 0; pc < bytecode.size();)
00088 {
00089 switch (bytecode[pc] >> 12)
00090 {
00091 case ASEBA_BYTECODE_SUB_CALL:
00092 {
00093 unsigned id = bytecode[pc] & 0x0fff;
00094 PreLinkBytecode::SubroutinesBytecode::iterator destIt = preLinkBytecode.subroutines.find(id);
00095 assert(destIt != preLinkBytecode.subroutines.end());
00096 if (myDepth + 1 > destIt->second.callDepth)
00097 {
00098 wasActivity = true;
00099 destIt->second.callDepth = myDepth + 1;
00100 }
00101 pc += 1;
00102 }
00103 break;
00104
00105 case ASEBA_BYTECODE_LARGE_IMMEDIATE:
00106 case ASEBA_BYTECODE_LOAD_INDIRECT:
00107 case ASEBA_BYTECODE_STORE_INDIRECT:
00108 case ASEBA_BYTECODE_CONDITIONAL_BRANCH:
00109 pc += 2;
00110 break;
00111
00112 case ASEBA_BYTECODE_EMIT:
00113 pc += 3;
00114 break;
00115
00116 default:
00117 pc += 1;
00118 break;
00119 }
00120 }
00121 }
00122 }
00123 while (wasActivity);
00124
00125 return true;
00126 }
00127
00130 }
00131