Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

golang: Sanity-check allocations #182

Merged
merged 3 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 33 additions & 25 deletions lib/xdrgen/generators/go.rb
Original file line number Diff line number Diff line change
Expand Up @@ -430,11 +430,11 @@ def render_typedef_encode_to_interface(out, typedef)
# encode.
def render_encode_to_body(out, var, type, self_encode:)
def check_error(str)
<<-EOS.strip_heredoc
if #{str}; err != nil {
return err
}
EOS
<<-EOS
if #{str}; err != nil {
return err
}
EOS
end
optional = type.sub_type == :optional
if optional
Expand Down Expand Up @@ -649,12 +649,12 @@ def render_variable_declaration(out, indent, var, type, declared_variables:)
# xdr.Decoder, and a variable defined by `var` that is the value to
# encode.
def render_decode_from_body(out, var, type, declared_variables:, self_encode:)
tail = <<-EOS.strip_heredoc
n += nTmp
if err != nil {
return n, fmt.Errorf("decoding #{name type}: %w", err)
}
EOS
tail = <<-EOS
n += nTmp
if err != nil {
return n, fmt.Errorf("decoding #{name type}: %w", err)
}
EOS
optional = type.sub_type == :optional
if optional
render_variable_declaration(out, " ", 'b', "bool", declared_variables: declared_variables)
Expand Down Expand Up @@ -688,13 +688,12 @@ def render_decode_from_body(out, var, type, declared_variables:, self_encode:)
when AST::Typespecs::Opaque
if type.fixed?
out.puts " nTmp, err = d.DecodeFixedOpaqueInplace(#{var}[:])"
out.puts tail
else
arg = "0"
arg = type.decl.resolved_size unless type.decl.resolved_size.nil?
out.puts " #{var}, nTmp, err = d.DecodeOpaque(#{arg})"
out.puts tail
end
out.puts tail
when AST::Typespecs::Simple
case type.sub_type
when :simple, :optional
Expand Down Expand Up @@ -742,8 +741,11 @@ def render_decode_from_body(out, var, type, declared_variables:, self_encode:)
end
out.puts " #{var} = nil"
out.puts " if l > 0 {"
out.puts " if il, ok := d.InputLen(); ok && uint(il) < uint(l) {"
out.puts " return n, fmt.Errorf(\"decoding #{name type}: length (%d) exceeds remaining input length (%d)\", l, il)"
out.puts " }"
out.puts " #{var} = make([]#{name type}, l)"
out.puts " for i := uint32(0); i < l; i++ {"
out.puts " for i := uint32(0); uint(i) < uint(l); i++ {"
element_var = "#{var}[i]"
optional_within = type.is_a?(AST::Identifier) && type.resolved_type.sub_type == :optional
if optional_within
Expand Down Expand Up @@ -793,8 +795,10 @@ def render_binary_interface(out, name)
out.puts "// UnmarshalBinary implements encoding.BinaryUnmarshaler."
out.puts "func (s *#{name}) UnmarshalBinary(inp []byte) error {"
out.puts " r := bytes.NewReader(inp)"
out.puts " d := xdr.NewDecoder(r)"
out.puts " _, err := s.DecodeFrom(d, xdr.DecodeDefaultMaxDepth)"
out.puts " o := xdr.DefaultDecodeOptions"
out.puts " o.MaxInputLen = len(inp)"
out.puts " d := xdr.NewDecoderWithOptions(r, o)"
out.puts " _, err := s.DecodeFrom(d, o.MaxDepth)"
out.puts " return err"
out.puts "}"
out.break
Expand All @@ -806,8 +810,7 @@ def render_binary_interface(out, name)
end

def render_xdr_type_interface(out, name)
out.puts "// xdrType signals that this type is an type representing"
out.puts "// representing XDR values defined by this package."
out.puts "// xdrType signals that this type represents XDR values defined by this package."
out.puts "func (s #{name}) xdrType() {}"
out.break
out.puts "var _ xdrType = (*#{name})(nil)"
Expand Down Expand Up @@ -836,12 +839,15 @@ def render_top_matter(out)
"errors"
"io"
"fmt"
"unsafe"

