Commit Graph

414 Commits

Author SHA1 Message Date
mpl
2e17cfab4f interp: do not wrap empty interface
The empty interface (interface{}), and its variants (such as []interface{} and map[string]interface{}), are commonly used in Go to (json) Unmarshal arbitrary data. Within Yaegi, all interface types are wrapped in a valueInterface struct in order to retain all the information needed for a consistent internal state (as reflect is not enough to achieve that). However, this wrapping ends up being problematic when it comes to the type assertions related to the aforementioned Unmarshaling.

Therefore, this PR is an attempt to consider the empty interface (and its variants) as an exception within Yaegi, that should never be wrapped within a valueInterface, and to treat it similarly to the other basic Go types. The assumption is that the wrapping should not be needed, as there is no information about implemented methods to maintain.

Fixes #984 
Fixes #829 
Fixes #1015
2021-02-04 12:08:04 +01:00
Marc Vertes
b9b0897d95 interp: fix nil value check in case of interface
A wrong logic was leading to panic in recover. Simplify the
workflow for clarity.

Fixes #1022.
2021-02-02 13:28:04 +01:00
Ludovic Fernandez
ccb8072759 chore: use GitHub Actions.
- use GitHub Actions instead of TravisCI
- updates golangci-lint to v1.36.0 and applies my rules
2021-02-01 12:23:29 +01:00
Nicholas Wiersma
ff521ecb1a fix: handle function references in composite bin map
When passing a function reference as an interface in a composite binary map, the case should be handled to not take the value of the the node.

Related to #886
2021-01-28 15:42:03 +01:00
Marc Vertes
100d090853 interp: fix sending object implementing an interface through channel
A channel can be used to interchange data with the pre-compiled
runtime and therefore objects impletementing interfaces must be
wrapped if necessary, using genInterfaceWrapper.

A similar treatment could be applied when sending interpreted
functions over a channel, to be provided in a new PR.

Fixes #1010.
2021-01-26 18:58:04 +01:00
Marc Vertes
bd60de5995 interp: allow early constant evaluation from builtin call
One builtin has been identified to be used for constant definition:
len(), with a constant string argument. Add support for this.

Fixes #1012.
2021-01-26 11:12:04 +01:00
Marc Vertes
24b5375636 interp: fix memory handling of global values
In some cases, the global character of a value was lost, leading to
undefined behaviour. Now a node level field of -1 means that the value
is global, and that it should be accessed from the root data frame.

Fixes #993.
2021-01-05 17:28:03 +01:00
Marc Vertes
a83f492309 interp: add support for binary composite slice
Fixes #987.
2020-12-15 18:20:04 +01:00
mpl
02c30482cc interp: enable type assertion from empty interface into slice
Fixes #985
2020-12-15 17:28:04 +01:00
Marc Vertes
9e1da978b0 interp: fix handling interface types in wrapped functions
The interpreter interface type was replaced by a reflect.Value in
objects passed or return to function wrappers, losing the ability
to retrieve methods.

The valueInterface is now preserved, and correctly accessed if
wrapped multiple times.

Fixes #977.
2020-12-15 16:14:05 +01:00
mpl
662838fd80 interp: fix and refactor typeAssertStatus in
typeAssertStatus deals with the 3rd form of type assertion ("_, ok"), for
when one does not care about the result of the assertion itself.
Some cases for it, which are already fixed for the two other forms of
type assertions, had not been fixed for this form yet.

Therefore, this change fixes such cases for this form, while integrating
typeAssertStatus to the same code path as for the two other forms.
2020-12-07 15:58:04 +01:00
mpl
2db4579b6f interp: fix short-form type assertions
The long-form (with comma-ok) ones were already fixed but the short-form
ones were not because they were in a completely different code path.

This PR also refactors the code so that both short-form and long-form
are now merged in the same function.

N.B: even though most (all?) cases seem to now be supported, one of them
still yields a result that does not satisfy reflect's Implements method
yet. It does not prevent the resulting assertion to be usable though.

N.B2: the code path for the third-form (_, ok) hasn't been fixed and/or
refactored yet.

Fixes #919
2020-12-02 14:46:03 +01:00
mpl
101633c380 interp: support two more type assertion cases
Fixes #967
2020-12-01 15:50:04 +01:00
mpl
1e0f6ece6e interp: support more type assertion cases
Fixes #955
2020-11-30 18:00:04 +01:00
Marc Vertes
81e1e5f206 interp: handle getting address of interpreter interface value
Fixes #963.
2020-11-30 11:48:04 +01:00
Marc Vertes
13783889cb interp: avoid useless interface wrapping
in `callBin`, call arguments are converted to the corresponding
parameter type. In a case of an interface, the original concrete type
should be preserved instead, and only wrapped to an interface type for
internal interpreter types, as runtime values should already implement the
interface.

This change removes the interface wrapping when parameter is a runtime
value (valueT or ptrT to valueT).

