val.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. #include "std.h"
  2. #include "val.h"
  3. #include "block.h"
  4. using namespace CG;
  5. static CGLit *literal( CGExp *e ){
  6. if( CGLit *t=e->lit() ) return t;
  7. if( CGDat *t=e->dat() ){
  8. if( t->exps.size()==3 ) return t->exps[2]->lit();
  9. }
  10. if( CGSym *t=e->sym() ){
  11. if( t->value=="bbEmptyString" ) return lit(bstring());
  12. }
  13. return 0;
  14. }
  15. //********************* Val ***********************
  16. Val::Val( int n,Type *ty ):type(ty){
  17. assert( ty->intType() );
  18. switch( ty->cgType() ){
  19. case CG_INT8:n&=0xff;break;
  20. case CG_INT16:n&=0xffff;break;
  21. }
  22. cg_exp=ty->cgType()==CG_INT64 ? lit( int64(n) ) : lit( int(n) );
  23. }
  24. Val::Val( int64 n,Type *ty ):type(ty){
  25. assert( ty->intType() );
  26. switch( ty->cgType() ){
  27. case CG_INT8 :n&=int64(0xff);break;
  28. case CG_INT16:n&=int64(0xffff);break;
  29. case CG_INT32:n&=int64(0xffffffff);break;
  30. }
  31. cg_exp=ty->cgType()==CG_INT64 ? lit( int64(n) ) : lit( int(n) );
  32. }
  33. Val::Val( float n,Type *ty ):type(ty){
  34. assert( ty->floatType() );
  35. cg_exp=ty->cgType()==CG_FLOAT64 ? lit( double(n) ) : lit( float(n) );
  36. }
  37. Val::Val( double n,Type *ty ):type(ty){
  38. assert( ty->floatType() );
  39. cg_exp=ty->cgType()==CG_FLOAT64 ? lit( double(n) ) : lit( float(n) );
  40. }
  41. Val::Val( bstring t ):type(Type::stringObject){
  42. cg_exp=genBBString(t);
  43. }
  44. Val::Val( const char *t ):type(Type::c_string){
  45. cg_exp=genCString(t);
  46. }
  47. Val::Val( Type *t,CGExp *e ):type(t),cg_exp(e){
  48. }
  49. Val::~Val(){
  50. }
  51. CGExp *Val::constant(){
  52. return cg_exp->lit() || cg_exp->sym() ? cg_exp : 0;
  53. }
  54. int64 Val::intValue(){
  55. CGLit *t=literal( cg_exp );
  56. assert(t);
  57. switch( t->type ){
  58. case CG_INT8:case CG_INT16:return t->int_value;
  59. case CG_INT32:case CG_INT64:return t->int_value;
  60. case CG_FLOAT32:case CG_FLOAT64:return (int64)t->float_value;
  61. case CG_BSTRING:return toint(tostring(t->string_value));
  62. }
  63. assert(0);
  64. return 0;
  65. }
  66. double Val::floatValue(){
  67. CGLit *t=literal( cg_exp );
  68. assert(t);
  69. switch( t->type ){
  70. case CG_INT8:case CG_INT16:return t->int_value;
  71. case CG_INT32:case CG_INT64:return t->int_value;
  72. case CG_FLOAT32:case CG_FLOAT64:return t->float_value;
  73. case CG_BSTRING:return tofloat(tostring(t->string_value));
  74. }
  75. assert(0);
  76. return 0;
  77. }
  78. bstring Val::stringValue(){
  79. CGLit *t=literal( cg_exp );
  80. assert(t);
  81. switch( t->type ){
  82. case CG_INT8:return tobstring(fromint(t->int_value));
  83. case CG_INT16:return tobstring(fromint(t->int_value));
  84. case CG_INT32:return tobstring(fromint(t->int_value));
  85. case CG_INT64:return tobstring(fromint(t->int_value));
  86. case CG_FLOAT32:return tobstring(fromfloat(t->float_value));
  87. case CG_FLOAT64:return tobstring(fromdouble(t->float_value));
  88. case CG_BSTRING:return t->string_value;
  89. }
  90. assert(0);
  91. return tobstring("");
  92. }
  93. Val *Val::cond(){
  94. CGExp *e=0;
  95. if( type->nullType() ){
  96. e=lit0;
  97. }else if( type->intType() ){
  98. if( type->cgType()!=CG_INT64 ) return this;
  99. e=scc(CG_NE,cg_exp,lit(int64(0)));
  100. }else if( type->floatType() ){
  101. if( constant() ) e=floatValue() ? lit1 : lit0;
  102. else e=scc(CG_NE,cg_exp,type->size()==8 ? lit(0.0) : lit(0.0f));
  103. }else if( type->stringType() ){
  104. if( constant() ) e=stringValue().size() ? lit1 : lit0;
  105. else e=mem(CG_INT32,cg_exp,8); //len of string
  106. }else if( type->arrayType() ){
  107. e=mem(CG_INT32,cg_exp,16); //len of array
  108. }else if( type->objectType() ){
  109. e=scc(CG_NE,cg_exp,sym("bbNullObject",CG_IMPORT));//cmp with null object
  110. }else if( type->exObjectType() ){
  111. e=scc(CG_NE,cg_exp,lit0); //cmp with 0
  112. }else if( type->ptrType() ){
  113. e=scc(CG_NE,cg_exp,lit0); //cmp with 0
  114. }else if( FunType *f=type->funType() ){
  115. if( !f->method() ){
  116. e=scc(CG_NE,cg_exp,sym("brl_blitz_NullFunctionError",CG_IMPORT));
  117. }
  118. }
  119. if( !e ) fail( "Unable to convert expression to conditional value" );
  120. return new Val(Type::int32,e);
  121. }
  122. Type *Val::balance( Val *t ){
  123. return balance( t->type );
  124. }
  125. Type *Val::balance( Type *y ){
  126. Type *x=type;
  127. if( x->intType() ){
  128. if( y->intType() ) return (x->cgType()==CG_INT64 || y->cgType()==CG_INT64) ? Type::int64 : Type::int32;
  129. if( y->floatType() ) return y;
  130. if( y->stringType() ) return y;
  131. if( y->objectType() ) return y;
  132. if( y->classType() ) return y;
  133. }else if( x->floatType() ){
  134. if( y->intType() ) return x;
  135. if( y->floatType() ) return (x->cgType()==CG_FLOAT64 || y->cgType()==CG_FLOAT64) ? Type::float64 : Type::float32;
  136. if( y->stringType() ) return y;
  137. if( y->classType() ) return y;
  138. if( y->objectType() ) return y;
  139. }else if( x->stringType() ){
  140. if( y->intType() ) return x;
  141. if( y->floatType() ) return x;
  142. if( y->stringType() ) return x;
  143. if( y->objectType() ) return y;
  144. if( y->classType() ) return y;
  145. }else if( FunType *p=x->funType() ){
  146. if( FunType *q=y->funType() ){
  147. if( p->extends(q) ) return y;
  148. if( q->extends(p) ) return x;
  149. }
  150. }else if( ObjectType *p=x->objectType() ){
  151. if( ObjectType *q=y->objectType() ){
  152. if( p->extends(q) ) return y;
  153. if( q->extends(p) ) return x;
  154. }
  155. }else if( ObjectType *p=x->exObjectType() ){
  156. if( ObjectType *q=y->exObjectType() ){
  157. if( p->extends(q) ) return y;
  158. if( q->extends(p) ) return x;
  159. }
  160. }
  161. if( x->nullType() ) return y;
  162. if( y->nullType() ) return x;
  163. fail( "Types '%s' and '%s' are unrelated",x->toString().c_str(),y->toString().c_str() );
  164. return 0;
  165. }
  166. Val *Val::cast( Type *dst ){
  167. //nop?
  168. if( type->equals(dst) ) return this;
  169. if( type->extends(dst) ) return new Val(dst,cg_exp);
  170. //null casts...
  171. if( type->nullType() ){
  172. if( dst->intType() ) return new Val(0,dst);
  173. if( dst->floatType() ) return new Val(0.0,dst);
  174. if( dst->ptrType() ) return new Val(dst,lit0);
  175. if( dst->cstringType() ) return new Val(dst,lit0);
  176. if( dst->wstringType() ) return new Val(dst,lit0);
  177. if( dst->stringType() ) return new Val(dst,sym("bbEmptyString",CG_IMPORT));
  178. if( dst->arrayType() ) return new Val(dst,sym("bbEmptyArray",CG_IMPORT));
  179. if( dst->objectType() ) return new Val(dst,sym("bbNullObject",CG_IMPORT));
  180. if( dst->exObjectType() ) return new Val(dst,lit0);
  181. if( dst->funType() ) return new Val(dst,sym("brl_blitz_NullFunctionError",CG_IMPORT));
  182. fail( "Unable to cast 'Null' to '%s'",(dst->toString()).c_str() );
  183. return 0;
  184. }
  185. int cg_ty=dst->cgType();
  186. //literal conversions
  187. if( constant() && type->numericType() ){
  188. switch( cg_ty ){
  189. case CG_INT8:return new Val( intValue(),Type::int8 );
  190. case CG_INT16:return new Val( intValue(),Type::int16 );
  191. case CG_INT32:return new Val( intValue(),Type::int32 );
  192. case CG_INT64:return new Val( intValue(),Type::int64 );
  193. case CG_FLOAT32:return new Val( floatValue(),Type::float32 );
  194. case CG_FLOAT64:return new Val( floatValue(),Type::float64 );
  195. default:if( dst->stringType() ) return new Val( stringValue() );
  196. }
  197. }
  198. CGExp *e=0;
  199. //standard type conversions
  200. if( type->intType() ){
  201. if( dst->intType() ){
  202. e=cvt(cg_ty,cg_exp);
  203. }else if( dst->floatType() ){
  204. e=cvt(cg_ty,cg_exp);
  205. }else if( dst->stringType() ){
  206. if( type->cgType()==CG_INT64 ){
  207. e=jsr(cg_ty,"bbStringFromLong",cg_exp);
  208. }else{
  209. e=jsr(cg_ty,"bbStringFromInt",cvt(CG_INT32,cg_exp));
  210. }
  211. }
  212. }else if( type->floatType() ){
  213. if( dst->intType() ){
  214. e=cvt(cg_ty,cg_exp);
  215. }else if( dst->floatType() ){
  216. e=cvt(cg_ty,cg_exp);
  217. }else if( dst->stringType() ){
  218. if( type->cgType()==CG_FLOAT64 ){
  219. e=jsr(cg_ty,"bbStringFromDouble",cg_exp );
  220. }else{
  221. e=jsr(cg_ty,"bbStringFromFloat",cg_exp );
  222. }
  223. }
  224. }else if( type->stringType() ){
  225. /*
  226. if( dst->cstringType() ){
  227. e=jsr(CG_PTR,"bbStringToCString",cg_exp);
  228. }else if( dst->wstringType() ){
  229. e=jsr(CG_PTR,"bbStringToWString",cg_exp);
  230. }
  231. */
  232. }else if( type->cstringType() ){
  233. /*
  234. if( dst->stringType() ){
  235. e=jsr(cg_ty,"bbStringFromCString",cg_exp);
  236. }else if( dst->cstringType() ){
  237. e=cg_exp;
  238. }
  239. */
  240. }else if( type->wstringType() ){
  241. /*
  242. if( dst->stringType() ){
  243. e=jsr(cg_ty,"bbStringFromWString",cg_exp);
  244. }else if( dst->wstringType() ){
  245. e=cg_exp;
  246. }
  247. */
  248. }else if( ArrayType *src_ty=type->arrayType() ){
  249. if( PtrType *dst_ty=dst->ptrType() ){
  250. Type *val_ty=dst_ty->val_type;
  251. if( val_ty->encoding()=="b" || val_ty->equals(src_ty->element_type) ){
  252. e=cg_exp;
  253. if( e->tmp() ){
  254. e=mem(CG_PTR,lea(e),0);
  255. }else if( !e->mem() ){
  256. CGTmp *t=tmp(CG_PTR);
  257. e=esq(mov(t,e),mem(CG_PTR,lea(t),0));
  258. }
  259. e=lea(mem(val_ty->cgType(),e,src_ty->dims*4+20));
  260. }
  261. }
  262. }else if( ObjectType *src_ty=type->objectType() ){
  263. if( PtrType *dst_ty=dst->ptrType() ){
  264. if( dst_ty->val_type->encoding()=="b" ){
  265. e=cg_exp;
  266. if( e->tmp() ){
  267. e=mem(CG_PTR,lea(e),0);
  268. }else if( !e->mem() ){
  269. CGTmp *t=tmp(CG_PTR);
  270. e=esq(mov(t,e),mem(CG_PTR,lea(t),0));
  271. }
  272. e=lea(mem(CG_PTR,e,8));
  273. }
  274. }
  275. }else if( ObjectType *src_ty=type->exObjectType() ){
  276. if( PtrType *dst_ty=dst->ptrType() ){
  277. if( dst_ty->val_type->encoding()=="b" ){
  278. e=cg_exp;
  279. }
  280. }
  281. }else if( PtrType *src_ty=type->ptrType() ){
  282. if( PtrType *dst_ty=dst->ptrType() ){
  283. if( dst_ty->val_type->equals(src_ty->val_type) || dst_ty->val_type->encoding()=="b" ){
  284. e=cg_exp;
  285. }
  286. }else if( FunType *dst_ty=dst->funType() ){
  287. if( src_ty->val_type->encoding()=="b" ){
  288. //check for '0' func!
  289. CGTmp *t=tmp(CG_PTR);
  290. CGSym *p=sym();
  291. CGStm *s=CG::seq(
  292. mov(t,cg_exp),
  293. bcc(CG_NE,t,lit0,p),
  294. mov(t,sym("brl_blitz_NullFunctionError",CG_IMPORT)),
  295. lab(p),
  296. 0 );
  297. e=esq(s,t);
  298. }
  299. }
  300. }else if( FunType *src_ty=type->funType() ){
  301. if( PtrType *dst_ty=dst->ptrType() ){
  302. if( !src_ty->method() && dst_ty->val_type->encoding()=="b" ) e=cg_exp;
  303. }
  304. }
  305. if( !e ) fail( "Unable to convert from '%s' to '%s'",type->toString().c_str(),dst->toString().c_str() );
  306. return new Val(dst,e);
  307. }
  308. Val *Val::initCast( Type *dst ){
  309. if( !strictMode && dst->cgType()==CG_INT32 ){
  310. if( type->objectType() && !type->stringType() && !type->arrayType() ){
  311. return new Val( dst,jsr(CG_INT32,"bbHandleFromObject",cg_exp) );
  312. }
  313. }
  314. return cast( dst );
  315. }
  316. Val *Val::funArgCast( Type *dst,CGSeq *cleanup ){
  317. //convert reference to var
  318. if( VarType *var=dst->varType() ){
  319. RefType *ref=type->refType();
  320. if( !ref ) fail( "Expression for 'Var' parameter must be a variable" );
  321. if( !ref->val_type->extends(var->val_type) ) fail( "Variable for 'Var' parameter is not of matching type" );
  322. CGExp *e=lea(cg_exp);
  323. if( !opt_threaded && var->val_type->objectType() && cg_exp->tmp() ){
  324. CGMem *m=mem(CG_INT32,cg_exp,4);
  325. e=esq(ati(m),e);
  326. CGSym *l=sym();
  327. cleanup->push_back( CG::seq(
  328. atd(m,l),
  329. eva(jsr(CG_INT32,"bbGCFree",cg_exp)),
  330. lab(l),
  331. 0) );
  332. }
  333. return new Val( dst,e );
  334. }
  335. //convert int32 to object
  336. if( !strictMode && type->cgType()==CG_INT32 ){
  337. if( dst->objectType() && !dst->stringType() && !dst->arrayType() ){
  338. Val *v=new Val( Type::objectObject,jsr(CG_PTR,"bbHandleToObject",cg_exp) );
  339. return v->explicitCast(dst);
  340. }
  341. }
  342. //convert string to cstring/wstring
  343. if( type->stringType() ){
  344. CGExp *e=0;
  345. if( dst->cstringType() || dst->ptrType("b") ){
  346. e=jsr(CG_PTR,"bbStringToCString",cg_exp);
  347. }else if( dst->wstringType() || dst->ptrType("s") ){
  348. e=jsr(CG_PTR,"bbStringToWString",cg_exp);
  349. }
  350. if( e ){
  351. CGTmp *t=tmp(CG_PTR);
  352. e=esq(mov(t,e),t);
  353. cleanup->push_back( eva(jsr(CG_INT32,"bbMemFree",t)) );
  354. return new Val( dst,e );
  355. }
  356. }
  357. return cast(dst);
  358. }
  359. Val *Val::explicitCast( Type *dst ){
  360. if( type->nullType() ) return cast(dst);
  361. if( type->equals(dst) ) return this;
  362. int cg_ty=dst->cgType();
  363. //literal conversions
  364. if( constant() && type->stringType() ){
  365. switch( cg_ty ){
  366. case CG_INT8:return new Val( intValue(),Type::int8 );
  367. case CG_INT16:return new Val( intValue(),Type::int16 );
  368. case CG_INT32:return new Val( intValue(),Type::int32 );
  369. case CG_INT64:return new Val( intValue(),Type::int64 );
  370. case CG_FLOAT32:return new Val( floatValue(),Type::float32 );
  371. case CG_FLOAT64:return new Val( floatValue(),Type::float64 );
  372. }
  373. }
  374. CGExp *e=0;
  375. if( type->ptrType() ){
  376. if( dst->intType() ){
  377. //ptr to int
  378. e=cvt(cg_ty,cg_exp);
  379. }else if( dst->ptrType() ){
  380. //ptr to ptr
  381. e=cg_exp;
  382. }
  383. }else if( type->intType() ){
  384. if( dst->ptrType() ){
  385. //int to ptr
  386. e=cvt(cg_ty,cg_exp);
  387. }
  388. }else if( type->stringType() ){
  389. if( dst->intType() ){
  390. //string to int
  391. if( cg_ty==CG_INT64 ){
  392. e=jsr(cg_ty,CG_CDECL,vfn(sym("bbStringToLong",CG_IMPORT),cg_exp) );
  393. }else{
  394. e=cvt(cg_ty,jsr(CG_INT32,"bbStringToInt",cg_exp));
  395. }
  396. }else if( dst->floatType() ){
  397. //string to float
  398. if( cg_ty==CG_FLOAT64 ){
  399. e=jsr(cg_ty,"bbStringToDouble",cg_exp );
  400. }else{
  401. e=jsr(cg_ty,"bbStringToFloat",cg_exp );
  402. }
  403. }
  404. }else if( ObjectType *src_ty=type->objectType() ){
  405. if( ObjectType *dst_ty=dst->objectType() ){
  406. if( dst_ty->extends(src_ty) ){
  407. if( ArrayType *arr_ty=dst->arrayType() ){
  408. e=jsr(CG_PTR,"bbArrayCastFromObject",cg_exp,genCString(arr_ty->element_type->encoding()) );
  409. }else{
  410. e=jsr(CG_PTR,"bbObjectDowncast",cg_exp,dst_ty->class_val->cg_exp);
  411. }
  412. if( dst->stringType() || dst->arrayType() ){
  413. CGSym *t=sym( (dst->stringType() ? "bbEmptyString" : "bbEmptyArray"),CG_IMPORT );
  414. CGTmp *r=tmp(CG_PTR);
  415. CGSym *l=sym();
  416. CGStm *s=CG::seq(
  417. mov(r,e),
  418. bcc(CG_NE,r,sym("bbNullObject",CG_IMPORT),l),
  419. mov(r,t),
  420. lab(l),
  421. 0 );
  422. e=esq(s,r);
  423. }
  424. }
  425. }
  426. }else if( ObjectType *src_ty=type->exObjectType() ){
  427. if( ObjectType *dst_ty=dst->exObjectType() ){
  428. if( dst_ty->extends(src_ty) ){
  429. e=cg_exp;
  430. }
  431. }
  432. }
  433. if( e ) return new Val( dst,e );
  434. return cast(dst);
  435. }
  436. Val *Val::forEachCast( Type *dst ){
  437. if( type->nullType() ) return cast(dst);
  438. if( type->equals(dst) ) return this;
  439. CGExp *e=0;
  440. int cg_ty=dst->cgType();
  441. if( ObjectType *src_ty=type->objectType() ){
  442. if( ObjectType *dst_ty=dst->objectType() ){
  443. if( dst_ty->extends(src_ty) ){
  444. if( dst_ty->objectClass()->attrs & ClassType::EXTERN ){
  445. e=cg_exp;
  446. }else if( ArrayType *arr_ty=dst->arrayType() ){
  447. e=jsr(CG_PTR,"bbArrayCastFromObject",cg_exp,genCString(arr_ty->element_type->encoding()) );
  448. }else{
  449. e=jsr(CG_PTR,"bbObjectDowncast",cg_exp,dst_ty->class_val->cg_exp);
  450. }
  451. }
  452. }
  453. }
  454. if( e ) return new Val( dst,e );
  455. return explicitCast( dst );
  456. }
  457. Val *Val::find( string id ){
  458. Val *v=type->find(id);
  459. if( !v ) return 0;
  460. int n_self=v->countTmps("@self");
  461. int n_type=v->countTmps("@type");
  462. if( !n_self && !n_type ) return v;
  463. CGExp *cg=cg_exp;
  464. if( n_self && opt_debug && !type->stringType() && !type->arrayType() ){
  465. cg=tmp(CG_PTR);
  466. CGSym *q=sym();
  467. CGStm *stms=CG::seq(
  468. mov(cg,cg_exp),
  469. bcc(CG_NE,cg,sym("bbNullObject",CG_IMPORT),q),
  470. eva(jsr(CG_INT32,"brl_blitz_NullObjectError")),
  471. lab(q),
  472. 0 );
  473. v=new Val(v->type,esq(stms,v->cg_exp));
  474. }else if( n_self+n_type>1 ){
  475. cg=tmp(CG_PTR);
  476. v=new Val(v->type,esq(mov(cg,cg_exp),v->cg_exp));
  477. }
  478. if( type->objectType() || type->exObjectType() ){
  479. if( n_self ) v=v->renameTmps( "@self",cg );
  480. if( n_type ) v=v->renameTmps( "@type",mem(CG_PTR,cg,0) );
  481. }else if( type->classType() ){
  482. assert( !n_self );
  483. if( n_type ) v=v->renameTmps( "@type",cg );
  484. }else{
  485. assert(0);
  486. }
  487. return v;
  488. }
  489. bool Val::refCounted(){
  490. if( opt_threaded ) return false;
  491. RefType *t=type->refType();
  492. return t && t->objectType() && cg_exp->mem();
  493. }
  494. Val *Val::retain(){
  495. if( opt_threaded ){
  496. fail( "Internal error: Val::retain() invoked in threaded mode." );
  497. }
  498. CGTmp *p=tmp(CG_PTR);
  499. CGMem *m=mem(CG_INT32,p,4);
  500. CGStm *t=seq(
  501. mov(p,cg_exp),
  502. ati(m),
  503. 0);
  504. return new Val(type,esq(t,p));
  505. }
  506. CGStm *Val::release(){
  507. if( opt_threaded ){
  508. fail( "Internal error: Val::release() invoked in threaded mode." );
  509. }
  510. CGTmp *p=tmp(CG_PTR);
  511. CGMem *m=mem(CG_INT32,p,4);
  512. CGSym *q=sym();
  513. CGStm *t=seq(
  514. mov(p,cg_exp),
  515. atd(m,q),
  516. eva(jsr(CG_INT32,"bbGCFree",p)),
  517. lab(q),
  518. 0);
  519. return t;
  520. }
  521. struct TmpCounter : public CGVisitor{
  522. int n;
  523. string ident;
  524. TmpCounter( string id ):n(0),ident(id){
  525. }
  526. CGExp *visit( CGExp *e ){
  527. if( CGTmp *t=e->tmp() ){
  528. if( ident==t->ident ) ++n;
  529. }
  530. return e;
  531. }
  532. };
  533. int Val::countTmps( string id ){
  534. if( !cg_exp ) return 0;
  535. TmpCounter cnt( id );
  536. cg_exp->visit( cnt );
  537. return cnt.n;
  538. }
  539. struct TmpRenamer : public CGVisitor{
  540. string ident;
  541. CGExp *cg_exp;
  542. TmpRenamer( string id,CGExp *e ):ident(id),cg_exp(e){
  543. }
  544. CGExp *visit( CGExp *e ){
  545. if( CGTmp *t=e->tmp() ){
  546. if( ident==t->ident ) return cg_exp;
  547. }
  548. return e;
  549. }
  550. };
  551. Val *Val::renameTmps( string id,CGExp *e ){
  552. if( !cg_exp ) return this;
  553. TmpRenamer ren( id,e );
  554. CGExp *t=cg_exp->visit( ren );
  555. return t==cg_exp ? this : new Val(type,t);
  556. }
  557. Val *Val::null( Type *ty ){
  558. return (new Val(Type::null,0))->cast(ty);
  559. }
  560. //*********************** SuperVal *************************
  561. SuperVal::SuperVal( Val *v ):Val(v->type,v->cg_exp){
  562. }
  563. Val *SuperVal::find( string id ){
  564. ObjectType *o=type->objectType();
  565. ClassType *t=o ? o->objectClass() : type->classType();
  566. assert(t);
  567. Val *v=0;
  568. bool method=false;
  569. for( t=t->superClass();t;t=t->superClass() ){
  570. v=t->methods.find(id);
  571. if( !v ) continue;
  572. method=v->type->funType()->method();
  573. if( o || !method ) break;
  574. v=0;
  575. }
  576. if( !v ) badid(id);
  577. if( method ) v=new Val( v->type,vfn(v->cg_exp,cg_exp) );
  578. return v;
  579. }