"github.com/stellar/go-xdr/xdr3"
)
EOS
out.break
out.puts <<-EOS.strip_heredoc
// Needed since unsafe is not used in all cases
var _ = unsafe.Sizeof(0)
// XdrFilesSHA256 is the SHA256 hashes of source files.
var XdrFilesSHA256 = map[string]string{
#{@output.relative_source_path_sha256_hashes.map(){ |path, hash| %{"#{path}": "#{hash}",} }.join("\n")}
Expand All @@ -861,12 +867,17 @@ def render_top_matter(out)

// Unmarshal reads an xdr element from `r` into `v`.
func Unmarshal(r io.Reader, v interface{}) (int, error) {
return UnmarshalWithOptions(r, v, xdr.DefaultDecodeOptions)
}

// UnmarshalWithOptions works like Unmarshal but uses decoding options.
func UnmarshalWithOptions(r io.Reader, v interface{}, options xdr.DecodeOptions) (int, error) {
if decodable, ok := v.(decoderFrom); ok {
d := xdr.NewDecoder(r)
return decodable.DecodeFrom(d, xdr.DecodeDefaultMaxDepth)
d := xdr.NewDecoderWithOptions(r, options)
return decodable.DecodeFrom(d, options.MaxDepth)
}
// delegate to xdr package's Unmarshal
return xdr.Unmarshal(r, v)
return xdr.UnmarshalWithOptions(r, v, options)
}

// Marshal writes an xdr element `v` into `w`.
Expand All @@ -888,10 +899,7 @@ def render_top_matter(out)
end

def render_bottom_matter(out)
out.puts <<-EOS
var fmtTest = fmt.Sprint("this is a dummy usage of fmt")

EOS
out.puts 'var fmtTest = fmt.Sprint("this is a dummy usage of fmt")'
end

private
Expand Down
26 changes: 17 additions & 9 deletions spec/output/generator_spec_go/block_comments.x/MyXDR_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ import (
"errors"
"io"
"fmt"
"unsafe"

"github.com/stellar/go-xdr/xdr3"
)

// Needed since unsafe is not used in all cases
var _ = unsafe.Sizeof(0)
// XdrFilesSHA256 is the SHA256 hashes of source files.
var XdrFilesSHA256 = map[string]string{
"spec/fixtures/generator/block_comments.x": "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30",
Expand All @@ -35,12 +38,17 @@ type decoderFrom interface {

// Unmarshal reads an xdr element from `r` into `v`.
func Unmarshal(r io.Reader, v interface{}) (int, error) {
return UnmarshalWithOptions(r, v, xdr.DefaultDecodeOptions)
}

// UnmarshalWithOptions works like Unmarshal but uses decoding options.
func UnmarshalWithOptions(r io.Reader, v interface{}, options xdr.DecodeOptions) (int, error) {
if decodable, ok := v.(decoderFrom); ok {
d := xdr.NewDecoder(r)
return decodable.DecodeFrom(d, xdr.DecodeDefaultMaxDepth)
d := xdr.NewDecoderWithOptions(r, options)
return decodable.DecodeFrom(d, options.MaxDepth)
}
// delegate to xdr package's Unmarshal
return xdr.Unmarshal(r, v)
return xdr.UnmarshalWithOptions(r, v, options)
}

// Marshal writes an xdr element `v` into `w`.
Expand Down Expand Up @@ -121,8 +129,10 @@ func (s AccountFlags) MarshalBinary() ([]byte, error) {
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
func (s *AccountFlags) UnmarshalBinary(inp []byte) error {
r := bytes.NewReader(inp)
d := xdr.NewDecoder(r)
_, err := s.DecodeFrom(d, xdr.DecodeDefaultMaxDepth)
o := xdr.DefaultDecodeOptions
o.MaxInputLen = len(inp)
d := xdr.NewDecoderWithOptions(r, o)
_, err := s.DecodeFrom(d, o.MaxDepth)
return err
}

Expand All @@ -131,11 +141,9 @@ var (
_ encoding.BinaryUnmarshaler = (*AccountFlags)(nil)
)

// xdrType signals that this type is an type representing
// representing XDR values defined by this package.
// xdrType signals that this type represents XDR values defined by this package.
func (s AccountFlags) xdrType() {}

var _ xdrType = (*AccountFlags)(nil)

var fmtTest = fmt.Sprint("this is a dummy usage of fmt")

var fmtTest = fmt.Sprint("this is a dummy usage of fmt")
63 changes: 36 additions & 27 deletions spec/output/generator_spec_go/const.x/MyXDR_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ import (
"errors"
"io"
"fmt"
"unsafe"

"github.com/stellar/go-xdr/xdr3"
)

// Needed since unsafe is not used in all cases
var _ = unsafe.Sizeof(0)
// XdrFilesSHA256 is the SHA256 hashes of source files.
var XdrFilesSHA256 = map[string]string{
"spec/fixtures/generator/const.x": "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37",
Expand All @@ -35,12 +38,17 @@ type decoderFrom interface {

// Unmarshal reads an xdr element from `r` into `v`.
func Unmarshal(r io.Reader, v interface{}) (int, error) {
return UnmarshalWithOptions(r, v, xdr.DefaultDecodeOptions)
}

// UnmarshalWithOptions works like Unmarshal but uses decoding options.
func UnmarshalWithOptions(r io.Reader, v interface{}, options xdr.DecodeOptions) (int, error) {
if decodable, ok := v.(decoderFrom); ok {
d := xdr.NewDecoder(r)
return decodable.DecodeFrom(d, xdr.DecodeDefaultMaxDepth)
d := xdr.NewDecoderWithOptions(r, options)
return decodable.DecodeFrom(d, options.MaxDepth)
}
// delegate to xdr package's Unmarshal
return xdr.Unmarshal(r, v)
return xdr.UnmarshalWithOptions(r, v, options)
}

// Marshal writes an xdr element `v` into `w`.
Expand Down Expand Up @@ -72,9 +80,9 @@ type TestArray [Foo]int32
// EncodeTo encodes this value using the Encoder.
func (s *TestArray) EncodeTo(e *xdr.Encoder) error {
var err error
if _, err = e.EncodeInt(int32(s)); err != nil {
return err
}
if _, err = e.EncodeInt(int32(s)); err != nil {
return err
}
return nil
}

Expand All @@ -89,10 +97,10 @@ func (s *TestArray) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) {
var n, nTmp int
var v [Foo]int32
v, nTmp, err = d.DecodeInt()
n += nTmp
if err != nil {
return n, fmt.Errorf("decoding Int: %w", err)
}
n += nTmp
if err != nil {
return n, fmt.Errorf("decoding Int: %w", err)
}
*s = TestArray(v)
return n, nil
}
Expand All @@ -108,8 +116,10 @@ func (s TestArray) MarshalBinary() ([]byte, error) {
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
func (s *TestArray) UnmarshalBinary(inp []byte) error {
r := bytes.NewReader(inp)
d := xdr.NewDecoder(r)
_, err := s.DecodeFrom(d, xdr.DecodeDefaultMaxDepth)
o := xdr.DefaultDecodeOptions
o.MaxInputLen = len(inp)
d := xdr.NewDecoderWithOptions(r, o)
_, err := s.DecodeFrom(d, o.MaxDepth)
return err
}

Expand All @@ -118,8 +128,7 @@ var (
_ encoding.BinaryUnmarshaler = (*TestArray)(nil)
)

// xdrType signals that this type is an type representing
// representing XDR values defined by this package.
// xdrType signals that this type represents XDR values defined by this package.
func (s TestArray) xdrType() {}

var _ xdrType = (*TestArray)(nil)
Expand All @@ -136,9 +145,9 @@ func (e TestArray2) XDRMaxSize() int {
// EncodeTo encodes this value using the Encoder.
func (s TestArray2) EncodeTo(e *xdr.Encoder) error {
var err error
if _, err = e.EncodeInt(int32(s)); err != nil {
return err
}
if _, err = e.EncodeInt(int32(s)); err != nil {
return err
}
return nil
}

Expand All @@ -153,10 +162,10 @@ func (s *TestArray2) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) {
var n, nTmp int
var v []int32
v, nTmp, err = d.DecodeInt()
n += nTmp
if err != nil {
return n, fmt.Errorf("decoding Int: %w", err)
}
n += nTmp
if err != nil {
return n, fmt.Errorf("decoding Int: %w", err)
}
*s = TestArray2(v)
return n, nil
}
Expand All @@ -172,8 +181,10 @@ func (s TestArray2) MarshalBinary() ([]byte, error) {
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
func (s *TestArray2) UnmarshalBinary(inp []byte) error {
r := bytes.NewReader(inp)
d := xdr.NewDecoder(r)
_, err := s.DecodeFrom(d, xdr.DecodeDefaultMaxDepth)
o := xdr.DefaultDecodeOptions
o.MaxInputLen = len(inp)
d := xdr.NewDecoderWithOptions(r, o)
_, err := s.DecodeFrom(d, o.MaxDepth)
return err
}

Expand All @@ -182,11 +193,9 @@ var (
_ encoding.BinaryUnmarshaler = (*TestArray2)(nil)
)

// xdrType signals that this type is an type representing
// representing XDR values defined by this package.
// xdrType signals that this type represents XDR values defined by this package.
func (s TestArray2) xdrType() {}

var _ xdrType = (*TestArray2)(nil)

var fmtTest = fmt.Sprint("this is a dummy usage of fmt")

var fmtTest = fmt.Sprint("this is a dummy usage of fmt")
Loading
Loading