This removes some overhead when handling runtime values, and keep a
similar behavior between interpreted and pre-compiled code. For
example, `io.Copy` preserves its internal optimisations when passed a
`bytes.Buffer`.
2020-11-12 10:48:04 +01:00
mpl
ed626f3fb9 interp: support conversion of runtime func into interp func
Conversion of interp func into runtime func already worked, but added a
test anyway to watch out for regressions.

Fixes #941
2020-11-10 00:40:04 +01:00
Marc Vertes
0ed4b362dc interp: implement conversion for interpreter function types
Interpreter function types are represented internally by the AST node
of their definition. The conversion operation creates a new node with
the type field pointing to the target type.

Fixes #936.
2020-11-03 17:48:03 +01:00
Marc Vertes
98807387a4 interp: resolve type for untyped shift expressions
A non-constant shift expression can be untyped, requiring to apply a
type from inherited context. This change insures that such context is
propagated during CFG pre-order walk, to be used if necessary.
    
Fixes #927.
2020-11-02 18:08:04 +01:00
mpl
3cb8bca81a interp: on panic, look for node where offending exec originated from
The execution flow is such that a node can end up running several chained exec
funcs, some of which actually originate from other nodes. For example, in:

var m []int // L0
println("hello world") // L1
m[0] = 1 // L2

the offending code is on a node on line 2 (out of range error). However, since
the assignment to m is part of the execution flow of the variable m, we'll get
the panic when running all the chained exec funcs attached to the node for m on
line 0.

Which is why, when that happens, we need to look for the actual node (the one on
L2) where the offending instruction originates from, in order to
properly report the origin of the panic.

Fixes #546
2020-11-02 10:26:04 +01:00
Marc Vertes
a38d19288f interp: fix testing for nil interface values
Fixes #924.
2020-10-30 16:20:04 +01:00
Marc Vertes
7f8ffa6719 interp: handle explicit nil values in literal composite values
Fixes #922.
2020-10-27 11:24:04 +01:00
Marc Vertes
513f5e37aa interp: fix type conversion for constant expressions
The case of a constant arithmetic expression being of float kind because
of quotient was not handled correctly. Simplify constant extraction to
reflect.Value first, then conversion to target type, and let reflect Convert
method panic if conversion is not valid.

Fixes #920.
2020-10-23 10:44:04 +02:00
Marc Vertes
473bc63588 fix: behavior of select and time ticker
There was several issues:
- access to field on pointer to struct from runtime: fix in
  lookupBinField
- assign operation was skipped when performed in a comm clause
- the direction of comm clause was wrong if a channel send operation was
  performed in a body of a receive comm clause

Fixes #884.
2020-10-14 15:50:04 +02:00
Marc Vertes
e32da38ad0 fix: append from / to runtime defined array
Check first for runtime defined array (typ.cat of valueT)
to avoid checking inexisting properties (an panic), when
deciding to use appendSlice or not.

Fixes #880.
2020-10-13 17:14:04 +02:00
Marc Vertes
b2b519c2fd fix: correctly return constant expressions in functions
In the case of a function returning a single value, a constant
result could be ignored, and the function would return a zero value.

Fixes #889.
2020-10-13 17:02:04 +02:00
Marc Vertes
9491e58920 fix: correct handling of select comm clause with empty body
Fixes #887.
2020-10-13 11:24:04 +02:00
Marc Vertes
a83ec1f925 fix: allow yaegi command to interpret itself
Since the introduction of restricted stdlib and syscall symbols, the
capability of yaegi to interpret itself was broken.
The use of unrestricted symbols is now also controlled by environment
variables, to allow propagation accross nested interpreters.
The interpreter Panic symbol was not wrapped, this is fixed now.
the import path resolution was failing if the working directory was
outside of GOPATH.
The documentation and readme have been ajusted.

Fixes #890.
2020-10-09 11:48:04 +02:00
mpl
155ca4e6ad interp: support implicit-type slice of pointers of struct composite literal
Also fix same case for implicit-type maps of etc.

Fixes #883
2020-10-09 10:32:03 +02:00
mpl
ca196a5768 interp: fix implicit type for bin composite lit case
When the type is implicit, the first element in the list of children is
not the type of the composite literal, but it is one of the actual
children, so it should not be discarded.

Fixes #862
2020-10-05 16:42:03 +02:00
Marc Vertes
0dde990d0b feature: improve extract, add unrestricted syscalls 2020-09-29 18:42:05 +02:00
mpl
3ae01a2af3 interp: refactor doComposite cases 2020-09-22 17:26:03 +02:00
Marc Vertes
c06f83f34a fix: correct access to parameter type for variadic binary methods 2020-09-22 15:18:03 +02:00
mpl
a2f56431ea interp: fix data race for composite literal creation
This change fixes two data races related to composite literal creation.

The first one isn't controversial as it is just about initializing the
variable that contains the values in the right place, i.e. within the
n.exec, so that this variable is local to each potential goroutine,
instead of being racily shared by all goroutines.

