OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include <u.h> | 5 #include <u.h> |
6 #include <libc.h> | 6 #include <libc.h> |
7 #include "go.h" | 7 #include "go.h" |
8 | 8 |
9 static Node* walkprint(Node*, NodeList**, int); | 9 static Node* walkprint(Node*, NodeList**, int); |
10 static Node* mapfn(char*, Type*); | 10 static Node* mapfn(char*, Type*); |
(...skipping 3153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3164 li = nod(OINDEX, l, nodintconst(i)); | 3164 li = nod(OINDEX, l, nodintconst(i)); |
3165 ri = nod(OINDEX, r, nodintconst(i)); | 3165 ri = nod(OINDEX, r, nodintconst(i)); |
3166 a = nod(n->op, li, ri); | 3166 a = nod(n->op, li, ri); |
3167 if(expr == N) | 3167 if(expr == N) |
3168 expr = a; | 3168 expr = a; |
3169 else | 3169 else |
3170 expr = nod(andor, expr, a); | 3170 expr = nod(andor, expr, a); |
3171 } | 3171 } |
3172 if(expr == N) | 3172 if(expr == N) |
3173 expr = nodbool(n->op == OEQ); | 3173 expr = nodbool(n->op == OEQ); |
3174 » » typecheck(&expr, Erv); | 3174 » » r = expr; |
3175 » » walkexpr(&expr, init); | 3175 » » goto ret; |
3176 » » expr->type = n->type; | |
3177 » » *np = expr; | |
3178 » » return; | |
3179 } | 3176 } |
3180 » | 3177 |
3181 if(t->etype == TSTRUCT && countfield(t) <= 4) { | 3178 if(t->etype == TSTRUCT && countfield(t) <= 4) { |
3182 // Struct of four or fewer fields. | 3179 // Struct of four or fewer fields. |
3183 // Inline comparisons. | 3180 // Inline comparisons. |
3184 for(t1=t->type; t1; t1=t1->down) { | 3181 for(t1=t->type; t1; t1=t1->down) { |
3185 if(isblanksym(t1->sym)) | 3182 if(isblanksym(t1->sym)) |
3186 continue; | 3183 continue; |
3187 li = nod(OXDOT, l, newname(t1->sym)); | 3184 li = nod(OXDOT, l, newname(t1->sym)); |
3188 ri = nod(OXDOT, r, newname(t1->sym)); | 3185 ri = nod(OXDOT, r, newname(t1->sym)); |
3189 a = nod(n->op, li, ri); | 3186 a = nod(n->op, li, ri); |
3190 if(expr == N) | 3187 if(expr == N) |
3191 expr = a; | 3188 expr = a; |
3192 else | 3189 else |
3193 expr = nod(andor, expr, a); | 3190 expr = nod(andor, expr, a); |
3194 } | 3191 } |
3195 if(expr == N) | 3192 if(expr == N) |
3196 expr = nodbool(n->op == OEQ); | 3193 expr = nodbool(n->op == OEQ); |
3197 » » typecheck(&expr, Erv); | 3194 » » r = expr; |
3198 » » walkexpr(&expr, init); | 3195 » » goto ret; |
3199 » » expr->type = n->type; | |
3200 » » *np = expr; | |
3201 » » return; | |
3202 } | 3196 } |
3203 » | 3197 |
3204 // Chose not to inline, but still have addresses. | 3198 // Chose not to inline, but still have addresses. |
3205 // Call equality function directly. | 3199 // Call equality function directly. |
3206 // The equality function requires a bool pointer for | 3200 // The equality function requires a bool pointer for |
3207 // storing its address, because it has to be callable | 3201 // storing its address, because it has to be callable |
3208 // from C, and C can't access an ordinary Go return value. | 3202 // from C, and C can't access an ordinary Go return value. |
3209 // To avoid creating many temporaries, cache one per function. | 3203 // To avoid creating many temporaries, cache one per function. |
3210 if(tempbool == N || tempbool->curfn != curfn) | 3204 if(tempbool == N || tempbool->curfn != curfn) |
3211 tempbool = temp(types[TBOOL]); | 3205 tempbool = temp(types[TBOOL]); |
3212 ········ | 3206 ········ |
3213 call = nod(OCALL, eqfor(t), N); | 3207 call = nod(OCALL, eqfor(t), N); |
(...skipping 12 matching lines...) Expand all Loading... |
3226 // temporary to hold the value (its address is not taken so it can | 3220 // temporary to hold the value (its address is not taken so it can |
3227 // be optimized away). | 3221 // be optimized away). |
3228 r = temp(types[TBOOL]); | 3222 r = temp(types[TBOOL]); |
3229 a = nod(OAS, r, tempbool); | 3223 a = nod(OAS, r, tempbool); |
3230 typecheck(&a, Etop); | 3224 typecheck(&a, Etop); |
3231 walkstmt(&a); | 3225 walkstmt(&a); |
3232 *init = list(*init, a); | 3226 *init = list(*init, a); |
3233 | 3227 |
3234 if(n->op != OEQ) | 3228 if(n->op != OEQ) |
3235 r = nod(ONOT, r, N); | 3229 r = nod(ONOT, r, N); |
3236 » typecheck(&r, Erv); | 3230 » goto ret; |
3237 » walkexpr(&r, init); | |
3238 » *np = r; | |
3239 » return; | |
3240 | 3231 |
3241 hard: | 3232 hard: |
3242 // Cannot take address of one or both of the operands. | 3233 // Cannot take address of one or both of the operands. |
3243 // Instead, pass directly to runtime helper function. | 3234 // Instead, pass directly to runtime helper function. |
3244 // Easier on the stack than passing the address | 3235 // Easier on the stack than passing the address |
3245 // of temporary variables, because we are better at reusing | 3236 // of temporary variables, because we are better at reusing |
3246 // the argument space than temporary variable space. | 3237 // the argument space than temporary variable space. |
3247 fn = syslook("equal", 1); | 3238 fn = syslook("equal", 1); |
3248 l = n->left; | 3239 l = n->left; |
3249 r = n->right; | 3240 r = n->right; |
3250 argtype(fn, n->left->type); | 3241 argtype(fn, n->left->type); |
3251 argtype(fn, n->left->type); | 3242 argtype(fn, n->left->type); |
3252 r = mkcall1(fn, n->type, init, typename(n->left->type), l, r); | 3243 r = mkcall1(fn, n->type, init, typename(n->left->type), l, r); |
3253 if(n->op == ONE) { | 3244 if(n->op == ONE) { |
3254 r = nod(ONOT, r, N); | 3245 r = nod(ONOT, r, N); |
3255 » » typecheck(&r, Erv); | 3246 » } |
| 3247 » goto ret; |
| 3248 |
| 3249 ret: |
| 3250 » typecheck(&r, Erv); |
| 3251 » walkexpr(&r, init); |
| 3252 » if(r->type != n->type) { |
| 3253 » » r = nod(OCONVNOP, r, N); |
| 3254 » » r->type = n->type; |
| 3255 » » r->typecheck = 1; |
3256 } | 3256 } |
3257 *np = r; | 3257 *np = r; |
3258 return; | 3258 return; |
3259 } | 3259 } |
3260 | 3260 |
3261 static int | 3261 static int |
3262 samecheap(Node *a, Node *b) | 3262 samecheap(Node *a, Node *b) |
3263 { | 3263 { |
3264 Node *ar, *br; | 3264 Node *ar, *br; |
3265 while(a != N && b != N && a->op == b->op) { | 3265 while(a != N && b != N && a->op == b->op) { |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3853 !candiscardlist(n->ninit) || | 3853 !candiscardlist(n->ninit) || |
3854 !candiscardlist(n->nbody) || | 3854 !candiscardlist(n->nbody) || |
3855 !candiscardlist(n->nelse) || | 3855 !candiscardlist(n->nelse) || |
3856 !candiscardlist(n->list) || | 3856 !candiscardlist(n->list) || |
3857 !candiscardlist(n->rlist)) { | 3857 !candiscardlist(n->rlist)) { |
3858 return 0; | 3858 return 0; |
3859 } | 3859 } |
3860 ········ | 3860 ········ |
3861 return 1; | 3861 return 1; |
3862 } | 3862 } |
OLD | NEW |