aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/src/erl_internal.erl
AgeCommit message (Collapse)Author
2018-08-13Correct error behavior of is_map_key/2 in guardsBjörn Gustavsson
Consider the following functions: foo() -> bar(not_a_map). bar(M) when not is_map_key(a, M) -> ok; bar(_) -> error. What will `foo/0` return? It depends. If the module is compiled with the default compiler options, the return value will be `ok`. If the module is compiled with the `inline` option, the return value will be `error`. The correct value is `error`, because the call to `is_map_key/2` when the second argument is not a map should fail the entire guard. That is the way other failing guards BIFs are handled. For example: foo() -> bar(not_a_tuple). bar(T) when not element(1, T) -> ok; bar(_) -> error. `foo/0` always returns `error` (whether the code is inlined or not). This bug can be fixed by changing the classification of `is_map_key/2` in the `erl_internal` module. It is now classified as a type test, which is incorrect because type tests should not fail. Reclassifying it as a plain guard BIF corrects the bug. This correction also fixes the internal consistency check failure which was reported in: https://bugs.erlang.org/browse/ERL-699
2018-06-18Update copyright yearHenrik Nord
2018-04-29Introduce is_map_key/2 guard BIFMichał Muskała
This complements the `map_get/2` guard BIF introduced in #1784. Rationale. `map_get/2` allows accessing map fields in guards, but it might be problematic in more complex guard expressions, for example: foo(X) when map_get(a, X) =:= 1 or is_list(X) -> ... The `is_list/1` part of the guard could never succeed since the `map_get/2` guard would fail the whole guard expression. In this situation, this could be solved by using `;` instead of `or` to separate the guards, but it is not possible in every case. To solve this situation, this PR proposes a `is_map_key/2` guard that allows to check if a map has key inside a guard before trying to access that key. When combined with `is_map/1` this allows to construct a purely boolean guard expression testing a value of a key in a map. Implementation. Given the use case motivating the introduction of this function, the PR contains compiler optimisations that produce optimial code for the following guard expression: foo(X) when is_map(X) and is_map_key(a, X) and map_get(a, X) =:= 1 -> ok; foo(_) -> error. Given all three tests share the failure label, the `is_map_key/2` and `is_map/2` tests are optimised away. As with `map_get/2` the `is_map_key/2` BIF is allowed in match specs.
2018-04-24Introduce map_get guard-safe functionMichał Muskała
Rationale Today all compound data types except for maps can be deconstructed in guards. For tuples we have `element/2` and for lists `hd/1` and `tl/1`. Maps are completely opaque to guards. This means matching on maps can't be abstracted into macros, which is often done with repetitive guards. It also means that maps have to be always selected whole from ETS tables, even when only one field would be enough, which creates a potential efficiency issue. This PR introduces an `erlang:map_get/2` guard-safe function that allows extracting a map field in guard. An alternative to this function would be to introduce the syntax for extracting a value from a map that was planned in the original EEP: `Map#{Key}`. Even outside of guards, since this function is a guard-BIF it is more efficient than using `maps:get/2` (since it does not need to set up the stack), and more convenient from pattern matching on the map (compare: `#{key := Value} = Map, Value` to `map_get(key, Map)`). Performance considerations A common concern against adding this function is the notion that "guards have to be fast" and ideally execute in constant time. While there are some counterexamples (`length/1`), what is more important is the fact that adding those functions does not change in any way the time complexity of pattern matching - it's already possible to match on map fields today directly in patterns - adding this ability to guards will niether slow down or speed up the execution, it will only make certain programs more convenient to write. This first version is very naive and does not perform any optimizations.
2017-05-04Update copyright yearRaimo Niskanen
2017-04-25erts: Add erlang:list_to_port/1 debug bifLukas Larsson
2017-04-25erts: Auto-import port_to_list for consistencyLukas Larsson
Follow the same pattern as pid_to_list
2017-04-21erts: Polish off erlang:list_to_ref/1Lukas Larsson
2016-09-05Implement the new ceil/1 and floor/1 guard BIFsBjörn Gustavsson
Implement as ceil/1 and floor/1 as new guard BIFs (essentially part of Erlang language). They are guard BIFs because trunc/1 is a guard BIF. It would be strange to have trunc/1 as a part of the language, but not ceil/1 and floor/1.
2016-09-01erl_internal: Add add_predefined_functions/1Björn Gustavsson
The sys_pre_expand module used to do a lot more (translate records and funs, for example), but now it does very little. Most of the code is an identify transformation of the abstract format. The identity transformation part of the code must be maintained and kept correct when new forms are added to the abstract format. That adds to the maintance burden. It also adds (slightly) to compilation times. Therefore, we want to eliminate sys_pre_expand, moving all of its (non-identity) transformations to better places. As a preliminary first step, move the code that adds the pre-defined functions (such as module_info/0) to a new function in erl_internal.
2016-06-22erl_internal: Eliminate duplication of guard testsBjörn Gustavsson
Guard tests (e.g. is_list/1) are listed both in guard_bif/2 and in new_type_test/2. That is a trap for anyone who wants to add a new guard test. Let guard_bif/2 call new_type_test/2 so that new guard tests only have to be added in one place. While we are it, also sort the clauses in guard_bif/2 and new_type/2.
2016-03-15update copyright-yearHenrik Nord
2015-06-18Change license text to APLv2Bruce Yinhe
2014-08-22stdlib: Auto-import erlang:get_keys/0Björn-Egil Dahlberg
2014-05-05Remove pre-defined types dict(), digraph(), &cHans Bolinder
The pre-defined types array(), dict(), digraph(), gb_set(), gb_tree(), queue(), set(), and tid() have been removed.
2014-04-29Allow more type namesHans Bolinder
product/_, union/_, range/2 as well as tuple/N (N > 0), map/N (N > 0), atom/1, integer/1, binary/2, record/_, and 'fun'/_ can now be used as type names.
2014-01-28erts: Add the type-testing guard BIF is_map/1Björn-Egil Dahlberg
To add a type-testing guard BIF, the following steps are needed: * The BIF itself is added to bif.tab (note that it should be declared using "ubif", not "bif"), and its implementation to erl_bif_op.c. * erl_internal must be modified in 3 places: The type test must be recognized as guard BIF, as a type test, and it must be auto-imported. * There must be an instruction that implements the same type test as the BIF (it will be used in guards). beam_utils:bif_to_test/3 must be updated to recognize the new guard BIF.
2014-01-28erts: Add the size-testing guard BIF map_size/1Björn-Egil Dahlberg
2013-11-18Execution of system tasks in context of another processRickard Green
A process requesting a system task to be executed in the context of another process will be notified by a message when the task has executed. This message will be on the form: {RequestType, RequestId, Pid, Result}. A process requesting a system task to be executed can set priority on the system task. The requester typically set the same priority on the task as its own process priority, and by this avoiding priority inversion. A request for execution of a system task is made by calling the statically linked in NIF erts_internal:request_system_task(Pid, Prio, Request). This is an undocumented ERTS internal function that should remain so. It should *only* be called from BIF implementations. Currently defined system tasks are: * garbage_collect * check_process_code Further system tasks can and will be implemented in the future. The erlang:garbage_collect/[1,2] and erlang:check_process_code/[2,3] BIFs are now implemented using system tasks. Both the 'garbage_collect' and the 'check_process_code' operations perform or may perform garbage_collections. By doing these via the system task functionality all garbage collect operations in the system will be performed solely in the context of the process being garbage collected. This makes it possible to later implement functionality for disabling garbage collection of a process over context switches. Newly introduced BIFs: * erlang:garbage_collect/2 - The new second argument is an option list. Introduced option: * {async, RequestId} - making it possible for users to issue asynchronous garbage collect requests. * erlang:check_process_code/3 - The new third argument is an option list. Introduced options: * {async, RequestId} - making it possible for users to issue asynchronous check process code requests. * {allow_gc, boolean()} - making it possible to issue requests that aren't allowed to garbage collect (operation will abort if gc should be needed). These options have been introduced as a preparation for parallelization of check_process_code operations when the code_server is about to purge a module.
2013-02-14Add float_to_binary and binary_to_floatLukas Larsson
2013-02-14Add new binary conversion bifsLukas Larsson
Added: binary_to_integer/1,2, integer_to_binary/1,2
2013-01-25Update copyright yearsBjörn-Egil Dahlberg
2013-01-21Text representation of a float formatted using given options.Serge Aleynikov
This BIF solves a problem of float_to_list/1 that doesn't allow specifying the number of digits after the decimal point when formatting floats. float_to_list(Float, Options) -> string() Float = float() Options = [Option] Option = {decimals, Decimals::0..249} | {scientific, Decimals::0..249} | compact Returns a string which corresponds to the text representation of a `Float` formatted using given options. When decimals option is specified the returned value will contain at most `Decimals` number of digits past the decimal point. When `compact` option is provided the trailing zeros at the end of the list are truncated (this option is only meaningful together with the `decimals` option). When `scientific` option is provided, the float will be formatted using scientific notation with `Decimals` digits of precision. If `Options` is `[]` the function behaves like `float_to_list/1`. When using `decimals` option and the number doesn't fit in the static internal buffer of 256 bytes the function throws `badarg`.
2012-03-21erts: Implement erlang:halt/2Raimo Niskanen
2011-09-02Merge branch 'dev' into majorBjörn Gustavsson
* dev: Make the check_old_code/1 BIF auto-imported Deprecate the docbuilder application Conflicts: lib/stdlib/src/otp_internal.erl
2011-09-01Make the check_old_code/1 BIF auto-importedBjörn Gustavsson
check_old_code/1 was documented to be auto-imported, but in fact was not auto-imported. Since check_process_code/2 and the other code loading BIFs are now auto-imported, for consistency auto-import check_old_code/1 too.
2011-07-06Remove deprecated concat_binary/1Björn Gustavsson
concat_binary/1 was deprecated in R13B04, but already in the R10B-2 release, the documentation recommends using list_to_binary/1 instead.
2011-05-12Types and specifications have been modified and addedHans Bolinder
2010-09-10Add new autoimports for R14BPatrik Nyblom
2010-06-02Make port_command/3 auto-importedPatrik Nyblom
2010-06-02Autoimport min/2 and max/2Patrik Nyblom
2010-06-02Teach erl_lint to better override BIFs with local functions and importsPatrik Nyblom
Added only a few testcases in compiler:error_SUITE and guard_SUITE The new behaviour of warnings and errors when overriding autoimported BIF's: Bifs that were autoimported before R14 are dangerous because old code using them and overriding them in exports can start behaving differently. For newly added autoimports this can't happen to the new code that wants to (or dont want to) use them, why only warnings are added for the BIFs autoimported after the compilator change. Errors are issued only for code that could have worked in one way in R13 and now will behave in a different way. If overriding autoimport with local function: - if explicit -compile directive supresses autoimport -> no message else - if called from inside module - if pre R14 autoimported bif -> error else -> warning else -> no message If overriding autoimport with import directive - if explicit -compile directive supresses autoimport -> no message else (regardless of actual usage) - if pre R14 autoimported bif -> error else -> warning Calls of local functions or imports overriding autoimported functions (either post R14 or by using explicit -compile supressions of autoimport) always goes to the local function or the imported. The compileation errors are added to not let code like this silently and disastrously change its semantic (probably to an infinite loop) between R13 and R14: ---------- -module(m). -export([length/1]). length(X) -> ... Y = length(Z), .... ---------- The user has to select if he/she wants to call length in 'erlang' explicitly or if the overriding semantics is desired, in which case the -compile directive has to be used. -compile({no_auto_import,[F/A]}). Is added to allow to override the autoimports so that code gets unanbiguous. The directive will remove an autoimport even if there is no local function or import overriding, because any other behaviour would be inconsistent and confusing. record_info and module_info can never be overridden.
2010-05-24Change binary_to_term/2 to be auto-importedJayson Vantuyl
While binary_to_term/2 was added in R13B04, it wasn't auto-imported. This conformed to longstanding policy of not changing auto-imports between major versions. This patch contains changes to auto-import binary_to_term/2 to coincide with the release of R14.
2010-05-20Merge branch 'pan/otp_8217_binary' into devErlang/OTP
* pan/otp_8217_binary: Add documentation for binary module Add more tests and make some go easier on small systems Correct Boyer More and trapping for longest_common_suffix Add longer timetrap to testcases and add binary to app file Add guard BIFs binary_part/2,3 Add binary:{encode,decode}_unsigned({1,2} Add referenced_byte_size/1 Add binary:list_to_bin/1 and binary:copy/1,2 Add bin_to_list/{1,2,3} Add binary:longest_common_prefix/longest_common_suffix Add binary:part to erl_bif_binary.c Move binary module bif's to erl_bif_binary.c Count reductions for process even when not trapping Add random compare testcase Teach BIF's binary:match/matches interrupting/restarting Teach binary.c the semantics to take longest instead of shortest match Initial commit of the binary EEP OTP-8217 Implement EEP31 The module binary from EEP31 (and EEP9) is implemented.
2010-05-17Add guard BIFs binary_part/2,3Patrik Nyblom
Add the gc_bif's to the VM. Add infrastructure for gc_bif's (guard bifs that can gc) with two and. three arguments in VM (loader and VM). Add compiler support for gc_bif with three arguments. Add compiler (and interpreter) support for new guard BIFs. Add testcases for new guard BIFs in compiler and emulator.
2009-11-20The R13B03 release.OTP_R13B03Erlang/OTP