1/* 2 * gomacro - A Go interpreter with Lisp-like macros 3 * 4 * Copyright (C) 2017-2019 Massimiliano Ghilardi 5 * 6 * This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * 11 * init.go 12 * 13 * Created on May 19, 2017 14 * Author Massimiliano Ghilardi 15 */ 16 17package xreflect 18 19import ( 20 "reflect" 21 "unsafe" 22 23 "go/types" 24) 25 26var rbasictypes = []reflect.Type{ 27 reflect.Bool: reflect.TypeOf(bool(false)), 28 reflect.Int: reflect.TypeOf(int(0)), 29 reflect.Int8: reflect.TypeOf(int8(0)), 30 reflect.Int16: reflect.TypeOf(int16(0)), 31 reflect.Int32: reflect.TypeOf(int32(0)), 32 reflect.Int64: reflect.TypeOf(int64(0)), 33 reflect.Uint: reflect.TypeOf(uint(0)), 34 reflect.Uint8: reflect.TypeOf(uint8(0)), 35 reflect.Uint16: reflect.TypeOf(uint16(0)), 36 reflect.Uint32: reflect.TypeOf(uint32(0)), 37 reflect.Uint64: reflect.TypeOf(uint64(0)), 38 reflect.Uintptr: reflect.TypeOf(uintptr(0)), 39 reflect.Float32: reflect.TypeOf(float32(0)), 40 reflect.Float64: reflect.TypeOf(float64(0)), 41 reflect.Complex64: reflect.TypeOf(complex64(0)), 42 reflect.Complex128: reflect.TypeOf(complex128(0)), 43 reflect.String: reflect.TypeOf(string("")), 44 reflect.UnsafePointer: reflect.TypeOf(unsafe.Pointer(nil)), 45} 46 47var ReflectBasicTypes = rbasictypes 48 49func (v *Universe) makeBasicTypes() []Type { 50 m := make([]Type, len(rbasictypes)) 51 for gkind := types.Bool; gkind <= types.UnsafePointer; gkind++ { 52 kind := ToReflectKind(gkind) 53 gtype := types.Typ[gkind] 54 rtype := rbasictypes[kind] 55 if gtype == nil || rtype == nil { 56 continue 57 } 58 t := wrap(&xtype{kind: kind, gtype: gtype, rtype: rtype, universe: v}) 59 v.add(t) 60 m[kind] = t 61 } 62 return m 63} 64 65func (v *Universe) makeError() Type { 66 t := wrap(&xtype{ 67 kind: reflect.Interface, 68 gtype: types.Universe.Lookup("error").Type(), 69 rtype: reflect.TypeOf((*error)(nil)).Elem(), 70 universe: v, 71 }) 72 v.add(t) 73 return t 74} 75 76func (v *Universe) makeInterface() Type { 77 t := wrap(&xtype{ 78 kind: reflect.Interface, 79 gtype: types.NewInterface(nil, nil).Complete(), 80 rtype: rTypeOfInterface, 81 universe: v, 82 }) 83 v.add(t) 84 return t 85} 86 87func (v *Universe) makeForward() Type { 88 t := wrap(&xtype{ 89 kind: reflect.Invalid, 90 gtype: types.NewInterface(nil, nil).Complete(), 91 rtype: rTypeOfForward, 92 universe: v, 93 }) 94 v.add(t) 95 return t 96} 97 98func NewUniverse() *Universe { 99 v := &Universe{} 100 v.BasicTypes = v.makeBasicTypes() 101 v.TypeOfForward = v.makeForward() 102 v.TypeOfInterface = v.makeInterface() 103 v.TypeOfError = v.makeError() 104 // critical! trying to rebuild "error" type creates a non-indentical copy... lots of conversions would fail 105 v.cache(v.TypeOfError.ReflectType(), v.TypeOfError) 106 v.cache(v.TypeOfInterface.ReflectType(), v.TypeOfInterface) 107 return v 108} 109 110const MaxDepth = int(^uint(0) >> 1) 111 112var ( 113 rTypeOfInterface = reflect.TypeOf((*interface{})(nil)).Elem() 114 rTypeOfInterfaceHeader = reflect.TypeOf(InterfaceHeader{}) 115 rTypeOfForward = reflect.TypeOf((*Forward)(nil)).Elem() 116) 117 118// Bits returns the size of the type in bits. 119// It panics if the type's Kind is not one of the 120// sized or unsized Int, Uint, Float, or Complex kinds. 121func (t *xtype) Bits() int { 122 return t.rtype.Bits() 123} 124 125// Align returns the alignment in bytes of a value of 126// this type when allocated in memory. 127func (t *xtype) Align() int { 128 return t.rtype.Align() 129} 130 131// FieldAlign returns the alignment in bytes of a value of 132// this type when used as a field in a struct. 133func (t *xtype) FieldAlign() int { 134 return t.rtype.FieldAlign() 135} 136