Commit Graph

63 Commits

Author SHA1 Message Date
Damian Gryski fb394c7685 reflect: add UnsafeAddr() 2023-03-14 16:53:57 +01:00
Damian Gryski a52cad3825 reflect: fix Addr() indirect value/flags and add tests. 2023-03-14 16:49:05 +01:00
Damian Gryski 69e5c5088d reflect: add support for remaining map types 2023-03-10 16:28:22 -08:00
Damian Gryski 2a821d2a66 reflect: improve Value.String() 2023-03-08 09:38:49 -08:00
Damian Gryski f9b6f8339b reflect: ensure all ValueError panics have Kind fields 2023-03-03 10:18:32 -08:00
Damian Gryski 0ff243e5e2 reflect: add OverflowFloat(), OverflowInt(), OverflowUint() 2023-03-03 10:18:32 -08:00
Damian Gryski 79930a209c reflect: add Addr() 2023-03-03 10:18:32 -08:00
Damian Gryski bbc79ee40a reflect: add Zero() 2023-03-03 10:18:32 -08:00
Damian Gryski 960a0b79bf reflect: add SetLen() 2023-03-03 10:18:32 -08:00
Damian Gryski 3a3de8a778 reflect: add pointerTo() 2023-03-03 10:18:32 -08:00
Ayke van Laethem 4ec1e58aa6 all: use unsafe.Add instead of unsafe.Pointer(uintptr(...) + ...)
We have an optimization for this specific pattern, but it's really just
a hack. With the addition of unsafe.Add in Go 1.17 we can directly
specify the intent instead and eventually remove this special case.

The code is also easier to read.
2023-03-03 16:55:13 +01:00
Damian Gryski d98c0afbab reflect: add Bytes() 2023-03-03 05:21:02 -08:00
Damian Gryski 12e3d1d81d reflect: add Copy() 2023-03-03 05:21:02 -08:00
Damian Gryski a7e3cf0826 reflect: add Slice3() 2023-03-03 05:21:02 -08:00
Damian Gryski 43a4b256bd reflect: add Slice() 2023-03-03 05:21:02 -08:00
Damian Gryski 5cc5f11b58 reflect: add MakeSlice() 2023-03-03 05:21:02 -08:00
Damian Gryski 836689fdd2 reflect: add Append() 2023-03-03 05:21:02 -08:00
Damian Gryski a2bb1d3805 reflect: add MapKeys() 2023-02-28 13:10:40 -08:00
Damian Gryski c4dadbaaab reflect: add MakeMap() 2023-02-28 13:10:40 -08:00
Damian Gryski 828c3169ab reflect: add SetMapIndex() 2023-02-28 13:10:40 -08:00
Damian Gryski f6ee470eda reflect: add MapRange/MapIter 2023-02-28 13:10:40 -08:00
Damian Gryski d0f4702f8b reflect: add MapIndex() 2023-02-28 13:10:40 -08:00
Ayke van Laethem 4e8453167f all: refactor reflect package
This is a big commit that changes the way runtime type information is stored in
the binary. Instead of compressing it and storing it in a number of sidetables,
it is stored similar to how the Go compiler toolchain stores it (but still more
compactly).

This has a number of advantages:

  * It is much easier to add new features to reflect support. They can simply
    be added to these structs without requiring massive changes (especially in
    the reflect lowering pass).
  * It removes the reflect lowering pass, which was a large amount of hard to
    understand and debug code.
  * The reflect lowering pass also required merging all LLVM IR into one
    module, which is terrible for performance especially when compiling large
    amounts of code. See issue 2870 for details.
  * It is (probably!) easier to reason about for the compiler.

The downside is that it increases code size a bit, especially when reflect is
involved. I hope to fix some of that in later patches.
2023-02-17 22:54:34 +01:00
Damian Gryski 86f125cf72 reflect: track flags when size changes from fits-in-pointer to not
Fixes #3328
2022-12-07 23:11:40 +01:00
Julia Ogris c759e6fc2d reflect: Add Value.IsZero() method
Add Value.IsZero() with tests, largely copied from the Go source code.

