Skip to content

Commit c9078fc

Browse files
authored
Merge pull request #373 from xssnick/dbg-rldp
TL Uintptr arithmetics changed to unsafe.Pointer with runtime keep-alive for safety
2 parents 17ffed7 + 8fb30be commit c9078fc

2 files changed

Lines changed: 16 additions & 14 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
[![Based on TON][ton-svg]][ton]
66
[![Telegram Channel][tgc-svg]][tg-channel]
7-
![Coverage](https://img.shields.io/badge/Coverage-70.1%25-brightgreen)
7+
![Coverage](https://img.shields.io/badge/Coverage-70.2%25-brightgreen)
88

99
Golang library for interacting with TON blockchain.
1010

tl/precompile.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/xssnick/tonutils-go/tvm/cell"
99
"net"
1010
"reflect"
11+
"runtime"
1112
"strconv"
1213
"strings"
1314
"unsafe"
@@ -398,7 +399,7 @@ func serializePrecompiled(ptr unsafe.Pointer, t *structInfo, boxed bool, buf *by
398399
return nil
399400
}
400401

401-
if err := executeSerialize(buf, uintptr(ptr), t); err != nil {
402+
if err := executeSerialize(buf, ptr, t); err != nil {
402403
buf.Truncate(bufStart)
403404
return fmt.Errorf("failed to serialize %s type: %w", t.tp.String(), err)
404405
}
@@ -482,18 +483,18 @@ func parsePrecompiled(ptr unsafe.Pointer, t *structInfo, boxed bool, buf []byte,
482483
return buf, nil
483484
}
484485

485-
if buf, err = executeParse(buf, uintptr(ptr), t, noCopy); err != nil {
486+
if buf, err = executeParse(buf, ptr, t, noCopy); err != nil {
486487
return nil, fmt.Errorf("failed to parse %s type: %w", t.tp.String(), err)
487488
}
488489
return buf, nil
489490
}
490491

491-
func executeParse(buf []byte, startPtr uintptr, si *structInfo, noCopy bool) ([]byte, error) {
492+
func executeParse(buf []byte, base unsafe.Pointer, si *structInfo, noCopy bool) ([]byte, error) {
492493
if !si.finalized {
493494
return nil, fmt.Errorf("TL struct %s is not registered", si.tp.String())
494495
}
495496

496-
// TODO: noCopy mode
497+
defer runtime.KeepAlive((*byte)(base))
497498

498499
var flags uint32
499500
for _, field := range si.fields {
@@ -502,8 +503,7 @@ func executeParse(buf []byte, startPtr uintptr, si *structInfo, noCopy bool) ([]
502503
continue
503504
}
504505

505-
//goland:noinspection GoVetUnsafePointer
506-
ptr := unsafe.Pointer(startPtr + field.offset)
506+
ptr := unsafe.Add(base, field.offset)
507507

508508
var err error
509509
switch t := field.typ; t {
@@ -756,43 +756,45 @@ func executeParse(buf []byte, startPtr uintptr, si *structInfo, noCopy bool) ([]
756756
sl := reflect.MakeSlice(field.structInfo.tp, ln, ln)
757757

758758
sz := field.structInfo.tp.Elem().Size()
759-
ePtr := sl.Pointer()
759+
ePtr := unsafe.Pointer(sl.Pointer())
760760

761761
for x := 0; x < ln; x++ {
762762
buf, err = executeParse(buf, ePtr, field.structInfo, noCopy)
763763
if err != nil {
764764
return nil, fmt.Errorf("failed to parse %s type, vector element %d: %w", si.tp.String(), x, err)
765765
}
766766

767-
ePtr += sz
767+
ePtr = unsafe.Add(ePtr, sz)
768768
}
769769

770770
*(*reflect.SliceHeader)(ptr) = reflect.SliceHeader{
771771
Data: sl.Pointer(),
772772
Len: ln,
773773
Cap: ln,
774774
}
775+
runtime.KeepAlive(sl)
775776
default:
776777
return nil, fmt.Errorf("unknown type %d for field %s", t, field.String())
777778
}
778779
}
779780
return buf, nil
780781
}
781782

782-
func executeSerialize(buf *bytes.Buffer, startPtr uintptr, si *structInfo) error {
783+
func executeSerialize(buf *bytes.Buffer, base unsafe.Pointer, si *structInfo) error {
783784
if !si.finalized {
784785
return fmt.Errorf("TL struct %s is not registered", si.tp.String())
785786
}
786787

788+
defer runtime.KeepAlive((*byte)(base))
789+
787790
var flags uint32
788791
for _, field := range si.fields {
789792
if field.hasFlags && (1<<field.flag)&flags == 0 {
790793
// skip serialization if flag is not set
791794
continue
792795
}
793796

794-
//goland:noinspection GoVetUnsafePointer
795-
ptr := unsafe.Pointer(startPtr + field.offset)
797+
ptr := unsafe.Add(base, field.offset)
796798

797799
switch t := field.typ; t {
798800
case _ExecuteTypeFlags:
@@ -1018,13 +1020,13 @@ func executeSerialize(buf *bytes.Buffer, startPtr uintptr, si *structInfo) error
10181020
buf.Write(tmp)
10191021

10201022
sz := field.structInfo.tp.Elem().Size()
1021-
ePtr := hdr.Data
1023+
ePtr := unsafe.Pointer(hdr.Data)
10221024

10231025
for x := 0; x < ln; x++ {
10241026
if err := executeSerialize(buf, ePtr, field.structInfo); err != nil {
10251027
return fmt.Errorf("failed to serialize %s type, vector element %d: %w", si.tp.String(), x, err)
10261028
}
1027-
ePtr += sz
1029+
ePtr = unsafe.Add(ePtr, sz)
10281030
}
10291031
default:
10301032
return fmt.Errorf("unknown type %d for field %s", t, field.String())

0 commit comments

Comments
 (0)