25
vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/opa.go
generated
vendored
Normal file
25
vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/opa.go
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/opa.wasm
generated
vendored
Normal file
BIN
vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/opa.wasm
generated
vendored
Normal file
Binary file not shown.
1013
vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go
generated
vendored
Normal file
1013
vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
42
vendor/github.com/open-policy-agent/opa/internal/file/archive/tarball.go
generated
vendored
Normal file
42
vendor/github.com/open-policy-agent/opa/internal/file/archive/tarball.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
package archive
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MustWriteTarGz write the list of file names and content
|
||||
// into a tarball.
|
||||
func MustWriteTarGz(files [][2]string) *bytes.Buffer {
|
||||
var buf bytes.Buffer
|
||||
gw := gzip.NewWriter(&buf)
|
||||
defer gw.Close()
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
for _, file := range files {
|
||||
if err := WriteFile(tw, file[0], []byte(file[1])); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return &buf
|
||||
}
|
||||
|
||||
// WriteFile adds a file header with content to the given tar writer
|
||||
func WriteFile(tw *tar.Writer, path string, bs []byte) error {
|
||||
|
||||
hdr := &tar.Header{
|
||||
Name: "/" + strings.TrimLeft(path, "/"),
|
||||
Mode: 0600,
|
||||
Typeflag: tar.TypeReg,
|
||||
Size: int64(len(bs)),
|
||||
}
|
||||
|
||||
if err := tw.WriteHeader(hdr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := tw.Write(bs)
|
||||
return err
|
||||
}
|
||||
42
vendor/github.com/open-policy-agent/opa/internal/file/url/url.go
generated
vendored
Normal file
42
vendor/github.com/open-policy-agent/opa/internal/file/url/url.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2019 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package url contains helpers for dealing with file paths and URLs.
|
||||
package url
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var goos = runtime.GOOS
|
||||
|
||||
// Clean returns a cleaned file path that may or may not be a URL.
|
||||
func Clean(path string) (string, error) {
|
||||
|
||||
if strings.Contains(path, "://") {
|
||||
|
||||
url, err := url.Parse(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if url.Scheme != "file" {
|
||||
return "", fmt.Errorf("unsupported URL scheme: %v", path)
|
||||
}
|
||||
|
||||
path = url.Path
|
||||
|
||||
// Trim leading slash on Windows if present. The url.Path field returned
|
||||
// by url.Parse has leading slash that causes CreateFile() calls to fail
|
||||
// on Windows. See https://github.com/golang/go/issues/6027 for details.
|
||||
if goos == "windows" && len(path) >= 1 && path[0] == '/' {
|
||||
path = path[1:]
|
||||
}
|
||||
}
|
||||
|
||||
return path, nil
|
||||
}
|
||||
395
vendor/github.com/open-policy-agent/opa/internal/ir/ir.go
generated
vendored
Normal file
395
vendor/github.com/open-policy-agent/opa/internal/ir/ir.go
generated
vendored
Normal file
@@ -0,0 +1,395 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package ir defines an intermediate representation (IR) for Rego.
|
||||
//
|
||||
// The IR specifies an imperative execution model for Rego policies similar to a
|
||||
// query plan in traditional databases.
|
||||
package ir
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type (
|
||||
// Policy represents a planned policy query.
|
||||
Policy struct {
|
||||
Static *Static
|
||||
Plan *Plan
|
||||
Funcs *Funcs
|
||||
}
|
||||
|
||||
// Static represents a static data segment that is indexed into by the policy.
|
||||
Static struct {
|
||||
Strings []*StringConst
|
||||
BuiltinFuncs []*BuiltinFunc
|
||||
}
|
||||
|
||||
// BuiltinFunc represents a built-in function that may be required by the
|
||||
// policy.
|
||||
BuiltinFunc struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// Funcs represents a collection of planned functions to include in the
|
||||
// policy.
|
||||
Funcs struct {
|
||||
Funcs []*Func
|
||||
}
|
||||
|
||||
// Func represents a named plan (function) that can be invoked. Functions
|
||||
// accept one or more parameters and return a value. By convention, the
|
||||
// input document and data documents are always passed as the first and
|
||||
// second arguments (respectively).
|
||||
Func struct {
|
||||
Name string
|
||||
Params []Local
|
||||
Return Local
|
||||
Blocks []*Block // TODO(tsandall): should this be a plan?
|
||||
}
|
||||
|
||||
// Plan represents an ordered series of blocks to execute. Plan execution
|
||||
// stops when a return statement is reached. Blocks are executed in-order.
|
||||
Plan struct {
|
||||
Blocks []*Block
|
||||
}
|
||||
|
||||
// Block represents an ordered sequence of statements to execute. Blocks are
|
||||
// executed until a return statement is encountered, a statement is undefined,
|
||||
// or there are no more statements. If all statements are defined but no return
|
||||
// statement is encountered, the block is undefined.
|
||||
Block struct {
|
||||
Stmts []Stmt
|
||||
}
|
||||
|
||||
// Stmt represents an operation (e.g., comparison, loop, dot, etc.) to execute.
|
||||
Stmt interface {
|
||||
}
|
||||
|
||||
// Local represents a plan-scoped variable.
|
||||
//
|
||||
// TODO(tsandall): should this be int32 for safety?
|
||||
Local int
|
||||
|
||||
// Const represents a constant value from the policy.
|
||||
Const interface {
|
||||
typeMarker()
|
||||
}
|
||||
|
||||
// NullConst represents a null value.
|
||||
NullConst struct{}
|
||||
|
||||
// BooleanConst represents a boolean value.
|
||||
BooleanConst struct {
|
||||
Value bool
|
||||
}
|
||||
|
||||
// StringConst represents a string value.
|
||||
StringConst struct {
|
||||
Value string
|
||||
}
|
||||
|
||||
// IntConst represents an integer constant.
|
||||
IntConst struct {
|
||||
Value int64
|
||||
}
|
||||
|
||||
// FloatConst represents a floating-point constant.
|
||||
FloatConst struct {
|
||||
Value float64
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
// Input is the local variable that refers to the global input document.
|
||||
Input Local = iota
|
||||
|
||||
// Data is the local variable that refers to the global data document.
|
||||
Data
|
||||
|
||||
// Unused is the free local variable that can be allocated in a plan.
|
||||
Unused
|
||||
)
|
||||
|
||||
func (a *Policy) String() string {
|
||||
return "Policy"
|
||||
}
|
||||
|
||||
func (a *Static) String() string {
|
||||
return fmt.Sprintf("Static (%d strings)", len(a.Strings))
|
||||
}
|
||||
|
||||
func (a *Funcs) String() string {
|
||||
return fmt.Sprintf("Funcs (%d funcs)", len(a.Funcs))
|
||||
}
|
||||
|
||||
func (a *Func) String() string {
|
||||
return fmt.Sprintf("%v (%d params: %v, %d blocks)", a.Name, len(a.Params), a.Params, len(a.Blocks))
|
||||
}
|
||||
|
||||
func (a *Plan) String() string {
|
||||
return fmt.Sprintf("Plan (%d blocks)", len(a.Blocks))
|
||||
}
|
||||
|
||||
func (a *Block) String() string {
|
||||
return fmt.Sprintf("Block (%d statements)", len(a.Stmts))
|
||||
}
|
||||
|
||||
func (a *BooleanConst) typeMarker() {}
|
||||
func (a *NullConst) typeMarker() {}
|
||||
func (a *IntConst) typeMarker() {}
|
||||
func (a *FloatConst) typeMarker() {}
|
||||
func (a *StringConst) typeMarker() {}
|
||||
|
||||
// ReturnLocalStmt represents a return statement that yields a local value.
|
||||
type ReturnLocalStmt struct {
|
||||
Source Local
|
||||
}
|
||||
|
||||
// CallStmt represents a named function call. The result should be stored in the
|
||||
// result local.
|
||||
type CallStmt struct {
|
||||
Func string
|
||||
Args []Local
|
||||
Result Local
|
||||
}
|
||||
|
||||
// BlockStmt represents a nested block. Nested blocks and break statements can
|
||||
// be used to short-circuit execution.
|
||||
type BlockStmt struct {
|
||||
Blocks []*Block
|
||||
}
|
||||
|
||||
func (a *BlockStmt) String() string {
|
||||
return fmt.Sprintf("BlockStmt (%d blocks)", len(a.Blocks))
|
||||
}
|
||||
|
||||
// BreakStmt represents a jump out of the current block. The index specifies how
|
||||
// many blocks to jump starting from zero (the current block). Execution will
|
||||
// continue from the end of the block that is jumped to.
|
||||
type BreakStmt struct {
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// DotStmt represents a lookup operation on a value (e.g., array, object, etc.)
|
||||
// The source of a DotStmt may be a scalar value in which case the statement
|
||||
// will be undefined.
|
||||
type DotStmt struct {
|
||||
Source Local
|
||||
Key Local
|
||||
Target Local
|
||||
}
|
||||
|
||||
// LenStmt represents a length() operation on a local variable. The
|
||||
// result is stored in the target local variable.
|
||||
type LenStmt struct {
|
||||
Source Local
|
||||
Target Local
|
||||
}
|
||||
|
||||
// ScanStmt represents a linear scan over a composite value. The
|
||||
// source may be a scalar in which case the block will never execute.
|
||||
type ScanStmt struct {
|
||||
Source Local
|
||||
Key Local
|
||||
Value Local
|
||||
Block *Block
|
||||
}
|
||||
|
||||
// NotStmt represents a negated statement.
|
||||
type NotStmt struct {
|
||||
Block *Block
|
||||
}
|
||||
|
||||
// AssignBooleanStmt represents an assignment of a boolean value to a local variable.
|
||||
type AssignBooleanStmt struct {
|
||||
Value bool
|
||||
Target Local
|
||||
}
|
||||
|
||||
// AssignIntStmt represents an assignment of an integer value to a
|
||||
// local variable.
|
||||
type AssignIntStmt struct {
|
||||
Value int64
|
||||
Target Local
|
||||
}
|
||||
|
||||
// AssignVarStmt represents an assignment of one local variable to another.
|
||||
type AssignVarStmt struct {
|
||||
Source Local
|
||||
Target Local
|
||||
}
|
||||
|
||||
// AssignVarOnceStmt represents an assignment of one local variable to another.
|
||||
// If the target is defined, execution aborts with a conflict error.
|
||||
//
|
||||
// TODO(tsandall): is there a better name for this?
|
||||
type AssignVarOnceStmt struct {
|
||||
Target Local
|
||||
Source Local
|
||||
}
|
||||
|
||||
// MakeStringStmt constructs a local variable that refers to a string constant.
|
||||
type MakeStringStmt struct {
|
||||
Index int
|
||||
Target Local
|
||||
}
|
||||
|
||||
// MakeNullStmt constructs a local variable that refers to a null value.
|
||||
type MakeNullStmt struct {
|
||||
Target Local
|
||||
}
|
||||
|
||||
// MakeBooleanStmt constructs a local variable that refers to a boolean value.
|
||||
type MakeBooleanStmt struct {
|
||||
Value bool
|
||||
Target Local
|
||||
}
|
||||
|
||||
// MakeNumberFloatStmt constructs a local variable that refers to a
|
||||
// floating-point number value.
|
||||
type MakeNumberFloatStmt struct {
|
||||
Value float64
|
||||
Target Local
|
||||
}
|
||||
|
||||
// MakeNumberIntStmt constructs a local variable that refers to an integer value.
|
||||
type MakeNumberIntStmt struct {
|
||||
Value int64
|
||||
Target Local
|
||||
}
|
||||
|
||||
// MakeNumberRefStmt constructs a local variable that refers to a number stored as a string.
|
||||
type MakeNumberRefStmt struct {
|
||||
Index int
|
||||
Target Local
|
||||
}
|
||||
|
||||
// MakeArrayStmt constructs a local variable that refers to an array value.
|
||||
type MakeArrayStmt struct {
|
||||
Capacity int32
|
||||
Target Local
|
||||
}
|
||||
|
||||
// MakeObjectStmt constructs a local variable that refers to an object value.
|
||||
type MakeObjectStmt struct {
|
||||
Target Local
|
||||
}
|
||||
|
||||
// MakeSetStmt constructs a local variable that refers to a set value.
|
||||
type MakeSetStmt struct {
|
||||
Target Local
|
||||
}
|
||||
|
||||
// EqualStmt represents an value-equality check of two local variables.
|
||||
type EqualStmt struct {
|
||||
A Local
|
||||
B Local
|
||||
}
|
||||
|
||||
// LessThanStmt represents a < check of two local variables.
|
||||
type LessThanStmt struct {
|
||||
A Local
|
||||
B Local
|
||||
}
|
||||
|
||||
// LessThanEqualStmt represents a <= check of two local variables.
|
||||
type LessThanEqualStmt struct {
|
||||
A Local
|
||||
B Local
|
||||
}
|
||||
|
||||
// GreaterThanStmt represents a > check of two local variables.
|
||||
type GreaterThanStmt struct {
|
||||
A Local
|
||||
B Local
|
||||
}
|
||||
|
||||
// GreaterThanEqualStmt represents a >= check of two local variables.
|
||||
type GreaterThanEqualStmt struct {
|
||||
A Local
|
||||
B Local
|
||||
}
|
||||
|
||||
// NotEqualStmt represents a != check of two local variables.
|
||||
type NotEqualStmt struct {
|
||||
A Local
|
||||
B Local
|
||||
}
|
||||
|
||||
// IsArrayStmt represents a dynamic type check on a local variable.
|
||||
type IsArrayStmt struct {
|
||||
Source Local
|
||||
}
|
||||
|
||||
// IsObjectStmt represents a dynamic type check on a local variable.
|
||||
type IsObjectStmt struct {
|
||||
Source Local
|
||||
}
|
||||
|
||||
// IsDefinedStmt represents a check of whether a local variable is defined.
|
||||
type IsDefinedStmt struct {
|
||||
Source Local
|
||||
}
|
||||
|
||||
// IsUndefinedStmt represents a check of whether local variable is undefined.
|
||||
type IsUndefinedStmt struct {
|
||||
Source Local
|
||||
}
|
||||
|
||||
// ArrayAppendStmt represents a dynamic append operation of a value
|
||||
// onto an array.
|
||||
type ArrayAppendStmt struct {
|
||||
Value Local
|
||||
Array Local
|
||||
}
|
||||
|
||||
// ObjectInsertStmt represents a dynamic insert operation of a
|
||||
// key/value pair into an object.
|
||||
type ObjectInsertStmt struct {
|
||||
Key Local
|
||||
Value Local
|
||||
Object Local
|
||||
}
|
||||
|
||||
// ObjectInsertOnceStmt represents a dynamic insert operation of a key/value
|
||||
// pair into an object. If the key already exists and the value differs,
|
||||
// execution aborts with a conflict error.
|
||||
type ObjectInsertOnceStmt struct {
|
||||
Key Local
|
||||
Value Local
|
||||
Object Local
|
||||
}
|
||||
|
||||
// ObjectMergeStmt performs a recursive merge of two object values. If either of
|
||||
// the locals refer to non-object values this operation will abort with a
|
||||
// conflict error. Overlapping object keys are merged recursively.
|
||||
type ObjectMergeStmt struct {
|
||||
A Local
|
||||
B Local
|
||||
Target Local
|
||||
}
|
||||
|
||||
// SetAddStmt represents a dynamic add operation of an element into a set.
|
||||
type SetAddStmt struct {
|
||||
Value Local
|
||||
Set Local
|
||||
}
|
||||
|
||||
// WithStmt replaces the Local or a portion of the document referred to by the
|
||||
// Local with the Value and executes the contained block. If the Path is
|
||||
// non-empty, the Value is upserted into the Local. If the intermediate nodes in
|
||||
// the Local referred to by the Path do not exist, they will be created. When
|
||||
// the WithStmt finishes the Local is reset to it's original value.
|
||||
type WithStmt struct {
|
||||
Local Local
|
||||
Path []int
|
||||
Value Local
|
||||
Block *Block
|
||||
}
|
||||
|
||||
// ResultSetAdd adds a value into the result set returned by the query plan.
|
||||
type ResultSetAdd struct {
|
||||
Value Local
|
||||
}
|
||||
44
vendor/github.com/open-policy-agent/opa/internal/ir/pretty.go
generated
vendored
Normal file
44
vendor/github.com/open-policy-agent/opa/internal/ir/pretty.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ir
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Pretty writes a human-readable representation of an IR object to w.
|
||||
func Pretty(w io.Writer, x interface{}) {
|
||||
|
||||
pp := &prettyPrinter{
|
||||
depth: -1,
|
||||
w: w,
|
||||
}
|
||||
Walk(pp, x)
|
||||
}
|
||||
|
||||
type prettyPrinter struct {
|
||||
depth int
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func (pp *prettyPrinter) Before(x interface{}) {
|
||||
pp.depth++
|
||||
}
|
||||
|
||||
func (pp *prettyPrinter) After(x interface{}) {
|
||||
pp.depth--
|
||||
}
|
||||
|
||||
func (pp *prettyPrinter) Visit(x interface{}) (Visitor, error) {
|
||||
pp.writeIndent("%T %+v", x, x)
|
||||
return pp, nil
|
||||
}
|
||||
|
||||
func (pp *prettyPrinter) writeIndent(f string, a ...interface{}) {
|
||||
pad := strings.Repeat("| ", pp.depth)
|
||||
fmt.Fprintf(pp.w, pad+f+"\n", a...)
|
||||
}
|
||||
84
vendor/github.com/open-policy-agent/opa/internal/ir/walk.go
generated
vendored
Normal file
84
vendor/github.com/open-policy-agent/opa/internal/ir/walk.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ir
|
||||
|
||||
// Visitor defines the interface for visiting IR nodes.
|
||||
type Visitor interface {
|
||||
Before(x interface{})
|
||||
Visit(x interface{}) (Visitor, error)
|
||||
After(x interface{})
|
||||
}
|
||||
|
||||
// Walk invokes the visitor for nodes under x.
|
||||
func Walk(vis Visitor, x interface{}) error {
|
||||
impl := walkerImpl{
|
||||
vis: vis,
|
||||
}
|
||||
impl.walk(x)
|
||||
return impl.err
|
||||
}
|
||||
|
||||
type walkerImpl struct {
|
||||
vis Visitor
|
||||
err error
|
||||
}
|
||||
|
||||
func (w *walkerImpl) walk(x interface{}) {
|
||||
|
||||
if x == nil {
|
||||
return
|
||||
}
|
||||
|
||||
prev := w.vis
|
||||
w.vis.Before(x)
|
||||
defer w.vis.After(x)
|
||||
w.vis, w.err = w.vis.Visit(x)
|
||||
if w.err != nil {
|
||||
return
|
||||
} else if w.vis == nil {
|
||||
w.vis = prev
|
||||
return
|
||||
}
|
||||
|
||||
switch x := x.(type) {
|
||||
case *Policy:
|
||||
w.walk(x.Static)
|
||||
w.walk(x.Plan)
|
||||
w.walk(x.Funcs)
|
||||
case *Static:
|
||||
for _, s := range x.Strings {
|
||||
w.walk(s)
|
||||
}
|
||||
for _, f := range x.BuiltinFuncs {
|
||||
w.walk(f)
|
||||
}
|
||||
case *Funcs:
|
||||
for _, fn := range x.Funcs {
|
||||
w.walk(fn)
|
||||
}
|
||||
case *Func:
|
||||
for _, b := range x.Blocks {
|
||||
w.walk(b)
|
||||
}
|
||||
case *Plan:
|
||||
for _, b := range x.Blocks {
|
||||
w.walk(b)
|
||||
}
|
||||
case *Block:
|
||||
for _, s := range x.Stmts {
|
||||
w.walk(s)
|
||||
}
|
||||
case *BlockStmt:
|
||||
for _, b := range x.Blocks {
|
||||
w.walk(b)
|
||||
}
|
||||
case *ScanStmt:
|
||||
w.walk(x.Block)
|
||||
case *NotStmt:
|
||||
w.walk(x.Block)
|
||||
case *WithStmt:
|
||||
w.walk(x.Block)
|
||||
}
|
||||
}
|
||||
170
vendor/github.com/open-policy-agent/opa/internal/leb128/leb128.go
generated
vendored
Normal file
170
vendor/github.com/open-policy-agent/opa/internal/leb128/leb128.go
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package leb128 implements LEB128 integer encoding.
|
||||
package leb128
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// MustReadVarInt32 returns an int32 from r or panics.
|
||||
func MustReadVarInt32(r io.Reader) int32 {
|
||||
i32, err := ReadVarInt32(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return i32
|
||||
}
|
||||
|
||||
// MustReadVarInt64 returns an int64 from r or panics.
|
||||
func MustReadVarInt64(r io.Reader) int64 {
|
||||
i64, err := ReadVarInt64(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return i64
|
||||
}
|
||||
|
||||
// MustReadVarUint32 returns an uint32 from r or panics.
|
||||
func MustReadVarUint32(r io.Reader) uint32 {
|
||||
u32, err := ReadVarUint32(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return u32
|
||||
}
|
||||
|
||||
// MustReadVarUint64 returns an uint64 from r or panics.
|
||||
func MustReadVarUint64(r io.Reader) uint64 {
|
||||
u64, err := ReadVarUint64(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return u64
|
||||
}
|
||||
|
||||
// Copied rom http://dwarfstd.org/doc/Dwarf3.pdf.
|
||||
|
||||
// ReadVarUint32 tries to read a uint32 from r.
|
||||
func ReadVarUint32(r io.Reader) (uint32, error) {
|
||||
u64, err := ReadVarUint64(r)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint32(u64), nil
|
||||
}
|
||||
|
||||
// ReadVarUint64 tries to read a uint64 from r.
|
||||
func ReadVarUint64(r io.Reader) (uint64, error) {
|
||||
var result uint64
|
||||
var shift uint64
|
||||
buf := make([]byte, 1)
|
||||
for {
|
||||
if _, err := r.Read(buf); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
v := uint64(buf[0])
|
||||
result |= (v & 0x7F) << shift
|
||||
if v&0x80 == 0 {
|
||||
return result, nil
|
||||
}
|
||||
shift += 7
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ReadVarInt32 tries to read a int32 from r.
|
||||
func ReadVarInt32(r io.Reader) (int32, error) {
|
||||
i64, err := ReadVarInt64(r)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int32(i64), nil
|
||||
}
|
||||
|
||||
// ReadVarInt64 tries to read a int64 from r.
|
||||
func ReadVarInt64(r io.Reader) (int64, error) {
|
||||
var result int64
|
||||
var shift uint64
|
||||
size := uint64(32)
|
||||
buf := make([]byte, 1)
|
||||
for {
|
||||
if _, err := r.Read(buf); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
v := int64(buf[0])
|
||||
result |= (v & 0x7F) << shift
|
||||
shift += 7
|
||||
if v&0x80 == 0 {
|
||||
if (shift < size) && (v&0x40 != 0) {
|
||||
result |= (^0 << shift)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WriteVarUint32 writes u to w.
|
||||
func WriteVarUint32(w io.Writer, u uint32) error {
|
||||
var b []byte
|
||||
_, err := w.Write(appendUleb128(b, uint64(u)))
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteVarUint64 writes u to w.
|
||||
func WriteVarUint64(w io.Writer, u uint64) error {
|
||||
var b []byte
|
||||
_, err := w.Write(appendUleb128(b, u))
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteVarInt32 writes u to w.
|
||||
func WriteVarInt32(w io.Writer, i int32) error {
|
||||
var b []byte
|
||||
_, err := w.Write(appendSleb128(b, int64(i)))
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteVarInt64 writes u to w.
|
||||
func WriteVarInt64(w io.Writer, i int64) error {
|
||||
var b []byte
|
||||
_, err := w.Write(appendSleb128(b, i))
|
||||
return err
|
||||
}
|
||||
|
||||
// Copied from https://github.com/golang/go/blob/master/src/cmd/internal/dwarf/dwarf.go.
|
||||
|
||||
// appendUleb128 appends v to b using DWARF's unsigned LEB128 encoding.
|
||||
func appendUleb128(b []byte, v uint64) []byte {
|
||||
for {
|
||||
c := uint8(v & 0x7f)
|
||||
v >>= 7
|
||||
if v != 0 {
|
||||
c |= 0x80
|
||||
}
|
||||
b = append(b, c)
|
||||
if c&0x80 == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// appendSleb128 appends v to b using DWARF's signed LEB128 encoding.
|
||||
func appendSleb128(b []byte, v int64) []byte {
|
||||
for {
|
||||
c := uint8(v & 0x7f)
|
||||
s := uint8(v & 0x40)
|
||||
v >>= 7
|
||||
if (v != -1 || s == 0) && (v != 0 || s != 0) {
|
||||
c |= 0x80
|
||||
}
|
||||
b = append(b, c)
|
||||
if c&0x80 == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
||||
40
vendor/github.com/open-policy-agent/opa/internal/merge/merge.go
generated
vendored
Normal file
40
vendor/github.com/open-policy-agent/opa/internal/merge/merge.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2017 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package merge contains helpers to merge data structures
|
||||
// frequently encountered in OPA.
|
||||
package merge
|
||||
|
||||
// InterfaceMaps returns the result of merging a and b. If a and b cannot be
|
||||
// merged because of conflicting key-value pairs, ok is false.
|
||||
func InterfaceMaps(a map[string]interface{}, b map[string]interface{}) (c map[string]interface{}, ok bool) {
|
||||
|
||||
c = map[string]interface{}{}
|
||||
for k := range a {
|
||||
c[k] = a[k]
|
||||
}
|
||||
|
||||
for k := range b {
|
||||
|
||||
add := b[k]
|
||||
exist, ok := c[k]
|
||||
if !ok {
|
||||
c[k] = add
|
||||
continue
|
||||
}
|
||||
|
||||
existObj, existOk := exist.(map[string]interface{})
|
||||
addObj, addOk := add.(map[string]interface{})
|
||||
if !existOk || !addOk {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
c[k], ok = InterfaceMaps(existObj, addObj)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
return c, true
|
||||
}
|
||||
1758
vendor/github.com/open-policy-agent/opa/internal/planner/planner.go
generated
vendored
Normal file
1758
vendor/github.com/open-policy-agent/opa/internal/planner/planner.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
156
vendor/github.com/open-policy-agent/opa/internal/planner/rules.go
generated
vendored
Normal file
156
vendor/github.com/open-policy-agent/opa/internal/planner/rules.go
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
package planner
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/open-policy-agent/opa/ast"
|
||||
)
|
||||
|
||||
// funcstack implements a simple map structure used to keep track of virtual
|
||||
// document => planned function names. The structure supports Push and Pop
|
||||
// operations so that the planner can shadow planned functions when 'with'
|
||||
// statements are found.
|
||||
type funcstack struct {
|
||||
stack []map[string]string
|
||||
gen int
|
||||
}
|
||||
|
||||
func newFuncstack() *funcstack {
|
||||
return &funcstack{
|
||||
stack: []map[string]string{
|
||||
map[string]string{},
|
||||
},
|
||||
gen: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (p funcstack) Add(key, value string) {
|
||||
p.stack[len(p.stack)-1][key] = value
|
||||
}
|
||||
|
||||
func (p funcstack) Get(key string) (string, bool) {
|
||||
value, ok := p.stack[len(p.stack)-1][key]
|
||||
return value, ok
|
||||
}
|
||||
|
||||
func (p *funcstack) Push(funcs map[string]string) {
|
||||
p.stack = append(p.stack, funcs)
|
||||
p.gen++
|
||||
}
|
||||
|
||||
func (p *funcstack) Pop() map[string]string {
|
||||
last := p.stack[len(p.stack)-1]
|
||||
p.stack = p.stack[:len(p.stack)-1]
|
||||
p.gen++
|
||||
return last
|
||||
}
|
||||
|
||||
// ruletrie implements a simple trie structure for organizing rules that may be
|
||||
// planned. The trie nodes are keyed by the rule path. The ruletrie supports
|
||||
// Push and Pop operations that allow the planner to shadow subtrees when 'with'
|
||||
// statements are found.
|
||||
type ruletrie struct {
|
||||
children map[ast.Value][]*ruletrie
|
||||
rules []*ast.Rule
|
||||
}
|
||||
|
||||
func newRuletrie() *ruletrie {
|
||||
return &ruletrie{
|
||||
children: map[ast.Value][]*ruletrie{},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *ruletrie) Arity() int {
|
||||
rules := t.Rules()
|
||||
if len(rules) > 0 {
|
||||
return len(rules[0].Head.Args)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (t *ruletrie) Rules() []*ast.Rule {
|
||||
if t != nil {
|
||||
return t.rules
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *ruletrie) Push(key ast.Ref) {
|
||||
node := t
|
||||
for i := 0; i < len(key)-1; i++ {
|
||||
node = node.Get(key[i].Value)
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
elem := key[len(key)-1]
|
||||
node.children[elem.Value] = append(node.children[elem.Value], nil)
|
||||
}
|
||||
|
||||
func (t *ruletrie) Pop(key ast.Ref) {
|
||||
node := t
|
||||
for i := 0; i < len(key)-1; i++ {
|
||||
node = node.Get(key[i].Value)
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
elem := key[len(key)-1]
|
||||
sl := node.children[elem.Value]
|
||||
node.children[elem.Value] = sl[:len(sl)-1]
|
||||
}
|
||||
|
||||
func (t *ruletrie) Insert(key ast.Ref) *ruletrie {
|
||||
node := t
|
||||
for _, elem := range key {
|
||||
child := node.Get(elem.Value)
|
||||
if child == nil {
|
||||
child = newRuletrie()
|
||||
node.children[elem.Value] = append(node.children[elem.Value], child)
|
||||
}
|
||||
node = child
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func (t *ruletrie) Lookup(key ast.Ref) *ruletrie {
|
||||
node := t
|
||||
for _, elem := range key {
|
||||
node = node.Get(elem.Value)
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func (t *ruletrie) LookupOrInsert(key ast.Ref) *ruletrie {
|
||||
if val := t.Lookup(key); val != nil {
|
||||
return val
|
||||
}
|
||||
return t.Insert(key)
|
||||
}
|
||||
|
||||
func (t *ruletrie) Children() []ast.Value {
|
||||
sorted := make([]ast.Value, 0, len(t.children))
|
||||
for key := range t.children {
|
||||
if t.Get(key) != nil {
|
||||
sorted = append(sorted, key)
|
||||
}
|
||||
}
|
||||
sort.Slice(sorted, func(i, j int) bool {
|
||||
return sorted[i].Compare(sorted[j]) < 0
|
||||
})
|
||||
return sorted
|
||||
}
|
||||
|
||||
func (t *ruletrie) Get(k ast.Value) *ruletrie {
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
nodes := t.children[k]
|
||||
if len(nodes) == 0 {
|
||||
return nil
|
||||
}
|
||||
return nodes[len(nodes)-1]
|
||||
}
|
||||
58
vendor/github.com/open-policy-agent/opa/internal/planner/varstack.go
generated
vendored
Normal file
58
vendor/github.com/open-policy-agent/opa/internal/planner/varstack.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2019 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package planner
|
||||
|
||||
import (
|
||||
"github.com/open-policy-agent/opa/ast"
|
||||
"github.com/open-policy-agent/opa/internal/ir"
|
||||
)
|
||||
|
||||
type varstack []map[ast.Var]ir.Local
|
||||
|
||||
func newVarstack(frames ...map[ast.Var]ir.Local) *varstack {
|
||||
vs := &varstack{}
|
||||
for _, f := range frames {
|
||||
vs.Push(f)
|
||||
}
|
||||
return vs
|
||||
}
|
||||
|
||||
func (vs varstack) GetOrElse(k ast.Var, orElse func() ir.Local) ir.Local {
|
||||
l, ok := vs.Get(k)
|
||||
if !ok {
|
||||
l = orElse()
|
||||
vs.Put(k, l)
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (vs varstack) GetOrEmpty(k ast.Var) ir.Local {
|
||||
l, _ := vs.Get(k)
|
||||
return l
|
||||
}
|
||||
|
||||
func (vs varstack) Get(k ast.Var) (ir.Local, bool) {
|
||||
for i := len(vs) - 1; i >= 0; i-- {
|
||||
if l, ok := vs[i][k]; ok {
|
||||
return l, true
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (vs varstack) Put(k ast.Var, v ir.Local) {
|
||||
vs[len(vs)-1][k] = v
|
||||
}
|
||||
|
||||
func (vs *varstack) Push(frame map[ast.Var]ir.Local) {
|
||||
*vs = append(*vs, frame)
|
||||
}
|
||||
|
||||
func (vs *varstack) Pop() map[ast.Var]ir.Local {
|
||||
sl := *vs
|
||||
last := sl[len(sl)-1]
|
||||
*vs = sl[:len(sl)-1]
|
||||
return last
|
||||
}
|
||||
40
vendor/github.com/open-policy-agent/opa/internal/version/version.go
generated
vendored
Normal file
40
vendor/github.com/open-policy-agent/opa/internal/version/version.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2019 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package version implements helper functions for the stored version.
|
||||
package version
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/open-policy-agent/opa/storage"
|
||||
"github.com/open-policy-agent/opa/version"
|
||||
)
|
||||
|
||||
var versionPath = storage.MustParsePath("/system/version")
|
||||
|
||||
// Write the build version information into storage. This makes the
|
||||
// version information available to the REPL and the HTTP server.
|
||||
func Write(ctx context.Context, store storage.Store, txn storage.Transaction) error {
|
||||
|
||||
if err := storage.MakeDir(ctx, store, txn, versionPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := store.Write(ctx, txn, storage.AddOp, versionPath, map[string]interface{}{
|
||||
"version": version.Version,
|
||||
"build_commit": version.Vcs,
|
||||
"build_timestamp": version.Timestamp,
|
||||
"build_hostname": version.Hostname,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UserAgent defines the current OPA instances User-Agent default header value.
|
||||
var UserAgent = fmt.Sprintf("Open Policy Agent/%s (%s, %s)", version.Version, runtime.GOOS, runtime.GOARCH)
|
||||
67
vendor/github.com/open-policy-agent/opa/internal/wasm/constant/constant.go
generated
vendored
Normal file
67
vendor/github.com/open-policy-agent/opa/internal/wasm/constant/constant.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package constant contains WASM constant definitions.
|
||||
package constant
|
||||
|
||||
// Magic bytes at the beginning of every WASM file ("\0asm").
|
||||
const Magic = uint32(0x6D736100)
|
||||
|
||||
// Version defines the WASM version.
|
||||
const Version = uint32(1)
|
||||
|
||||
// WASM module section IDs.
|
||||
const (
|
||||
CustomSectionID uint8 = iota
|
||||
TypeSectionID
|
||||
ImportSectionID
|
||||
FunctionSectionID
|
||||
TableSectionID
|
||||
MemorySectionID
|
||||
GlobalSectionID
|
||||
ExportSectionID
|
||||
StartSectionID
|
||||
ElementSectionID
|
||||
CodeSectionID
|
||||
DataSectionID
|
||||
)
|
||||
|
||||
// FunctionTypeID indicates the start of a function type definition.
|
||||
const FunctionTypeID = byte(0x60)
|
||||
|
||||
// ValueType represents an intrinsic value type in WASM.
|
||||
const (
|
||||
ValueTypeF64 byte = iota + 0x7C
|
||||
ValueTypeF32
|
||||
ValueTypeI64
|
||||
ValueTypeI32
|
||||
)
|
||||
|
||||
// WASM import descriptor types.
|
||||
const (
|
||||
ImportDescType byte = iota
|
||||
ImportDescTable
|
||||
ImportDescMem
|
||||
ImportDescGlobal
|
||||
)
|
||||
|
||||
// WASM export descriptor types.
|
||||
const (
|
||||
ExportDescType byte = iota
|
||||
ExportDescTable
|
||||
ExportDescMem
|
||||
ExportDescGlobal
|
||||
)
|
||||
|
||||
// ElementTypeAnyFunc indicates the type of a table import.
|
||||
const ElementTypeAnyFunc byte = 0x70
|
||||
|
||||
// BlockTypeEmpty represents a block type.
|
||||
const BlockTypeEmpty byte = 0x40
|
||||
|
||||
// WASM global varialbe mutability flag.
|
||||
const (
|
||||
Const byte = iota
|
||||
Mutable
|
||||
)
|
||||
6
vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/doc.go
generated
vendored
Normal file
6
vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/doc.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package encoding implements WASM module reading and writing.
|
||||
package encoding
|
||||
809
vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/reader.go
generated
vendored
Normal file
809
vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/reader.go
generated
vendored
Normal file
@@ -0,0 +1,809 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/leb128"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/constant"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/instruction"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/module"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/opcode"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/types"
|
||||
)
|
||||
|
||||
// ReadModule reads a binary-encoded WASM module from r.
|
||||
func ReadModule(r io.Reader) (*module.Module, error) {
|
||||
|
||||
wr := &reader{r: r, n: 0}
|
||||
module, err := readModule(wr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "offset 0x%x", wr.n)
|
||||
}
|
||||
|
||||
return module, nil
|
||||
}
|
||||
|
||||
// ReadCodeEntry reads a binary-encoded WASM code entry from r.
|
||||
func ReadCodeEntry(r io.Reader) (*module.CodeEntry, error) {
|
||||
|
||||
wr := &reader{r: r, n: 0}
|
||||
entry, err := readCodeEntry(wr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "offset 0x%x", wr.n)
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
// CodeEntries returns the WASM code entries contained in r.
|
||||
func CodeEntries(m *module.Module) ([]*module.CodeEntry, error) {
|
||||
|
||||
entries := make([]*module.CodeEntry, len(m.Code.Segments))
|
||||
|
||||
for i, s := range m.Code.Segments {
|
||||
buf := bytes.NewBuffer(s.Code)
|
||||
entry, err := ReadCodeEntry(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entries[i] = entry
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
type reader struct {
|
||||
r io.Reader
|
||||
n int
|
||||
}
|
||||
|
||||
func (r *reader) Read(bs []byte) (int, error) {
|
||||
n, err := r.r.Read(bs)
|
||||
r.n += n
|
||||
return n, err
|
||||
}
|
||||
|
||||
func readModule(r io.Reader) (*module.Module, error) {
|
||||
|
||||
if err := readMagic(r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := readVersion(r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m module.Module
|
||||
|
||||
if err := readSections(r, &m); err != nil && err != io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func readCodeEntry(r io.Reader) (*module.CodeEntry, error) {
|
||||
|
||||
var entry module.CodeEntry
|
||||
|
||||
if err := readLocals(r, &entry.Func.Locals); err != nil {
|
||||
return nil, errors.Wrapf(err, "local declarations")
|
||||
}
|
||||
|
||||
return &entry, readExpr(r, &entry.Func.Expr)
|
||||
}
|
||||
|
||||
func readMagic(r io.Reader) error {
|
||||
var v uint32
|
||||
if err := binary.Read(r, binary.LittleEndian, &v); err != nil {
|
||||
return err
|
||||
} else if v != constant.Magic {
|
||||
return fmt.Errorf("illegal magic value")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func readVersion(r io.Reader) error {
|
||||
var v uint32
|
||||
if err := binary.Read(r, binary.LittleEndian, &v); err != nil {
|
||||
return err
|
||||
} else if v != constant.Version {
|
||||
return fmt.Errorf("illegal wasm version")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func readSections(r io.Reader, m *module.Module) error {
|
||||
for {
|
||||
id, err := readByte(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
size, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := make([]byte, size)
|
||||
if _, err := io.ReadFull(r, buf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bufr := bytes.NewReader(buf)
|
||||
|
||||
switch id {
|
||||
case constant.CustomSectionID, constant.StartSectionID, constant.MemorySectionID:
|
||||
continue
|
||||
case constant.TypeSectionID:
|
||||
if err := readTypeSection(bufr, &m.Type); err != nil {
|
||||
return errors.Wrap(err, "type section")
|
||||
}
|
||||
case constant.ImportSectionID:
|
||||
if err := readImportSection(bufr, &m.Import); err != nil {
|
||||
return errors.Wrap(err, "import section")
|
||||
}
|
||||
case constant.GlobalSectionID:
|
||||
if err := readGlobalSection(bufr, &m.Global); err != nil {
|
||||
return errors.Wrap(err, "global section")
|
||||
}
|
||||
case constant.TableSectionID:
|
||||
if err := readTableSection(bufr, &m.Table); err != nil {
|
||||
return errors.Wrap(err, "table section")
|
||||
}
|
||||
case constant.FunctionSectionID:
|
||||
if err := readFunctionSection(bufr, &m.Function); err != nil {
|
||||
return errors.Wrap(err, "function section")
|
||||
}
|
||||
case constant.ExportSectionID:
|
||||
if err := readExportSection(bufr, &m.Export); err != nil {
|
||||
return errors.Wrap(err, "export section")
|
||||
}
|
||||
case constant.ElementSectionID:
|
||||
if err := readElementSection(bufr, &m.Element); err != nil {
|
||||
return errors.Wrap(err, "element section")
|
||||
}
|
||||
case constant.DataSectionID:
|
||||
if err := readDataSection(bufr, &m.Data); err != nil {
|
||||
return errors.Wrap(err, "data section")
|
||||
}
|
||||
case constant.CodeSectionID:
|
||||
if err := readRawCodeSection(bufr, &m.Code); err != nil {
|
||||
return errors.Wrap(err, "code section")
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("illegal section id")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readTypeSection(r io.Reader, s *module.TypeSection) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
|
||||
var ftype module.FunctionType
|
||||
if err := readFunctionType(r, &ftype); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Functions = append(s.Functions, ftype)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readImportSection(r io.Reader, s *module.ImportSection) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
|
||||
var imp module.Import
|
||||
|
||||
if err := readImport(r, &imp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Imports = append(s.Imports, imp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readTableSection(r io.Reader, s *module.TableSection) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
|
||||
var table module.Table
|
||||
|
||||
if elem, err := readByte(r); err != nil {
|
||||
return err
|
||||
} else if elem != constant.ElementTypeAnyFunc {
|
||||
return fmt.Errorf("illegal element type")
|
||||
} else {
|
||||
table.Type = types.Anyfunc
|
||||
}
|
||||
|
||||
if err := readLimits(r, &table.Lim); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Tables = append(s.Tables, table)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readGlobalSection(r io.Reader, s *module.GlobalSection) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
|
||||
var global module.Global
|
||||
|
||||
if err := readGlobal(r, &global); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Globals = append(s.Globals, global)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readFunctionSection(r io.Reader, s *module.FunctionSection) error {
|
||||
return readVarUint32Vector(r, &s.TypeIndices)
|
||||
}
|
||||
|
||||
func readExportSection(r io.Reader, s *module.ExportSection) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
|
||||
var exp module.Export
|
||||
|
||||
if err := readExport(r, &exp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Exports = append(s.Exports, exp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readElementSection(r io.Reader, s *module.ElementSection) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
|
||||
var seg module.ElementSegment
|
||||
|
||||
if err := readElementSegment(r, &seg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Segments = append(s.Segments, seg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readDataSection(r io.Reader, s *module.DataSection) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
|
||||
var seg module.DataSegment
|
||||
|
||||
if err := readDataSegment(r, &seg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Segments = append(s.Segments, seg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readRawCodeSection(r io.Reader, s *module.RawCodeSection) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
var seg module.RawCodeSegment
|
||||
|
||||
if err := readRawCodeSegment(r, &seg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Segments = append(s.Segments, seg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readFunctionType(r io.Reader, ftype *module.FunctionType) error {
|
||||
|
||||
if b, err := readByte(r); err != nil {
|
||||
return err
|
||||
} else if b != constant.FunctionTypeID {
|
||||
return fmt.Errorf("illegal function type id 0x%x", b)
|
||||
}
|
||||
|
||||
if err := readValueTypeVector(r, &ftype.Params); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return readValueTypeVector(r, &ftype.Results)
|
||||
}
|
||||
|
||||
func readGlobal(r io.Reader, global *module.Global) error {
|
||||
|
||||
if err := readValueType(r, &global.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := readByte(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if b == 1 {
|
||||
global.Mutable = true
|
||||
} else if b != 0 {
|
||||
return fmt.Errorf("illegal mutability flag")
|
||||
}
|
||||
|
||||
if err := readConstantExpr(r, &global.Init); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readImport(r io.Reader, imp *module.Import) error {
|
||||
|
||||
if err := readByteVectorString(r, &imp.Module); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := readByteVectorString(r, &imp.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := readByte(r)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
if b == constant.ImportDescType {
|
||||
index, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
imp.Descriptor = module.FunctionImport{
|
||||
Func: index,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if b == constant.ImportDescTable {
|
||||
if elem, err := readByte(r); err != nil {
|
||||
return err
|
||||
} else if elem != constant.ElementTypeAnyFunc {
|
||||
return fmt.Errorf("illegal element type")
|
||||
}
|
||||
desc := module.TableImport{
|
||||
Type: types.Anyfunc,
|
||||
}
|
||||
if err := readLimits(r, &desc.Lim); err != nil {
|
||||
return err
|
||||
}
|
||||
imp.Descriptor = desc
|
||||
return nil
|
||||
}
|
||||
|
||||
if b == constant.ImportDescMem {
|
||||
desc := module.MemoryImport{}
|
||||
if err := readLimits(r, &desc.Mem.Lim); err != nil {
|
||||
return err
|
||||
}
|
||||
imp.Descriptor = desc
|
||||
return nil
|
||||
}
|
||||
|
||||
if b == constant.ImportDescGlobal {
|
||||
desc := module.GlobalImport{}
|
||||
if err := readValueType(r, &desc.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := readByte(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b == 1 {
|
||||
desc.Mutable = true
|
||||
} else if b != 0 {
|
||||
return fmt.Errorf("illegal mutability flag")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("illegal import descriptor type")
|
||||
}
|
||||
|
||||
func readExport(r io.Reader, exp *module.Export) error {
|
||||
|
||||
if err := readByteVectorString(r, &exp.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := readByte(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch b {
|
||||
case constant.ExportDescType:
|
||||
exp.Descriptor.Type = module.FunctionExportType
|
||||
case constant.ExportDescTable:
|
||||
exp.Descriptor.Type = module.TableExportType
|
||||
case constant.ExportDescMem:
|
||||
exp.Descriptor.Type = module.MemoryExportType
|
||||
case constant.ExportDescGlobal:
|
||||
exp.Descriptor.Type = module.GlobalExportType
|
||||
default:
|
||||
return fmt.Errorf("illegal export descriptor type")
|
||||
}
|
||||
|
||||
exp.Descriptor.Index, err = leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readElementSegment(r io.Reader, seg *module.ElementSegment) error {
|
||||
|
||||
if err := readVarUint32(r, &seg.Index); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := readConstantExpr(r, &seg.Offset); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := readVarUint32Vector(r, &seg.Indices); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readDataSegment(r io.Reader, seg *module.DataSegment) error {
|
||||
|
||||
if err := readVarUint32(r, &seg.Index); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := readConstantExpr(r, &seg.Offset); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := readByteVector(r, &seg.Init); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readRawCodeSegment(r io.Reader, seg *module.RawCodeSegment) error {
|
||||
return readByteVector(r, &seg.Code)
|
||||
}
|
||||
|
||||
func readConstantExpr(r io.Reader, expr *module.Expr) error {
|
||||
|
||||
instrs := make([]instruction.Instruction, 0)
|
||||
|
||||
for {
|
||||
b, err := readByte(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch opcode.Opcode(b) {
|
||||
case opcode.I32Const:
|
||||
i32, err := leb128.ReadVarInt32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
instrs = append(instrs, instruction.I32Const{Value: i32})
|
||||
case opcode.I64Const:
|
||||
i64, err := leb128.ReadVarInt64(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
instrs = append(instrs, instruction.I64Const{Value: i64})
|
||||
case opcode.End:
|
||||
expr.Instrs = instrs
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("illegal constant expr opcode 0x%x", b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readExpr(r io.Reader, expr *module.Expr) (err error) {
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
switch r := r.(type) {
|
||||
case error:
|
||||
err = r
|
||||
default:
|
||||
err = fmt.Errorf("unknown panic")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return readInstructions(r, &expr.Instrs)
|
||||
}
|
||||
|
||||
func readInstructions(r io.Reader, instrs *[]instruction.Instruction) error {
|
||||
|
||||
ret := make([]instruction.Instruction, 0)
|
||||
|
||||
for {
|
||||
b, err := readByte(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch opcode.Opcode(b) {
|
||||
case opcode.I32Const:
|
||||
ret = append(ret, instruction.I32Const{Value: leb128.MustReadVarInt32(r)})
|
||||
case opcode.I64Const:
|
||||
ret = append(ret, instruction.I64Const{Value: leb128.MustReadVarInt64(r)})
|
||||
case opcode.I32Eqz:
|
||||
ret = append(ret, instruction.I32Eqz{})
|
||||
case opcode.GetLocal:
|
||||
ret = append(ret, instruction.GetLocal{Index: leb128.MustReadVarUint32(r)})
|
||||
case opcode.SetLocal:
|
||||
ret = append(ret, instruction.SetLocal{Index: leb128.MustReadVarUint32(r)})
|
||||
case opcode.Call:
|
||||
ret = append(ret, instruction.Call{Index: leb128.MustReadVarUint32(r)})
|
||||
case opcode.BrIf:
|
||||
ret = append(ret, instruction.BrIf{Index: leb128.MustReadVarUint32(r)})
|
||||
case opcode.Return:
|
||||
ret = append(ret, instruction.Return{})
|
||||
case opcode.Block:
|
||||
block := instruction.Block{}
|
||||
if err := readBlockValueType(r, block.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := readInstructions(r, &block.Instrs); err != nil {
|
||||
return err
|
||||
}
|
||||
ret = append(ret, block)
|
||||
case opcode.Loop:
|
||||
loop := instruction.Loop{}
|
||||
if err := readBlockValueType(r, loop.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := readInstructions(r, &loop.Instrs); err != nil {
|
||||
return err
|
||||
}
|
||||
ret = append(ret, loop)
|
||||
case opcode.End:
|
||||
*instrs = ret
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("illegal opcode 0x%x", b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readLimits(r io.Reader, l *module.Limit) error {
|
||||
|
||||
b, err := readByte(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
min, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.Min = min
|
||||
|
||||
if b == 1 {
|
||||
max, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.Max = &max
|
||||
} else if b != 0 {
|
||||
return fmt.Errorf("illegal limit flag")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readLocals(r io.Reader, locals *[]module.LocalDeclaration) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ret := make([]module.LocalDeclaration, n)
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
if err := readVarUint32(r, &ret[i].Count); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := readValueType(r, &ret[i].Type); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
*locals = ret
|
||||
return nil
|
||||
}
|
||||
|
||||
func readByteVector(r io.Reader, v *[]byte) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := make([]byte, n)
|
||||
if _, err := io.ReadFull(r, buf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = buf
|
||||
return nil
|
||||
}
|
||||
|
||||
func readByteVectorString(r io.Reader, v *string) error {
|
||||
|
||||
var buf []byte
|
||||
|
||||
if err := readByteVector(r, &buf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = string(buf)
|
||||
return nil
|
||||
}
|
||||
|
||||
func readVarUint32Vector(r io.Reader, v *[]uint32) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ret := make([]uint32, n)
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
if err := readVarUint32(r, &ret[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
*v = ret
|
||||
return nil
|
||||
}
|
||||
|
||||
func readValueTypeVector(r io.Reader, v *[]types.ValueType) error {
|
||||
|
||||
n, err := leb128.ReadVarUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ret := make([]types.ValueType, n)
|
||||
|
||||
for i := uint32(0); i < n; i++ {
|
||||
if err := readValueType(r, &ret[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
*v = ret
|
||||
return nil
|
||||
}
|
||||
|
||||
func readVarUint32(r io.Reader, v *uint32) error {
|
||||
var err error
|
||||
*v, err = leb128.ReadVarUint32(r)
|
||||
return err
|
||||
}
|
||||
|
||||
func readValueType(r io.Reader, v *types.ValueType) error {
|
||||
if b, err := readByte(r); err != nil {
|
||||
return err
|
||||
} else if b == constant.ValueTypeI32 {
|
||||
*v = types.I32
|
||||
} else if b == constant.ValueTypeI64 {
|
||||
*v = types.I64
|
||||
} else if b == constant.ValueTypeF32 {
|
||||
*v = types.F32
|
||||
} else if b == constant.ValueTypeF64 {
|
||||
*v = types.F64
|
||||
} else {
|
||||
return fmt.Errorf("illegal value type: 0x%x", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func readBlockValueType(r io.Reader, v *types.ValueType) error {
|
||||
if b, err := readByte(r); err != nil {
|
||||
return err
|
||||
} else if b == constant.ValueTypeI32 {
|
||||
*v = types.I32
|
||||
} else if b == constant.ValueTypeI64 {
|
||||
*v = types.I64
|
||||
} else if b == constant.ValueTypeF32 {
|
||||
*v = types.F32
|
||||
} else if b == constant.ValueTypeF64 {
|
||||
*v = types.F64
|
||||
} else if b != constant.BlockTypeEmpty {
|
||||
return fmt.Errorf("illegal value type: 0x%x", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func readByte(r io.Reader) (byte, error) {
|
||||
buf := make([]byte, 1)
|
||||
_, err := r.Read(buf)
|
||||
return buf[0], err
|
||||
}
|
||||
615
vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/writer.go
generated
vendored
Normal file
615
vendor/github.com/open-policy-agent/opa/internal/wasm/encoding/writer.go
generated
vendored
Normal file
@@ -0,0 +1,615 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/leb128"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/constant"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/instruction"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/module"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/opcode"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/types"
|
||||
)
|
||||
|
||||
// WriteModule writes a binary-encoded representation of module to w.
|
||||
func WriteModule(w io.Writer, module *module.Module) error {
|
||||
|
||||
if err := writeMagic(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeVersion(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if module == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := writeTypeSection(w, module.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeImportSection(w, module.Import); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeFunctionSection(w, module.Function); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeTableSection(w, module.Table); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeGlobalSection(w, module.Global); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeExportSection(w, module.Export); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeElementSection(w, module.Element); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeRawCodeSection(w, module.Code); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeDataSection(w, module.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteCodeEntry writes a binary encoded representation of entry to w.
|
||||
func WriteCodeEntry(w io.Writer, entry *module.CodeEntry) error {
|
||||
|
||||
if err := leb128.WriteVarUint32(w, uint32(len(entry.Func.Locals))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, local := range entry.Func.Locals {
|
||||
|
||||
if err := leb128.WriteVarUint32(w, local.Count); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeValueType(w, local.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeInstructions(w, entry.Func.Expr.Instrs)
|
||||
}
|
||||
|
||||
func writeMagic(w io.Writer) error {
|
||||
return binary.Write(w, binary.LittleEndian, constant.Magic)
|
||||
}
|
||||
|
||||
func writeVersion(w io.Writer) error {
|
||||
return binary.Write(w, binary.LittleEndian, constant.Version)
|
||||
}
|
||||
|
||||
func writeTypeSection(w io.Writer, s module.TypeSection) error {
|
||||
|
||||
if len(s.Functions) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := writeByte(w, constant.TypeSectionID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(len(s.Functions))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, fsig := range s.Functions {
|
||||
if err := writeFunctionType(&buf, fsig); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeRawSection(w, &buf)
|
||||
}
|
||||
|
||||
func writeImportSection(w io.Writer, s module.ImportSection) error {
|
||||
|
||||
if len(s.Imports) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := writeByte(w, constant.ImportSectionID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(len(s.Imports))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, imp := range s.Imports {
|
||||
if err := writeImport(&buf, imp); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeRawSection(w, &buf)
|
||||
}
|
||||
|
||||
func writeGlobalSection(w io.Writer, s module.GlobalSection) error {
|
||||
|
||||
if len(s.Globals) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := writeByte(w, constant.GlobalSectionID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(len(s.Globals))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, global := range s.Globals {
|
||||
if err := writeGlobal(&buf, global); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeRawSection(w, &buf)
|
||||
}
|
||||
|
||||
func writeFunctionSection(w io.Writer, s module.FunctionSection) error {
|
||||
|
||||
if len(s.TypeIndices) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := writeByte(w, constant.FunctionSectionID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(len(s.TypeIndices))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, idx := range s.TypeIndices {
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(idx)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeRawSection(w, &buf)
|
||||
}
|
||||
|
||||
func writeTableSection(w io.Writer, s module.TableSection) error {
|
||||
|
||||
if len(s.Tables) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := writeByte(w, constant.TableSectionID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(len(s.Tables))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, table := range s.Tables {
|
||||
switch table.Type {
|
||||
case types.Anyfunc:
|
||||
if err := writeByte(&buf, constant.ElementTypeAnyFunc); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("illegal table element type")
|
||||
}
|
||||
if err := writeLimits(&buf, table.Lim); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeRawSection(w, &buf)
|
||||
|
||||
}
|
||||
|
||||
func writeExportSection(w io.Writer, s module.ExportSection) error {
|
||||
|
||||
if len(s.Exports) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := writeByte(w, constant.ExportSectionID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(len(s.Exports))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, exp := range s.Exports {
|
||||
if err := writeByteVector(&buf, []byte(exp.Name)); err != nil {
|
||||
return err
|
||||
}
|
||||
var tpe byte
|
||||
switch exp.Descriptor.Type {
|
||||
case module.FunctionExportType:
|
||||
tpe = constant.ExportDescType
|
||||
case module.TableExportType:
|
||||
tpe = constant.ExportDescTable
|
||||
case module.MemoryExportType:
|
||||
tpe = constant.ExportDescMem
|
||||
case module.GlobalExportType:
|
||||
tpe = constant.ExportDescGlobal
|
||||
default:
|
||||
return fmt.Errorf("illegal export descriptor type 0x%x", exp.Descriptor.Type)
|
||||
}
|
||||
if err := writeByte(&buf, tpe); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := leb128.WriteVarUint32(&buf, exp.Descriptor.Index); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeRawSection(w, &buf)
|
||||
}
|
||||
|
||||
func writeElementSection(w io.Writer, s module.ElementSection) error {
|
||||
|
||||
if len(s.Segments) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := writeByte(w, constant.ElementSectionID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(len(s.Segments))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, seg := range s.Segments {
|
||||
if err := leb128.WriteVarUint32(&buf, seg.Index); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeInstructions(&buf, seg.Offset.Instrs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeVarUint32Vector(&buf, seg.Indices); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeRawSection(w, &buf)
|
||||
}
|
||||
|
||||
func writeRawCodeSection(w io.Writer, s module.RawCodeSection) error {
|
||||
|
||||
if len(s.Segments) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := writeByte(w, constant.CodeSectionID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(len(s.Segments))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, seg := range s.Segments {
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(len(seg.Code))); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := buf.Write(seg.Code); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeRawSection(w, &buf)
|
||||
}
|
||||
|
||||
func writeDataSection(w io.Writer, s module.DataSection) error {
|
||||
|
||||
if len(s.Segments) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := writeByte(w, constant.DataSectionID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := leb128.WriteVarUint32(&buf, uint32(len(s.Segments))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, seg := range s.Segments {
|
||||
if err := leb128.WriteVarUint32(&buf, seg.Index); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeInstructions(&buf, seg.Offset.Instrs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeByteVector(&buf, seg.Init); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return writeRawSection(w, &buf)
|
||||
}
|
||||
|
||||
func writeFunctionType(w io.Writer, fsig module.FunctionType) error {
|
||||
|
||||
if err := writeByte(w, constant.FunctionTypeID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeValueTypeVector(w, fsig.Params); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeValueTypeVector(w, fsig.Results)
|
||||
}
|
||||
|
||||
func writeImport(w io.Writer, imp module.Import) error {
|
||||
|
||||
if err := writeByteVector(w, []byte(imp.Module)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeByteVector(w, []byte(imp.Name)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch desc := imp.Descriptor.(type) {
|
||||
case module.FunctionImport:
|
||||
if err := writeByte(w, constant.ImportDescType); err != nil {
|
||||
return err
|
||||
}
|
||||
return leb128.WriteVarUint32(w, desc.Func)
|
||||
case module.TableImport:
|
||||
if err := writeByte(w, constant.ImportDescTable); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeByte(w, constant.ElementTypeAnyFunc); err != nil {
|
||||
return err
|
||||
}
|
||||
return writeLimits(w, desc.Lim)
|
||||
case module.MemoryImport:
|
||||
if err := writeByte(w, constant.ImportDescMem); err != nil {
|
||||
return err
|
||||
}
|
||||
return writeLimits(w, desc.Mem.Lim)
|
||||
case module.GlobalImport:
|
||||
if err := writeByte(w, constant.ImportDescGlobal); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeValueType(w, desc.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
if desc.Mutable {
|
||||
return writeByte(w, constant.Mutable)
|
||||
}
|
||||
return writeByte(w, constant.Const)
|
||||
default:
|
||||
return fmt.Errorf("illegal import descriptor type")
|
||||
}
|
||||
}
|
||||
|
||||
func writeGlobal(w io.Writer, global module.Global) error {
|
||||
|
||||
if err := writeValueType(w, global.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
if global.Mutable {
|
||||
err = writeByte(w, constant.Mutable)
|
||||
} else {
|
||||
err = writeByte(w, constant.Const)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeInstructions(w, global.Init.Instrs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeInstructions(w io.Writer, instrs []instruction.Instruction) error {
|
||||
|
||||
for i, instr := range instrs {
|
||||
|
||||
_, err := w.Write([]byte{byte(instr.Op())})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, arg := range instr.ImmediateArgs() {
|
||||
var err error
|
||||
switch arg := arg.(type) {
|
||||
case int32:
|
||||
err = leb128.WriteVarInt32(w, arg)
|
||||
case int64:
|
||||
err = leb128.WriteVarInt64(w, arg)
|
||||
case uint32:
|
||||
err = leb128.WriteVarUint32(w, arg)
|
||||
case uint64:
|
||||
err = leb128.WriteVarUint64(w, arg)
|
||||
case float32:
|
||||
u32 := math.Float32bits(arg)
|
||||
err = binary.Write(w, binary.LittleEndian, u32)
|
||||
case float64:
|
||||
u64 := math.Float64bits(arg)
|
||||
err = binary.Write(w, binary.LittleEndian, u64)
|
||||
default:
|
||||
return fmt.Errorf("illegal immediate argument type on instruction %d", i)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if si, ok := instr.(instruction.StructuredInstruction); ok {
|
||||
if err := writeBlockValueType(w, si.BlockType()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeInstructions(w, si.Instructions()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_, err := w.Write([]byte{byte(opcode.End)})
|
||||
return err
|
||||
}
|
||||
|
||||
func writeLimits(w io.Writer, lim module.Limit) error {
|
||||
if lim.Max == nil {
|
||||
if err := writeByte(w, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := writeByte(w, 1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := leb128.WriteVarUint32(w, lim.Min); err != nil {
|
||||
return err
|
||||
}
|
||||
if lim.Max != nil {
|
||||
return leb128.WriteVarUint32(w, *lim.Max)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeVarUint32Vector(w io.Writer, v []uint32) error {
|
||||
|
||||
if err := leb128.WriteVarUint32(w, uint32(len(v))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range v {
|
||||
if err := leb128.WriteVarUint32(w, v[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeValueTypeVector(w io.Writer, v []types.ValueType) error {
|
||||
|
||||
if err := leb128.WriteVarUint32(w, uint32(len(v))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range v {
|
||||
if err := writeValueType(w, v[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeBlockValueType(w io.Writer, v *types.ValueType) error {
|
||||
var b byte
|
||||
if v != nil {
|
||||
switch *v {
|
||||
case types.I32:
|
||||
b = constant.ValueTypeI32
|
||||
case types.I64:
|
||||
b = constant.ValueTypeI64
|
||||
case types.F32:
|
||||
b = constant.ValueTypeF32
|
||||
case types.F64:
|
||||
b = constant.ValueTypeF64
|
||||
}
|
||||
} else {
|
||||
b = constant.BlockTypeEmpty
|
||||
}
|
||||
return writeByte(w, b)
|
||||
}
|
||||
|
||||
func writeValueType(w io.Writer, v types.ValueType) error {
|
||||
var b byte
|
||||
switch v {
|
||||
case types.I32:
|
||||
b = constant.ValueTypeI32
|
||||
case types.I64:
|
||||
b = constant.ValueTypeI64
|
||||
case types.F32:
|
||||
b = constant.ValueTypeF32
|
||||
case types.F64:
|
||||
b = constant.ValueTypeF64
|
||||
}
|
||||
return writeByte(w, b)
|
||||
}
|
||||
|
||||
func writeRawSection(w io.Writer, buf *bytes.Buffer) error {
|
||||
|
||||
size := buf.Len()
|
||||
|
||||
if err := leb128.WriteVarUint32(w, uint32(size)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := io.Copy(w, buf)
|
||||
return err
|
||||
}
|
||||
|
||||
func writeByteVector(w io.Writer, bs []byte) error {
|
||||
|
||||
if err := leb128.WriteVarUint32(w, uint32(len(bs))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := w.Write(bs)
|
||||
return err
|
||||
}
|
||||
|
||||
func writeByte(w io.Writer, b byte) error {
|
||||
buf := make([]byte, 1)
|
||||
buf[0] = b
|
||||
_, err := w.Write(buf)
|
||||
return err
|
||||
}
|
||||
139
vendor/github.com/open-policy-agent/opa/internal/wasm/instruction/control.go
generated
vendored
Normal file
139
vendor/github.com/open-policy-agent/opa/internal/wasm/instruction/control.go
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package instruction
|
||||
|
||||
import (
|
||||
"github.com/open-policy-agent/opa/internal/wasm/opcode"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/types"
|
||||
)
|
||||
|
||||
// Unreachable reprsents an unreachable opcode.
|
||||
type Unreachable struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (Unreachable) Op() opcode.Opcode {
|
||||
return opcode.Unreachable
|
||||
}
|
||||
|
||||
// Nop represents a WASM no-op instruction.
|
||||
type Nop struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (Nop) Op() opcode.Opcode {
|
||||
return opcode.Nop
|
||||
}
|
||||
|
||||
// Block represents a WASM block instruction.
|
||||
type Block struct {
|
||||
NoImmediateArgs
|
||||
Type *types.ValueType
|
||||
Instrs []Instruction
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction
|
||||
func (Block) Op() opcode.Opcode {
|
||||
return opcode.Block
|
||||
}
|
||||
|
||||
// BlockType returns the type of the block's return value.
|
||||
func (i Block) BlockType() *types.ValueType {
|
||||
return i.Type
|
||||
}
|
||||
|
||||
// Instructions returns the instructions contained in the block.
|
||||
func (i Block) Instructions() []Instruction {
|
||||
return i.Instrs
|
||||
}
|
||||
|
||||
// Loop represents a WASM loop instruction.
|
||||
type Loop struct {
|
||||
NoImmediateArgs
|
||||
Type *types.ValueType
|
||||
Instrs []Instruction
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (Loop) Op() opcode.Opcode {
|
||||
return opcode.Loop
|
||||
}
|
||||
|
||||
// BlockType returns the type of the loop's return value.
|
||||
func (i Loop) BlockType() *types.ValueType {
|
||||
return i.Type
|
||||
}
|
||||
|
||||
// Instructions represents the instructions contained in the loop.
|
||||
func (i Loop) Instructions() []Instruction {
|
||||
return i.Instrs
|
||||
}
|
||||
|
||||
// Br represents a WASM br instruction.
|
||||
type Br struct {
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (Br) Op() opcode.Opcode {
|
||||
return opcode.Br
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the block index to break to.
|
||||
func (i Br) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Index}
|
||||
}
|
||||
|
||||
// BrIf represents a WASM br_if instruction.
|
||||
type BrIf struct {
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (BrIf) Op() opcode.Opcode {
|
||||
return opcode.BrIf
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the block index to break to.
|
||||
func (i BrIf) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Index}
|
||||
}
|
||||
|
||||
// Call represents a WASM call instruction.
|
||||
type Call struct {
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (Call) Op() opcode.Opcode {
|
||||
return opcode.Call
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the function index.
|
||||
func (i Call) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Index}
|
||||
}
|
||||
|
||||
// Return represents a WASM return instruction.
|
||||
type Return struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (Return) Op() opcode.Opcode {
|
||||
return opcode.Return
|
||||
}
|
||||
|
||||
// End represents the special WASM end instruction.
|
||||
type End struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (End) Op() opcode.Opcode {
|
||||
return opcode.End
|
||||
}
|
||||
33
vendor/github.com/open-policy-agent/opa/internal/wasm/instruction/instruction.go
generated
vendored
Normal file
33
vendor/github.com/open-policy-agent/opa/internal/wasm/instruction/instruction.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package instruction defines WASM instruction types.
|
||||
package instruction
|
||||
|
||||
import (
|
||||
"github.com/open-policy-agent/opa/internal/wasm/opcode"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/types"
|
||||
)
|
||||
|
||||
// NoImmediateArgs indicates the instruction has no immediate arguments.
|
||||
type NoImmediateArgs struct {
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the immedate arguments of an instruction.
|
||||
func (NoImmediateArgs) ImmediateArgs() []interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Instruction represents a single WASM instruction.
|
||||
type Instruction interface {
|
||||
Op() opcode.Opcode
|
||||
ImmediateArgs() []interface{}
|
||||
}
|
||||
|
||||
// StructuredInstruction represents a structured control instruction like br_if.
|
||||
type StructuredInstruction interface {
|
||||
Instruction
|
||||
BlockType() *types.ValueType
|
||||
Instructions() []Instruction
|
||||
}
|
||||
39
vendor/github.com/open-policy-agent/opa/internal/wasm/instruction/memory.go
generated
vendored
Normal file
39
vendor/github.com/open-policy-agent/opa/internal/wasm/instruction/memory.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2019 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package instruction
|
||||
|
||||
import "github.com/open-policy-agent/opa/internal/wasm/opcode"
|
||||
|
||||
// I32Load represents the WASM i32.load instruction.
|
||||
type I32Load struct {
|
||||
Offset int32
|
||||
Align int32 // expressed as a power of two
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I32Load) Op() opcode.Opcode {
|
||||
return opcode.I32Load
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the static offset and alignment operands.
|
||||
func (i I32Load) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Align, i.Offset}
|
||||
}
|
||||
|
||||
// I32Store represents the WASM i32.store instruction.
|
||||
type I32Store struct {
|
||||
Offset int32
|
||||
Align int32 // expressed as a power of two
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I32Store) Op() opcode.Opcode {
|
||||
return opcode.I32Store
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the static offset and alignment operands.
|
||||
func (i I32Store) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Align, i.Offset}
|
||||
}
|
||||
139
vendor/github.com/open-policy-agent/opa/internal/wasm/instruction/numeric.go
generated
vendored
Normal file
139
vendor/github.com/open-policy-agent/opa/internal/wasm/instruction/numeric.go
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package instruction
|
||||
|
||||
import (
|
||||
"github.com/open-policy-agent/opa/internal/wasm/opcode"
|
||||
)
|
||||
|
||||
// I32Const represents the WASM i32.const instruction.
|
||||
type I32Const struct {
|
||||
Value int32
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I32Const) Op() opcode.Opcode {
|
||||
return opcode.I32Const
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the i32 value to push onto the stack.
|
||||
func (i I32Const) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Value}
|
||||
}
|
||||
|
||||
// I64Const represents the WASM i64.const instruction.
|
||||
type I64Const struct {
|
||||
Value int64
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I64Const) Op() opcode.Opcode {
|
||||
return opcode.I64Const
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the i64 value to push onto the stack.
|
||||
func (i I64Const) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Value}
|
||||
}
|
||||
|
||||
// F32Const represents the WASM f32.const instruction.
|
||||
type F32Const struct {
|
||||
Value int32
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (F32Const) Op() opcode.Opcode {
|
||||
return opcode.F32Const
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the f32 value to push onto the stack.
|
||||
func (i F32Const) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Value}
|
||||
}
|
||||
|
||||
// F64Const represents the WASM f64.const instruction.
|
||||
type F64Const struct {
|
||||
Value float64
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (F64Const) Op() opcode.Opcode {
|
||||
return opcode.F64Const
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the f64 value to push onto the stack.
|
||||
func (i F64Const) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Value}
|
||||
}
|
||||
|
||||
// I32Eqz represents the WASM i32.eqz instruction.
|
||||
type I32Eqz struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I32Eqz) Op() opcode.Opcode {
|
||||
return opcode.I32Eqz
|
||||
}
|
||||
|
||||
// I32Eq represents the WASM i32.eq instruction.
|
||||
type I32Eq struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I32Eq) Op() opcode.Opcode {
|
||||
return opcode.I32Eq
|
||||
}
|
||||
|
||||
// I32Ne represents the WASM i32.ne instruction.
|
||||
type I32Ne struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I32Ne) Op() opcode.Opcode {
|
||||
return opcode.I32Ne
|
||||
}
|
||||
|
||||
// I32GtS represents the WASM i32.gt_s instruction.
|
||||
type I32GtS struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I32GtS) Op() opcode.Opcode {
|
||||
return opcode.I32GtS
|
||||
}
|
||||
|
||||
// I32GeS represents the WASM i32.ge_s instruction.
|
||||
type I32GeS struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I32GeS) Op() opcode.Opcode {
|
||||
return opcode.I32GeS
|
||||
}
|
||||
|
||||
// I32LtS represents the WASM i32.lt_s instruction.
|
||||
type I32LtS struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I32LtS) Op() opcode.Opcode {
|
||||
return opcode.I32LtS
|
||||
}
|
||||
|
||||
// I32LeS represents the WASM i32.le_s instruction.
|
||||
type I32LeS struct {
|
||||
NoImmediateArgs
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (I32LeS) Op() opcode.Opcode {
|
||||
return opcode.I32LeS
|
||||
}
|
||||
38
vendor/github.com/open-policy-agent/opa/internal/wasm/instruction/variable.go
generated
vendored
Normal file
38
vendor/github.com/open-policy-agent/opa/internal/wasm/instruction/variable.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package instruction
|
||||
|
||||
import "github.com/open-policy-agent/opa/internal/wasm/opcode"
|
||||
|
||||
// GetLocal represents the WASM get_local instruction.
|
||||
type GetLocal struct {
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (GetLocal) Op() opcode.Opcode {
|
||||
return opcode.GetLocal
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the index of the local variable to push onto the stack.
|
||||
func (i GetLocal) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Index}
|
||||
}
|
||||
|
||||
// SetLocal represents the WASM set_local instruction.
|
||||
type SetLocal struct {
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// Op returns the opcode of the instruction.
|
||||
func (SetLocal) Op() opcode.Opcode {
|
||||
return opcode.SetLocal
|
||||
}
|
||||
|
||||
// ImmediateArgs returns the index of the local variable to set with the top of
|
||||
// the stack.
|
||||
func (i SetLocal) ImmediateArgs() []interface{} {
|
||||
return []interface{}{i.Index}
|
||||
}
|
||||
340
vendor/github.com/open-policy-agent/opa/internal/wasm/module/module.go
generated
vendored
Normal file
340
vendor/github.com/open-policy-agent/opa/internal/wasm/module/module.go
generated
vendored
Normal file
@@ -0,0 +1,340 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package module
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/wasm/instruction"
|
||||
"github.com/open-policy-agent/opa/internal/wasm/types"
|
||||
)
|
||||
|
||||
type (
|
||||
// Module represents a WASM module.
|
||||
Module struct {
|
||||
Version uint32
|
||||
Type TypeSection
|
||||
Import ImportSection
|
||||
Function FunctionSection
|
||||
Table TableSection
|
||||
Element ElementSection
|
||||
Global GlobalSection
|
||||
Export ExportSection
|
||||
Code RawCodeSection
|
||||
Data DataSection
|
||||
}
|
||||
|
||||
// TypeSection represents a WASM type section.
|
||||
TypeSection struct {
|
||||
Functions []FunctionType
|
||||
}
|
||||
|
||||
// ImportSection represents a WASM import section.
|
||||
ImportSection struct {
|
||||
Imports []Import
|
||||
}
|
||||
|
||||
// FunctionSection represents a WASM function section.
|
||||
FunctionSection struct {
|
||||
TypeIndices []uint32
|
||||
}
|
||||
|
||||
// TableSection represents a WASM table section.
|
||||
TableSection struct {
|
||||
Tables []Table
|
||||
}
|
||||
|
||||
// ElementSection represents a WASM element section.
|
||||
ElementSection struct {
|
||||
Segments []ElementSegment
|
||||
}
|
||||
|
||||
// GlobalSection represents a WASM global section.
|
||||
GlobalSection struct {
|
||||
Globals []Global
|
||||
}
|
||||
|
||||
// ExportSection represents a WASM export section.
|
||||
ExportSection struct {
|
||||
Exports []Export
|
||||
}
|
||||
|
||||
// RawCodeSection represents a WASM code section. The code section is left as a
|
||||
// raw byte sequence. See CodeSection for the decoded version.
|
||||
RawCodeSection struct {
|
||||
Segments []RawCodeSegment
|
||||
}
|
||||
|
||||
// DataSection represents a WASM data section.
|
||||
DataSection struct {
|
||||
Segments []DataSegment
|
||||
}
|
||||
|
||||
// FunctionType represents a WASM function type definition.
|
||||
FunctionType struct {
|
||||
Params []types.ValueType
|
||||
Results []types.ValueType
|
||||
}
|
||||
|
||||
// Import represents a WASM import statement.
|
||||
Import struct {
|
||||
Module string
|
||||
Name string
|
||||
Descriptor ImportDescriptor
|
||||
}
|
||||
|
||||
// ImportDescriptor represents a WASM import descriptor.
|
||||
ImportDescriptor interface {
|
||||
fmt.Stringer
|
||||
Kind() ImportDescriptorType
|
||||
}
|
||||
|
||||
// ImportDescriptorType defines allowed kinds of import descriptors.
|
||||
ImportDescriptorType int
|
||||
|
||||
// FunctionImport represents a WASM function import statement.
|
||||
FunctionImport struct {
|
||||
Func uint32
|
||||
}
|
||||
|
||||
// MemoryImport represents a WASM memory import statement.
|
||||
MemoryImport struct {
|
||||
Mem MemType
|
||||
}
|
||||
|
||||
// MemType defines the attributes of a memory import.
|
||||
MemType struct {
|
||||
Lim Limit
|
||||
}
|
||||
|
||||
// TableImport represents a WASM table import statement.
|
||||
TableImport struct {
|
||||
Type types.ElementType
|
||||
Lim Limit
|
||||
}
|
||||
|
||||
// ElementSegment represents a WASM element segment.
|
||||
ElementSegment struct {
|
||||
Index uint32
|
||||
Offset Expr
|
||||
Indices []uint32
|
||||
}
|
||||
|
||||
// GlobalImport represents a WASM global variable import statement.
|
||||
GlobalImport struct {
|
||||
Type types.ValueType
|
||||
Mutable bool
|
||||
}
|
||||
|
||||
// Limit represents a WASM limit.
|
||||
Limit struct {
|
||||
Min uint32
|
||||
Max *uint32
|
||||
}
|
||||
|
||||
// Table represents a WASM table statement.
|
||||
Table struct {
|
||||
Type types.ElementType
|
||||
Lim Limit
|
||||
}
|
||||
|
||||
// Global represents a WASM global statement.
|
||||
Global struct {
|
||||
Type types.ValueType
|
||||
Mutable bool
|
||||
Init Expr
|
||||
}
|
||||
|
||||
// Export represents a WASM export statement.
|
||||
Export struct {
|
||||
Name string
|
||||
Descriptor ExportDescriptor
|
||||
}
|
||||
|
||||
// ExportDescriptor represents a WASM export descriptor.
|
||||
ExportDescriptor struct {
|
||||
Type ExportDescriptorType
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// ExportDescriptorType defines the allowed kinds of export descriptors.
|
||||
ExportDescriptorType int
|
||||
|
||||
// RawCodeSegment represents a binary-encoded WASM code segment.
|
||||
RawCodeSegment struct {
|
||||
Code []byte
|
||||
}
|
||||
|
||||
// DataSegment represents a WASM data segment.
|
||||
DataSegment struct {
|
||||
Index uint32
|
||||
Offset Expr
|
||||
Init []byte
|
||||
}
|
||||
|
||||
// Expr represents a WASM expression.
|
||||
Expr struct {
|
||||
Instrs []instruction.Instruction
|
||||
}
|
||||
|
||||
// CodeEntry represents a code segment entry.
|
||||
CodeEntry struct {
|
||||
Func Function
|
||||
}
|
||||
|
||||
// Function represents a function in a code segment.
|
||||
Function struct {
|
||||
Locals []LocalDeclaration
|
||||
Expr Expr
|
||||
}
|
||||
|
||||
// LocalDeclaration represents a local variable declaration.
|
||||
LocalDeclaration struct {
|
||||
Count uint32
|
||||
Type types.ValueType
|
||||
}
|
||||
)
|
||||
|
||||
// Defines the allowed kinds of imports.
|
||||
const (
|
||||
FunctionImportType ImportDescriptorType = iota
|
||||
TableImportType
|
||||
MemoryImportType
|
||||
GlobalImportType
|
||||
)
|
||||
|
||||
func (x ImportDescriptorType) String() string {
|
||||
switch x {
|
||||
case FunctionImportType:
|
||||
return "func"
|
||||
case TableImportType:
|
||||
return "table"
|
||||
case MemoryImportType:
|
||||
return "memory"
|
||||
case GlobalImportType:
|
||||
return "global"
|
||||
}
|
||||
panic("illegal value")
|
||||
}
|
||||
|
||||
// Defines the allowed kinds of exports.
|
||||
const (
|
||||
FunctionExportType ExportDescriptorType = iota
|
||||
TableExportType
|
||||
MemoryExportType
|
||||
GlobalExportType
|
||||
)
|
||||
|
||||
func (x ExportDescriptorType) String() string {
|
||||
switch x {
|
||||
case FunctionExportType:
|
||||
return "func"
|
||||
case TableExportType:
|
||||
return "table"
|
||||
case MemoryExportType:
|
||||
return "memory"
|
||||
case GlobalExportType:
|
||||
return "global"
|
||||
}
|
||||
panic("illegal value")
|
||||
}
|
||||
|
||||
// Kind returns the function import type kind.
|
||||
func (i FunctionImport) Kind() ImportDescriptorType {
|
||||
return FunctionImportType
|
||||
}
|
||||
|
||||
func (i FunctionImport) String() string {
|
||||
return fmt.Sprintf("%v[type=%v]", i.Kind(), i.Func)
|
||||
}
|
||||
|
||||
// Kind returns the memory import type kind.
|
||||
func (i MemoryImport) Kind() ImportDescriptorType {
|
||||
return MemoryImportType
|
||||
}
|
||||
|
||||
func (i MemoryImport) String() string {
|
||||
return fmt.Sprintf("%v[%v]", i.Kind(), i.Mem.Lim)
|
||||
}
|
||||
|
||||
// Kind returns the table import type kind.
|
||||
func (i TableImport) Kind() ImportDescriptorType {
|
||||
return TableImportType
|
||||
}
|
||||
|
||||
func (i TableImport) String() string {
|
||||
return fmt.Sprintf("%v[%v, %v]", i.Kind(), i.Type, i.Lim)
|
||||
}
|
||||
|
||||
// Kind returns the global import type kind.
|
||||
func (i GlobalImport) Kind() ImportDescriptorType {
|
||||
return GlobalImportType
|
||||
}
|
||||
|
||||
func (i GlobalImport) String() string {
|
||||
return fmt.Sprintf("%v[%v, mut=%v]", i.Kind(), i.Type, i.Mutable)
|
||||
}
|
||||
|
||||
func (tpe FunctionType) String() string {
|
||||
params := make([]string, len(tpe.Params))
|
||||
results := make([]string, len(tpe.Results))
|
||||
for i := range tpe.Params {
|
||||
params[i] = tpe.Params[i].String()
|
||||
}
|
||||
for i := range tpe.Results {
|
||||
results[i] = tpe.Results[i].String()
|
||||
}
|
||||
return "(" + strings.Join(params, ", ") + ") -> (" + strings.Join(results, ", ") + ")"
|
||||
}
|
||||
|
||||
// Equal returns true if tpe equals other.
|
||||
func (tpe FunctionType) Equal(other FunctionType) bool {
|
||||
|
||||
if len(tpe.Params) != len(other.Params) || len(tpe.Results) != len(other.Results) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range tpe.Params {
|
||||
if tpe.Params[i] != other.Params[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for i := range tpe.Results {
|
||||
if tpe.Results[i] != other.Results[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (imp Import) String() string {
|
||||
return fmt.Sprintf("%v %v.%v", imp.Descriptor.String(), imp.Module, imp.Name)
|
||||
}
|
||||
|
||||
func (exp Export) String() string {
|
||||
return fmt.Sprintf("%v[%v] %v", exp.Descriptor.Type, exp.Descriptor.Index, exp.Name)
|
||||
}
|
||||
|
||||
func (seg RawCodeSegment) String() string {
|
||||
return fmt.Sprintf("<code %d bytes>", len(seg.Code))
|
||||
}
|
||||
|
||||
func (seg DataSegment) String() string {
|
||||
return fmt.Sprintf("<data index=%v [%v] len=%d bytes>", seg.Index, seg.Offset, len(seg.Init))
|
||||
}
|
||||
|
||||
func (e Expr) String() string {
|
||||
return fmt.Sprintf("%d instr(s)", len(e.Instrs))
|
||||
}
|
||||
|
||||
func (lim Limit) String() string {
|
||||
if lim.Max == nil {
|
||||
return fmt.Sprintf("min=%v", lim.Min)
|
||||
}
|
||||
return fmt.Sprintf("min=%v max=%v", lim.Min, lim.Max)
|
||||
}
|
||||
84
vendor/github.com/open-policy-agent/opa/internal/wasm/module/pretty.go
generated
vendored
Normal file
84
vendor/github.com/open-policy-agent/opa/internal/wasm/module/pretty.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package module
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// PrettyOption defines options for controlling pretty printing.
|
||||
type PrettyOption struct {
|
||||
Contents bool // show raw byte content of data+code sections.
|
||||
}
|
||||
|
||||
// Pretty writes a human-readable representation of m to w.
|
||||
func Pretty(w io.Writer, m *Module, opts ...PrettyOption) {
|
||||
fmt.Fprintln(w, "version:", m.Version)
|
||||
fmt.Fprintln(w, "types:")
|
||||
for _, fn := range m.Type.Functions {
|
||||
fmt.Fprintln(w, " -", fn)
|
||||
}
|
||||
fmt.Fprintln(w, "imports:")
|
||||
for i, imp := range m.Import.Imports {
|
||||
if imp.Descriptor.Kind() == FunctionImportType {
|
||||
fmt.Printf(" - [%d] %v\n", i, imp)
|
||||
} else {
|
||||
fmt.Fprintln(w, " -", imp)
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(w, "functions:")
|
||||
for _, fn := range m.Function.TypeIndices {
|
||||
if fn >= uint32(len(m.Type.Functions)) {
|
||||
fmt.Fprintln(w, " -", "???")
|
||||
} else {
|
||||
fmt.Fprintln(w, " -", m.Type.Functions[fn])
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(w, "exports:")
|
||||
for _, exp := range m.Export.Exports {
|
||||
fmt.Fprintln(w, " -", exp)
|
||||
}
|
||||
fmt.Fprintln(w, "code:")
|
||||
for _, seg := range m.Code.Segments {
|
||||
fmt.Fprintln(w, " -", seg)
|
||||
}
|
||||
fmt.Fprintln(w, "data:")
|
||||
for _, seg := range m.Data.Segments {
|
||||
fmt.Fprintln(w, " -", seg)
|
||||
}
|
||||
if len(opts) == 0 {
|
||||
return
|
||||
}
|
||||
fmt.Fprintln(w)
|
||||
for _, opt := range opts {
|
||||
if opt.Contents {
|
||||
newline := false
|
||||
if len(m.Data.Segments) > 0 {
|
||||
fmt.Fprintln(w, "data section:")
|
||||
for _, seg := range m.Data.Segments {
|
||||
if newline {
|
||||
fmt.Fprintln(w)
|
||||
}
|
||||
fmt.Fprintln(w, hex.Dump(seg.Init))
|
||||
newline = true
|
||||
}
|
||||
newline = false
|
||||
}
|
||||
if len(m.Code.Segments) > 0 {
|
||||
fmt.Fprintln(w, "code section:")
|
||||
for _, seg := range m.Code.Segments {
|
||||
if newline {
|
||||
fmt.Fprintln(w)
|
||||
}
|
||||
fmt.Fprintln(w, hex.Dump(seg.Code))
|
||||
newline = true
|
||||
}
|
||||
newline = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
218
vendor/github.com/open-policy-agent/opa/internal/wasm/opcode/opcode.go
generated
vendored
Normal file
218
vendor/github.com/open-policy-agent/opa/internal/wasm/opcode/opcode.go
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package opcode contains constants and utilities for working with WASM opcodes.
|
||||
package opcode
|
||||
|
||||
// Opcode represents a WASM instruction opcode.
|
||||
type Opcode byte
|
||||
|
||||
// Control instructions.
|
||||
const (
|
||||
Unreachable Opcode = iota
|
||||
Nop
|
||||
Block
|
||||
Loop
|
||||
If
|
||||
Else
|
||||
)
|
||||
|
||||
const (
|
||||
// End defines the special end WASM opcode.
|
||||
End Opcode = 0x0B
|
||||
)
|
||||
|
||||
// Extended control instructions.
|
||||
const (
|
||||
Br Opcode = iota + 0x0C
|
||||
BrIf
|
||||
BrTable
|
||||
Return
|
||||
Call
|
||||
CallIndirect
|
||||
)
|
||||
|
||||
// Parameter instructions.
|
||||
const (
|
||||
Drop Opcode = iota + 0x1A
|
||||
Select
|
||||
)
|
||||
|
||||
// Variable instructions.
|
||||
const (
|
||||
GetLocal Opcode = iota + 0x20
|
||||
SetLocal
|
||||
TeeLocal
|
||||
GetGlobal
|
||||
SetGlobal
|
||||
)
|
||||
|
||||
// Memory instructions.
|
||||
const (
|
||||
I32Load Opcode = iota + 0x28
|
||||
I64Load
|
||||
F32Load
|
||||
F64Load
|
||||
I32Load8S
|
||||
I32Load8U
|
||||
I32Load16S
|
||||
I32Load16U
|
||||
I64Load8S
|
||||
I64Load8U
|
||||
I64Load16S
|
||||
I64Load16U
|
||||
I64Load32S
|
||||
I64Load32U
|
||||
I32Store
|
||||
I64Store
|
||||
F32Store
|
||||
F64Store
|
||||
I32Store8
|
||||
I32Store16
|
||||
I64Store8
|
||||
I64Store16
|
||||
I64Store32
|
||||
MemorySize
|
||||
MemoryGrow
|
||||
)
|
||||
|
||||
// Numeric instructions.
|
||||
const (
|
||||
I32Const Opcode = iota + 0x41
|
||||
I64Const
|
||||
F32Const
|
||||
F64Const
|
||||
|
||||
I32Eqz
|
||||
I32Eq
|
||||
I32Ne
|
||||
I32LtS
|
||||
I32LtU
|
||||
I32GtS
|
||||
I32GtU
|
||||
I32LeS
|
||||
I32LeU
|
||||
I32GeS
|
||||
I32GeU
|
||||
|
||||
I64Eqz
|
||||
I64Eq
|
||||
I64Ne
|
||||
I64LtS
|
||||
I64LtU
|
||||
I64GtS
|
||||
I64GtU
|
||||
I64LeS
|
||||
I64LeU
|
||||
I64GeS
|
||||
I64GeU
|
||||
|
||||
F32Eq
|
||||
F32Ne
|
||||
F32Lt
|
||||
F32Gt
|
||||
F32Le
|
||||
F32Ge
|
||||
|
||||
F64Eq
|
||||
F64Ne
|
||||
F64Lt
|
||||
F64Gt
|
||||
F64Le
|
||||
F64Ge
|
||||
|
||||
I32Clz
|
||||
I32Ctz
|
||||
I32Popcnt
|
||||
I32Add
|
||||
I32Sub
|
||||
I32Mul
|
||||
I32DivS
|
||||
I32DivU
|
||||
I32RemS
|
||||
I32RemU
|
||||
I32And
|
||||
I32Or
|
||||
I32Xor
|
||||
I32Shl
|
||||
I32ShrS
|
||||
I32ShrU
|
||||
I32Rotl
|
||||
I32Rotr
|
||||
|
||||
I64Clz
|
||||
I64Ctz
|
||||
I64Popcnt
|
||||
I64Add
|
||||
I64Sub
|
||||
I64Mul
|
||||
I64DivS
|
||||
I64DivU
|
||||
I64RemS
|
||||
I64RemU
|
||||
I64And
|
||||
I64Or
|
||||
I64Xor
|
||||
I64Shl
|
||||
I64ShrS
|
||||
I64ShrU
|
||||
I64Rotl
|
||||
I64Rotr
|
||||
|
||||
F32Abs
|
||||
F32Neg
|
||||
F32Ceil
|
||||
F32Floor
|
||||
F32Trunc
|
||||
F32Nearest
|
||||
F32Sqrt
|
||||
F32Add
|
||||
F32Sub
|
||||
F32Mul
|
||||
F32Div
|
||||
F32Min
|
||||
F32Max
|
||||
F32Copysign
|
||||
|
||||
F64Abs
|
||||
F64Neg
|
||||
F64Ceil
|
||||
F64Floor
|
||||
F64Trunc
|
||||
F64Nearest
|
||||
F64Sqrt
|
||||
F64Add
|
||||
F64Sub
|
||||
F64Mul
|
||||
F64Div
|
||||
F64Min
|
||||
F64Max
|
||||
F64Copysign
|
||||
|
||||
I32WrapI64
|
||||
I32TruncSF32
|
||||
I32TruncUF32
|
||||
I32TruncSF64
|
||||
I32TruncUF64
|
||||
I64ExtendSI32
|
||||
I64ExtendUI32
|
||||
I64TruncSF32
|
||||
I64TruncUF32
|
||||
I64TruncSF64
|
||||
I64TruncUF64
|
||||
F32ConvertSI32
|
||||
F32ConvertUI32
|
||||
F32ConvertSI64
|
||||
F32ConvertUI64
|
||||
F32DemoteF64
|
||||
F64ConvertSI32
|
||||
F64ConvertUI32
|
||||
F64ConvertSI64
|
||||
F64ConvertUI64
|
||||
F64PromoteF32
|
||||
I32ReinterpretF32
|
||||
I64ReinterpretF64
|
||||
F32ReinterpretI32
|
||||
F64ReinterpretI64
|
||||
)
|
||||
36
vendor/github.com/open-policy-agent/opa/internal/wasm/types/types.go
generated
vendored
Normal file
36
vendor/github.com/open-policy-agent/opa/internal/wasm/types/types.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2018 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package types defines the WASM value type constants.
|
||||
package types
|
||||
|
||||
// ValueType represents an intrinsic value in WASM.
|
||||
type ValueType int
|
||||
|
||||
// Defines the intrinsic value types.
|
||||
const (
|
||||
I32 ValueType = iota
|
||||
I64
|
||||
F32
|
||||
F64
|
||||
)
|
||||
|
||||
func (tpe ValueType) String() string {
|
||||
if tpe == I32 {
|
||||
return "i32"
|
||||
} else if tpe == I64 {
|
||||
return "i64"
|
||||
} else if tpe == F32 {
|
||||
return "f32"
|
||||
}
|
||||
return "f64"
|
||||
}
|
||||
|
||||
// ElementType defines the type of table elements.
|
||||
type ElementType int
|
||||
|
||||
const (
|
||||
// Anyfunc is the union of all table types.
|
||||
Anyfunc ElementType = iota
|
||||
)
|
||||
Reference in New Issue
Block a user