Commit Graph

958 Commits

Author SHA1 Message Date
Nicholas Wiersma
84424b52bc interp: handle alias of an alias
When dealing with an alias of an alias, the actual underlying type of the source alias should be used.
2021-09-27 10:08:11 +02:00
Marc Vertes
98c2dcd3e5 interp: fix interface wrapper for struct types
This change fixes a regression introduced by PR #1192 in a program using
https://github.com/NYTimes/gziphandler which defines several types
implementing stdlib interfaces. We do not implement a wrapper
if we see that a type already implements an interface, except that
it can be falsly reported by reflect in case of a struct with
embedded interface field. We need to force the wrapper generation
in this case.
The problem occurs only for wrappers on struct, not on pointers or
other indirection types.
2021-09-24 13:20:12 +02:00
Ethan Reesor
808f0bde9d interp: add a function to directly compile Go AST
Adds CompileAST, which can be used to compile Go AST directly. This
allows users to delegate parsing of source to their own code instead of
relying on the interpreter.

CLoses #1251
2021-09-23 12:34:12 +02:00
Nicholas Wiersma
c5c6012947 interp: support type spec assign
This supports type spec assign types which disallows the attachment of methods onto the alias type as per the Go spec.

Fixes #1154
2021-09-23 12:16:11 +02:00
Nicholas Wiersma
836060c8ad interp: allow GTA revisit for unresolved define statements
When a define statement relies on a selector or type that may exist in another file it should revisit once GTA is complete. This allows that revisit.

**Note:** In order to keep the original GTA error for the define statement, so the error received is correct and meaningful, I have added a node `meta` property. I decided to make it generic as it may be useful in future. There may be a better way to stash errors across the GTA runs and am open to suggestion here.

Fixes #1253
2021-09-20 12:04:06 +02:00
Nicholas Wiersma
7a54353c7b chore: update linter to v1.42.1
* chore: update linter to v1.42.1

* fix: linter issues
2021-09-20 10:18:14 +02:00
Marc Vertes
b591ba0e78 interp: do not export RealFS, used internally only v0.10.0 2021-09-15 16:22:07 +02:00
Nicholas Wiersma
5af51aefe6 interp: fix type selector precedence
The current `nodeType` selector precedence is heavy handed in favour of package type. It seems to often create `typeSym` symbols as variable types in the scope will never be found. To fix this if the ancestor node is a field expression, the package type is searched for. After this, if the type is still `nil` the normal scope is searched using `nodeType2`.

Fixes #1158
2021-09-15 10:42:08 +02:00
mpl
e7c0f68bab interp: fix Clone documentation 2021-09-14 12:30:13 +02:00
Marc Vertes
bd9a6a4f8a interp: improve processing of recursive types
Make sure to keep always a single copy of incomplete type structures.
Remove remnants of recursive types processing.