The tests were altered to remove the parts calling `Zero()` as that is
still unimplemented in tinygo, and to remove a test that tries to catch
a panic which is not supported on wasi.

A new case for `UnsafePointer` in `Value.IsNil()` was required for
unsafe.Pointer tests to pass.

Link: https://cs.opensource.google/go/go/+/refs/tags/go1.19.3:src/reflect/value.go;l=1568
Link: https://cs.opensource.google/go/go/+/refs/tags/go1.19.3:src/reflect/all_test.go;l=1322
Co-authored-by: Cam Hutchison <camh@xdna.net>
2022-11-21 14:51:22 +01:00
Ayke van Laethem e955aa1941 reflect: implement CanInterface and fix string Index()
This commit fixes two related issues:

 1. CanInterface was unimplemented. It now uses the same check as is
    used in Interface() itself.
    This issue led to https://github.com/tinygo-org/tinygo/issues/3033
 2. Allow making an interface out of a string char element.

Doing this in one commit (instead of two) because they are shown to be
correct with the same tests.
2022-09-01 21:42:22 +02:00
Ayke van Laethem 4262f0ff1f compiler: really define runtime.mem* as LLVM intrinsic wrappers
This makes it possible to //go:linkname them from other places, like in
the reflect package. And is in my opinion a much cleaner solution.
2022-06-24 11:10:24 +02:00
Ayke van Laethem caf405b01d reflect: add Value.UnsafePointer method
This was added in Go 1.18.
2022-06-12 01:08:02 +02:00
Elliott Sales de Andrade f159573975 Add reflect.Value.FieldByIndexErr stub 2022-03-24 06:31:02 +01:00
Kyle Conroy cfed3f0213 fix: Add stubs for more missing reflect methods
With these methods stubbed out, the text/template package can be
imported. These changes also allow code generated by protoc to compile.
2022-02-24 12:32:40 -05:00
Damian Gryski 518745ea79 src/reflect: make sure indirect pointers are handled correctly
Fixes #2370
Fixes #2323
2021-12-18 10:02:36 +01:00
Ayke van Laethem 335fb71d2f reflect: add support for DeepEqual
The implementation has been mostly copied from the Go reference
implementation with some small changes to fit TinyGo.

Source: https://github.com/golang/go/blob/77a11c05d6a6f766c75f804ea9b8796f9a9f85a3/src/reflect/deepequal.go

In addition, this commit also contains the following:

  - A set of tests copied from the Go reflect package.
  - An increased stack size for the riscv-qemu and hifive1-qemu targets
    (because they otherwise fail to run the tests). Because these
    targets are only used for testing, this seems fine to me.
2021-11-12 21:27:27 +01:00
Ayke van Laethem 5866a47e77 reflect: fix Value.Index() in a specific case
In the case where:

 - Value.Index() was called on an array
 - that array was bigger than a pointer
 - the element type fits in a pointer
 - the 'indirect' flag isn't set

the Value.Index() method would still (incorrectly) load the value.
This commit fixes that.

The next commit adds a test which would have triggered this bug so works
as a regression test.
2021-11-12 21:27:27 +01:00
Ayke van Laethem 823c9c25cf reflect: implement Value.Elem() for interface values 2021-11-12 21:27:27 +01:00
Ayke van Laethem d15e32fb89 reflect: don't construct an interface-in-interface value
v.Interaface() could construct an interface in interface value if v was
of type interface. This is not correct, and doesn't follow upstream Go
behavior. Instead, it should return the interface value itself.
2021-11-12 21:27:27 +01:00
Ayke van Laethem f24a93c51d compiler, runtime: add layout parameter to runtime.alloc
This layout parameter is currently always nil and ignored, but will
eventually contain a pointer to a memory layout.

