Skip to content
This repository was archived by the owner on Dec 23, 2025. It is now read-only.

Commit 03ad9c4

Browse files
committed
fix: fix field pointer offset
Change-Id: I23d228b3c19dfd3a7c7dd7c6d6f1ce9fab892242
1 parent 9462ab2 commit 03ad9c4

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

tagexpr.go

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ type structVM struct {
4545

4646
// fieldVM tag expression set of struct field
4747
type fieldVM struct {
48-
reflect.StructField
48+
StructField reflect.StructField
49+
offset uintptr
4950
ptrDeep int
5051
elemType reflect.Type
5152
elemKind reflect.Kind
@@ -153,7 +154,7 @@ func (vm *VM) registerStructLocked(structType reflect.Type) (*structVM, error) {
153154
field.setUnsupportGetter()
154155
switch field.elemKind {
155156
case reflect.Struct:
156-
sub, err = vm.registerStructLocked(field.Type)
157+
sub, err = vm.registerStructLocked(field.StructField.Type)
157158
if err != nil {
158159
return nil, err
159160
}
@@ -189,13 +190,14 @@ func (vm *VM) newStructVM() *structVM {
189190
func (s *structVM) newFieldVM(structField reflect.StructField) (*fieldVM, error) {
190191
f := &fieldVM{
191192
StructField: structField,
193+
offset: structField.Offset,
192194
origin: s,
193195
}
194196
err := f.parseExprs(structField.Tag.Get(s.vm.tagName))
195197
if err != nil {
196198
return nil, err
197199
}
198-
s.fields[f.Name] = f
200+
s.fields[f.StructField.Name] = f
199201
var t = structField.Type
200202
var ptrDeep int
201203
for t.Kind() == reflect.Ptr {
@@ -213,26 +215,28 @@ func (s *structVM) newFieldVM(structField reflect.StructField) (*fieldVM, error)
213215
}
214216

215217
func (s *structVM) copySubFields(field *fieldVM, sub *structVM) {
216-
nameSpace := field.Name
218+
nameSpace := field.StructField.Name
219+
offset := field.offset
217220
ptrDeep := field.ptrDeep
218221
for k, v := range sub.fields {
219222
valueGetter := v.valueGetter
220223
reflectValueGetter := v.reflectValueGetter
221224
f := &fieldVM{
222225
StructField: v.StructField,
226+
offset: offset + v.offset,
223227
origin: v.origin,
224228
}
225229
if valueGetter != nil {
226230
if ptrDeep == 0 {
227231
f.valueGetter = func(ptr uintptr) interface{} {
228-
return valueGetter(ptr + field.Offset)
232+
return valueGetter(ptr + field.offset)
229233
}
230234
f.reflectValueGetter = func(ptr uintptr) reflect.Value {
231-
return reflectValueGetter(ptr + field.Offset)
235+
return reflectValueGetter(ptr + field.offset)
232236
}
233237
} else {
234238
f.valueGetter = func(ptr uintptr) interface{} {
235-
newFieldVM := reflect.NewAt(field.Type, unsafe.Pointer(ptr+field.Offset))
239+
newFieldVM := reflect.NewAt(field.StructField.Type, unsafe.Pointer(ptr+field.offset))
236240
for i := 0; i < ptrDeep; i++ {
237241
newFieldVM = newFieldVM.Elem()
238242
}
@@ -242,7 +246,7 @@ func (s *structVM) copySubFields(field *fieldVM, sub *structVM) {
242246
return valueGetter(uintptr(newFieldVM.Pointer()))
243247
}
244248
f.reflectValueGetter = func(ptr uintptr) reflect.Value {
245-
newFieldVM := reflect.NewAt(field.Type, unsafe.Pointer(ptr+field.Offset))
249+
newFieldVM := reflect.NewAt(field.StructField.Type, unsafe.Pointer(ptr+field.offset))
246250
for i := 0; i < ptrDeep; i++ {
247251
newFieldVM = newFieldVM.Elem()
248252
}
@@ -264,15 +268,15 @@ func (s *structVM) copySubFields(field *fieldVM, sub *structVM) {
264268
}
265269

266270
func (f *fieldVM) elemPtr(ptr uintptr) uintptr {
267-
ptr = ptr + f.Offset
271+
ptr = ptr + f.offset
268272
for i := f.ptrDeep; i > 0; i-- {
269273
ptr = uintptrElem(ptr)
270274
}
271275
return ptr
272276
}
273277

274278
func (f *fieldVM) packRawFrom(ptr uintptr) reflect.Value {
275-
return reflect.NewAt(f.Type, unsafe.Pointer(ptr+f.Offset)).Elem()
279+
return reflect.NewAt(f.StructField.Type, unsafe.Pointer(ptr+f.offset)).Elem()
276280
}
277281

278282
func (f *fieldVM) packElemFrom(ptr uintptr) reflect.Value {
@@ -321,7 +325,7 @@ func (vm *VM) runFromValue(v reflect.Value) (*TagExpr, bool) {
321325
func (f *fieldVM) setFloatGetter() {
322326
if f.ptrDeep == 0 {
323327
f.valueGetter = func(ptr uintptr) interface{} {
324-
return getFloat64(f.elemKind, ptr+f.Offset)
328+
return getFloat64(f.elemKind, ptr+f.offset)
325329
}
326330
} else {
327331
f.valueGetter = func(ptr uintptr) interface{} {
@@ -337,7 +341,7 @@ func (f *fieldVM) setFloatGetter() {
337341
func (f *fieldVM) setBoolGetter() {
338342
if f.ptrDeep == 0 {
339343
f.valueGetter = func(ptr uintptr) interface{} {
340-
return *(*bool)(unsafe.Pointer(ptr + f.Offset))
344+
return *(*bool)(unsafe.Pointer(ptr + f.offset))
341345
}
342346
} else {
343347
f.valueGetter = func(ptr uintptr) interface{} {
@@ -353,7 +357,7 @@ func (f *fieldVM) setBoolGetter() {
353357
func (f *fieldVM) setStringGetter() {
354358
if f.ptrDeep == 0 {
355359
f.valueGetter = func(ptr uintptr) interface{} {
356-
return *(*string)(unsafe.Pointer(ptr + f.Offset))
360+
return *(*string)(unsafe.Pointer(ptr + f.offset))
357361
}
358362
} else {
359363
f.valueGetter = func(ptr uintptr) interface{} {
@@ -404,7 +408,7 @@ func (f *fieldVM) parseExprs(tag string) error {
404408
if err != nil {
405409
return err
406410
}
407-
selector := f.Name
411+
selector := f.StructField.Name
408412
f.origin.exprs[selector] = expr
409413
f.origin.selectorList = append(f.origin.selectorList, selector)
410414
return nil
@@ -422,9 +426,9 @@ func (f *fieldVM) parseExprs(tag string) error {
422426
case "":
423427
continue
424428
case "@":
425-
selector = f.Name
429+
selector = f.StructField.Name
426430
default:
427-
selector = f.Name + "@" + selector
431+
selector = f.StructField.Name + "@" + selector
428432
}
429433
if _, had := f.origin.exprs[selector]; had {
430434
return fmt.Errorf("duplicate expression name: %s", selector)

tagexpr_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,3 +486,27 @@ func TestStruct(t *testing.T) {
486486
return true
487487
})
488488
}
489+
490+
func TestStruct2(t *testing.T) {
491+
type IframeBlock struct {
492+
XBlock struct {
493+
BlockType string `vd:"$"`
494+
}
495+
Props struct {
496+
Data struct {
497+
DataType string `vd:"$"`
498+
}
499+
}
500+
}
501+
b := new(IframeBlock)
502+
b.XBlock.BlockType = "BlockType"
503+
b.Props.Data.DataType = "DataType"
504+
vm := New("vd")
505+
expr := vm.MustRun(b)
506+
// if expr.EvalString("XBlock.BlockType") != "BlockType" {
507+
// t.Fatal(expr.EvalString("XBlock.BlockType"))
508+
// }
509+
if expr.EvalString("Props.Data.DataType") != "DataType" {
510+
t.Fatal(expr.EvalString("Props.Data.DataType"))
511+
}
512+
}

0 commit comments

Comments
 (0)