The second one is more worrying, i.e. having to protect the node typ
with a mutex, because a call to func (t *itype) refType actually
modifies the itype itself, which means it is not concurrent safe.
The change seems to work, and does not seem to introduce regression, but
it is still a concern as it probably is a sign that more similar
guarding has to be done in several other places.
2020-09-14 16:22:04 +02:00
Marc Vertes
f1f3ca7e06 fix: handle interface fields in literal composite structs
Struct fields of type interface must be converted in wrapper
values to be reachable by the runtime. Call genInterfaceWrapper
on such values.

Fixes #832.
2020-09-09 13:44:04 +02:00
Marc Vertes
341c69d922 feat: configure stdin, stdout and stderr per interpreter
The goal is to provide greater control of input, output and error
streams of the interpreter. It is now possible to specify those
as options when creating a new interpreter. The provided values
are propagated to relevant stdlib symbols (i.e fmt.Print, etc).
Care is taken to not update the global variables os.Stdout, os.Stdin
and os.Stderr, as to not interfere with the host process.

The REPL function is now simplified. The deprecated version is removed.

The tests are updated to take advantage of the simplified access
to the interpreter output and errors.

Fixes #752.
2020-08-31 15:42:03 +02:00
Nicholas Wiersma
3640f2f820 feat: add type assertion expression type checking
This adds type checking to TypeAssertExpr. In order to allow for this, method types now have a receiver type in both reflect and native cases.
2020-08-20 17:06:05 +02:00
Marc Vertes
065d4fa4d7 fix: add mutual exclusion locks for cancelable select
In a couple of occurences, tests with enabled race detector exposed
some concurrent accesses to the cancelation callback used in select and
channel operations send and recv for EvalWithContext. This change ensure
that all accesses to this object are protected by mutex.

Fixes #815.
2020-08-19 13:52:04 +02:00
Nicholas Wiersma
da9e6a0d6c fix: composite literal type check
In the case of a pointer or alias composite literal expression, `compositeGenerator` changes the type to remove the pointer or alias. This causes a nested composite literal to have the wrong type.

Instead of changing the node type, the removal of the pointer or alias is moved to the runtime, allowing the node type to remain unchanged. This fixes potential issues in the type checking.
2020-08-14 12:14:03 +02:00
Nicholas Wiersma
cdc352cee2 feat: add index and composite literal type checking
This adds type checking to both `IndexExpr` and `CompositeLitExpr` as well as handling any required constant type conversion.

This includes a change to the type propagation to the children of a composite literal. Previously in most cases the composite literal type was propagated to its children. This does not work with type checking as the actual child type is needed.
2020-08-11 15:58:04 +02:00
Nicholas Wiersma
88569f5df7 fix: interface call regression from #787
Fix #787 changes how interfaces are set on a struct (compositeSparce). This change however makes calling the interface panic. 

This PR reverts part of the change in #787 and adds a test to ensure it does not break again.
2020-08-10 16:32:05 +02:00
Nicholas Wiersma
bd4ce37baa feat: refactor type checking
The previous type checking was off and did not do untyped type conversion. This endeavours to fix this with better type checking in its own type.
2020-07-31 14:00:03 +02:00
Marc Vertes
589b2a0cd2 fix: correct conversion to int in slice index expressions. 2020-07-23 12:05:03 +02:00
Marc Vertes
5eecbe515b fix: compositeSparse handles fields of interface kind
Fixes #776.
2020-07-13 17:55:04 +02:00
Marc Vertes
0c8f538cd9 fix: apply method receiver offset when generating interface wrapper
Fixes #772.
2020-07-12 14:20:03 +02:00
Nicholas Wiersma
98eacf3610 fix: execute global variables in the correct order
* fix: constant definition loop on out of order vars

* fix: do not wire global varDecl

* fix: wire and execute global vars

* chore: add tests

* fix: refactor and lint
2020-07-09 14:05:03 +02:00
Marc Vertes
640d1429e5 fix: type assert when status is _
If the status is _, there is no storage allocated in frame, and
the status assign operation should be skipped.

Fixes #761.
2020-07-09 08:45:03 +02:00
Nicholas Wiersma
659913eebe fix: convert type properly to the correct type 2020-07-08 22:55:03 +02:00
Marc Vertes
b3766509cc feature: restrict symbols which can exit the interpreter process
* feature: restrict symbols which can exit the interpreter process

Some symbols such as os.Exit or log.Fatal, which make the current process
to exit, are now restricted. They are replaced by a version which panics
instead of exiting, as panics are recovered by Eval.

The restricted os.FindProcess version is identical to the original
except it errors when trying to return the self process, in order to
forbid killing or signaling the interpreter process from script.

The os/exec symbols are available only through unrestricted package.

The original symbols are stored in an unrestricted package, which
requires an explicit Use, as for unsafe and syscall packages.

The Use() interpreter method has been slightly modified to allow inplace
updating of package symbols, allowing to replace some symbols but not
the entire imported package.

A command line option -unrestricted has been added to yaegi CLI to use
the unrestricted symbols.

Fixes #486.

* fix: lint
2020-07-08 22:35:04 +02:00
Nicholas Wiersma
9d4685deea fix: handle interfaces in composite sparce (#749)
Co-authored-by: Marc Vertes <mvertes@free.fr>
2020-07-06 15:41:27 +02:00