Age | Commit message (Collapse) | Author |
|
When optimizing boolean expressions, it is not always possible
to find a number of live registers for a GC BIF that both preserves
all source registers that will be tested and at the same time
does not include registers that are not initialized.
As currently implemented, we have incomplete information about
the register calculated from the free variables. Some registers
are marked as "reserved". Reserved registers means that we don't
know anything about them; they may or may not be initialized.
As a conservative correction (suitable for a maintenance release), we
will abort the optimization if we find any reserved registers when
calculating the number of live registers. We will not attempt to
improve the information about the registers in this commit.
By examining the coverage when running the existing compiler test
suite we find that the optimization is aborted 15 times (before
adding any new test cases). To put that in perspective, the
optimization is successfully applied 4927 times, and aborted for
other reasons 547 times.
Reported-by: Ulf Norell
Reported-by: Anthony Ramine
|
|
* andreaTP/added-aes-ecb-to-crypto/OTP-12403:
aligned implementation following last specs
finally fixed docs
fixed incorrect tag
proposal of documentation
fixes and tests
add aes ecb to crypto library
|
|
Old versions of the Erlang mode for Emacs used to indent try...catch
strangely - the first clause following the 'catch' would be indented
with one space less than the following clauses.
If we are to use the new Erlang mode when we add more clauses, they
would be indented with one space less than the preceding clauses.
That would look silly.
|
|
The optimization of a 'case' statement could lead to incorrect
code that would cause an exception at run-time.
Here is an example to show how the optimization went wrong. Start
with the following code:
f({r,#{key:=Val},X}=S) ->
case S of
{r,_,_} ->
setelement(3, Val, S)
end.
(The record operations have already been translated to the
corresponding tuple operations.) The first step in case_opt/3 is
to substitute S to obtain:
f({r,#{key:=Val},X}=S) ->
case {r,#{key:=Val},X} of
{r,_,_} ->
setelement(3, Val, S)
end.
After that substitution the 'case' can be simplified to:
f({r,#{key:=Val},_}=S) ->
case #{key:=Val} of
NewVar ->
setelement(3, Val, S)
end.
That is the result from case_opt/3. Now eval_case/2 notices
that since there is only one clause left in the 'case', the
'case' can eliminated:
f({r,#{key:=Val},_}=S) ->
NewVar = #{key:=Val},
setelement(3, Val, S).
Since the map construction may have a side effect, it was not
eliminated, but assigned to a variable that is never used.
The problem is that '#{key:=Val}' is fine as a pattern, but in a
construction of a new map, the '=>' operator must be used. So the
map construction will fail, generating an exception.
As a conservative correction for a maintenance release, we will
abort the 'case' optimization if the substitution into the 'case'
expression is anything but data items (tuples, conses, or
literals) or variables.
Reported-by: Dmitry Aleksandrov
|
|
|
|
* marcus/rabbe-doc-typos/OTP-12399:
fix doc typos found by Rabbe Fogelholm
|
|
|
|
* dotsimon/sctp_paddrinfo_state:
Fix inet:getopts involving #sctp_paddrinfo{}
|
|
|
|
* nox/http_uri-fragment/OTP-12398:
Properly parse URI fragments
|
|
* maint:
wx: Fix connect when terminating
|
|
* dgud/wx/connect-when-terminating/OTP-12374:
wx: Fix connect when terminating
|
|
The ddbe8a821ad commit was embarrassingly broken.
|
|
|
|
* essen/irregardless:
Fix "irregardless" -> "regardless"
|
|
* maint:
debugger: Fix debugger save options on mac
wx: Do not crash server when going down
|
|
* dgud/debugger/save-state-mac/OTP-12378:
debugger: Fix debugger save options on mac
|
|
* dgud/wx/connect-when-terminating/OTP-12374:
wx: Do not crash server when going down
|
|
|
|
* bjorn/asn1/rfc-5912/OTP-12395: (79 commits)
Remove the old unused yecc-based parser
Improve error handling for illegal object definitions
Reimplement storeindb/2 to avoid excessive process communication
Remove useless fields in #state{}
Remove vestiges of obsolete {TypeName,Value} notation
Remove old error handling
Modernize the remaining cases
Further improve error handling for instatiation of parameterized types
asn1ct_tok: Clean up
Add a test case for EXTENSIBILITY IMPLIED
asn1ct_parser2: Remove expensive lookahead_assignment/1 function
asn1ct_parser2: Clean up error handling and reporting
asn1ct, asn1ct_parser2: Refactor the upper levels of error handling
asn1ct_parser2: Eliminate all uses of old-style 'catch'
asn1ct_parser2: Clean up parse_or/3 and parse_or_tag/3
asn1ct_parser2: Correct extraction of line number from token
asn1ct_parser2: Throw an {asn1_error,...} for *all* parse errors
asn1ct_parser2: Simplify parse_Type/1
asn1ct_parser2: Remove unsuccessful parsing of ValueSetFromObjects
Move checking of UNIQUE & DEFAULT error to asn1ct_check
...
|
|
|
|
|
|
As currently implemented, there is one call to asn1db:dbget() and
asn1db:dbput() for each type/value definitions in an ASN.1 specification.
If we check for duplicate definitions locally, we can send all
definitions in a single call.
|
|
Three fields ('type','value', and 'vname') are almost unused. They
are set, but almost never read. Eliminate the last remaining uses
and the fields themselves.
|
|
|
|
And while we are at it cleanup and rewrite code to use try catch.
|
|
|
|
|
|
|
|
|
|
In the parsing of a value assignment, such as:
value INTEGER ::= 42
there is call to a function called lookahead_assignment/1 that
will ensure that the sequence of tokens that follows the value
is a valid assignment. The problem is that if the next assignment
is a value assignment, that too will look ahead to the next
assignment. That means that the complexity will be quadratic
if there are many value assignments following each other.
The reason for the test in the first place is unclear; my guess
is that it was an attempt to provide better error reporting.
|
|
Errors were reported using a throw like this:
throw({asn1_error,{get_line(hd(Tokens)),get(asn1_module),
[got,get_token(hd(Tokens)),expected,typereference]}}).
The attempt to tell the user what was expected was often mis-leading.
It is time-consuming and non-trival to provide correct information
of what is expected. Therefore, we will not even try. Instead we will
spend more effort to report the token where the error was discovered.
We will replace each throw with a function call:
parse_error(Tokens).
Also add the syntax_SUITE test suite to test error reporting and to
cover all error reporting code. Remove the old c_syntax/1 test case.
Also remove all out-commented code.
|
|
Responsibilities for parse error handling were split between
asn1ct and asn1ct_parser2 in a confusing way. Let asn1ct_parser2
return structured_error tuples in the same way as the check
pass.
|
|
Most uses of 'catch' are not necessary. For example,
parse_or/2 is typically called like this:
case catch parse_or(Tokens, Flist) of
{'EXIT',Reason} ->
exit(Reason);
{asn1_error,_}=AsnErr ->
throw(AsnErr);
Result ->
Result
end.
Since {asn1_error,_} is always thrown (never returned) and
a successful is always returned (never thrown), the 'case' and
the 'catch' are not necessary. The code can be simplified too:
parse_or(Tokens, Flist)
In a few cases, we will need to replace the 'catch' with
'try'...'catch'.
|
|
Use try...catch instead of catch.
|
|
The first position in a token tuple is always an atom, the second
the line number. The code tested the third position.
|
|
In a future commit, we want to tighten what we catch. Therefore,
legitimate parsing errors should always throw a controlled exception,
instead of arbitrarily crashing.
|
|
The parse_Type/1 calls various type parse functions. Most of those
functions return a #type record, but not all of them. If a #type{}
record is not returned, parse_Type/1 will wrap the return value in a
We can simplify the code in parse_Type/1 if we make sure that the
type parsing functions called by parse_Type/1 always return
a #type{} record.
|
|
The TypeFromObject and ValueSetFromObjects grammar productions cannot
be distinguished by the parser without the help of type information
(which the parser does not have). Since the parser attempts to
parse TypeFromObject before ValueSetFromObjects, the parsing of
ValueSetFromObjects will always fail.
|
|
To keep the error reporting code in asn1ct_parser2 simple, we
only want to handle pure syntactic errors. Therefore, move the check
that UNIQUE and DEFAULT are not applied to the same field to
asn1ct_check.
|
|
asn1ct_gen_check.erl was added in 7df687d6.
|
|
"SET OF id < Type" was not tested. Also make sure that all of
assigned values are correct.
|
|
|
|
|
|
While we are at it, also remove an unreachable (too many extensions)
error case.
|
|
|
|
|
|
|
|
Clean up the checking of ENUMERATED and modernize the error reporting.
Also eliminate the unused constraints argument for check_enumerated().
|
|
The ASN.1 compiler would go into an infinite loop if a value
in an ENUMERATED was negative.
|