Граф коммитов

17 коммитов

Автор SHA1 Сообщение Дата
Damian Gryski
777048cfa9 compiler: fix crash on type assert on interfaces with no methods 2023-11-08 19:41:25 +01:00
Damian Gryski
f5f4751088 compiler,transform: fix for pointer-to-pointer type switches from @aykevl 2023-06-09 17:30:02 +02:00
Ayke van Laethem
523c6c0e3b compiler: correctly generate code for local named types
It is possible to create function-local named types:

    func foo() any {
        type named int
        return named(0)
    }

This patch makes sure they don't alias with named types declared at the
package scope.

Bug originally found by Damian Gryski while working on reflect support.
2023-03-21 22:22:03 +01:00
Ayke van Laethem
c0d257d682 compiler: fix difference in aliases in interface methods
There used to be a difference between `byte` and `uint8` in interface
methods. These are aliases, so they should be treated the same.
This patch introduces a custom serialization format for types,
circumventing the `Type.String()` method that is slightly wrong for our
purposes.

This also fixes an issue with the `any` keyword in Go 1.18, which
suffers from the same problem (but this time actually leads to a crash).
2022-04-07 12:54:17 +02:00
Ayke van Laethem
0596b3c003 compiler: add support for anonymous type asserts
This is used for example by the errors package, which contains:

    if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) {
        return true
    }

The interface here is not a named type.
2020-03-29 08:39:07 +02:00
Ayke van Laethem
9222bda9c6 interp: add support for constant type asserts
Non-constant type asserts are not yet implemented, but should be
relatively easy to add at a later time. They should result in a clear
error message for now.
2020-03-20 22:22:24 +01:00
Ayke van Laethem
14474e7099 compiler: fix assertion on empty interface
This fixes issue #453.
2019-12-26 09:20:22 +01:00
Jaden Weiss
98eee7c22a
compiler: add support for async interface calls 2019-11-17 23:46:10 +01:00
Ayke van Laethem
45b5decb4e runtime: implement comparing uintptr values in interfaces
This was an oversight in https://github.com/tinygo-org/tinygo/pull/686.
With this PR, it's possible to compare interface values that contain
values/fields of type uintptr.
2019-11-09 13:41:27 -05:00
Konstantin Itskov
ac330f4a70 runtime: implement interface equality
Code copied from Konstantin Itskov and modified by Ayke van Laethem.
For details: https://github.com/tinygo-org/tinygo/pull/569
2019-11-04 15:19:41 +01:00
Ayke van Laethem
f43d01bdc7 compiler: make struct types more unique
There are a lot more fields that are important when comparing structs
with each other. Take them into account when building the unique ID per
struct type.

Example code that differs between the compilers:
https://play.golang.org/p/nDX4tSHOf_T
2019-08-08 15:23:47 +02:00
Ayke van Laethem
33dc4b5121 compiler: fix crash with linked lists in interfaces
This commit fixes the following issue:
https://github.com/tinygo-org/tinygo/issues/309
Also, it prepares for some other reflect-related changes that should
make it easier to add support for named types (etc.) in the future.
2019-08-05 14:44:30 +02:00
Ayke van Laethem
b4c90f3677
compiler: lower interfaces in a separate pass
This commit changes many things:

  * Most interface-related operations are moved into an optimization
    pass for more modularity. IR construction creates pseudo-calls which
    are lowered in this pass.
  * Type codes are assigned in this interface lowering pass, after DCE.
  * Type codes are sorted by usage: types more often used in type
    asserts are assigned lower numbers to ease jump table construction
    during machine code generation.
  * Interface assertions are optimized: they are replaced by constant
    false, comparison against a constant, or a typeswitch with only
    concrete types in the general case.
  * Interface calls are replaced with unreachable, direct calls, or a
    concrete type switch with direct calls depending on the number of
    implementing types. This hopefully makes some interface patterns
    zero-cost.

These changes lead to a ~0.5K reduction in code size on Cortex-M for
testdata/interface.go. It appears that a major cause for this is the
replacement of function pointers with direct calls, which are far more
susceptible to optimization. Also, not having a fixed global array of
function pointers greatly helps dead code elimination.

This change also makes future optimizations easier, like optimizations
on interface value comparisons.
2018-12-01 13:26:06 +01:00
Ayke van Laethem
6c6a43310a
compiler: fix invalid incoming block in complex typeassert flow
A single *ssa.BasicBlock may be split in multiple LLVM basic blocks due
to typeassert instructions. This means the incoming block and outgoing
block are different. PHI nodes need to get the result from the outgoing
block, which was fixed before, but incoming branches need to branch to
the incoming block, not the outgoing block.

Branching to the outgoing block led to a LLVM verification error when
compiling the fmt package.

Originally found in (*fmt.pp).handleMethods.
2018-10-23 15:00:37 +02:00
Ayke van Laethem
73709922b2
main: extra interface test for simple named types 2018-10-07 19:40:21 +02:00
Ayke van Laethem
e8f211935e
compiler: fix expanded structs in invoke calls 2018-10-07 13:19:38 +02:00
Ayke van Laethem
4957db89f4
compiler: fix interface calls for big underlying values
When the underlying value of an interface does not fit in a pointer, a
pointer to the value was correctly inserted in the heap. However, the
receiving method still assumed it got the underlying value instead of a
pointer to it leading to a crash.

This commit inserts wrapper functions for method calls on interfaces.

The bug wasn't obvious as on a 64-bit system, the underlying value was
almost always put directly in the interface. However, it led to a crash
on the AVR platform where pointer are (usually) just 16 bits making it
far more likely that underlying values cannot be directly stored in an
interface.
2018-10-07 02:06:48 +02:00