Now `import "go.uber.org/zap"` works again (see #1172), fixing regressions
introduced since #1236.
2021-09-13 18:24:10 +02:00
Nicholas Wiersma
3eb2c79fd8 interp: fix nil funcs in composite literals
When a nil are used in a func composite literal, the nil type is a `func` not a `*node`. This handles this case.

Fixes #1249
2021-09-13 16:32:12 +02:00
Nicholas Wiersma
4653d87298 interp: types should not recover data for aliases
When `nodeType` recovers names and methods, it can overwrite the data if the type is an aliasT. When aliasing a type, do not recover the methods, this will be done in the GTA typeSpec pass.

Related to #1158
2021-09-06 18:24:04 +02:00
Nicholas Wiersma
45d569c215 interp: fix parsing of late binding consts
When a const is late binding and specified with a type, the GTA defineStmt was creating the symbol with the current scopes `iota` which is incorrect. The symbol should be created with the source nodes `rval`.

Related to #1158
2021-09-06 17:30:12 +02:00
Nicholas Wiersma
c33caeb573 interp: improve handling of wrapped interface values
This test (assert2.go) display 2 separate issues:
1. assert2.go L28: Type assert tries to set an `interface{}` to a `valueInterface`. The typing here is complex, we have a valueT(strings.Builder) wrapped in a ptrT wrapped in a src iface wrapped in a valueT(interface{}). Type assert fails to realise that the `valueT` `interface{}` is wrapping the `valueInterface`.
2. assert2.go L29: `genValueBinMethodOnInterface` does not try and get the bin method, as the `typ.node` (`ptrT` or a `valueT`(`string.Builder`)) is set. In this case the src iface is called with a receiver argument. To fix this the method is looked for first if possible, and only if not found does it fall back to the `defaultGen`.

Fixes #1227
2021-09-06 17:16:11 +02:00
Ethan Reesor
91a55cc4c5 interp: add debug interface
Adds an interface to `interp` that can be used to build an interactive debugger, such as those used by IDEs.

Closes #1188

All basic debugger features work, with one exception: breakpoints in some locations don't work, due to `setExec` creating a temporary `bltn` (https://github.com/traefik/yaegi/issues/1188#issuecomment-886107905).

Example, using a Debug Adapter implementation with VSCode:

![image](https://user-images.githubusercontent.com/879055/128620736-94b6efde-2e5f-43ad-82c9-d919c3fe401f.png)
2021-09-06 15:32:10 +02:00
Nicholas Wiersma
05f08d776a interp: complete type constructors
This completes the types constructors, cleaning up `nodeType`.
2021-09-01 14:46:08 +02:00
Nicholas Wiersma
d2569a85a6 interp: fix default types for runes
When using an untyped rune in an interface, the default type was blindly untyping it. This fixes this issue.

Fixes #1238
2021-08-31 12:32:10 +02:00
Nicholas Wiersma
772cd68fea interp: make use of type constructors
It was initially assumed that `nodeType` needed to rebuild the type from scratch, but this is not the case anymore. The existing type constructors are now used in `nodeType` to make it more readable. In doing this some bugs in type strings were found and fixed, along with adding the real package name to the type.

As `ptrOf` is now the only place that pointer types are constructed, it is feasible to cache the pointer type on the value type. To ensures that we have a consistent pointer type for any value type.
2021-08-31 10:34:12 +02:00
Nicholas Wiersma
4af992bccb interp: create real recursive types with unsafe type swapping
As the unsafe and pointer methods in `reflect` are to be depreciated, and seeing no replacement functions, it is now forced that some unsafe is needed to replace this as when and interface is dereferenced it is made unsettable by reflect.

With this in mind, this adds real recursive types by hot swapping the struct field type on the fly. This removes a lot of compensation code, simplifying all previous cases.

**Note:** While the struct field type is swapped for the real type, the type string is not changed. Due to this, unsafe will recreate the same type.
2021-08-30 18:38:12 +02:00
Nicholas Wiersma
da922ce90b interp: build type strings on the fly
This adds `itype.str` which is a string representation of the type built when the type is built. The goal is to make type comparison simpler and centralise the creation of types just to constructors and `nodeType`. `nodeType` continues to build types in parts so to reuse underlying types better.
2021-08-27 19:44:05 +02:00
Aloïs Micard
7b77b0fa22 test: only enable race detector when supported
Closes: #1228
2021-08-27 15:50:13 +02:00
Marc Vertes
b7f9a39eff interp: fix support of 32 bits and big-endian arch
Force recompute of bits.UintSize, make related tests portable.

Fixes #1230.
2021-08-27 14:54:05 +02:00
Marc Vertes
d2b25a7426 interp: fix append with 1 argument
Fixes #1224.
2021-08-24 12:16:08 +02:00
Johnny
b5bf4ef31a interp: allow for reading source files from diverse filesystems
Make use of fs.FS (new to go 1.16) to allow for reading source files from diverse filesystems (local, embed, custom).

* `Options` has a new field `SourcecodeFilesystem fs.FS` so users can supply their own read-only filesystem containing source code.
* Defaults to the local filesystems (via `RealFS` - a thin `os.Open` wrapper complying with `fs.FS`) so regular users should see no change in behaviour.
* When no filesystem is available (e.g. WASM, or if you want to embed files to retain single binary distribution) an alternative filesystem is preferable to using `Eval(string)` as that requires the stringy code to be a single file monolith instead of multiple files. By using an `fs.FS` we can use `EvalPath()` and gain the ability to handle multiple files and packages.
* You can make use of embed filesystems (https://pkg.go.dev/embed) and custom filesystems obeying the `fs.FS` interface (I use one for http served zip files when targeting wasm as there is no local filesystem on wasm). Tests can make use of `fstest.Map`.
* NOTE: This does NOT affect what the running yaegi code considers its local filesystem, this is only for the interpreter finding the source code.

See `example/fs/fs_test.go` for an example.

Fixes #1200.
2021-08-19 11:28:13 +02:00
Nicholas Wiersma
a69b9bc2dc stdlib: support go1.17 unsafe functions
This adds support for go1.17 `unsafe.Add` and `unsafe.Slice`.
2021-08-19 10:38:05 +02:00
Marc Vertes
b84278dcc6 stdlib: remove wrapper of runtime/cgo
Temporarily removing this wrapper which causes a failure
on freebsd system at build.

Fixes #1221.
v0.9.23
2021-08-17 16:38:12 +02:00
Nicholas Wiersma
32cbcfb412 feat: update stdlib mapping for go1.17
* Drop go1.15
* Generate go1.17
* Update minimum extract version
* Update the CI config
v0.9.22
2021-08-17 11:42:07 +02:00
Nicholas Wiersma
5c73f30f36 interp: fix handling of forward function declaration
Set node address in `val` field at creation of `funcDecl` node so it can be used correctly at closure generation, even in the case of forward function declarations, where the value was zero.

Fixes #1214
2021-08-16 16:24:05 +02:00
Nicholas Wiersma
5cc6fa42e4 feat: fix zero instance issue
When calling a function, if the input param is a "zero" instance, it is not set on the input. This is an issue where the param is an `interface{}` as a `nil` value is set instead of the zero value.

The actual solution for this is to remove the `if !val.IsZero()`, this however runs into an issue on `_test/struct48.go` where we have a zero recursive struct instance (`*interface{}`) and we have no way to get its real type. Should a way be figured out to keep tabs on the original type, the `if` can go away, and in the zero case of `genValueRecursiveInterfacePtrValue`, the actual zero type can be returned. 

Fixes #1215
2021-08-16 10:34:09 +02:00
Marc Vertes
37fe3422d8 interp: improve handling of interface struct field
Wrap non empty interface value  in struct field, to allow method
lookup.

Fixes #1208.
2021-08-06 12:16:10 +02:00
Dan Kortschak
d4e25f0259 interp: fix package lookup for type analysis of local types
Fixes #1203.
2021-08-02 12:14:11 +02:00
Marc Vertes
32ff3fb9b0 interp: fix handling of interface values in variadic calls
Fixes #1205.
2021-07-29 14:36:10 +02:00
Marc Vertes
b41fa6eb9d stdlib: add missing wrappers of io/fs for go1.16
Fixes #1195
2021-07-27 10:58:06 +02:00
Marc Vertes
c80c605ab9 interp: support wrapping of nested interfaces
Add getConcreteType to retrieve the concrete type of a nested interface
value implementing a specific interface for which a wrapper exists.

If method resolution fails at runtime, a panic is now issued instead
of an error message and continue.

Fixes #1187.
2021-07-26 19:12:11 +02:00
Marc Vertes
bf843fc09e interp: fix handling returned func values
Fixes #1202.
2021-07-26 17:42:05 +02:00
Marc Vertes
a913a4ea8b interp: fix handling map of interfaces
Map handling builtins getIndexMap and rangeMap had some leftover
code of previous way of emulating interfaces, which was modified
following changes in #1017.

Specific code for interfaceT is removed, as not necessary anymore.
Map builtins are now simplified and more robust.

Fixes #1189.
2021-07-26 17:30:12 +02:00
Marc Vertes
2f8493c405 interp: fix map update by assign operators
When operating on map elements, result of assign operators were not
written to the map entry. Now check if the destination of an assign
operator is in a map, and if so, set the result to it.

Fixes #1194.
2021-07-21 11:44:04 +02:00
Marc Vertes
c7fcfa8534 interp: fix interface wrapper generation
Add early detection of cases where no wrapper is necessary because
the value type already implements the target interface.

It should both increase performances by avoiding the wrapper overhead,
and fix errors due to replacing valid values by incomplete wrappers,
caused by the presence of private methods in the interface definition,
as in #1191.

Fixes #1191.
v0.9.21
2021-07-19 15:38:11 +02:00
Ludovic Fernandez
aa012b992e chore: update linter
- update golangci-lint to v1.41.1
- fix GitHub action cache configuration
2021-07-17 12:14:06 +02:00
Marc Vertes
538182e12c interp: fix append of values to an array of interface objects
Interface wrappers were not properly generated.

Fixes #1185
v0.9.20
2021-07-15 11:38:12 +02:00
Marc Vertes
13d554acbe interp: fix receiver for exported method objects
When a function variable is assigned from an exported method,
make sure the receiver is updated from the coresponding symbol.

Fixes #1182.
2021-07-13 11:00:14 +02:00
Marc Vertes
4fcf90edae interp: fix swap assign with extra operation
The optimization in unary operaror bypasses the necessary temporary
variable in that case and must be disabled.

Fixes #1181.
2021-07-12 18:00:09 +02:00
Marc Vertes
fc970799a1 interp: add support of interface wrappers to type assertions
Store the interpreter value of the interface object to wrap as
a field called IValue, at offset 0 in wrapper structures.

Update extract to include IValue field.

In typeAssert, detect interface wrapper, and dereference the
interpreter value from IValue wrapper field.

Fixes #1166.
2021-07-12 17:10:13 +02:00
Marc Vertes
78d7e85352 interp: fix method resolution on pointer to binary values
In that case, the value must be derefenced before extracting
the method by index, otherwise an incorrect method is returned.

Fixes #1167.
2021-07-09 12:08:14 +02:00
Marc Vertes
c503855262 interp: fix handling of interface value in forwarding return calls
Special wrapping of interface value at return is no longer necessary and
must be avoided now.

Fixes #1179.
2021-07-08 16:04:08 +02:00
Marc Vertes
77acfb4593 interp: fix type checking of address of multi dimension array
Fixes #1177.
2021-07-08 12:40:09 +02:00
Marc Vertes
f6d0cf95fd interp: fix array declaration with a typed constant size
In parsing array type declaration, The type check of array size was
restricted to `int`. Broaden the test to accept any valid integer
kind.

Fixes #1175.
2021-07-08 12:30:12 +02:00
Marc Vertes
25b570d7e9 interp: fix the detection of builtin calls during parsing
Avoid shortcuts, and apply regular scoping rules for symbol
resolution when checking for builtin calls.

Fixes #1173.
2021-07-08 11:26:05 +02:00
Marc Vertes
297b40d526 interp: improve field and method resolution in presence of collisions.
The resolution method was not compliant with the Go specification which
requires to retain the object where the field or method is the most
shallowed.

The detection of ambiguous fields or methods (same depth in different
objects) has also been added.

Fixes #1163.
2021-07-06 12:12:05 +02:00
Daniel Tomcej
bd2cb06789 Update README.md
This PR:

- Updates the Readme to reflect the current supported Go versions 😄
2021-07-06 08:16:13 +02:00