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