github.com/primecitizens/pcz/std@v0.2.1/encoding/binfmt/wasm/import.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  
     4  package wasm
     5  
     6  import (
     7  	"unsafe"
     8  )
     9  
    10  type ImportSection struct {
    11  	// Entries is the count of import entries to decode.
    12  	Entries uint32
    13  }
    14  
    15  func (sect *ImportSection) Decode(data []byte) (next []byte, ok bool) {
    16  	sect.Entries, next, ok = readU32(data)
    17  	return
    18  }
    19  
    20  type ImportKind uint8
    21  
    22  const (
    23  	ImportKindFunction ImportKind = iota
    24  	ImportKindTable
    25  	ImportKindMemory
    26  	ImportKindGlobal
    27  )
    28  
    29  type ImportEntry struct {
    30  	Module string
    31  	Field  string
    32  
    33  	Kind ImportKind
    34  
    35  	Function FunctionImport
    36  	Table    TableImport
    37  	Memory   MemoryImport
    38  	Global   GlobalImport
    39  }
    40  
    41  func (e *ImportEntry) Parse(data []byte) (next []byte, ok bool) {
    42  	sz, data, ok := readU32(data)
    43  	if ok = ok && int(sz) < len(data); !ok {
    44  		return
    45  	}
    46  
    47  	e.Module = unsafe.String(unsafe.SliceData(data), sz)
    48  
    49  	sz, data, ok = readU32(data[sz:])
    50  	if ok = ok && int(sz) < len(data); !ok {
    51  		return
    52  	}
    53  
    54  	e.Field = unsafe.String(unsafe.SliceData(data), sz)
    55  
    56  	if e.Kind, data, ok = readU8[ImportKind](data[sz:]); !ok {
    57  		return
    58  	}
    59  
    60  	switch e.Kind {
    61  	case ImportKindFunction:
    62  		e.Function.Index, next, ok = readU32(data)
    63  	case ImportKindTable:
    64  		if e.Table.ElemType, data, ok = readU8[int8](data); !ok {
    65  			return
    66  		}
    67  
    68  		next, ok = e.Table.Limits.Parse(data)
    69  	case ImportKindMemory:
    70  		next, ok = e.Memory.Limits.Parse(data)
    71  	case ImportKindGlobal:
    72  		if e.Global.ContentType, data, ok = readU8[int8](data); !ok {
    73  			return
    74  		}
    75  		var mutable uint8
    76  		mutable, next, ok = readU8[uint8](data)
    77  		e.Global.Mutable = mutable == 1
    78  	default:
    79  		return
    80  	}
    81  
    82  	return
    83  }
    84  
    85  type FunctionImport struct {
    86  	Index uint32
    87  }
    88  
    89  type MemoryImport struct {
    90  	Limits ResizableLimits
    91  }
    92  
    93  type TableImport struct {
    94  	ElemType int8
    95  	Limits   ResizableLimits
    96  }
    97  
    98  type GlobalImport struct {
    99  	ContentType int8
   100  	Mutable     bool
   101  }
   102  
   103  type ResizableLimits struct {
   104  	Initial uint32
   105  	Maximum uint32
   106  }
   107  
   108  func (l *ResizableLimits) Parse(data []byte) (next []byte, ok bool) {
   109  	var hasMax uint8
   110  	if hasMax, data, ok = readU8[uint8](data); !ok {
   111  		return
   112  	}
   113  
   114  	if l.Initial, data, ok = readU32(data); !ok {
   115  		return
   116  	}
   117  
   118  	if hasMax == 0 {
   119  		return data, true
   120  	}
   121  
   122  	l.Maximum, next, ok = readU32(data)
   123  	return
   124  }