{"id":13601177,"url":"https://github.com/perlin-network/life","last_synced_at":"2025-05-14T14:08:34.654Z","repository":{"id":42622941,"uuid":"141270618","full_name":"perlin-network/life","owner":"perlin-network","description":"A secure WebAssembly VM catered for decentralized applications.","archived":false,"fork":false,"pushed_at":"2022-03-30T17:36:24.000Z","size":4132,"stargazers_count":1699,"open_issues_count":36,"forks_count":119,"subscribers_count":57,"default_branch":"master","last_synced_at":"2025-04-11T18:22:45.184Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/perlin-network.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-17T10:02:23.000Z","updated_at":"2025-02-26T04:16:30.000Z","dependencies_parsed_at":"2022-09-03T09:51:27.193Z","dependency_job_id":null,"html_url":"https://github.com/perlin-network/life","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perlin-network%2Flife","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perlin-network%2Flife/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perlin-network%2Flife/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perlin-network%2Flife/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/perlin-network","download_url":"https://codeload.github.com/perlin-network/life/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254159825,"owners_count":22024564,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T18:00:57.423Z","updated_at":"2025-05-14T14:08:34.634Z","avatar_url":"https://github.com/perlin-network.png","language":"Go","funding_links":[],"categories":["Go","Runtimes"],"sub_categories":["**Go**"],"readme":"# Life\n\n[![GoDoc][1]][2] [![Discord][7]][8] [![MIT licensed][5]][6] [![Build Status][9]][10] [![Go Report Card][11]][12]\n\n[1]: https://godoc.org/github.com/perlin-network/life?status.svg\n[2]: https://godoc.org/github.com/perlin-network/life\n[5]: https://img.shields.io/badge/license-MIT-blue.svg\n[6]: LICENSE\n[7]: https://shields.dougley.com/discord/458332417909063682.svg\n[8]: https://discord.gg/dMYfDPM\n[9]: https://travis-ci.org/perlin-network/life.svg?branch=master\n[10]: https://travis-ci.org/perlin-network/life\n[11]: https://goreportcard.com/badge/github.com/perlin-network/life\n[12]: https://goreportcard.com/report/github.com/perlin-network/life\n\n**life** is a secure \u0026 fast WebAssembly VM built for decentralized applications, written in [Go](https://golang.org/) by Perlin Network.\n\n## Features\n\n- **Fast** - Includes a fast interpreter and an experimental AOT compilation engine.\n- **Correct** - Implements WebAssembly execution semantics and passes most of the [official test suite](https://github.com/WebAssembly/testsuite) (66/72 passed, none of the failures are related to the execution semantics).\n- **Secure** - User code executed is fully sandboxed. A WebAssembly module's access to resources (instruction cycles, memory usage) may easily be controlled to the very finest detail.\n- **Pure** - Does not rely on any native dependencies in interpreter-only mode, and may easily be cross-compiled for running WebAssembly modules on practically any platform (Windows/Linux/Mac/Android/iOS/etc).\n- **Practical** - Make full use of the minimal nature of WebAssembly to write code once and run anywhere. Completely customize how WebAssembly module imports are resolved and integrated, and have complete control over the execution lifecycle of your WebAssembly modules.\n\n\n## Getting Started\n\n```bash\n# enable go modules: https://github.com/golang/go/wiki/Modules\nexport GO111MODULE=on\n\n# download the dependencies to vendor folder\ngo mod vendor\n\n# build test suite runner\ngo build github.com/perlin-network/life/spec/test_runner\n\n# run official test suite\npython3 run_spec_tests.py /path/to/testsuite\n\n# build main program\ngo build\n\n# run your wasm program\n# entry point is `app_main` by default if entry flag is omitted, array with \n# param in it is optional arguements for entrypoint. params should be converted into `int`.\n./life -entry 'method' /path/to/your/wasm/program.wasm [param,...] \n\n# run your wasm program with the Polymerase AOT compilation engine enabled\n./life -polymerase -entry 'method' /path/to/your/wasm/program.wasm [param,...]\n\n```\n\n## Executing WebAssembly Modules\n\nSuppose we have already loaded our *.wasm module's bytecode into the variable `var input []byte`.\n\nLets pass the bytecode into a newly instantiated virtual machine:\n```go\nvm, err := exec.NewVirtualMachine(input, exec.VMConfig{}, \u0026exec.NopResolver{}, nil)\nif err != nil { // if the wasm bytecode is invalid\n    panic(err)\n}\n```\n\nLookup the function ID to a desired entry-point function titled `app_main`:\n```go\nentryID, ok := vm.GetFunctionExport(\"app_main\") // can be changed to your own exported function\nif !ok {\n    panic(\"entry function not found\")\n}\n```\n\nAnd startup the VM; printing out the result of the entry-point function:\n```go\nret, err := vm.Run(entryID)\nif err != nil {\n    vm.PrintStackTrace()\n    panic(err)\n}\nfmt.Printf(\"return value = %d\\n\", ret)\n```\n\nInterested to tinker with more options? Check out our fully-documented example [here](main.go) .\n\n## Import Resolvers\n\nOne extremely powerful feature is that you may completely customize how WebAssembly module import functions are resolved, executed, and defined.\n\nWith import resolvers, you may now securely call external code/functions inside your WebAssembly modules which are executed through **life**.\n\nTake for example the following Rust module compiled down to a WebAssembly module:\n\n```rust\nextern \"C\" {\n    fn __life_log(msg: *const u8, len: usize);\n}\n\n#[no_mangle]\npub extern \"C\" fn app_main() -\u003e i32 {\n    let message = \"This is being called outside of WebAssembly!\".as_bytes();\n\n    unsafe {\n        __life_log(message.as_ptr(), message.len());\n    }\n\n    return 0;\n}\n```\n\nWe can define an import resolver into our WebAssembly virtual machine that will let us define whatever code the function `__life_log` may execute in our host environment.\n\n```go\ntype Resolver struct{}\n\nfunc (r *Resolver) ResolveFunc(module, field string) exec.FunctionImport {\n\tswitch module {\n\tcase \"env\":\n\t\tswitch field {\n\t\tcase \"__life_log\":\n\t\t\treturn func(vm *exec.VirtualMachine) int64 {\n\t\t\t\tptr := int(uint32(vm.GetCurrentFrame().Locals[0]))\n\t\t\t\tmsgLen := int(uint32(vm.GetCurrentFrame().Locals[1]))\n\t\t\t\tmsg := vm.Memory[ptr : ptr+msgLen]\n\t\t\t\tfmt.Printf(\"[app] %s\\n\", string(msg))\n\t\t\t\treturn 0\n\t\t\t}\n\n\t\tdefault:\n\t\t\tpanic(fmt.Errorf(\"unknown import resolved: %s\", field))\n\t\t}\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unknown module: %s\", module))\n\t}\n}\n\nfunc (r *Resolver) ResolveGlobal(module, field string) int64 {\n\tpanic(\"we're not resolving global variables for now\")\n}\n\n```\n\nWe can then include the import resolver into our WebAssembly VM:\n\n```go\nvm, err := exec.NewVirtualMachine(input, exec.VMConfig{}, new(Resolver), nil)\nif err != nil {\n    panic(err)\n}\n```\n\nAnd have the VM run the entry-point function `app_main` to see the result:\n\n```bash\n[app] This is being called from outside WebAssembly!\n```\n\n## Benchmarks\n\nWe benchmarked **life** alongside a couple of other WebAssembly implementations in different programming languages ([go-interpreter/wagon](https://github.com/go-interpreter/wagon), [paritytech/wasmi](https://github.com/paritytech/wasmi)).\n\n\u003cp align=\"center\"\u003e\n\t\u003cimg width=600 src=\"media/bench.png\"\u003e\n\u003c/p\u003e\n\nRaw results are [here](https://gist.github.com/losfair/5605f61602537916f342c3e4ace1cc9b).\n\n## Contributions\n\nWe at Perlin love reaching out to the open-source community and are open to accepting issues and pull-requests.\n\nFor all code contributions, please ensure they adhere as close as possible to the following guidelines:\n\n1. **Strictly** follows the formatting and styling rules denoted [here](https://github.com/golang/go/wiki/CodeReviewComments).\n2. Commit messages are in the format `module_name: Change typed down as a sentence.` This allows our maintainers and everyone else to know what specific code changes you wish to address.\n    - `compiler/liveness: Implemented full liveness analysis.`\n    - `exec/helpers: Added function to run the VM with time limit.`\n3. Consider backwards compatibility. New methods are perfectly fine, though changing the existing public API should only be done should there be a good reason.\n\nIf you...\n\n1. love the work we are doing,\n2. want to work full-time with us,\n3. or are interested in getting paid for working on open-source projects\n\n... **we're hiring**.\n\nTo grab our attention, just make a PR and start contributing.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperlin-network%2Flife","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fperlin-network%2Flife","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperlin-network%2Flife/lists"}