00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <assert.h>
00039 #include <stdint.h>
00040 #include <stdlib.h>
00041 #include <dirent.h>
00042 #include <fstream>
00043 #include <iostream>
00044 #include <string>
00045 #include <sstream>
00046
00047 #include <libsherpa/UExcept.hxx>
00048
00049 #include "AST.hxx"
00050 #include "Type.hxx"
00051 #include "machine-dep.hxx"
00052
00053 using namespace boost;
00054 using namespace sherpa;
00055
00056 static size_t
00057 calc_struct_size(const shared_ptr<Type> t)
00058 {
00059 size_t start=0;
00060 size_t sz = 0;
00061 shared_ptr<AST> base = GC_NULL;
00062
00063 if (t->typeTag == ty_structv) {
00064 start = 0;
00065 base = t->defAst->defForm->child(4);
00066 }
00067 else if (t->typeTag == ty_uconv) {
00068 start = 1;
00069 base = t->defAst;
00070 }
00071 else
00072 assert(false);
00073
00074
00075
00076
00077 size_t compCnt=0;
00078 for (size_t i=start; i < base->children.size(); i++) {
00079 shared_ptr<AST> fld = base->child(i);
00080
00081 switch(fld->astType) {
00082 case at_fill:
00083 {
00084 sz += fld->field_bits;
00085 break;
00086 }
00087
00088 case at_field:
00089 {
00090 if (fld->field_bits != 0) {
00091 assert(fld->symType->isIntegral());
00092 sz += fld->field_bits;
00093 }
00094 else {
00095 sz+= t->CompType(compCnt)->size();
00096 }
00097
00098 if ((fld->flags & FLD_IS_DISCM) == 0)
00099 compCnt++;
00100 break;
00101 }
00102
00103 case at_methdecl:
00104
00105 break;
00106
00107 default:
00108 {
00109 assert(false);
00110 break;
00111 }
00112 }
00113 }
00114
00115 return sz;
00116 }
00117
00118
00119 static size_t
00120 calc_unin_size(const shared_ptr<Type> t)
00121 {
00122 assert(t->typeTag == ty_unionv);
00123 shared_ptr<AST> base = t->defAst->defForm;
00124
00125 size_t max=0;
00126 for (size_t i=0; i < base->children.size(); i++) {
00127 shared_ptr<AST> ctr = base->child(i);
00128
00129
00130 if (ctr->symType->isUval())
00131 continue;
00132
00133 assert(ctr->symType->isUcon());
00134 size_t sz = calc_struct_size(ctr->symType);
00135
00136 if (max < sz)
00137 max = sz;
00138 }
00139
00140 size_t tag=0;
00141 if ((base->flags & ENUM_UN) || (base->flags & SINGLE_LEG_UN) ||
00142 (base->flags & CARDELLI_UN) || (base->flags & UNION_IS_REPR))
00143 tag=0;
00144 else
00145 tag = base->tagType->size();
00146
00147 return (max + tag);
00148 }
00149
00150
00151 size_t
00152 Type::size()
00153 {
00154 if (getType() != shared_from_this())
00155 return link->getType()->size();
00156
00157 if (mark & MARK_SIZE)
00158 assert(false);
00159
00160 mark |= MARK_SIZE;
00161
00162 size_t theSize=0;
00163
00164 switch(typeTag) {
00165 case ty_unit:
00166 case ty_bool:
00167 case ty_char:
00168 theSize = 8;
00169 break;
00170
00171 case ty_int8:
00172 case ty_uint8:
00173 case ty_int16:
00174 case ty_uint16:
00175 case ty_int32:
00176 case ty_uint32:
00177 case ty_int64:
00178 case ty_uint64:
00179 theSize = nBits();
00180 break;
00181
00182 case ty_word:
00183 theSize = TARGET_WORD_SIZE;
00184 break;
00185
00186 case ty_float:
00187 theSize = TARGET_FLOAT_SIZE;
00188 break;
00189
00190 case ty_double:
00191 theSize = TARGET_DOUBLE_SIZE;
00192 break;
00193
00194 case ty_quad:
00195 theSize = TARGET_QUAD_SIZE;
00196 break;
00197
00198 #ifdef KEEP_BF
00199 case ty_bitfield:
00200 theSize = Isize;
00201 break;
00202 #endif
00203
00204 case ty_fn:
00205 case ty_method:
00206 case ty_string:
00207 case ty_dummy:
00208 case ty_structr:
00209 case ty_unionr:
00210 case ty_uvalr:
00211 case ty_uconr:
00212 case ty_vector:
00213 case ty_ref:
00214 case ty_byref:
00215 case ty_exn:
00216 theSize = TARGET_WORD_SIZE;
00217 break;
00218
00219 case ty_array_ref:
00220 theSize = TARGET_WORD_SIZE * 2;
00221 break;
00222
00223 case ty_tvar:
00224 case ty_fnarg:
00225 case ty_tyfn:
00226 case ty_letGather:
00227 case ty_typeclass:
00228 case ty_pcst:
00229 case ty_kvar:
00230 case ty_kfix:
00231 case ty_field:
00232 assert(false);
00233 break;
00234
00235 case ty_structv:
00236 {
00237
00238
00239
00240
00241
00242
00243 theSize = calc_struct_size(shared_from_this());
00244 break;
00245 }
00246
00247 case ty_unionv:
00248 {
00249 theSize = calc_unin_size(shared_from_this());
00250 break;
00251 }
00252
00253 case ty_uvalv:
00254 case ty_uconv:
00255 {
00256 theSize = getUnionType()->size();
00257 break;
00258 }
00259
00260 case ty_array:
00261 {
00262 theSize = Base()->size() * arrLen->len;
00263 break;
00264 }
00265
00266 case ty_mbTop:
00267 case ty_mbFull:
00268 {
00269 theSize = Core()->size();
00270 }
00271
00272 case ty_mutable:
00273 case ty_const:
00274 {
00275 theSize = Base()->size();
00276 break;
00277 }
00278 }
00279
00280 mark &= ~MARK_SIZE;
00281 return theSize;
00282 }
00283