Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 2735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2746 n++; | 2746 n++; |
2747 return n; | 2747 return n; |
2748 } | 2748 } |
2749 | 2749 |
2750 static void | 2750 static void |
2751 walkcompare(Node **np, NodeList **init) | 2751 walkcompare(Node **np, NodeList **init) |
2752 { | 2752 { |
2753 Node *n, *l, *r, *fn, *call, *a, *li, *ri, *expr; | 2753 Node *n, *l, *r, *fn, *call, *a, *li, *ri, *expr; |
2754 int andor, i; | 2754 int andor, i; |
2755 Type *t, *t1; | 2755 Type *t, *t1; |
2756 » Node *tempbool; | 2756 » static Node *tempbool; |
2757 ········ | 2757 ········ |
2758 n = *np; | 2758 n = *np; |
2759 ········ | 2759 ········ |
2760 // Must be comparison of array or struct. | 2760 // Must be comparison of array or struct. |
2761 // Otherwise back end handles it. | 2761 // Otherwise back end handles it. |
2762 t = n->left->type; | 2762 t = n->left->type; |
2763 switch(t->etype) { | 2763 switch(t->etype) { |
2764 default: | 2764 default: |
2765 return; | 2765 return; |
2766 case TARRAY: | 2766 case TARRAY: |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2835 expr->type = n->type; | 2835 expr->type = n->type; |
2836 *np = expr; | 2836 *np = expr; |
2837 return; | 2837 return; |
2838 } | 2838 } |
2839 ········ | 2839 ········ |
2840 // Chose not to inline, but still have addresses. | 2840 // Chose not to inline, but still have addresses. |
2841 // Call equality function directly. | 2841 // Call equality function directly. |
2842 // The equality function requires a bool pointer for | 2842 // The equality function requires a bool pointer for |
2843 // storing its address, because it has to be callable | 2843 // storing its address, because it has to be callable |
2844 // from C, and C can't access an ordinary Go return value. | 2844 // from C, and C can't access an ordinary Go return value. |
2845 » tempbool = temp(types[TBOOL]); | 2845 » // To avoid creating many temporaries, cache one per function. |
2846 » if(tempbool == N || tempbool->curfn != curfn) | |
2847 » » tempbool = temp(types[TBOOL]); | |
2846 ········ | 2848 ········ |
2847 call = nod(OCALL, eqfor(t), N); | 2849 call = nod(OCALL, eqfor(t), N); |
2848 a = nod(OADDR, tempbool, N); | 2850 a = nod(OADDR, tempbool, N); |
2849 a->etype = 1; // does not escape | 2851 a->etype = 1; // does not escape |
2850 call->list = list(call->list, a); | 2852 call->list = list(call->list, a); |
2851 call->list = list(call->list, nodintconst(t->width)); | 2853 call->list = list(call->list, nodintconst(t->width)); |
2852 call->list = list(call->list, l); | 2854 call->list = list(call->list, l); |
2853 call->list = list(call->list, r); | 2855 call->list = list(call->list, r); |
2854 typecheck(&call, Etop); | 2856 typecheck(&call, Etop); |
2855 walkstmt(&call); | 2857 walkstmt(&call); |
2856 *init = list(*init, call); | 2858 *init = list(*init, call); |
DMorsing
2013/03/31 10:16:01
Make a new temporary and put a nod(OAS, newtemp, t
| |
2857 »······· | 2859 |
2858 » if(n->op == OEQ) | 2860 » // tempbool cannot be used directly as multiple comparison |
2859 » » r = tempbool; | 2861 » // expressions may exist in the same statement. Create another |
DMorsing
2013/03/31 10:16:01
use newtemp here and below.
| |
2860 » else | 2862 » // temporary to hold the value (its address is not taken so it can |
2861 » » r = nod(ONOT, tempbool, N); | 2863 » // be optimized away). |
2864 » r = temp(types[TBOOL]); | |
2865 » a = nod(OAS, r, tempbool); | |
2866 » typecheck(&a, Etop); | |
2867 » walkstmt(&a); | |
2868 » *init = list(*init, a); | |
2869 | |
2870 » if(n->op != OEQ) | |
2871 » » r = nod(ONOT, r, N); | |
2862 typecheck(&r, Erv); | 2872 typecheck(&r, Erv); |
2863 walkexpr(&r, init); | 2873 walkexpr(&r, init); |
2864 *np = r; | 2874 *np = r; |
2865 return; | 2875 return; |
2866 | 2876 |
2867 hard: | 2877 hard: |
2868 // Cannot take address of one or both of the operands. | 2878 // Cannot take address of one or both of the operands. |
2869 // Instead, pass directly to runtime helper function. | 2879 // Instead, pass directly to runtime helper function. |
2870 // Easier on the stack than passing the address | 2880 // Easier on the stack than passing the address |
2871 // of temporary variables, because we are better at reusing | 2881 // of temporary variables, because we are better at reusing |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3464 !candiscardlist(n->ninit) || | 3474 !candiscardlist(n->ninit) || |
3465 !candiscardlist(n->nbody) || | 3475 !candiscardlist(n->nbody) || |
3466 !candiscardlist(n->nelse) || | 3476 !candiscardlist(n->nelse) || |
3467 !candiscardlist(n->list) || | 3477 !candiscardlist(n->list) || |
3468 !candiscardlist(n->rlist)) { | 3478 !candiscardlist(n->rlist)) { |
3469 return 0; | 3479 return 0; |
3470 } | 3480 } |
3471 ········ | 3481 ········ |
3472 return 1; | 3482 return 1; |
3473 } | 3483 } |
LEFT | RIGHT |