summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/jit/beam_jit_common.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/jit/beam_jit_common.cpp')
-rw-r--r--erts/emulator/beam/jit/beam_jit_common.cpp111
1 files changed, 106 insertions, 5 deletions
diff --git a/erts/emulator/beam/jit/beam_jit_common.cpp b/erts/emulator/beam/jit/beam_jit_common.cpp
index b1a43206d8..d03ca7fcfd 100644
--- a/erts/emulator/beam/jit/beam_jit_common.cpp
+++ b/erts/emulator/beam/jit/beam_jit_common.cpp
@@ -664,11 +664,7 @@ Eterm beam_jit_bs_init_bits(Process *c_p,
Binary *bptr;
ProcBin *pb;
- test_bin_vheap(c_p,
- reg,
- num_bytes / sizeof(Eterm),
- alloc,
- Live);
+ test_bin_vheap(c_p, reg, num_bytes / sizeof(Eterm), alloc, Live);
/*
* Allocate the binary struct itself.
@@ -742,6 +738,111 @@ Eterm beam_jit_bs_get_integer(Process *c_p,
return erts_bs_get_integer_2(c_p, size, flags, mb);
}
+void beam_jit_bs_construct_fail_info(Process *c_p,
+ Uint packed_error_info,
+ Eterm bad_value) {
+ Eterm *hp = HAlloc(c_p, Sint(MAP3_SZ + 3 + 1));
+ Eterm cause_tuple;
+ Eterm error_info;
+ Uint segment = BSC_GET_SEGMENT(packed_error_info);
+ Uint op = BSC_GET_OP(packed_error_info);
+ Uint info = BSC_GET_INFO(packed_error_info);
+ Uint reason = BSC_GET_REASON(packed_error_info);
+ Eterm Op = am_none;
+ Eterm Info = am_none;
+
+ switch (op) {
+ case BSC_OP_BINARY:
+ Op = am_binary;
+ break;
+ case BSC_OP_FLOAT:
+ Op = am_float;
+ break;
+ case BSC_OP_INTEGER:
+ Op = am_integer;
+ break;
+ case BSC_OP_UTF8:
+ Op = am_utf8;
+ break;
+ case BSC_OP_UTF16:
+ Op = am_utf16;
+ break;
+ case BSC_OP_UTF32:
+ Op = am_utf32;
+ break;
+ }
+
+ switch (reason) {
+ case BSC_REASON_FREASON:
+ reason = c_p->freason;
+ break;
+ case BSC_REASON_BADARG:
+ reason = BADARG;
+ break;
+ case BSC_REASON_SYSTEM_LIMIT:
+ reason = SYSTEM_LIMIT;
+ break;
+ case BSC_REASON_DEPENDS:
+ if ((is_small(bad_value) && signed_val(bad_value) >= 0) ||
+ (is_big(bad_value) && !big_sign(bad_value))) {
+ reason = SYSTEM_LIMIT;
+ } else {
+ reason = BADARG;
+ }
+ break;
+ }
+
+ switch (info) {
+ case BSC_INFO_FVALUE:
+ Info = c_p->fvalue;
+ break;
+ case BSC_INFO_TYPE:
+ Info = am_type;
+ break;
+ case BSC_INFO_SIZE:
+ Info = am_size;
+ break;
+ case BSC_INFO_NEGATIVE:
+ Info = am_negative_size;
+ break;
+ case BSC_INFO_UNIT:
+ Info = am_unit;
+ break;
+ case BSC_INFO_DEPENDS:
+ if (reason == SYSTEM_LIMIT) {
+ Info = am_size;
+ } else if (is_small(bad_value) || is_big(bad_value)) {
+ Info = am_negative_size;
+ } else {
+ Info = am_size;
+ }
+ break;
+ }
+
+ cause_tuple = TUPLE3(hp, make_small(segment), Op, Info);
+ hp += 4;
+ error_info = MAP3(hp,
+ am_cause,
+ cause_tuple,
+ am_function,
+ am_format_bs_fail,
+ am_module,
+ am_erl_erts_errors);
+ c_p->fvalue = error_info;
+ c_p->freason = reason | EXF_HAS_EXT_INFO;
+}
+
+Sint beam_jit_bs_bit_size(Eterm term) {
+ if (is_binary(term)) {
+ ASSERT(sizeof(Uint) == 8); /* Only support 64-bit machines. */
+ Uint byte_size = binary_size(term);
+ return (Sint)((byte_size << 3) + binary_bitsize(term));
+ }
+
+ /* Signal error */
+ return (Sint)-1;
+}
+
ErtsMessage *beam_jit_decode_dist(Process *c_p, ErtsMessage *msgp) {
if (!erts_proc_sig_decode_dist(c_p, ERTS_PROC_LOCK_MAIN, msgp, 0)) {
/*