Skip to content

Commit 5662000

Browse files
committed
Add erlang:get/0 and erlang:erase/0
Signed-off-by: Paul Guyot <pguyot@kallisys.net>
1 parent c60d126 commit 5662000

File tree

5 files changed

+88
-2
lines changed

5 files changed

+88
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2525
- Added `erlang:spawn_monitor/1`, `erlang:spawn_monitor/3`
2626
- Added `lists:dropwhile/2`.
2727
- Support for `float/1` BIF.
28+
- Added `erlang:get/0` and `erlang:erase/0`.
2829

2930
### Fixed
3031
- ESP32: improved sntp sync speed from a cold boot.

libs/estdlib/src/erlang.erl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@
4343
min/2,
4444
max/2,
4545
memory/1,
46+
get/0,
4647
get/1,
4748
put/2,
49+
erase/0,
4850
erase/1,
4951
function_exported/3,
5052
display/1,
@@ -506,6 +508,15 @@ memory(_Type) ->
506508
monotonic_time(_Unit) ->
507509
erlang:nif_error(undefined).
508510

511+
%%-----------------------------------------------------------------------------
512+
%% @returns the process directory
513+
%% @doc Return all values from the process dictionary
514+
%% @end
515+
%%-----------------------------------------------------------------------------
516+
-spec get() -> [{any(), any()}].
517+
get() ->
518+
erlang:nif_error(undefined).
519+
509520
%%-----------------------------------------------------------------------------
510521
%% @param Key key in the process dictionary
511522
%% @returns value associated with this key or undefined
@@ -527,6 +538,15 @@ get(_Key) ->
527538
put(_Key, _Value) ->
528539
erlang:nif_error(undefined).
529540

541+
%%-----------------------------------------------------------------------------
542+
%% @returns the previous process dictionary.
543+
%% @doc Erase all keys from the process dictionary.
544+
%% @end
545+
%%-----------------------------------------------------------------------------
546+
-spec erase() -> [{any(), any()}].
547+
erase() ->
548+
erlang:nif_error(undefined).
549+
530550
%%-----------------------------------------------------------------------------
531551
%% @param Key key to erase from the process dictionary
532552
%% @returns the previous value associated with this key or undefined

src/libAtomVM/nifs.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ static term nif_erlang_binary_to_list_1(Context *ctx, int argc, term argv[]);
103103
static term nif_erlang_binary_to_existing_atom_1(Context *ctx, int argc, term argv[]);
104104
static term nif_erlang_concat_2(Context *ctx, int argc, term argv[]);
105105
static term nif_erlang_display_1(Context *ctx, int argc, term argv[]);
106+
static term nif_erlang_erase_0(Context *ctx, int argc, term argv[]);
106107
static term nif_erlang_erase_1(Context *ctx, int argc, term argv[]);
107108
static term nif_erlang_error(Context *ctx, int argc, term argv[]);
108109
static term nif_erlang_exit(Context *ctx, int argc, term argv[]);
@@ -141,6 +142,7 @@ static term nif_erlang_process_flag(Context *ctx, int argc, term argv[]);
141142
static term nif_erlang_processes(Context *ctx, int argc, term argv[]);
142143
static term nif_erlang_process_info(Context *ctx, int argc, term argv[]);
143144
static term nif_erlang_fun_info_2(Context *ctx, int argc, term argv[]);
145+
static term nif_erlang_get_0(Context *ctx, int argc, term argv[]);
144146
static term nif_erlang_put_2(Context *ctx, int argc, term argv[]);
145147
static term nif_erlang_system_info(Context *ctx, int argc, term argv[]);
146148
static term nif_erlang_system_flag(Context *ctx, int argc, term argv[]);
@@ -309,7 +311,13 @@ static const struct Nif display_nif =
309311
.nif_ptr = nif_erlang_display_1
310312
};
311313

312-
static const struct Nif erase_nif =
314+
static const struct Nif erase_0_nif =
315+
{
316+
.base.type = NIFFunctionType,
317+
.nif_ptr = nif_erlang_erase_0
318+
};
319+
320+
static const struct Nif erase_1_nif =
313321
{
314322
.base.type = NIFFunctionType,
315323
.nif_ptr = nif_erlang_erase_1
@@ -531,6 +539,12 @@ static const struct Nif process_info_nif =
531539
.nif_ptr = nif_erlang_process_info
532540
};
533541

