1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "runtime.h"
6 #include "type.h"
7 #include "malloc.h"
8
9 enum
10 {
11 // If an empty interface has these bits set in its type
12 // pointer, it was copied from a reflect.Value and is
13 // not a valid empty interface.
14 reflectFlags = 3,
15 };
16
17 void
18 runtime·printiface(Iface i)
19 {
20 runtime·printf("(%p,%p)", i.tab, i.data);
21 }
22
23 void
24 runtime·printeface(Eface e)
25 {
26 runtime·printf("(%p,%p)", e.type, e.data);
27 }
28
29 /*
30 * layout of Itab known to compilers
31 */
32 struct Itab
33 {
34 InterfaceType* inter;
35 Type* type;
36 Itab* link;
37 int32 bad;
38 int32 unused;
39 void (*fun[])(void);
40 };
41
42 static Itab* hash[1009];
43 static Lock ifacelock;
44
45 static Itab*
46 itab(InterfaceType *inter, Type *type, int32 canfail)
47 {
48 int32 locked;
49 int32 ni;
50 Method *t, *et;
51 IMethod *i, *ei;
52 uint32 h;
53 String *iname, *ipkgPath;
54 Itab *m;
55 UncommonType *x;
56 Type *itype;
57 Eface err;
58
59 if(inter->mhdr.len == 0)
60 runtime·throw("internal error - misuse of itab");
61
62 locked = 0;
63
64 // easy case
65 x = type->x;
66 if(x == nil) {
67 if(canfail)
68 return nil;
69 iname = inter->m[0].name;
70 goto throw;
71 }
72
73 // compiler has provided some good hash codes for us.
74 h = inter->hash;
75 h += 17 * type->hash;
76 // TODO(rsc): h += 23 * x->mhash ?
77 h %= nelem(hash);
78
79 // look twice - once without lock, once with.
80 // common case will be no lock contention.
81 for(locked=0; locked<2; locked++) {
82 if(locked)
83 runtime·lock(&ifacelock);
84 for(m=runtime·atomicloadp(&hash[h]); m!=nil; m=m->link) {
85 if(m->inter == inter && m->type == type) {
86 if(m->bad) {
87 m = nil;
88 if(!canfail) {
89 // this can only happen if the conversion
90 // was already done once using the , ok form
91 // and we have a cached negative result.
92 // the cached result doesn't record which
93 // interface function was missing, so jump
94 // down to the interface check, which will
95 // do more work but give a better error.
96 goto search;
97 }
98 }
99 if(locked)
100 runtime·unlock(&ifacelock);
101 return m;
102 }
103 }
104 }
105
106 ni = inter->mhdr.len;
107 m = runtime·malloc(sizeof(*m) + ni*sizeof m->fun[0]);
108 m->inter = inter;
109 m->type = type;
110
111 search:
112 // both inter and type have method sorted by name,
113 // and interface names are unique,
114 // so can iterate over both in lock step;
115 // the loop is O(ni+nt) not O(ni*nt).
116 i = inter->m;
117 ei = i + inter->mhdr.len;
118 t = x->m;
119 et = t + x->mhdr.len;
120 for(; i < ei; i++) {
121 itype = i->type;
122 iname = i->name;
123 ipkgPath = i->pkgPath;
124 for(;; t++) {
125 if(t >= et) {
126 if(!canfail) {
127 throw:
128 // didn't find method
129 runtime·newTypeAssertionError(nil, type, inter,
130 nil, type->string, inter->string,
131 iname, &err);
132 if(locked)
133 runtime·unlock(&ifacelock);
134 runtime·panic(err);
135 return nil; // not reached
136 }
137 m->bad = 1;
138 goto out;
139 }
140 if(t->mtyp == itype && t->name == iname && t->pkgPath == ipkgPath)
141 break;
142 }
143 if(m)
144 m->fun[i - inter->m] = t->ifn;
145 }
146
147 out:
148 if(!locked)
149 runtime·panicstring("invalid itab locking");
150 m->link = hash[h];
151 runtime·atomicstorep(&hash[h], m);
152 runtime·unlock(&ifacelock);
153 if(m->bad)
154 return nil;
155 return m;
156 }
157
158 static void
159 copyin(Type *t, void *src, void **dst)
160 {
161 int32 wid, alg;
162 void *p;
163
164 wid = t->size;
165 alg = t->alg;
166
167 if(wid <= sizeof(*dst))
168 runtime·algarray[alg].copy(wid, dst, src);
169 else {
170 p = runtime·mal(wid);
171 runtime·algarray[alg].copy(wid, p, src);
172 *dst = p;
173 }
174 }
175
176 static void
177 copyout(Type *t, void **src, void *dst)
178 {
179 int32 wid, alg;
180
181 wid = t->size;
182 alg = t->alg;
183
184 if(wid <= sizeof(*src))
185 runtime·algarray[alg].copy(wid, dst, src);
186 else
187 runtime·algarray[alg].copy(wid, dst, *src);
188 }
189
190 // func convT2I(typ *byte, typ2 *byte, elem any) (ret any)
191 #pragma textflag 7
192 void
193 runtime·convT2I(Type *t, InterfaceType *inter, ...)
194 {
195 byte *elem;
196 Iface *ret;
197 int32 wid;
198
199 elem = (byte*)(&inter+1);
200 wid = t->size;
201 ret = (Iface*)(elem + runtime·rnd(wid, Structrnd));
202 ret->tab = itab(inter, t, 0);
203 copyin(t, elem, &ret->data);
204 }
205
206 // func convT2E(typ *byte, elem any) (ret any)
207 #pragma textflag 7
208 void
209 runtime·convT2E(Type *t, ...)
210 {
211 byte *elem;
212 Eface *ret;
213 int32 wid;
214
215 elem = (byte*)(&t+1);
216 wid = t->size;
217 ret = (Eface*)(elem + runtime·rnd(wid, Structrnd));
218 ret->type = t;
219 copyin(t, elem, &ret->data);
220 }
221
222 static void assertI2Tret(Type *t, Iface i, byte *ret);
223
224 // func ifaceI2T(typ *byte, iface any) (ret any)
225 #pragma textflag 7
226 void
227 runtime·assertI2T(Type *t, Iface i, ...)
228 {
229 byte *ret;
230
231 ret = (byte*)(&i+1);
232 assertI2Tret(t, i, ret);
233 }
234
235 static void
236 assertI2Tret(Type *t, Iface i, byte *ret)
237 {
238 Itab *tab;
239 Eface err;
240
241 tab = i.tab;
242 if(tab == nil) {
243 runtime·newTypeAssertionError(nil, nil, t,
244 nil, nil, t->string,
245 nil, &err);
246 runtime·panic(err);
247 }
248 if(tab->type != t) {
249 runtime·newTypeAssertionError(tab->inter, tab->type, t,
250 tab->inter->string, tab->type->string, t->string,
251 nil, &err);
252 runtime·panic(err);
253 }
254 copyout(t, &i.data, ret);
255 }
256
257 // func ifaceI2T2(typ *byte, iface any) (ret any, ok bool)
258 #pragma textflag 7
259 void
260 runtime·assertI2T2(Type *t, Iface i, ...)
261 {
262 byte *ret;
263 bool *ok;
264 int32 wid;
265
266 ret = (byte*)(&i+1);
267 wid = t->size;
268 ok = (bool*)(ret + wid);
269
270 if(i.tab == nil || i.tab->type != t) {
271 *ok = false;
272 runtime·memclr(ret, wid);
273 return;
274 }
275
276 *ok = true;
277 copyout(t, &i.data, ret);
278 }
279
280 static void assertE2Tret(Type *t, Eface e, byte *ret);
281
282 // func ifaceE2T(typ *byte, iface any) (ret any)
283 #pragma textflag 7
284 void
285 runtime·assertE2T(Type *t, Eface e, ...)
286 {
287 byte *ret;
288
289 if(((uintptr)e.type&reflectFlags) != 0)
290 runtime·throw("invalid interface value");
291 ret = (byte*)(&e+1);
292 assertE2Tret(t, e, ret);
293 }
294
295 static void
296 assertE2Tret(Type *t, Eface e, byte *ret)
297 {
298 Eface err;
299
300 if(((uintptr)e.type&reflectFlags) != 0)
301 runtime·throw("invalid interface value");
302 if(e.type == nil) {
303 runtime·newTypeAssertionError(nil, nil, t,
304 nil, nil, t->string,
305 nil, &err);
306 runtime·panic(err);
307 }
308 if(e.type != t) {
309 runtime·newTypeAssertionError(nil, e.type, t,
310 nil, e.type->string, t->string,
311 nil, &err);
312 runtime·panic(err);
313 }
314 copyout(t, &e.data, ret);
315 }
316
317 // func ifaceE2T2(sigt *byte, iface any) (ret any, ok bool);
318 #pragma textflag 7
319 void
320 runtime·assertE2T2(Type *t, Eface e, ...)
321 {
322 byte *ret;
323 bool *ok;
324 int32 wid;
325
326 if(((uintptr)e.type&reflectFlags) != 0)
327 runtime·throw("invalid interface value");
328 ret = (byte*)(&e+1);
329 wid = t->size;
330 ok = (bool*)(ret + wid);
331
332 if(t != e.type) {
333 *ok = false;
334 runtime·memclr(ret, wid);
335 return;
336 }
337
338 *ok = true;
339 copyout(t, &e.data, ret);
340 }
341
342 // func convI2E(elem any) (ret any)
343 void
344 runtime·convI2E(Iface i, Eface ret)
345 {
346 Itab *tab;
347
348 ret.data = i.data;
349 if((tab = i.tab) == nil)
350 ret.type = nil;
351 else
352 ret.type = tab->type;
353 FLUSH(&ret);
354 }
355
356 // func ifaceI2E(typ *byte, iface any) (ret any)
357 void
358 runtime·assertI2E(InterfaceType* inter, Iface i, Eface ret)
359 {
360 Itab *tab;
361 Eface err;
362
363 tab = i.tab;
364 if(tab == nil) {
365 // explicit conversions require non-nil interface value.
366 runtime·newTypeAssertionError(nil, nil, inter,
367 nil, nil, inter->string,
368 nil, &err);
369 runtime·panic(err);
370 }
371 ret.data = i.data;
372 ret.type = tab->type;
373 FLUSH(&ret);
374 }
375
376 // func ifaceI2E2(typ *byte, iface any) (ret any, ok bool)
377 void
378 runtime·assertI2E2(InterfaceType* inter, Iface i, Eface ret, bool ok)
379 {
380 Itab *tab;
381
382 USED(inter);
383 tab = i.tab;
384 if(tab == nil) {
385 ret.type = nil;
386 ok = 0;
387 } else {
388 ret.type = tab->type;
389 ok = 1;
390 }
391 ret.data = i.data;
392 FLUSH(&ret);
393 FLUSH(&ok);
394 }
395
396 // func convI2I(typ *byte, elem any) (ret any)
397 void
398 runtime·convI2I(InterfaceType* inter, Iface i, Iface ret)
399 {
400 Itab *tab;
401
402 ret.data = i.data;
403 if((tab = i.tab) == nil)
404 ret.tab = nil;
405 else if(tab->inter == inter)
406 ret.tab = tab;
407 else
408 ret.tab = itab(inter, tab->type, 0);
409 FLUSH(&ret);
410 }
411
412 void
413 runtime·ifaceI2I(InterfaceType *inter, Iface i, Iface *ret)
414 {
415 Itab *tab;
416 Eface err;
417
418 tab = i.tab;
419 if(tab == nil) {
420 // explicit conversions require non-nil interface value.
421 runtime·newTypeAssertionError(nil, nil, inter,
422 nil, nil, inter->string,
423 nil, &err);
424 runtime·panic(err);
425 }
426 ret->data = i.data;
427 ret->tab = itab(inter, tab->type, 0);
428 }
429
430 // func ifaceI2I(sigi *byte, iface any) (ret any)
431 void
432 runtime·assertI2I(InterfaceType* inter, Iface i, Iface ret)
433 {
434 runtime·ifaceI2I(inter, i, &ret);
435 }
436
437 // func ifaceI2I2(sigi *byte, iface any) (ret any, ok bool)
438 void
439 runtime·assertI2I2(InterfaceType *inter, Iface i, Iface ret, bool ok)
440 {
441 Itab *tab;
442
443 tab = i.tab;
444 if(tab != nil && (tab->inter == inter || (tab = itab(inter, tab->type, 1)) != nil)) {
445 ret.data = i.data;
446 ret.tab = tab;
447 ok = 1;
448 } else {
449 ret.data = 0;
450 ret.tab = 0;
451 ok = 0;
452 }
453 FLUSH(&ret);
454 FLUSH(&ok);
455 }
456
457 void
458 runtime·ifaceE2I(InterfaceType *inter, Eface e, Iface *ret)
459 {
460 Type *t;
461 Eface err;
462
463 if(((uintptr)e.type&reflectFlags) != 0)
464 runtime·throw("invalid interface value");
465 t = e.type;
466 if(t == nil) {
467 // explicit conversions require non-nil interface value.
468 runtime·newTypeAssertionError(nil, nil, inter,
469 nil, nil, inter->string,
470 nil, &err);
471 runtime·panic(err);
472 }
473 ret->data = e.data;
474 ret->tab = itab(inter, t, 0);
475 }
476
477 // For reflect
478 // func ifaceE2I(t *InterfaceType, e interface{}, dst *Iface)
479 void
480 reflect·ifaceE2I(InterfaceType *inter, Eface e, Iface *dst)
481 {
482 runtime·ifaceE2I(inter, e, dst);
483 }
484
485 // func ifaceE2I(sigi *byte, iface any) (ret any)
486 void
487 runtime·assertE2I(InterfaceType* inter, Eface e, Iface ret)
488 {
489 runtime·ifaceE2I(inter, e, &ret);
490 }
491
492 // ifaceE2I2(sigi *byte, iface any) (ret any, ok bool)
493 void
494 runtime·assertE2I2(InterfaceType *inter, Eface e, Iface ret, bool ok)
495 {
496 if(((uintptr)e.type&reflectFlags) != 0)
497 runtime·throw("invalid interface value");
498 if(e.type == nil) {
499 ok = 0;
500 ret.data = nil;
501 ret.tab = nil;
502 } else if((ret.tab = itab(inter, e.type, 1)) == nil) {
503 ok = 0;
504 ret.data = nil;
505 } else {
506 ok = 1;
507 ret.data = e.data;
508 }
509 FLUSH(&ret);
510 FLUSH(&ok);
511 }
512
513 // func ifaceE2E(typ *byte, iface any) (ret any)
514 void
515 runtime·assertE2E(InterfaceType* inter, Eface e, Eface ret)
516 {
517 Type *t;
518 Eface err;
519
520 if(((uintptr)e.type&reflectFlags) != 0)
521 runtime·throw("invalid interface value");
522 t = e.type;
523 if(t == nil) {
524 // explicit conversions require non-nil interface value.
525 runtime·newTypeAssertionError(nil, nil, inter,
526 nil, nil, inter->string,
527 nil, &err);
528 runtime·panic(err);
529 }
530 ret = e;
531 FLUSH(&ret);
532 }
533
534 // func ifaceE2E2(iface any) (ret any, ok bool)
535 void
536 runtime·assertE2E2(InterfaceType* inter, Eface e, Eface ret, bool ok)
537 {
538 if(((uintptr)e.type&reflectFlags) != 0)
539 runtime·throw("invalid interface value");
540 USED(inter);
541 ret = e;
542 ok = e.type != nil;
543 FLUSH(&ret);
544 FLUSH(&ok);
545 }
546
547 static uintptr
548 ifacehash1(void *data, Type *t)
549 {
550 int32 alg, wid;
551 Eface err;
552
553 if(t == nil)
554 return 0;
555
556 alg = t->alg;
557 wid = t->size;
558 if(runtime·algarray[alg].hash == runtime·nohash) {
559 // calling nohash will panic too,
560 // but we can print a better error.
561 runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"hash of unhashable type "), *t->string), &err);
562 runtime·panic(err);
563 }
564 if(wid <= sizeof(data))
565 return runtime·algarray[alg].hash(wid, &data);
566 return runtime·algarray[alg].hash(wid, data);
567 }
568
569 uintptr
570 runtime·ifacehash(Iface a)
571 {
572 if(a.tab == nil)
573 return 0;
574 return ifacehash1(a.data, a.tab->type);
575 }
576
577 uintptr
578 runtime·efacehash(Eface a)
579 {
580 return ifacehash1(a.data, a.type);
581 }
582
583 static bool
584 ifaceeq1(void *data1, void *data2, Type *t)
585 {
586 int32 alg, wid;
587 Eface err;
588
589 alg = t->alg;
590 wid = t->size;
591
592 if(runtime·algarray[alg].equal == runtime·noequal) {
593 // calling noequal will panic too,
594 // but we can print a better error.
595 runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"comparing uncomparable type "), *t->string), &err);
596 runtime·panic(err);
597 }
598
599 if(wid <= sizeof(data1))
600 return runtime·algarray[alg].equal(wid, &data1, &data2);
601 return runtime·algarray[alg].equal(wid, data1, data2);
602 }
603
604 bool
605 runtime·ifaceeq_c(Iface i1, Iface i2)
606 {
607 if(i1.tab != i2.tab)
608 return false;
609 if(i1.tab == nil)
610 return true;
611 return ifaceeq1(i1.data, i2.data, i1.tab->type);
612 }
613
614 bool
615 runtime·efaceeq_c(Eface e1, Eface e2)
616 {
617 if(((uintptr)e1.type&reflectFlags) != 0)
618 runtime·throw("invalid interface value");
619 if(((uintptr)e2.type&reflectFlags) != 0)
620 runtime·throw("invalid interface value");
621 if(e1.type != e2.type)
622 return false;
623 if(e1.type == nil)
624 return true;
625 return ifaceeq1(e1.data, e2.data, e1.type);
626 }
627
628 // ifaceeq(i1 any, i2 any) (ret bool);
629 void
630 runtime·ifaceeq(Iface i1, Iface i2, bool ret)
631 {
632 ret = runtime·ifaceeq_c(i1, i2);
633 FLUSH(&ret);
634 }
635
636 // efaceeq(i1 any, i2 any) (ret bool)
637 void
638 runtime·efaceeq(Eface e1, Eface e2, bool ret)
639 {
640 ret = runtime·efaceeq_c(e1, e2);
641 FLUSH(&ret);
642 }
643
644 // ifacethash(i1 any) (ret uint32);
645 void
646 runtime·ifacethash(Iface i1, uint32 ret)
647 {
648 Itab *tab;
649
650 ret = 0;
651 tab = i1.tab;
652 if(tab != nil)
653 ret = tab->type->hash;
654 FLUSH(&ret);
655 }
656
657 // efacethash(e1 any) (ret uint32)
658 void
659 runtime·efacethash(Eface e1, uint32 ret)
660 {
661 Type *t;
662
663 if(((uintptr)e1.type&reflectFlags) != 0)
664 runtime·throw("invalid interface value");
665 ret = 0;
666 t = e1.type;
667 if(t != nil)
668 ret = t->hash;
669 FLUSH(&ret);
670 }
671
672 void
673 unsafe·Typeof(Eface e, Eface ret)
674 {
675 if(((uintptr)e.type&reflectFlags) != 0)
676 runtime·throw("invalid interface value");
677 if(e.type == nil) {
678 ret.type = nil;
679 ret.data = nil;
680 } else {
681 ret = *(Eface*)(e.type);
682 }
683 FLUSH(&ret);
684 }
685
686 void
687 unsafe·Reflect(Eface e, Eface rettype, void *retaddr)
688 {
689 uintptr *p;
690 uintptr x;
691
692 if(((uintptr)e.type&reflectFlags) != 0)
693 runtime·throw("invalid interface value");
694 if(e.type == nil) {
695 rettype.type = nil;
696 rettype.data = nil;
697 retaddr = 0;
698 } else {
699 rettype = *(Eface*)e.type;
700 if(e.type->size <= sizeof(uintptr)) {
701 // Copy data into x ...
702 x = 0;
703 runtime·algarray[e.type->alg].copy(e.type->size, &x, &e.data);
704
705 // but then build pointer to x so that Reflect
706 // always returns pointer to data.
707 p = runtime·mal(sizeof(uintptr));
708 *p = x;
709 } else {
710 // Already a pointer, but still make a copy,
711 // to preserve value semantics for interface data.
712 p = runtime·mal(e.type->size);
713 runtime·algarray[e.type->alg].copy(e.type->size, p, e.data);
714 }
715 retaddr = p;
716 }
717 FLUSH(&rettype);
718 FLUSH(&retaddr);
719 }
720
721 void
722 unsafe·Unreflect(Eface typ, void *addr, Eface e)
723 {
724 if(((uintptr)typ.type&reflectFlags) != 0)
725 runtime·throw("invalid interface value");
726
727 // Reflect library has reinterpreted typ
728 // as its own kind of type structure.
729 // We know that the pointer to the original
730 // type structure sits before the data pointer.
731 e.type = (Type*)((Eface*)typ.data-1);
732
733 // Interface holds either pointer to data
734 // or copy of original data.
735 if(e.type->size <= sizeof(uintptr))
736 runtime·algarray[e.type->alg].copy(e.type->size, &e.data, addr);
737 else {
738 // Easier: already a pointer to data.
739 // TODO(rsc): Should this make a copy?
740 e.data = addr;
741 }
742
743 FLUSH(&e);
744 }
745
746 void
747 unsafe·New(Eface typ, void *ret)
748 {
749 Type *t;
750
751 if(((uintptr)typ.type&reflectFlags) != 0)
752 runtime·throw("invalid interface value");
753
754 // Reflect library has reinterpreted typ
755 // as its own kind of type structure.
756 // We know that the pointer to the original
757 // type structure sits before the data pointer.
758 t = (Type*)((Eface*)typ.data-1);
759
760 if(t->kind&KindNoPointers)
761 ret = runtime·mallocgc(t->size, FlagNoPointers, 1, 1);
762 else
763 ret = runtime·mal(t->size);
764 FLUSH(&ret);
765 }
766
767 void
768 unsafe·NewArray(Eface typ, uint32 n, void *ret)
769 {
770 uint64 size;
771 Type *t;
772
773 if(((uintptr)typ.type&reflectFlags) != 0)
774 runtime·throw("invalid interface value");
775
776 // Reflect library has reinterpreted typ
777 // as its own kind of type structure.
778 // We know that the pointer to the original
779 // type structure sits before the data pointer.
780 t = (Type*)((Eface*)typ.data-1);
781
782 size = n*t->size;
783 if(t->kind&KindNoPointers)
784 ret = runtime·mallocgc(size, FlagNoPointers, 1, 1);
785 else
786 ret = runtime·mal(size);
787 FLUSH(&ret);
788 }