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 "runtime.h" | 5 #include "runtime.h" |
6 #include "arch.h" | 6 #include "arch.h" |
7 #include "type.h" | 7 #include "type.h" |
8 #include "malloc.h" | 8 #include "malloc.h" |
9 | 9 |
10 enum· | 10 enum· |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 runtime·atomicstorep(&hash[h], m); | 152 runtime·atomicstorep(&hash[h], m); |
153 runtime·unlock(&ifacelock); | 153 runtime·unlock(&ifacelock); |
154 if(m->bad) | 154 if(m->bad) |
155 return nil; | 155 return nil; |
156 return m; | 156 return m; |
157 } | 157 } |
158 | 158 |
159 static void | 159 static void |
160 copyin(Type *t, void *src, void **dst) | 160 copyin(Type *t, void *src, void **dst) |
161 { | 161 { |
162 » int32 wid, alg; | 162 » uintptr size; |
163 void *p; | 163 void *p; |
164 | 164 » Alg *alg; |
165 » wid = t->size; | 165 |
| 166 » size = t->size; |
166 alg = t->alg; | 167 alg = t->alg; |
167 | 168 |
168 » if(wid <= sizeof(*dst)) | 169 » if(size <= sizeof(*dst)) |
169 » » runtime·algarray[alg].copy(wid, dst, src); | 170 » » alg->copy(size, dst, src); |
170 else { | 171 else { |
171 » » p = runtime·mal(wid); | 172 » » p = runtime·mal(size); |
172 » » runtime·algarray[alg].copy(wid, p, src); | 173 » » alg->copy(size, p, src); |
173 *dst = p; | 174 *dst = p; |
174 } | 175 } |
175 } | 176 } |
176 | 177 |
177 static void | 178 static void |
178 copyout(Type *t, void **src, void *dst) | 179 copyout(Type *t, void **src, void *dst) |
179 { | 180 { |
180 » int32 wid, alg; | 181 » uintptr size; |
181 | 182 » Alg *alg; |
182 » wid = t->size; | 183 |
| 184 » size = t->size; |
183 alg = t->alg; | 185 alg = t->alg; |
184 | 186 |
185 » if(wid <= sizeof(*src)) | 187 » if(size <= sizeof(*src)) |
186 » » runtime·algarray[alg].copy(wid, dst, src); | 188 » » alg->copy(size, dst, src); |
187 else | 189 else |
188 » » runtime·algarray[alg].copy(wid, dst, *src); | 190 » » alg->copy(size, dst, *src); |
189 } | 191 } |
190 | 192 |
191 // func convT2I(typ *byte, typ2 *byte, elem any) (ret any) | 193 // func convT2I(typ *byte, typ2 *byte, elem any) (ret any) |
192 #pragma textflag 7 | 194 #pragma textflag 7 |
193 void | 195 void |
194 runtime·convT2I(Type *t, InterfaceType *inter, ...) | 196 runtime·convT2I(Type *t, InterfaceType *inter, ...) |
195 { | 197 { |
196 byte *elem; | 198 byte *elem; |
197 Iface *ret; | 199 Iface *ret; |
198 int32 wid; | 200 int32 wid; |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 USED(inter); | 543 USED(inter); |
542 ret = e; | 544 ret = e; |
543 ok = e.type != nil; | 545 ok = e.type != nil; |
544 FLUSH(&ret); | 546 FLUSH(&ret); |
545 FLUSH(&ok); | 547 FLUSH(&ok); |
546 } | 548 } |
547 | 549 |
548 static uintptr | 550 static uintptr |
549 ifacehash1(void *data, Type *t) | 551 ifacehash1(void *data, Type *t) |
550 { | 552 { |
551 » int32 alg, wid; | 553 » Alg *alg; |
| 554 » uintptr size, h; |
552 Eface err; | 555 Eface err; |
553 | 556 |
554 if(t == nil) | 557 if(t == nil) |
555 return 0; | 558 return 0; |
556 | 559 |
557 alg = t->alg; | 560 alg = t->alg; |
558 » wid = t->size; | 561 » size = t->size; |
559 » if(runtime·algarray[alg].hash == runtime·nohash) { | 562 » if(alg->hash == runtime·nohash) { |
560 // calling nohash will panic too, | 563 // calling nohash will panic too, |
561 // but we can print a better error. | 564 // but we can print a better error. |
562 runtime·newErrorString(runtime·catstring(runtime·gostringnocopy(
(byte*)"hash of unhashable type "), *t->string), &err); | 565 runtime·newErrorString(runtime·catstring(runtime·gostringnocopy(
(byte*)"hash of unhashable type "), *t->string), &err); |
563 runtime·panic(err); | 566 runtime·panic(err); |
564 } | 567 } |
565 » if(wid <= sizeof(data)) | 568 » h = 0; |
566 » » return runtime·algarray[alg].hash(wid, &data); | 569 » if(size <= sizeof(data)) |
567 » return runtime·algarray[alg].hash(wid, data); | 570 » » alg->hash(&h, size, &data); |
| 571 » else |
| 572 » » alg->hash(&h, size, data); |
| 573 » return h; |
568 } | 574 } |
569 | 575 |
570 uintptr | 576 uintptr |
571 runtime·ifacehash(Iface a) | 577 runtime·ifacehash(Iface a) |
572 { | 578 { |
573 if(a.tab == nil) | 579 if(a.tab == nil) |
574 return 0; | 580 return 0; |
575 return ifacehash1(a.data, a.tab->type); | 581 return ifacehash1(a.data, a.tab->type); |
576 } | 582 } |
577 | 583 |
578 uintptr | 584 uintptr |
579 runtime·efacehash(Eface a) | 585 runtime·efacehash(Eface a) |
580 { | 586 { |
581 return ifacehash1(a.data, a.type); | 587 return ifacehash1(a.data, a.type); |
582 } | 588 } |
583 | 589 |
584 static bool | 590 static bool |
585 ifaceeq1(void *data1, void *data2, Type *t) | 591 ifaceeq1(void *data1, void *data2, Type *t) |
586 { | 592 { |
587 » int32 alg, wid; | 593 » uintptr size; |
| 594 » Alg *alg; |
588 Eface err; | 595 Eface err; |
| 596 bool eq; |
589 | 597 |
590 alg = t->alg; | 598 alg = t->alg; |
591 » wid = t->size; | 599 » size = t->size; |
592 | 600 |
593 » if(runtime·algarray[alg].equal == runtime·noequal) { | 601 » if(alg->equal == runtime·noequal) { |
594 // calling noequal will panic too, | 602 // calling noequal will panic too, |
595 // but we can print a better error. | 603 // but we can print a better error. |
596 runtime·newErrorString(runtime·catstring(runtime·gostringnocopy(
(byte*)"comparing uncomparable type "), *t->string), &err); | 604 runtime·newErrorString(runtime·catstring(runtime·gostringnocopy(
(byte*)"comparing uncomparable type "), *t->string), &err); |
597 runtime·panic(err); | 605 runtime·panic(err); |
598 } | 606 } |
599 | 607 |
600 » if(wid <= sizeof(data1)) | 608 » eq = 0; |
601 » » return runtime·algarray[alg].equal(wid, &data1, &data2); | 609 » if(size <= sizeof(data1)) |
602 » return runtime·algarray[alg].equal(wid, data1, data2); | 610 » » alg->equal(&eq, size, &data1, &data2); |
| 611 » else |
| 612 » » alg->equal(&eq, size, data1, data2); |
| 613 » return eq; |
603 } | 614 } |
604 | 615 |
605 bool | 616 bool |
606 runtime·ifaceeq_c(Iface i1, Iface i2) | 617 runtime·ifaceeq_c(Iface i1, Iface i2) |
607 { | 618 { |
608 if(i1.tab != i2.tab) | 619 if(i1.tab != i2.tab) |
609 return false; | 620 return false; |
610 if(i1.tab == nil) | 621 if(i1.tab == nil) |
611 return true; | 622 return true; |
612 return ifaceeq1(i1.data, i2.data, i1.tab->type); | 623 return ifaceeq1(i1.data, i2.data, i1.tab->type); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 runtime·throw("invalid interface value"); | 705 runtime·throw("invalid interface value"); |
695 if(e.type == nil) { | 706 if(e.type == nil) { |
696 rettype.type = nil; | 707 rettype.type = nil; |
697 rettype.data = nil; | 708 rettype.data = nil; |
698 retaddr = 0; | 709 retaddr = 0; |
699 } else { | 710 } else { |
700 rettype = *(Eface*)e.type; | 711 rettype = *(Eface*)e.type; |
701 if(e.type->size <= sizeof(uintptr)) { | 712 if(e.type->size <= sizeof(uintptr)) { |
702 // Copy data into x ... | 713 // Copy data into x ... |
703 x = 0; | 714 x = 0; |
704 » » » runtime·algarray[e.type->alg].copy(e.type->size, &x, &e.
data); | 715 » » » e.type->alg->copy(e.type->size, &x, &e.data); |
705 | 716 |
706 // but then build pointer to x so that Reflect | 717 // but then build pointer to x so that Reflect |
707 // always returns pointer to data. | 718 // always returns pointer to data. |
708 p = runtime·mal(sizeof(uintptr)); | 719 p = runtime·mal(sizeof(uintptr)); |
709 *p = x; | 720 *p = x; |
710 } else { | 721 } else { |
711 // Already a pointer, but still make a copy, | 722 // Already a pointer, but still make a copy, |
712 // to preserve value semantics for interface data. | 723 // to preserve value semantics for interface data. |
713 p = runtime·mal(e.type->size); | 724 p = runtime·mal(e.type->size); |
714 » » » runtime·algarray[e.type->alg].copy(e.type->size, p, e.da
ta); | 725 » » » e.type->alg->copy(e.type->size, p, e.data); |
715 } | 726 } |
716 retaddr = p; | 727 retaddr = p; |
717 } | 728 } |
718 FLUSH(&rettype); | 729 FLUSH(&rettype); |
719 FLUSH(&retaddr); | 730 FLUSH(&retaddr); |
720 } | 731 } |
721 | 732 |
722 void | 733 void |
723 unsafe·Unreflect(Eface typ, void *addr, Eface e) | 734 unsafe·Unreflect(Eface typ, void *addr, Eface e) |
724 { | 735 { |
725 if(((uintptr)typ.type&reflectFlags) != 0) | 736 if(((uintptr)typ.type&reflectFlags) != 0) |
726 runtime·throw("invalid interface value"); | 737 runtime·throw("invalid interface value"); |
727 | 738 |
728 // Reflect library has reinterpreted typ | 739 // Reflect library has reinterpreted typ |
729 // as its own kind of type structure. | 740 // as its own kind of type structure. |
730 // We know that the pointer to the original | 741 // We know that the pointer to the original |
731 // type structure sits before the data pointer. | 742 // type structure sits before the data pointer. |
732 e.type = (Type*)((Eface*)typ.data-1); | 743 e.type = (Type*)((Eface*)typ.data-1); |
733 | 744 |
734 // Interface holds either pointer to data | 745 // Interface holds either pointer to data |
735 // or copy of original data. | 746 // or copy of original data. |
736 if(e.type->size <= sizeof(uintptr)) | 747 if(e.type->size <= sizeof(uintptr)) |
737 » » runtime·algarray[e.type->alg].copy(e.type->size, &e.data, addr); | 748 » » e.type->alg->copy(e.type->size, &e.data, addr); |
738 else { | 749 else { |
739 // Easier: already a pointer to data. | 750 // Easier: already a pointer to data. |
740 // TODO(rsc): Should this make a copy? | 751 // TODO(rsc): Should this make a copy? |
741 e.data = addr; | 752 e.data = addr; |
742 } | 753 } |
743 | 754 |
744 FLUSH(&e); | 755 FLUSH(&e); |
745 } | 756 } |
746 | 757 |
747 void | 758 void |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 // type structure sits before the data pointer. | 791 // type structure sits before the data pointer. |
781 t = (Type*)((Eface*)typ.data-1); | 792 t = (Type*)((Eface*)typ.data-1); |
782 ········ | 793 ········ |
783 size = n*t->size; | 794 size = n*t->size; |
784 if(t->kind&KindNoPointers) | 795 if(t->kind&KindNoPointers) |
785 ret = runtime·mallocgc(size, FlagNoPointers, 1, 1); | 796 ret = runtime·mallocgc(size, FlagNoPointers, 1, 1); |
786 else | 797 else |
787 ret = runtime·mal(size); | 798 ret = runtime·mal(size); |
788 FLUSH(&ret); | 799 FLUSH(&ret); |
789 } | 800 } |
LEFT | RIGHT |