@@ -101,6 +101,83 @@ func (f flag) ro() flag {
101
101
return 0
102
102
}
103
103
104
+ func (v Value ) typ () * abi.Type {
105
+ // Types are either static (for compiler-created types) or
106
+ // heap-allocated but always reachable (for reflection-created
107
+ // types, held in the central map). So there is no need to
108
+ // escape types. noescape here help avoid unnecessary escape
109
+ // of v.
110
+ return (* abi .Type )(unsafe .Pointer (v .typ_ ))
111
+ }
112
+
113
+ // pointer returns the underlying pointer represented by v.
114
+ // v.Kind() must be Pointer, Map, Chan, Func, or UnsafePointer
115
+ // if v.Kind() == Pointer, the base type must not be not-in-heap.
116
+ func (v Value ) pointer () unsafe.Pointer {
117
+ /*
118
+ if v.typ().Size() != goarch.PtrSize || !v.typ().Pointers() {
119
+ panic("can't call pointer on a non-pointer Value")
120
+ }
121
+ if v.flag&flagIndir != 0 {
122
+ return *(*unsafe.Pointer)(v.ptr)
123
+ }
124
+ return v.ptr
125
+ */
126
+ panic ("todo" )
127
+ }
128
+
129
+ // packEface converts v to the empty interface.
130
+ func packEface (v Value ) any {
131
+ t := v .typ ()
132
+ var i any
133
+ e := (* emptyInterface )(unsafe .Pointer (& i ))
134
+ // First, fill in the data portion of the interface.
135
+ switch {
136
+ case t .IfaceIndir ():
137
+ if v .flag & flagIndir == 0 {
138
+ panic ("bad indir" )
139
+ }
140
+ // Value is indirect, and so is the interface we're making.
141
+ ptr := v .ptr
142
+ if v .flag & flagAddr != 0 {
143
+ // TODO: pass safe boolean from valueInterface so
144
+ // we don't need to copy if safe==true?
145
+ c := unsafe_New (t )
146
+ typedmemmove (t , c , ptr )
147
+ ptr = c
148
+ }
149
+ e .word = ptr
150
+ case v .flag & flagIndir != 0 :
151
+ // Value is indirect, but interface is direct. We need
152
+ // to load the data at v.ptr into the interface data word.
153
+ e .word = * (* unsafe .Pointer )(v .ptr )
154
+ default :
155
+ // Value is direct, and so is the interface.
156
+ e .word = v .ptr
157
+ }
158
+ // Now, fill in the type portion. We're very careful here not
159
+ // to have any operation between the e.word and e.typ assignments
160
+ // that would let the garbage collector observe the partially-built
161
+ // interface value.
162
+ e .typ = t
163
+ return i
164
+ }
165
+
166
+ // unpackEface converts the empty interface i to a Value.
167
+ func unpackEface (i any ) Value {
168
+ e := (* emptyInterface )(unsafe .Pointer (& i ))
169
+ // NOTE: don't read e.word until we know whether it is really a pointer or not.
170
+ t := e .typ
171
+ if t == nil {
172
+ return Value {}
173
+ }
174
+ f := flag (t .Kind ())
175
+ if t .IfaceIndir () {
176
+ f |= flagIndir
177
+ }
178
+ return Value {t , e .word , f }
179
+ }
180
+
104
181
// A ValueError occurs when a Value method is invoked on
105
182
// a Value that does not support it. Such cases are documented
106
183
// in the description of each method.
@@ -227,14 +304,17 @@ func (v Value) Int() int64 {
227
304
p := v .ptr
228
305
switch k {
229
306
case Int :
230
- return int64 (* ( * int ) (p ))
307
+ return int64 (uintptr (p ))
231
308
case Int8 :
232
- return int64 (* ( * int8 ) (p ))
309
+ return int64 (uintptr (p ))
233
310
case Int16 :
234
- return int64 (* ( * int16 ) (p ))
311
+ return int64 (uintptr (p ))
235
312
case Int32 :
236
- return int64 (* ( * int32 ) (p ))
313
+ return int64 (uintptr (p ))
237
314
case Int64 :
315
+ if unsafe .Sizeof (uintptr (0 )) == 8 {
316
+ return int64 (uintptr (p ))
317
+ }
238
318
return * (* int64 )(p )
239
319
}
240
320
panic (& ValueError {"reflect.Value.Int" , v .kind ()})
@@ -520,6 +600,16 @@ func unsafe_New(*abi.Type) unsafe.Pointer
520
600
//go:linkname unsafe_NewArray github.com/goplus/llgo/internal/runtime.NewArray
521
601
func unsafe_NewArray (* abi.Type , int ) unsafe.Pointer
522
602
603
+ // ValueOf returns a new Value initialized to the concrete value
604
+ // stored in the interface i. ValueOf(nil) returns the zero Value.
605
+ func ValueOf (i any ) Value {
606
+ if i == nil {
607
+ return Value {}
608
+ }
609
+
610
+ return unpackEface (i )
611
+ }
612
+
523
613
// Zero returns a Value representing the zero value for the specified type.
524
614
// The result is different from the zero value of the Value struct,
525
615
// which represents no value at all.
@@ -546,3 +636,46 @@ func Zero(typ Type) Value {
546
636
// TODO(xsw): check this
547
637
// must match declarations in runtime/map.go.
548
638
const maxZero = runtime .MaxZero
639
+
640
+ // memmove copies size bytes to dst from src. No write barriers are used.
641
+ //
642
+ //go:linkname memmove C.memmove
643
+ func memmove (dst , src unsafe.Pointer , size uintptr )
644
+
645
+ // typedmemmove copies a value of type t to dst from src.
646
+ //
647
+ //go:linkname typedmemmove github.com/goplus/llgo/internal/runtime.Typedmemmove
648
+ func typedmemmove (t * abi.Type , dst , src unsafe.Pointer )
649
+
650
+ /* TODO(xsw):
651
+ // typedmemclr zeros the value at ptr of type t.
652
+ //
653
+ //go:noescape
654
+ func typedmemclr(t *abi.Type, ptr unsafe.Pointer)
655
+
656
+ // typedmemclrpartial is like typedmemclr but assumes that
657
+ // dst points off bytes into the value and only clears size bytes.
658
+ //
659
+ //go:noescape
660
+ func typedmemclrpartial(t *abi.Type, ptr unsafe.Pointer, off, size uintptr)
661
+
662
+ // typedslicecopy copies a slice of elemType values from src to dst,
663
+ // returning the number of elements copied.
664
+ //
665
+ //go:noescape
666
+ func typedslicecopy(t *abi.Type, dst, src unsafeheaderSlice) int
667
+
668
+ // typedarrayclear zeroes the value at ptr of an array of elemType,
669
+ // only clears len elem.
670
+ //
671
+ //go:noescape
672
+ func typedarrayclear(elemType *abi.Type, ptr unsafe.Pointer, len int)
673
+
674
+ //go:noescape
675
+ func typehash(t *abi.Type, p unsafe.Pointer, h uintptr) uintptr
676
+
677
+ func verifyNotInHeapPtr(p uintptr) bool
678
+
679
+ //go:noescape
680
+ func growslice(t *abi.Type, old unsafeheaderSlice, num int) unsafeheaderSlice
681
+ */
0 commit comments