|
32 | 32 | #include "defaultatoms.h" |
33 | 33 | #include "memory.h" |
34 | 34 | #include "module.h" |
| 35 | +#include "resources.h" |
35 | 36 | #include "term.h" |
36 | 37 | #include "unicode.h" |
37 | 38 | #include "utils.h" |
@@ -488,20 +489,38 @@ static int serialize_term(uint8_t *buf, term t, GlobalContext *glb) |
488 | 489 | buf[0] = NEWER_REFERENCE_EXT; |
489 | 490 | } |
490 | 491 | size_t k = 1; |
491 | | - uint32_t len = 2; |
| 492 | + uint32_t len; |
| 493 | + if (term_is_resource_reference(t)) { |
| 494 | + len = 4; |
| 495 | + } else { |
| 496 | + len = 2; |
| 497 | + } |
492 | 498 | if (!IS_NULL_PTR(buf)) { |
493 | 499 | WRITE_16_UNALIGNED(buf + k, len); |
494 | 500 | } |
495 | 501 | k += 2; |
496 | 502 | term node_name = glb->node_name; |
497 | 503 | uint32_t creation = node_name == NONODE_AT_NOHOST_ATOM ? 0 : glb->creation; |
498 | 504 | k += serialize_term(IS_NULL_PTR(buf) ? NULL : buf + k, node_name, glb); |
499 | | - if (!IS_NULL_PTR(buf)) { |
500 | | - uint64_t ticks = term_to_ref_ticks(t); |
501 | | - WRITE_32_UNALIGNED(buf + k, creation); |
502 | | - WRITE_64_UNALIGNED(buf + k + 4, ticks); |
| 505 | + if (term_is_resource_reference(t)) { |
| 506 | + if (!IS_NULL_PTR(buf)) { |
| 507 | + WRITE_32_UNALIGNED(buf + k, creation); |
| 508 | + struct RefcBinary *refc_binary = term_resource_refc_binary_ptr(t); |
| 509 | + struct ResourceType *resource_type = refc_binary->resource_type; |
| 510 | + void *resource = refc_binary->data; |
| 511 | + uint64_t serialize_ref = resource_serialize(resource, resource_type); |
| 512 | + WRITE_64_UNALIGNED(buf + k + 4, ((uintptr_t) resource_type)); |
| 513 | + WRITE_64_UNALIGNED(buf + k + 12, ((uintptr_t) serialize_ref)); |
| 514 | + } |
| 515 | + return k + 20; |
| 516 | + } else { |
| 517 | + if (!IS_NULL_PTR(buf)) { |
| 518 | + uint64_t ticks = term_to_ref_ticks(t); |
| 519 | + WRITE_32_UNALIGNED(buf + k, creation); |
| 520 | + WRITE_64_UNALIGNED(buf + k + 4, ticks); |
| 521 | + } |
| 522 | + return k + 12; |
503 | 523 | } |
504 | | - return k + 12; |
505 | 524 | } else if (term_is_external_reference(t)) { |
506 | 525 | if (!IS_NULL_PTR(buf)) { |
507 | 526 | buf[0] = NEWER_REFERENCE_EXT; |
@@ -882,6 +901,11 @@ static term parse_external_terms(const uint8_t *external_term_buf, size_t *eterm |
882 | 901 | if (len == 2 && node == this_node && creation == this_creation) { |
883 | 902 | uint64_t ticks = ((uint64_t) data[0]) << 32 | data[1]; |
884 | 903 | return term_from_ref_ticks(ticks, heap); |
| 904 | + } else if (len == 4 && node == this_node && creation == this_creation) { |
| 905 | + // This is a resource |
| 906 | + uint64_t resource_type_ptr = ((uint64_t) data[0]) << 32 | data[1]; |
| 907 | + uint64_t resource_serialize_ref = ((uint64_t) data[2]) << 32 | data[3]; |
| 908 | + return term_from_resource_type_and_serialize_ref(resource_type_ptr, resource_serialize_ref, heap, glb); |
885 | 909 | } else { |
886 | 910 | return term_make_external_reference(node, len, data, creation, heap); |
887 | 911 | } |
@@ -1294,8 +1318,12 @@ static int calculate_heap_usage(const uint8_t *external_term_buf, size_t remaini |
1294 | 1318 | } |
1295 | 1319 | if (external_term_buf[3] == SMALL_ATOM_UTF8_EXT) { |
1296 | 1320 | // Check if it's non-distributed node, in which case it's always a local ref |
1297 | | - if (len == 2 && external_term_buf[4] == strlen("nonode@nohost") && memcmp(external_term_buf + 5, "nonode@nohost", strlen("nonode@nohost")) == 0) { |
1298 | | - heap_size = REF_SIZE; |
| 1321 | + if (external_term_buf[4] == strlen("nonode@nohost") && memcmp(external_term_buf + 5, "nonode@nohost", strlen("nonode@nohost")) == 0) { |
| 1322 | + if (len == 2) { |
| 1323 | + heap_size = REF_SIZE; |
| 1324 | + } else if (len == 4) { |
| 1325 | + heap_size = TERM_BOXED_REFERENCE_RESOURCE_SIZE; |
| 1326 | + } |
1299 | 1327 | } |
1300 | 1328 | // See above for pids |
1301 | 1329 | } else if (UNLIKELY(external_term_buf[3] != ATOM_EXT)) { |
|
0 commit comments