github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/examples/import-go/age-calculator.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	_ "embed"
     6  	"fmt"
     7  	"log"
     8  	"os"
     9  	"strconv"
    10  	"time"
    11  
    12  	"github.com/bananabytelabs/wazero"
    13  )
    14  
    15  // ageCalculatorWasm was generated by the following:
    16  //
    17  //	cd testdata; wat2wasm --debug-names age_calculator.wat
    18  //
    19  //go:embed testdata/age_calculator.wasm
    20  var ageCalculatorWasm []byte
    21  
    22  // main shows how to define, import and call a Go-defined function from a
    23  // WebAssembly-defined function.
    24  //
    25  // See README.md for a full description.
    26  func main() {
    27  	// Choose the context to use for function calls.
    28  	ctx := context.Background()
    29  
    30  	// Create a new WebAssembly Runtime.
    31  	r := wazero.NewRuntime(ctx)
    32  	defer r.Close(ctx) // This closes everything this Runtime created.
    33  
    34  	// Instantiate a Go-defined module named "env" that exports functions to
    35  	// get the current year and log to the console.
    36  	//
    37  	// Note: As noted on wazero.HostFunctionBuilder documentation, function
    38  	// signatures are constrained to a subset of numeric types.
    39  	// Note: "env" is a module name conventionally used for arbitrary
    40  	// host-defined functions, but any name would do.
    41  	_, err := r.NewHostModuleBuilder("env").
    42  		NewFunctionBuilder().
    43  		WithFunc(func(v uint32) {
    44  			fmt.Println("log_i32 >>", v)
    45  		}).
    46  		Export("log_i32").
    47  		NewFunctionBuilder().
    48  		WithFunc(func() uint32 {
    49  			if envYear, err := strconv.ParseUint(os.Getenv("CURRENT_YEAR"), 10, 64); err == nil {
    50  				return uint32(envYear) // Allow env-override to prevent annual test maintenance!
    51  			}
    52  			return uint32(time.Now().Year())
    53  		}).
    54  		Export("current_year").
    55  		Instantiate(ctx)
    56  	if err != nil {
    57  		log.Panicln(err)
    58  	}
    59  
    60  	// Instantiate a WebAssembly module named "age-calculator" that imports
    61  	// functions defined in "env".
    62  	//
    63  	// Note: The import syntax in both Text and Binary format is the same
    64  	// regardless of if the function was defined in Go or WebAssembly.
    65  	ageCalculator, err := r.Instantiate(ctx, ageCalculatorWasm)
    66  	if err != nil {
    67  		log.Panicln(err)
    68  	}
    69  
    70  	// Read the birthYear from the arguments to main
    71  	birthYear, err := strconv.ParseUint(os.Args[1], 10, 64)
    72  	if err != nil {
    73  		log.Panicf("invalid arg %v: %v", os.Args[1], err)
    74  	}
    75  
    76  	// First, try calling the "get_age" function and printing to the console externally.
    77  	results, err := ageCalculator.ExportedFunction("get_age").Call(ctx, birthYear)
    78  	if err != nil {
    79  		log.Panicln(err)
    80  	}
    81  	fmt.Println("println >>", results[0])
    82  
    83  	// First, try calling the "log_age" function and printing to the console externally.
    84  	_, err = ageCalculator.ExportedFunction("log_age").Call(ctx, birthYear)
    85  	if err != nil {
    86  		log.Panicln(err)
    87  	}
    88  }