542+
static const struct Nif get_0_nif =
543+
{
544+
.base.type = NIFFunctionType,
545+
.nif_ptr = nif_erlang_get_0
546+
};
547+
534548
static const struct Nif put_nif =
535549
{
536550
.base.type = NIFFunctionType,
@@ -3646,6 +3660,32 @@ static term nif_erlang_fun_info_2(Context *ctx, int argc, term argv[])
36463660
return fun_info_tuple;
36473661
}
36483662

3663+
static term nif_erlang_get_0(Context *ctx, int argc, term argv[])
3664+
{
3665+
UNUSED(argc);
3666+
UNUSED(argv);
3667+
3668+
term result = term_nil();
3669+
size_t size = 0;
3670+
struct ListHead *dictionary = &ctx->dictionary;
3671+
struct ListHead *item;
3672+
LIST_FOR_EACH (item, dictionary) {
3673+
size++;
3674+
}
3675+
if (UNLIKELY(memory_ensure_free(ctx, LIST_SIZE(size, TUPLE_SIZE(2))) != MEMORY_GC_OK)) {
3676+
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
3677+
}
3678+
LIST_FOR_EACH (item, dictionary) {
3679+
struct DictEntry *dict_entry = GET_LIST_ENTRY(item, struct DictEntry, head);
3680+
term tuple = term_alloc_tuple(2, &ctx->heap);
3681+
term_put_tuple_element(tuple, 0, dict_entry->key);
3682+
term_put_tuple_element(tuple, 1, dict_entry->value);
3683+
result = term_list_prepend(tuple, result, &ctx->heap);
3684+
}
3685+
3686+
return result;
3687+
}
3688+
36493689
static term nif_erlang_put_2(Context *ctx, int argc, term argv[])
36503690
{
36513691
UNUSED(argc);
@@ -3659,6 +3699,19 @@ static term nif_erlang_put_2(Context *ctx, int argc, term argv[])
36593699
return old;
36603700
}
36613701

3702+
static term nif_erlang_erase_0(Context *ctx, int argc, term argv[])
3703+
{
3704+
UNUSED(argc);
3705+
3706+
term result = nif_erlang_get_0(ctx, argc, argv);
3707+
if (LIKELY(!term_is_invalid_term(result))) {
3708+
dictionary_destroy(&ctx->dictionary);
3709+
list_init(&ctx->dictionary);
3710+
}
3711+
3712+
return result;
3713+
}
3714+
36623715
static term nif_erlang_erase_1(Context *ctx, int argc, term argv[])
36633716
{
36643717
UNUSED(argc);

src/libAtomVM/nifs.gperf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ erlang:binary_to_integer/2, &binary_to_integer_nif
5050
erlang:binary_to_list/1, &binary_to_list_nif
5151
erlang:binary_to_existing_atom/1, &binary_to_existing_atom_1_nif
5252
erlang:delete_element/2, &delete_element_nif
53-
erlang:erase/1, &erase_nif
53+
erlang:erase/0, &erase_0_nif
54+
erlang:erase/1, &erase_1_nif
5455
erlang:error/1, &error_nif
5556
erlang:error/2, &error_nif
5657
erlang:error/3, &error_nif
@@ -106,6 +107,7 @@ erlang:process_flag/2, &process_flag_nif
106107
erlang:process_flag/3, &process_flag_nif
107108
erlang:processes/0, &processes_nif
108109
erlang:process_info/2, &process_info_nif
110+
erlang:get/0, &get_0_nif
109111
erlang:put/2, &put_nif
110112
erlang:binary_to_term/1, &binary_to_term_nif
111113
erlang:binary_to_term/2, &binary_to_term_nif

tests/erlang_tests/test_dict.erl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
-export([start/0, put_int/1, stringize/1, factorial/1, id/1, the_get/1, the_erase/1]).
2424

2525
start() ->
26+
ok = test_get_0_erase_0(),
2627
put_int(0),
2728
X = put_int(1),
2829
put_int(2),
@@ -80,3 +81,12 @@ test_put_get_erase() ->
8081
2 = apply(erlang, list_to_atom("erase"), [{any_term}]),
8182
undefined = erase({any_term}),
8283
ok.
84+
85+
test_get_0_erase_0() ->
86+
[] = get(),
87+
undefined = put({any_term}, 1),
88+
[{{any_term}, 1}] = get(),
89+
[{{any_term}, 1}] = erase(),
90+
[] = get(),
91+
[] = erase(),
92+
ok.

0 commit comments

Comments
 (0)