18 Commits

Author SHA1 Message Date
Johan Fylling 8e410b830a String interpolation (#8109)
Adding string interpolation support to the Rego language.

An interpolated string is composed of a template-string that can contain zero or more template-expressions that interpolates values into the string generated at eval-time.

Requires the `template_strings` capability feature and `internal.template_string` built-in function.

Implements: #4733
2025-12-16 11:47:04 +01:00
Anders Eknert 55e87e79ae Add perfsprint linter (#7334)
And update code to conform to the rule.

- Replace unnecessary fmt.Sprintf with string concatenation
- Replace fmt.Sprint with more efficient strconv.Itoa
- Replace static fmt.Errorf calls with more efficient errors.New

Thanks @srenatus for pushing me down this rabbit hole!

Signed-off-by: Anders Eknert <anders@styra.com>
2025-01-31 20:24:05 +01:00
Anders Eknert b942136a4a Use Go 1.22+ int ranges (#7328)
With "some" help from `golangci-lint run --fix ./...`

Signed-off-by: Anders Eknert <anders@styra.com>
2025-01-30 09:57:27 +01:00
Stephan Renatus 20885fe4a9 golangci: bump version, addess all new findings
The previous version has been failing without any good reason for me,
so let's try this.

About the version pick: It's not the latest version (v1.62.0 at the
moment), because that would introduce a new revive rule,
redeclares-builtin-id, and that flags every variable called `min` or
`max` in the code base. I had started addressing these, but they were
just too many.

The new issues related to this version are mostly that it complains
whenever it finds a non-static string that makes its way into a printf-
like function. However, that's a common pattern in some place here, so
I've sprinkled some nolint:govet on it.

Signed-off-by: Stephan Renatus <stephan@styra.com>
2024-11-14 20:36:50 +01:00
Johan Fylling 5464b005e8 Bumping golangci-lint to v1.59.1 (#6817)
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-06-19 15:13:43 +02:00
Anders Eknert 9a597feb2e chore: don't use the deprecated ioutil functions (#5319)
Another annoyance removed :P

Signed-off-by: Anders Eknert <anders@eknert.com>
2022-10-27 14:30:26 +02:00
Anders Eknert 95708108f3 linters: add unconvert (#5318)
Got a few warnings from my IDE about redundant type conversions,
so I decided to look into it. Added the unconvert linter to our
checks, and fixed the violations. Added two ignore comments as I
wasn't sure about whether they'd change the semantics of the code.

Signed-off-by: Anders Eknert <anders@eknert.com>
2022-10-27 13:35:39 +02:00
Stephan Renatus 21ac58bddc build/wasm: use golang1.16 go:embed mechanism (#5123)
With the embed directive, we no longer need our custom code that predates
Go 1.16. Also, with the release of 1.19, we no longer desire compatibility
with anything predating 1.16, so this cleanup becomes possible.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-09-12 17:42:44 +02:00
Jason Hall 4dd7fb1c0d Remove use of github.com/pkg/errors (#4696)
This package is deprecated, archived, and in maintenance mode, since Go
errors support wrapping natively.

For #2152.

Signed-off-by: Jason Hall <jason@chainguard.dev>
2022-05-18 11:29:35 +02:00
Stephan Renatus 5240170c68 wasm: deal with importing memory in the compiler (#3763)
This sets the stage for eventually allowing OPA wasm modules that do NOT
import memory.

With this change, we add the necessary segments to the wasm module that
declare that memory is to be imported, in the wasm compiler. As far as
LLVM and our C base is concerned, the memory is NOT imported.

The test runners have been adapted, `make wasm-lib-test` works without
having imported memory now. `make wasm-rego-test` can deal with both: it
will provide memory in its `imports` for instantiation, but if the wasm
module happens to not want that import, it'll be ignored. The memory used
in the other host methods is the exported one. (Whether that is exported
or re-exported imported doesn't make a difference.)

Some first steps have been included to make OPA's Wasm SDK work without
imported memory. There are a few loose ends around enforcing memory
limits, to be taken care of later.

----

This also addresses a problem we've seen in the wild before: when our
additions to the wasm modules' data segments exceed the number of pages
needed for the memory import, a "data segment overflowing memory" issue
could have happened. That was because the minimal memory size for the
imported memory was determined by LLVM, and we'd just squeeze our added
data segments in, without adjusting that limit.

Now, the limit will be set properly; and if a too small memory was
provided, a more descriptive failure will happen at instantiation time.
Wasmtime, for example, raises

    incompatible import type for `env::memory`
    Caused by:
        memory types incompatible

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-10-18 14:02:08 +02:00
Will Beason 3be1d08b87 Change check-lint to use golangci-lint (#3465)
golint is deprecated. The author of the code no longer supports the
codebase. golangci-lint is faster than golint, and is in use by other
opa repositories (e.g. Gatekeeper).

This commit changes tools.go to reference golangci (so it ends up in
vendor) and modifies check-lint to use golangci instead.

Breaking API Changes:

- plugins/rest/rest.go: Fix typo "AllowInsureTLS" -> "AllowInsecureTLS"
- storage/errors.go: Removed unused IndexingNotSupportedErr

Signed-off-by: Will Beason <willbeason@google.com>
2021-05-19 07:52:02 +02:00
Stephan Renatus 81a774a60d wasm: dynamically dispatch data functions with "seen" ref pieces using call_indirect (#3058)
* wasm: optimize package access with non-ground refs using call_indrect

We now

1. write an object corresponding to data paths into the module data
2. initialize an opa_object_t from that using `_initialize`, called
   as the module's Start function
3. write out CallDynamicStmts in IR when the ref is not all ground,
   but its vars have been seen
4. compile those CallDynamicStmts to call_indirect invocations in
   WASM, preceded by a lookup using the path in the object prepared
   in (2.)
5. if the lookup fails to come up with a result, the eval goes
   undefined

What it looks like:

With t.rego as

    package t

    p {
      data.foo[input.x].bar.p
    }

and foo.rego as

    package foo.a.bar

    p = true

when building policy.wasm using `opa build -t wasm -e t/p t.rego foo.rego`,
the body of function `g0.data.t.p` will contain

    i32.const 5
    call $opa_array_with_cap
    local.set $11
    local.get $11
    local.get $7
    call $opa_array_append
    local.get $11
    local.get $8
    call $opa_array_append
    local.get $11
    local.get $6
    call $opa_array_append
    local.get $11
    local.get $9
    call $opa_array_append
    local.get $11
    local.get $10
    call $opa_array_append
    local.get $0
    local.get $1
    local.get $11
    call $opa_mapping_lookup
    local.tee $12
    i32.eqz
    br_if $block
    local.get $12
    call_indirect $29 (type $1)
    local.tee $13
    i32.eqz
    br_if $block

Where the array-related functions build an array of

    ["g0", "foo", input.x, "bar", "p"]

and pass that to `opa_mapping_lookup` to determine the element index to
pass to `call_indirect`. The lookup function returns 74 from the JSON
blob put into the data section,

    (data $38 (i32.const 56485)
      "{\"g0\": {\"foo\": {\"a\": {\"bar\": {\"p\": 74}}}, \"t\": {\"p\": 75}}}")

iff input.x happens to be "a". Otherwise, it'll return 0, and the result
will end up being undefined.

Element 74 of the modules func table is, of course, $g0.data.foo.a.bar.p:

    (elem $33 (i32.const 74)
      $g0.data.foo.a.bar.p $g0.data.t.p)

($33 is some id of that piece of function table, an artifact of the
`wavm disassemble` output.)

* compiler/wasm: add memoization to call_indirect logic

- adds a data segment for mapping element indices (used with call_indirect)
  to function indices (as used with opa_memoize_{get,insert})
- emits mapping function elem -> func idx that uses that data segment
- wires up memoization lookup and insert in call_indirect code path

The added test case would cause `make wasm-rego-test` to fail like this
if memoization wasn't happening:

    ERROR 019_call_indirect_optimization.json: memoization: should have been memoized

* planner: add debug messages, carry them over into the compiler

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-01-21 18:17:27 +01:00
Stephan Renatus 2e122c9e69 wasm: read/write custom sections (incl. dwarf), deal with Name section specifically (#2900)
* wasm: read/write custom sections (incl. dwarf)

I've extended the roundtrip OPA test to have some assertions
on custom sections that work for both debug and non-debug
wasm builds.

Without debugging enabled, we had still been stripping the
`names` and `producers` sections. This changes therefore
increases the size of wasm modules. For a simple policy,

    package test
    default allow = false
    allow {
        input.foo == "bar"
    }

the size generated is 544K (master) vs 620K (this commit).

With debugging enabled (and the opa binary rebuilt), the
size becomes 6.1M.

* wasm/encoding: treat 'name' custom section separately

This roundtrips module, functions, and locals, as per
https://webassembly.github.io/spec/core/appendix/custom.html#name-section

There is currently no use of module and locals, afaict.

* compiler/wasm: record function names in 'name' custom section

Quality-of-life improvement when dealing with our generated WASM
code.

Before:

    local.get 2
    local.get 3
    call 1172
    local.set 6

After:

    local.get 2
    local.get 3
    call $g0.data.foo.p
    local.set 6

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-01-13 09:30:39 +01:00
Torin Sandall 1ee7c43cee wasm: Add support for reading/writing element sections
Element sections are required for initializing the table used for
indirect calls. Since we now make use of function pointers in the
JSON serialization and printf implementation, indirect calls must be
supported.

See https://webassembly.github.io/spec/core/syntax/modules.html#syntax-elem

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-10-28 16:41:32 -04:00
Patrick East b48c534722 Run make fmt with new goimports cmd
Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-09-27 09:55:11 -04:00
Guangming Wang 17bd04316e fix static check error in reader.go
Signed-off-by: Guangming Wang <guangming.wang@daocloud.io>
2019-08-28 18:18:58 -07:00
Torin Sandall 58f476b5de Add table and global section encoding support
These sections are required so that we can statically link the policy
and the OPA-WASM library together.

Also, add test case that roundtrips the OPA module for sanity.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2018-10-09 14:38:48 -07:00
Torin Sandall 622bcbdf9d Add WASM compiler backend and required types
These changes implement a basic WASM compiler backend for the IR added
in the previous commit. These changes also include a binary-encoding
package that can roundtrip simple WASM modules.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2018-10-08 17:29:18 -07:00