Age | Commit message (Collapse) | Author |
|
|
|
The filters in a list comprehension can be guard expressions or
an ordinary expressions.
If a guard expression is used as a filter, an exception will basically
mean the same as 'false':
t() ->
L = [{some_tag,42},an_atom],
[X || X <- L, element(1, X) =:= some_tag]
%% Returns [{some_tag,42}]
On the other hand, if an ordinary expression is used as a filter, there
will be an exception:
my_element(N, T) -> element(N, T).
t() ->
L = [{some_tag,42},an_atom],
[X || X <- L, my_element(1, X) =:= some_tag]
%% Causes a 'badarg' exception when element(1, an_atom) is evaluated
It has been allowed for several releases to override a BIF with
a local function. Thus, if we define a function called element/2,
it will be called instead of the BIF element/2 within the module.
We must use the "erlang:" prefix to call the BIF.
Therefore, the following code is expected to work the same way as in
our second example above:
-compile({no_auto_import,[element/2]}).
element(N, T) ->
erlang:element(N, T).
t() ->
L = [{some_tag,42},an_atom],
[X || X <- L, element(1, X) =:= some_tag].
%% Causes a 'badarg' exception when element(1, an_atom) is evaluated
But the compiler refuses to compile the code with the following
diagnostic:
call to local/imported function element/2 is illegal in guard
|
|
|
|
This speeds up the compilation of binary literals
with string values in them. For example, compiling
a file with a ~340kB binary would yield the following
times by the compiler:
Compiling "foo"
parse_module : 0.130 s 5327.6 kB
transform_module : 0.000 s 5327.6 kB
lint_module : 0.011 s 5327.8 kB
expand_module : 0.508 s 71881.2 kB
v3_core : 0.463 s 11.5 kB
Notice the increase in memory and processing time
in expand_module and v3_core. This happened because
expand_module would expand the string in binaries
into chars. For example, the binary <<"foo">>, which
is represented as
{bin, 1, [
{bin_element, 1, {string, 1, "foo"}, default, default}
]}
would be converted to
{bin, 1, [
{bin_element, 1, {char, 1, $f}, default, default},
{bin_element, 1, {char, 1, $o}, default, default},
{bin_element, 1, {char, 1, $o}, default, default}
]}
However, v3_core would then traverse all of those
characters and convert it into an actual binary, as it
is a literal value.
This patch addresses this issue by moving the expansion
of string into chars to v3_core and only if a literal
value cannot not be built. This reduces the compilation
time of the file mentioned above to the values below:
Compiling "bar"
parse_module : 0.134 s 5327.6 kB
transform_module : 0.000 s 5327.6 kB
lint_module : 0.005 s 5327.8 kB
expand_module : 0.000 s 5328.7 kB
v3_core : 0.013 s 11.2 kB
|
|
|
|
The (harmless) bug was introduced in 541e87f.
|
|
|
|
Make sure that we recognize map literals at load time, as we
do for lists and tuples. Also use maps:from_list/1 to build
a new map instead of building it up from scratch inserting one
key/value pair at the time.
|
|
The pattern in the generator for a list or binary comprehension
was processed as an expression instead of as a pattern. That
happened to work because expressions and patterns were translated
in the same way.
In the future we might want to process expressions and patterns
differently.
|
|
|
|
Dialyzer recognizes a certain pattern that makes it possible to get
rid of 'The created fun has no local return' warnings.
|
|
* nox/debugger/erl_eval_SUITE/OTP-11676:
Truly test debugger in erl_eval_SUITE copy
|
|
The module was not interpreted.
This surfaced two bugs, related to shadowed variables in binary patterns in
comprehension generators, and guard filters not properly detected. The guard
detection code from dbg_iload is deleted in favor of erl_lint:is_guard_test/1.
The erl_lint module is now safe to use because it can handle all expressions
emitted by sys_pre_expand, the following warning is thus obsolete and has been
removed from code:
%% Cannot use erl_lint here as sys_pre_expand has transformed source.
|
|
A test is commented-out in map_SUITE:t_update_exact/1, waiting for a fixed
maps:update/3 function with correct integer/float semantics.
|
|
The current code for the evaluation of ordinary funs is dependent
on the order on variables in the fun environment as returned by
erlang:fun_info(Fun, env). As it happened, adding the code for
named funs changed the order in the environment for ordinary funs.
To avoid the problem in the future, make sure that we only have one
free variable in the funs that we will need to inspect using
erlang:fun_info(Fun, env).
|
|
Currently, the external fun syntax "fun M:F/A" only supports
literals. That is, "fun lists:reverse/1" is allowed but not
"fun M:F/A".
In many real-life situations, some or all of M, F, A are
not known until run-time, and one is forced to either use
the undocumented erlang:make_fun/3 BIF or to use a
"tuple fun" (which is deprecated).
EEP-23 suggests that the parser (erl_parse) should immediately
transform "fun M:F/A" to "erlang:make_fun(M, F, A)". We have
not followed that approach in this implementation, because we
want the abstract code to mirror the source code as closely
as possible, and we also consider erlang:make_fun/3 to
be an implementation detail that we might want to remove in
the future.
Instead, we will change the abstract format for "fun M:F/A" (in a way
that is not backwards compatible), and while we are at it, we will
move the translation from "fun M:F/A" to "erlang:make_fun(M, F, A)"
from sys_pre_expand down to the v3_core pass. We will also update
the debugger and xref to use the new format.
We did consider making the abstract format backward compatible if
no variables were used in the fun, but decided against it. Keeping
it backward compatible would mean that there would be different
abstract formats for the no-variable and variable case, and tools
would have to handle both formats, probably forever.
Reference: http://www.erlang.org/eeps/eep-0023.html
|
|
Since the run-time system cannot load those BEAM files, it was
not possible to debug them anyway.
|
|
The 'no_tail' option was broken and would work almost as the
'all' option, because it would use #ieval.top (formerly
known as #ieval.last_call) as the basis for its decision
to push or not.
Fix it by including a boolean in each call/apply instruction
indicating whether the call is tail-recursive and pass
that boolean to the dbg_istk:push() function.
|
|
In a list comprehension, a failing call to a guard BIF means
false (rather than an exception).
|
|
Expressions in guards such as:
f() when [1,2,3] ->
ok.
would cause the debugger to crash when attempting to interpret the
module containing the expressions. Other kind of constants such as:
f() when 42 ->
ok.
were converted to an invalid internal format ({integer,Line,42}
instead of {value,Line,42}), but that happened to work because
because anything not equal to 'true' (even a crash) was interpreted
as 'false'.
Make sure to handle all possible expressions and convert them
directly to {value,Line,false}. Remove the special handling of
the atom 'true' in and_guard/1 since it is no longer needed.
|
|
erlang:raise/3 was evaluated in the real process, which produced
a correct stacktrace, but did not set emulated stacktrace for the
process. Thus, a subsequent call to erlang:get_stacktrace/0 would
retrieve the previous stacktrace for the process.
|
|
sys_pre_expand has already rewritten old guard tests to
new guard tests.
|
|
Many releases ago, Mod:module_info/{0,1} used to be specially
handled in the BEAM loader. The debugger has similar special
handling.
In the current implementation, Mod:module_info/{0,1} are ordinary
functions that call special BIFs to do their work.
Therefore, remove the special handling of Mod:module_info/{0,1}
in the debugger.
|
|
BIFs that spawn new processes once upon a time needed/benefited
from special handling, but now they are handled in exactly the
same way as an unsafe BIF (except for a bug in the handling of
the return value trace). Therefore, treat spawn BIFs as unsafe
BIFs.
|
|
|
|
Make sure that all guards BIFs are handled as safe BIFs in function
bodies. BIFs in guards are already handled as safe. (self/0 is not
safe, but it is already specially handled.)
|
|
Since erlang:fault/{1,2} is no longer supported in the run-time
system (it was removed several releases ago), there is no need
to still support it in the debugger.
|
|
concat_binary/1 was deprecated in R13B04, but already in
the R10B-2 release, the documentation recommends using
list_to_binary/1 instead.
|
|
* ks/cleanups:
compiler: Fix incorrect types and specs
escript: Add more types to records
debugger: Clean up as suggested by tidier
docbuilder: Clean up as suggested by tidier
Conflicts:
lib/debugger/src/dbg_iload.erl
lib/debugger/src/dbg_ui_trace_win.erl
|
|
* ks/ets-tid-type:
Remove tid() from the predefined builtin types.
OTP-8687 ks/ets-tid-type
The predefined builtin type tid() has been removed. Instead, ets:tid()
should be used.
|
|
Change erl_lint not to recognize this type as builtin and
add a new erl_lint.beam version in bootstrap.
Add an -opaque type declaration for this type in ets.erl
and also declare this as an exported type. Use this type
in file debugger/src/dbg_iload.erl in a spec.
While at it, also clean up this later file a bit.
|
|
|
|
|