This commit also adds module verification to the transform tests, as I
found out that it didn't (and therefore didn't initially catch all
bugs).
2021-11-02 22:16:15 +01:00
Federico G. Schwindt 793a3175d3 reflect: add stubs required for net/http 2021-06-02 13:28:38 +02:00
Ayke van Laethem 541d8dcd2e reflect: implement AppendSlice
This implementation of AppendSlice simply calls through to the version
used in the runtime: runtime.sliceAppend.
2021-05-22 21:41:06 +02:00
Ayke van Laethem c8742e2b96 reflect: use SliceHeader and StringHeader variant for internal use
These variants uses an unsafe.Pointer instead of uintptr so that the
pointer/non-pointer fields match those of real slices and strings. This
may be necessary in the future once we switch to a precise garbage
collector.
2021-05-22 21:41:06 +02:00
Ayke van Laethem e587b1d1b4 reflect: implement New function
This is very important for some use cases, for example for Vecty.
2021-04-12 14:49:26 +02:00
Ayke van Laethem 2aa2e750b9 reflect: implement Value.CanAddr
It is used in the crypto/sha512 test, for example. And it is very simple
to implement.
2021-03-28 19:28:55 +02:00
Ayke van Laethem f800f7507c reflect: check for access in the Interface method call
This fixes a type system loophole. The following program would
incorrectly run in TinyGo, while it would trigger a panic in Go:

    package main

    import "reflect"

    func main() {
        v := reflect.ValueOf(struct {
            x int
        }{})
        x := v.Field(0).Interface()
        println("x:", x.(int))
    }

Playground link: https://play.golang.org/p/nvvA18XFqFC

The panic in Go is the following:

    panic: reflect.Value.Interface: cannot return value obtained from unexported field or method

I've shortened it in TinyGo to save a little bit of space.
2021-03-24 12:19:16 +01:00
Ayke van Laethem 9f3dcf3733 reflect: implement a number of stub functions
These stub functions are necessary for the encoding/json package. They
don't seem to be called in trivial cases, so leave them as simple stubs
for now.
2021-03-23 15:48:33 +01:00
Ayke van Laethem c849bccb83 reflect: let reflect.Type be of interface type
This matches the main Go implementation and (among others) fixes a
compatibility issue with the encoding/json package. The encoding/json
package compares reflect.Type variables against nil, which does not work
as long as reflect.Type is of integer type.

This also adds a reflect.RawType() function (like reflect.Type()) that
makes it easier to avoid working with interfaces in the runtime package.
It is internal only, but exported to let the runtime package use it.

This change introduces a small code size increase when working with the
reflect package, but I've tried to keep it to a minimum. Most programs
that don't make extensive use of the reflect package (and don't use
package like fmt) should not be impacted by this.
2021-03-23 14:32:33 +01:00
Cornel 720a54a0fe extend stdlib to allow import of more packages (#1099)
* stdlib: extend stdlib to allow import of more packages
2020-06-23 11:56:28 +02:00
cornelk 2c71f08922 reflect: add Cap and Len support for map and chan 2020-05-12 01:17:27 +02:00
Ayke van Laethem eaa54bc7e3 compiler,runtime: use LLVM intrinsics for memcpy/memmove
This replaces the custom runtime.memcpy and runtime.memmove functions
with calls to LLVM builtins that should hopefully allow LLVM to better
optimize such calls. They will be lowered to regular libc memcpy/memmove
when they can't be optimized away.

When testing this change with some smoke tests, I found that many smoke
tests resulted in slightly larger binary sizes with this commit applied.
I looked into it and it appears that machine.sendUSBPacket was not
inlined before while it is with this commit applied. Additionally, when
I compared all driver smoke tests with -opt=1 I saw that many were
reduced slightly in binary size and none increased in size.
2020-03-27 21:01:59 +01:00
Jaden Weiss d17f500c8b replace reflect.interfaceHeader with strongly typed runtime functions 2019-09-22 16:36:11 +02:00
Ayke van Laethem c19c738f52 reflect: implement support for array types 2019-08-19 11:08:26 +02:00
Ayke van Laethem 0818a125c0 reflect: fix IsNil and Pointer for addressable pointer types 2019-08-11 15:00:43 +02:00