aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_bif_binary.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/erl_bif_binary.c')
-rw-r--r--erts/emulator/beam/erl_bif_binary.c109
1 files changed, 55 insertions, 54 deletions
diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
index 9f72b8c0ac..b1ebf0327e 100644
--- a/erts/emulator/beam/erl_bif_binary.c
+++ b/erts/emulator/beam/erl_bif_binary.c
@@ -531,21 +531,23 @@ static void ac_init_find_all(ACFindAllState *state, ACTrie *act, Sint startpos,
state->out = NULL;
}
-static void ac_restore_find_all(ACFindAllState *state, char *buff)
+static void ac_restore_find_all(ACFindAllState *state,
+ const ACFindAllState *src)
{
- memcpy(state,buff,sizeof(ACFindAllState));
+ memcpy(state, src, sizeof(ACFindAllState));
if (state->allocated > 0) {
state->out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) * (state->allocated));
- memcpy(state->out,buff+sizeof(ACFindAllState),sizeof(FindallData)*state->m);
+ memcpy(state->out, src+1, sizeof(FindallData)*state->m);
} else {
state->out = NULL;
}
}
-static void ac_serialize_find_all(ACFindAllState *state, char *buff)
+static void ac_serialize_find_all(const ACFindAllState *state,
+ ACFindAllState *dst)
{
- memcpy(buff,state,sizeof(ACFindAllState));
- memcpy(buff+sizeof(ACFindAllState),state->out,sizeof(FindallData)*state->m);
+ memcpy(dst, state, sizeof(ACFindAllState));
+ memcpy(dst+1, state->out, sizeof(FindallData)*state->m);
}
static void ac_clean_find_all(ACFindAllState *state)
@@ -805,24 +807,24 @@ static void bm_init_find_all(BMFindAllState *state, Sint startpos, Uint len)
state->out = NULL;
}
-static void bm_restore_find_all(BMFindAllState *state, char *buff)
+static void bm_restore_find_all(BMFindAllState *state,
+ const BMFindAllState *src)
{
- memcpy(state,buff,sizeof(BMFindAllState));
+ memcpy(state, src, sizeof(BMFindAllState));
if (state->allocated > 0) {
state->out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) *
(state->allocated));
- memcpy(state->out,buff+sizeof(BMFindAllState),
- sizeof(FindallData)*state->m);
+ memcpy(state->out, src+1, sizeof(FindallData)*state->m);
} else {
state->out = NULL;
}
}
-static void bm_serialize_find_all(BMFindAllState *state, char *buff)
+static void bm_serialize_find_all(const BMFindAllState *state,
+ BMFindAllState *dst)
{
- memcpy(buff,state,sizeof(BMFindAllState));
- memcpy(buff+sizeof(BMFindAllState),state->out,
- sizeof(FindallData)*state->m);
+ memcpy(dst, state, sizeof(BMFindAllState));
+ memcpy(dst+1, state->out, sizeof(FindallData)*state->m);
}
static void bm_clean_find_all(BMFindAllState *state)
@@ -1032,6 +1034,17 @@ typedef struct BinaryFindState {
Eterm (*global_result) (Process *, Eterm, struct BinaryFindState *, FindallData *, Uint);
} BinaryFindState;
+typedef struct BinaryFindState_bignum {
+ Eterm bignum_hdr;
+ BinaryFindState bfs;
+ union {
+ BMFindFirstState bmffs;
+ BMFindAllState bmfas;
+ ACFindFirstState acffs;
+ ACFindAllState acfas;
+ } data;
+} BinaryFindState_bignum;
+
#define SIZEOF_BINARY_FIND_STATE(S) \
(sizeof(BinaryFindState)+sizeof(S))
@@ -1197,7 +1210,7 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
byte *bytes;
Uint bitoffs, bitsize;
byte *temp_alloc = NULL;
- char *state_ptr = NULL;
+ BinaryFindState_bignum *state_ptr = NULL;
ERTS_GET_BINARY_BYTES(subject, bytes, bitoffs, bitsize);
if (bitsize != 0) {
@@ -1207,17 +1220,14 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
bytes = erts_get_aligned_binary_bytes(subject, &temp_alloc);
}
if (state_term != NIL) {
- state_ptr = (char *)(big_val(state_term));
- state_ptr += sizeof(Eterm);
- bfs = (BinaryFindState *)(state_ptr);
- state_ptr += sizeof(BinaryFindState);
+ state_ptr = (BinaryFindState_bignum *)(big_val(state_term));
+ bfs = &(state_ptr->bfs);
}
if (bfs->flags & BINARY_FIND_ALL) {
if (bfs->type == am_bm) {
BMData *bm;
Sint pos;
- Eterm *hp;
BMFindAllState state;
Uint reds = get_reds(p, BM_LOOP_FACTOR);
Uint save_reds = reds;
@@ -1229,7 +1239,7 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
if (state_term == NIL) {
bm_init_find_all(&state, bfs->hsstart, bfs->hsend);
} else {
- bm_restore_find_all(&state, state_ptr);
+ bm_restore_find_all(&state, &(state_ptr->data.bmfas));
}
pos = bm_find_all_non_overlapping(&state, bm, bytes, &reds);
@@ -1242,12 +1252,11 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
#ifdef HARDDEBUG
erts_printf("Trap bm!\n");
#endif
- hp = HAlloc(p, x+1);
- hp[0] = make_pos_bignum_header(x);
- state_ptr = (char *)(hp);
- memcpy((void *)(state_ptr+sizeof(Eterm)), bfs, sizeof(BinaryFindState));
- bm_serialize_find_all(&state, state_ptr+sizeof(Eterm)+sizeof(BinaryFindState));
- *res_term = make_big(hp);
+ state_ptr = (BinaryFindState_bignum*) HAlloc(p, x+1);
+ state_ptr->bignum_hdr = make_pos_bignum_header(x);
+ memcpy(&state_ptr->bfs, bfs, sizeof(BinaryFindState));
+ bm_serialize_find_all(&state, &state_ptr->data.bmfas);
+ *res_term = make_big(&state_ptr->bignum_hdr);
erts_free_aligned_binary_bytes(temp_alloc);
bm_clean_find_all(&state);
return DO_BIN_MATCH_RESTART;
@@ -1262,7 +1271,6 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
ACTrie *act;
int acr;
ACFindAllState state;
- Eterm *hp;
Uint reds = get_reds(p, AC_LOOP_FACTOR);
Uint save_reds = reds;
@@ -1273,7 +1281,7 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
if (state_term == NIL) {
ac_init_find_all(&state, act, bfs->hsstart, bfs->hsend);
} else {
- ac_restore_find_all(&state, state_ptr);
+ ac_restore_find_all(&state, &(state_ptr->data.acfas));
}
acr = ac_find_all_non_overlapping(&state, bytes, &reds);
if (acr == AC_NOT_FOUND) {
@@ -1285,12 +1293,11 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
#ifdef HARDDEBUG
erts_printf("Trap ac!\n");
#endif
- hp = HAlloc(p, x+1);
- hp[0] = make_pos_bignum_header(x);
- state_ptr = (char *)(hp);
- memcpy((void *)(state_ptr+sizeof(Eterm)), bfs, sizeof(BinaryFindState));
- ac_serialize_find_all(&state, state_ptr+sizeof(Eterm)+sizeof(BinaryFindState));
- *res_term = make_big(hp);
+ state_ptr = (BinaryFindState_bignum*) HAlloc(p, x+1);
+ state_ptr->bignum_hdr = make_pos_bignum_header(x);
+ memcpy(&state_ptr->bfs, bfs, sizeof(BinaryFindState));
+ ac_serialize_find_all(&state, &state_ptr->data.acfas);
+ *res_term = make_big(&state_ptr->bignum_hdr);
erts_free_aligned_binary_bytes(temp_alloc);
ac_clean_find_all(&state);
return DO_BIN_MATCH_RESTART;
@@ -1306,7 +1313,6 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
if (bfs->type == am_bm) {
BMData *bm;
Sint pos;
- Eterm *hp;
BMFindFirstState state;
Uint reds = get_reds(p, BM_LOOP_FACTOR);
Uint save_reds = reds;
@@ -1318,7 +1324,7 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
if (state_term == NIL) {
bm_init_find_first_match(&state, bfs->hsstart, bfs->hsend);
} else {
- memcpy((void *)(&state), (const void *)(state_ptr), sizeof(BMFindFirstState));
+ memcpy(&state, &state_ptr->data.bmffs, sizeof(BMFindFirstState));
}
#ifdef HARDDEBUG
@@ -1335,13 +1341,11 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
#ifdef HARDDEBUG
erts_printf("Trap bm!\n");
#endif
- hp = HAlloc(p, x+1);
- hp[0] = make_pos_bignum_header(x);
- state_ptr = (char *)(hp);
- memcpy((void *)(state_ptr+sizeof(Eterm)), bfs, sizeof(BinaryFindState));
- memcpy((void *)(state_ptr+sizeof(Eterm)+sizeof(BinaryFindState)),
- (const void *)(&state), sizeof(BMFindFirstState));
- *res_term = make_big(hp);
+ state_ptr = (BinaryFindState_bignum*) HAlloc(p, x+1);
+ state_ptr->bignum_hdr = make_pos_bignum_header(x);
+ memcpy(&state_ptr->bfs, bfs, sizeof(BinaryFindState));
+ memcpy(&state_ptr->data.acffs, &state, sizeof(BMFindFirstState));
+ *res_term = make_big(&state_ptr->bignum_hdr);
erts_free_aligned_binary_bytes(temp_alloc);
return DO_BIN_MATCH_RESTART;
} else {
@@ -1355,7 +1359,6 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
Uint pos, rlen;
int acr;
ACFindFirstState state;
- Eterm *hp;
Uint reds = get_reds(p, AC_LOOP_FACTOR);
Uint save_reds = reds;
@@ -1366,7 +1369,7 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
if (state_term == NIL) {
ac_init_find_first_match(&state, act, bfs->hsstart, bfs->hsend);
} else {
- memcpy((void *)(&state), (const void *)(state_ptr), sizeof(ACFindFirstState));
+ memcpy(&state, &state_ptr->data.acffs, sizeof(ACFindFirstState));
}
acr = ac_find_first_match(&state, bytes, &pos, &rlen, &reds);
if (acr == AC_NOT_FOUND) {
@@ -1378,13 +1381,11 @@ static int do_binary_find(Process *p, Eterm subject, BinaryFindState *bfs, Binar
#ifdef HARDDEBUG
erts_printf("Trap ac!\n");
#endif
- hp = HAlloc(p, x+1);
- hp[0] = make_pos_bignum_header(x);
- state_ptr = (char *)(hp);
- memcpy((void *)(state_ptr+sizeof(Eterm)), bfs, sizeof(BinaryFindState));
- memcpy((void *)(state_ptr+sizeof(Eterm)+sizeof(BinaryFindState)),
- (const void *)(&state), sizeof(ACFindFirstState));
- *res_term = make_big(hp);
+ state_ptr = (BinaryFindState_bignum*) HAlloc(p, x+1);
+ state_ptr->bignum_hdr = make_pos_bignum_header(x);
+ memcpy(&state_ptr->bfs, bfs, sizeof(BinaryFindState));
+ memcpy(&state_ptr->data.acffs, &state, sizeof(ACFindFirstState));
+ *res_term = make_big(&state_ptr->bignum_hdr);
erts_free_aligned_binary_bytes(temp_alloc);
return DO_BIN_MATCH_RESTART;
} else {
@@ -1763,7 +1764,7 @@ static BIF_RETTYPE binary_find_trap(BIF_ALIST_3)
int runres;
Eterm result;
Binary *bin = ((ProcBin *) binary_val(BIF_ARG_3))->val;
- runres = do_binary_find(BIF_P, BIF_ARG_1, THE_NON_VALUE, bin, BIF_ARG_2, &result);
+ runres = do_binary_find(BIF_P, BIF_ARG_1, NULL, bin, BIF_ARG_2, &result);
if (runres == DO_BIN_MATCH_OK) {
BIF_RET(result);
} else {