LEFT | RIGHT |
(no file at all) | |
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 #include "md5.h" | 8 #include "md5.h" |
9 #include "y.tab.h" | 9 #include "y.tab.h" |
10 #include "yerr.h" | 10 #include "yerr.h" |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 n->op = op; | 497 n->op = op; |
498 n->left = nleft; | 498 n->left = nleft; |
499 n->right = nright; | 499 n->right = nright; |
500 n->lineno = parserline(); | 500 n->lineno = parserline(); |
501 n->xoffset = BADWIDTH; | 501 n->xoffset = BADWIDTH; |
502 n->orig = n; | 502 n->orig = n; |
503 n->curfn = curfn; | 503 n->curfn = curfn; |
504 return n; | 504 return n; |
505 } | 505 } |
506 | 506 |
| 507 static int |
| 508 ispaddedfield(Type *t) |
| 509 { |
| 510 if(t->etype != TFIELD) |
| 511 fatal("ispaddedfield called non-field %T", t); |
| 512 return t->down != T && t->width + t->type->width != t->down->width; |
| 513 } |
| 514 |
507 int | 515 int |
508 algtype1(Type *t, Type **bad) | 516 algtype1(Type *t, Type **bad) |
509 { | 517 { |
510 int a, ret; | 518 int a, ret; |
511 Type *t1; | 519 Type *t1; |
512 ········ | 520 ········ |
513 if(bad) | 521 if(bad) |
514 *bad = T; | 522 *bad = T; |
515 | 523 |
516 switch(t->etype) { | 524 switch(t->etype) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 } | 582 } |
575 return -1; // needs special compare | 583 return -1; // needs special compare |
576 | 584 |
577 case TSTRUCT: | 585 case TSTRUCT: |
578 if(t->type != T && t->type->down == T) { | 586 if(t->type != T && t->type->down == T) { |
579 // One-field struct is same as that one field alone. | 587 // One-field struct is same as that one field alone. |
580 return algtype1(t->type->type, bad); | 588 return algtype1(t->type->type, bad); |
581 } | 589 } |
582 ret = AMEM; | 590 ret = AMEM; |
583 for(t1=t->type; t1!=T; t1=t1->down) { | 591 for(t1=t->type; t1!=T; t1=t1->down) { |
584 » » » if(isblanksym(t1->sym)) | 592 » » » // Blank fields and padding must be ignored, |
| 593 » » » // so need special compare. |
| 594 » » » if(isblanksym(t1->sym) || ispaddedfield(t1)) { |
| 595 » » » » ret = -1; |
585 continue; | 596 continue; |
| 597 } |
586 a = algtype1(t1->type, bad); | 598 a = algtype1(t1->type, bad); |
587 if(a == ANOEQ) | 599 if(a == ANOEQ) |
588 return ANOEQ; // not comparable | 600 return ANOEQ; // not comparable |
589 if(a != AMEM) | 601 if(a != AMEM) |
590 ret = -1; // needs special compare | 602 ret = -1; // needs special compare |
591 } | 603 } |
592 return ret; | 604 return ret; |
593 } | 605 } |
594 | 606 |
595 fatal("algtype1: unexpected type %T", t); | 607 fatal("algtype1: unexpected type %T", t); |
(...skipping 2091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2687 n->nbody = list(n->nbody, call); | 2699 n->nbody = list(n->nbody, call); |
2688 | 2700 |
2689 fn->nbody = list(fn->nbody, n); | 2701 fn->nbody = list(fn->nbody, n); |
2690 break; | 2702 break; |
2691 | 2703 |
2692 case TSTRUCT: | 2704 case TSTRUCT: |
2693 // Walk the struct using memhash for runs of AMEM | 2705 // Walk the struct using memhash for runs of AMEM |
2694 // and calling specific hash functions for the others. | 2706 // and calling specific hash functions for the others. |
2695 first = T; | 2707 first = T; |
2696 for(t1=t->type;; t1=t1->down) { | 2708 for(t1=t->type;; t1=t1->down) { |
2697 » » » if(t1 != T && (isblanksym(t1->sym) || algtype1(t1->type,
nil) == AMEM)) { | 2709 » » » if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblan
ksym(t1->sym)) { |
2698 » » » » if(first == T && !isblanksym(t1->sym)) | 2710 » » » » if(first == T) |
2699 first = t1; | 2711 first = t1; |
2700 » » » » continue; | 2712 » » » » // If it's a memory field but it's padded, stop
here. |
| 2713 » » » » if(ispaddedfield(t1)) |
| 2714 » » » » » t1 = t1->down; |
| 2715 » » » » else |
| 2716 » » » » » continue; |
2701 } | 2717 } |
2702 // Run memhash for fields up to this one. | 2718 // Run memhash for fields up to this one. |
2703 while(first != T && isblanksym(first->sym)) | |
2704 first = first->down; | |
2705 if(first != T) { | 2719 if(first != T) { |
2706 if(first->down == t1) | 2720 if(first->down == t1) |
2707 size = first->type->width; | 2721 size = first->type->width; |
2708 else if(t1 == T) | 2722 else if(t1 == T) |
2709 size = t->width - first->width; // firs
t->width is offset | 2723 size = t->width - first->width; // firs
t->width is offset |
2710 else | 2724 else |
2711 size = t1->width - first->width; // bot
h are offsets | 2725 size = t1->width - first->width; // bot
h are offsets |
2712 hashel = hashmem(first->type); | 2726 hashel = hashmem(first->type); |
2713 // hashel(h, size, &p.first) | 2727 // hashel(h, size, &p.first) |
2714 call = nod(OCALL, hashel, N); | 2728 call = nod(OCALL, hashel, N); |
2715 call->list = list(call->list, nh); | 2729 call->list = list(call->list, nh); |
2716 call->list = list(call->list, nodintconst(size))
; | 2730 call->list = list(call->list, nodintconst(size))
; |
2717 nx = nod(OXDOT, np, newname(first->sym)); // TO
DO: fields from other packages? | 2731 nx = nod(OXDOT, np, newname(first->sym)); // TO
DO: fields from other packages? |
2718 na = nod(OADDR, nx, N); | 2732 na = nod(OADDR, nx, N); |
2719 na->etype = 1; // no escape to heap | 2733 na->etype = 1; // no escape to heap |
2720 call->list = list(call->list, na); | 2734 call->list = list(call->list, na); |
2721 fn->nbody = list(fn->nbody, call); | 2735 fn->nbody = list(fn->nbody, call); |
2722 | 2736 |
2723 first = T; | 2737 first = T; |
2724 } | 2738 } |
2725 if(t1 == T) | 2739 if(t1 == T) |
2726 break; | 2740 break; |
| 2741 if(isblanksym(t1->sym)) |
| 2742 continue; |
2727 | 2743 |
2728 // Run hash for this field. | 2744 // Run hash for this field. |
2729 hashel = hashfor(t1->type); | 2745 hashel = hashfor(t1->type); |
2730 // hashel(h, size, &p.t1) | 2746 // hashel(h, size, &p.t1) |
2731 call = nod(OCALL, hashel, N); | 2747 call = nod(OCALL, hashel, N); |
2732 call->list = list(call->list, nh); | 2748 call->list = list(call->list, nh); |
2733 call->list = list(call->list, nodintconst(t1->type->widt
h)); | 2749 call->list = list(call->list, nodintconst(t1->type->widt
h)); |
2734 nx = nod(OXDOT, np, newname(t1->sym)); // TODO: fields
from other packages? | 2750 nx = nod(OXDOT, np, newname(t1->sym)); // TODO: fields
from other packages? |
2735 na = nod(OADDR, nx, N); | 2751 na = nod(OADDR, nx, N); |
2736 na->etype = 1; // no escape to heap | 2752 na->etype = 1; // no escape to heap |
2737 call->list = list(call->list, na); | 2753 call->list = list(call->list, na); |
2738 fn->nbody = list(fn->nbody, call); | 2754 fn->nbody = list(fn->nbody, call); |
2739 } | 2755 } |
| 2756 // make sure body is not empty. |
| 2757 fn->nbody = list(fn->nbody, nod(ORETURN, N, N)); |
2740 break; | 2758 break; |
2741 } | 2759 } |
2742 | 2760 |
2743 if(debug['r']) | 2761 if(debug['r']) |
2744 dumplist("genhash body", fn->nbody); | 2762 dumplist("genhash body", fn->nbody); |
2745 | 2763 |
2746 funcbody(fn); | 2764 funcbody(fn); |
2747 curfn = fn; | 2765 curfn = fn; |
2748 fn->dupok = 1; | 2766 fn->dupok = 1; |
2749 typecheck(&fn, Etop); | 2767 typecheck(&fn, Etop); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2902 nrange->nbody = list(nrange->nbody, nif); | 2920 nrange->nbody = list(nrange->nbody, nif); |
2903 fn->nbody = list(fn->nbody, nrange); | 2921 fn->nbody = list(fn->nbody, nrange); |
2904 | 2922 |
2905 // *eq = true; | 2923 // *eq = true; |
2906 fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool(
1))); | 2924 fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool(
1))); |
2907 break; | 2925 break; |
2908 | 2926 |
2909 case TSTRUCT: | 2927 case TSTRUCT: |
2910 // Walk the struct using memequal for runs of AMEM | 2928 // Walk the struct using memequal for runs of AMEM |
2911 // and calling specific equality tests for the others. | 2929 // and calling specific equality tests for the others. |
| 2930 // Skip blank-named fields. |
2912 first = T; | 2931 first = T; |
2913 for(t1=t->type;; t1=t1->down) { | 2932 for(t1=t->type;; t1=t1->down) { |
2914 » » » if(t1 != T && (isblanksym(t1->sym) || algtype1(t1->type,
nil) == AMEM)) { | 2933 » » » if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblan
ksym(t1->sym)) { |
2915 » » » » if(first == T && !isblanksym(t1->sym)) | 2934 » » » » if(first == T) |
2916 first = t1; | 2935 first = t1; |
2917 » » » » continue; | 2936 » » » » // If it's a memory field but it's padded, stop
here. |
| 2937 » » » » if(ispaddedfield(t1)) |
| 2938 » » » » » t1 = t1->down; |
| 2939 » » » » else |
| 2940 » » » » » continue; |
2918 } | 2941 } |
2919 // Run memequal for fields up to this one. | 2942 // Run memequal for fields up to this one. |
2920 // TODO(rsc): All the calls to newname are wrong for | 2943 // TODO(rsc): All the calls to newname are wrong for |
2921 // cross-package unexported fields. | 2944 // cross-package unexported fields. |
2922 while(first != T && isblanksym(first->sym)) | |
2923 first = first->down; | |
2924 if(first != T) { | 2945 if(first != T) { |
2925 if(first->down == t1) { | 2946 if(first->down == t1) { |
2926 fn->nbody = list(fn->nbody, eqfield(np,
nq, newname(first->sym), neq)); | 2947 fn->nbody = list(fn->nbody, eqfield(np,
nq, newname(first->sym), neq)); |
2927 } else if(first->down->down == t1) { | 2948 } else if(first->down->down == t1) { |
2928 fn->nbody = list(fn->nbody, eqfield(np,
nq, newname(first->sym), neq)); | 2949 fn->nbody = list(fn->nbody, eqfield(np,
nq, newname(first->sym), neq)); |
2929 first = first->down; | 2950 first = first->down; |
2930 if(!isblanksym(first->sym)) | 2951 if(!isblanksym(first->sym)) |
2931 fn->nbody = list(fn->nbody, eqfi
eld(np, nq, newname(first->sym), neq)); | 2952 fn->nbody = list(fn->nbody, eqfi
eld(np, nq, newname(first->sym), neq)); |
2932 } else { | 2953 } else { |
2933 // More than two fields: use memequal. | 2954 // More than two fields: use memequal. |
2934 if(t1 == T) | 2955 if(t1 == T) |
2935 size = t->width - first->width;
// first->width is offset | 2956 size = t->width - first->width;
// first->width is offset |
2936 else | 2957 else |
2937 size = t1->width - first->width;
// both are offsets | 2958 size = t1->width - first->width;
// both are offsets |
2938 fn->nbody = list(fn->nbody, eqmem(np, nq
, newname(first->sym), size, neq)); | 2959 fn->nbody = list(fn->nbody, eqmem(np, nq
, newname(first->sym), size, neq)); |
2939 } | 2960 } |
2940 first = T; | 2961 first = T; |
2941 } | 2962 } |
2942 if(t1 == T) | 2963 if(t1 == T) |
2943 break; | 2964 break; |
| 2965 if(isblanksym(t1->sym)) |
| 2966 continue; |
2944 | 2967 |
2945 // Check this field, which is not just memory. | 2968 // Check this field, which is not just memory. |
2946 fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1->
sym), neq)); | 2969 fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1->
sym), neq)); |
2947 } | 2970 } |
2948 | 2971 |
2949 // *eq = true; | 2972 // *eq = true; |
2950 fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool(
1))); | 2973 fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool(
1))); |
2951 break; | 2974 break; |
2952 } | 2975 } |
2953 | 2976 |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3670 yyerror("import path contains space character: \"%Z\"",
path); | 3693 yyerror("import path contains space character: \"%Z\"",
path); |
3671 return 1; | 3694 return 1; |
3672 } | 3695 } |
3673 if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}", r)) { | 3696 if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}", r)) { |
3674 yyerror("import path contains invalid character '%C': \"
%Z\"", r, path); | 3697 yyerror("import path contains invalid character '%C': \"
%Z\"", r, path); |
3675 return 1; | 3698 return 1; |
3676 } | 3699 } |
3677 } | 3700 } |
3678 return 0; | 3701 return 0; |
3679 } | 3702 } |
LEFT | RIGHT |