234
240
int ci; /* Current index into loaded code. */
236
242
Uint put_strings; /* Linked list of put_string instructions. */
237
Uint bs_put_strings; /* Linked list of bs_put_string instructions. */
243
#if !defined(HEAP_FRAG_ELIM_TEST)
244
Uint bs_put_strings; /* Linked list of i_bs_put_string instructions. */
246
Uint new_bs_put_strings; /* Linked list of i_new_bs_put_string instructions. */
238
247
Uint catches; /* Linked list of catch_yf instructions. */
239
248
unsigned loaded_size; /* Final size of code when loaded. */
240
249
byte mod_md5[16]; /* MD5 for module code. */
418
static int bin_load(Eterm group_leader, Eterm* modp, byte* bytes, int unloaded_size);
431
static int bin_load(Process *c_p, Uint32 c_p_locks,
432
Eterm group_leader, Eterm* modp, byte* bytes, int unloaded_size);
419
433
static void init_state(LoaderState* stp);
420
static int insert_new_code(Eterm group_leader, Eterm module,
434
static int insert_new_code(Process *c_p, Uint32 c_p_locks,
435
Eterm group_leader, Eterm module,
421
436
Eterm* code, Uint size, Uint catches);
422
437
static int scan_iff_file(LoaderState* stp, Uint* chunk_types,
423
438
Uint num_types, Uint num_mandatory);
439
454
GenOpArg Size, GenOpArg* Rest);
440
455
static GenOp* gen_func_info(LoaderState* stp, GenOpArg mod, GenOpArg Func,
441
456
GenOpArg arity, GenOpArg label);
457
#if defined(HEAP_FRAG_ELIM_TEST)
459
gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
460
GenOpArg Src, GenOpArg Dst);
442
463
static int freeze_code(LoaderState* stp);
444
465
static void final_touch(LoaderState* stp);
514
537
ErlDrvBinary* bin;
517
if ((bin = (ErlDrvBinary *) gzinflate_buffer(code, size)) == NULL) {
540
if (size >= 4 && code[0] == 'F' && code[1] == 'O' &&
541
code[2] == 'R' && code[3] == '1') {
543
* The BEAM module is not compressed.
545
result = bin_load(c_p, c_p_locks, group_leader, modp, code, size);
548
* The BEAM module is compressed (or possibly invalid/corrupted).
550
if ((bin = (ErlDrvBinary *) gzinflate_buffer((char*)code, size)) == NULL) {
553
result = bin_load(c_p, c_p_locks, group_leader, modp,
554
(byte*)bin->orig_bytes, bin->orig_size);
555
driver_free_binary(bin);
520
result = bin_load(group_leader, modp, bin->orig_bytes, bin->orig_size);
521
driver_free_binary(bin);
527
bin_load(Eterm group_leader, Eterm* modp, byte* bytes, int unloaded_size)
562
bin_load(Process *c_p, Uint32 c_p_locks,
563
Eterm group_leader, Eterm* modp, byte* bytes, int unloaded_size)
529
565
LoaderState state;
675
711
stp->lambdas_allocated = sizeof(stp->def_lambdas)/sizeof(Lambda);
676
712
stp->lambdas = stp->def_lambdas;
677
713
stp->lambda_error = NULL;
678
stp->generate_heap_bin = 0;
714
stp->new_float_instructions = 0;
682
insert_new_code(Eterm group_leader, Eterm module, Eterm* code, Uint size, Uint catches)
718
insert_new_code(Process *c_p, Uint32 c_p_locks,
719
Eterm group_leader, Eterm module, Eterm* code, Uint size, Uint catches)
688
if ((rval = beam_make_current_old(module)) < 0) {
690
erl_printf(CBUF, "Module ");
691
print_atom(atom_val(module), CBUF);
692
erl_printf(CBUF, " must be purged before loading\n");
693
send_error_to_logger(group_leader);
725
if ((rval = beam_make_current_old(c_p, c_p_locks, module)) < 0) {
726
erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
727
erts_dsprintf(dsbufp,
728
"Module %T must be purged before loading\n",
730
erts_send_error_to_logger(group_leader, dsbufp);
984
1030
for (i = 0; i < stp->num_exps; i++) {
988
1037
GetInt(stp, 4, n);
989
GetAtom(stp, n, stp->export[i].function);
992
LoadError2(stp, "export table entry %d: absurdly high arity %d", i, n);
1038
GetAtom(stp, n, func);
1039
stp->export[i].function = func;
1040
GetInt(stp, 4, arity);
1041
if (arity > MAX_REG) {
1042
LoadError2(stp, "export table entry %d: absurdly high arity %d", i, arity);
994
stp->export[i].arity = n;
1044
stp->export[i].arity = arity;
995
1045
GetInt(stp, 4, n);
996
1046
if (n >= stp->num_labels) {
997
1047
LoadError3(stp, "export table entry %d: invalid label %d (highest defined label is %d)", i, n, stp->num_labels);
1001
1051
LoadError2(stp, "export table entry %d: label %d not resolved", i, n);
1003
1053
stp->export[i].address = stp->code + value;
1056
* Check that we are not redefining a BIF (except the ones allowed to
1059
if ((e = erts_find_export_entry(stp->module, func, arity)) != NULL) {
1060
if (e->code[3] == (Uint) em_apply_bif) {
1063
for (j = 0; j < sizeof(allow_redef)/sizeof(allow_redef[0]); j++) {
1064
if (stp->module == allow_redef[j].mod &&
1065
func == allow_redef[j].func &&
1066
arity == allow_redef[j].arity) {
1070
if (j == sizeof(allow_redef)/sizeof(allow_redef[0])) {
1071
LoadError2(stp, "exported function %T/%d redefines BIF",
1252
1330
GetValue(stp, first, last_op->a[arg].val);
1253
1331
if (last_op->a[arg].val == 0) {
1254
1332
last_op->a[arg].type = TAG_r;
1333
} else if (last_op->a[arg].val >= MAX_REG) {
1334
LoadError1(stp, "invalid x register number: %u",
1335
last_op->a[arg].val);
1258
1339
GetValue(stp, first, last_op->a[arg].val);
1340
if (last_op->a[arg].val >= MAX_REG) {
1341
LoadError1(stp, "invalid y register number: %u",
1342
last_op->a[arg].val);
1259
1344
last_op->a[arg].val += CP_SIZE;
1333
1418
VerifyTag(stp, tag, TAG_u);
1334
1419
last_op->a[arg].type = TAG_l;
1421
case 3: /* Allocation list. */
1428
stp->new_float_instructions = 1;
1429
GetTagAndValue(stp, tag, n);
1430
VerifyTag(stp, tag, TAG_u);
1432
GetTagAndValue(stp, tag, type);
1433
VerifyTag(stp, tag, TAG_u);
1434
GetTagAndValue(stp, tag, val);
1435
VerifyTag(stp, tag, TAG_u);
1437
case 0: /* Heap words */
1441
words += FLOAT_SIZE_OBJECT*val;
1444
LoadError1(stp, "alloc list: bad allocation descriptor %d", type);
1448
last_op->a[arg].type = TAG_u;
1449
last_op->a[arg].val = words;
1337
1453
LoadError1(stp, "invalid extended tag %d", ext_tag);
1506
* Special error message instruction.
1508
if (stp->genop->op == genop_too_old_compiler_0) {
1509
#if defined(HEAP_FRAG_ELIM_TEST)
1510
LoadError0(stp, "please re-compile this module with an R11B compiler");
1512
LoadError0(stp, "this module was compiled by an obsolete compiler (R5B/R6B); please re-compile it");
1388
1517
* From the collected generic instruction, find the specific
1393
Uint mask[2] = {0, 0};
1522
Uint mask[3] = {0, 0, 0};
1395
1524
tmp_op = stp->genop;
1396
1525
arity = gen_opc[tmp_op->op].arity;
1398
1527
for (arg = 0; arg < arity; arg++) {
1399
1528
mask[arg/2] |= (1 << (tmp_op->a[arg].type)) << ((arg%2)*16);
1809
1943
stp->bs_put_strings = ci - 3;
1947
case op_i_new_bs_put_string_II:
1952
* code[ci-3] &&lb_i_new_bs_put_string_II
1953
* code[ci-2] length of string
1954
* code[ci-1] offset into string table
1956
* Since we don't know the address of the string table yet,
1957
* just check the offset and length for validity, and use
1958
* the instruction field as a link field to link all put_string
1959
* instructions into a single linked list. At exit:
1961
* code[ci-3] pointer to next i_new_bs_put_string instruction (or 0
1962
* if this is the last)
1964
Uint offset = code[ci-1];
1965
Uint len = code[ci-2];
1966
unsigned strtab_size = stp->chunks[STR_CHUNK].size;
1967
if (offset > strtab_size || offset + len > strtab_size) {
1968
LoadError2(stp, "invalid string reference %d, size %d", offset, len);
1970
code[ci-3] = stp->new_bs_put_strings;
1971
stp->new_bs_put_strings = ci - 3;
1813
1975
case op_catch_yf:
1814
1976
/* code[ci-3] &&lb_catch_yf
1874
2036
return early in latter case, before we access the values */
1875
2037
if (Rest[0].type != TAG_i || Rest[1].type != TAG_f)
1877
min = max = signed_val(Rest[0].val);
2039
min = max = Rest[0].val;
1878
2040
for (i = 2; i < Size.val; i += 2) {
1879
2041
if (Rest[i].type != TAG_i || Rest[i+1].type != TAG_f) {
1882
if (signed_val(Rest[i].val) < min) {
1883
min = signed_val(Rest[i].val);
1884
} else if (max < signed_val(Rest[i].val)) {
1885
max = signed_val(Rest[i].val);
2044
if (Rest[i].val < min) {
2046
} else if (max < Rest[i].val) {
2014
gen_get_integer(LoaderState* stp, GenOpArg Fail, GenOpArg Size, GenOpArg Unit,
2015
GenOpArg Flags, GenOpArg Dst)
2164
gen_get_integer2(LoaderState* stp, GenOpArg Fail, GenOpArg Ms, GenOpArg Live,
2165
GenOpArg Size, GenOpArg Unit,
2166
GenOpArg Flags, GenOpArg Dst)
2018
2169
NEW_GENOP(stp, op);
2020
2171
NATIVE_ENDIAN(Flags);
2021
2172
if (Size.type == TAG_i) {
2022
if (Flags.val & BSF_ALIGNED && (Flags.val & BSF_SIGNED) == 0) {
2023
Uint bits = signed_val(Size.val) * Unit.val;
2025
op->op = genop_i_bs_get_integer8_2;
2173
if ((Flags.val & BSF_SIGNED) == 0) {
2174
Uint bits = Size.val * Unit.val;
2176
op->op = genop_i_bs_get_integer2_8_3;
2027
2178
op->a[0] = Fail;
2029
2181
} else if (bits == 16 && (Flags.val & BSF_LITTLE) == 0) {
2030
op->op = genop_i_bs_get_integer16_2;
2182
op->op = genop_i_bs_get_integer2_16_3;
2032
2184
op->a[0] = Fail;
2034
2187
} else if (bits == 32 && (Flags.val & BSF_LITTLE) == 0) {
2035
op->op = genop_i_bs_get_integer32_2;
2188
op->op = genop_i_bs_get_integer2_32_4;
2037
2190
op->a[0] = Fail;
2044
op->op = genop_i_bs_get_integer_imm_4;
2199
op->op = genop_i_bs_get_integer_imm2_6;
2046
2201
op->a[0] = Fail;
2047
op->a[1].type = TAG_u;
2048
op->a[1].val = signed_val(Size.val) * Unit.val;
2204
op->a[3].type = TAG_u;
2205
op->a[3].val = Size.val * Unit.val;
2053
op->op = genop_i_bs_get_integer_4;
2210
op->op = genop_i_bs_get_integer2_6;
2055
2212
op->a[0] = Fail;
2057
op->a[2].type = TAG_u;
2058
op->a[2].val = (Unit.val << 3) | Flags.val;
2216
op->a[4].type = TAG_u;
2217
op->a[4].val = (Unit.val << 3) | Flags.val;
2061
2220
op->next = NULL;
2076
2236
NATIVE_ENDIAN(Flags);
2077
2237
if (Size.type == TAG_a && Size.val == am_all) {
2078
op->op = genop_i_bs_get_binary_all_2;
2238
op->op = genop_i_bs_get_binary_all2_5;
2080
2240
op->a[0] = Fail;
2082
2245
} else if (Size.type == TAG_i) {
2083
op->op = genop_i_bs_get_binary_imm_4;
2246
op->op = genop_i_bs_get_binary_imm2_6;
2085
2248
op->a[0] = Fail;
2086
op->a[1].type = TAG_u;
2087
op->a[1].val = signed_val(Size.val) * Unit.val;
2251
op->a[3].type = TAG_u;
2252
op->a[3].val = Size.val * Unit.val;
2091
op->op = genop_i_bs_get_binary_4;
2256
op->op = genop_i_bs_get_binary2_6;
2093
2258
op->a[0] = Fail;
2095
op->a[2].type = TAG_u;
2096
op->a[2].val = (Unit.val << 3) | Flags.val;
2262
op->a[4].type = TAG_u;
2263
op->a[4].val = (Unit.val << 3) | Flags.val;
2099
2266
op->next = NULL;
2271
* Predicate to test whether a heap binary should be generated.
2275
should_gen_heap_bin(LoaderState* stp, GenOpArg Src)
2277
return Src.val <= ERL_ONHEAP_BIN_LIMIT;
2280
#if !defined(HEAP_FRAG_ELIM_TEST)
2282
old_bs_instructions(LoaderState* stp)
2284
stp->new_instructions = 0;
2290
new_bs_instructions(LoaderState* stp)
2292
stp->new_instructions = 1;
2296
#define query_new_instructions(stp) (stp->new_instructions)
2298
#if defined(HEAP_FRAG_ELIM_TEST)
2299
# define NEW_OR_OLD(New,Old) New
2301
# define NEW_OR_OLD(New,Old) \
2302
(stp->new_instructions ? New : Old)
2305
#define new_float_allocation(Stp) ((Stp)->new_float_instructions)
2104
2308
gen_put_binary(LoaderState* stp, GenOpArg Fail,GenOpArg Size,
2105
2309
GenOpArg Unit, GenOpArg Flags, GenOpArg Src)
2110
2314
NATIVE_ENDIAN(Flags);
2111
2315
if (Size.type == TAG_a && Size.val == am_all) {
2112
op->op = genop_i_bs_put_binary_all_2;
2316
op->op = NEW_OR_OLD(genop_i_new_bs_put_binary_all_2,genop_i_bs_put_binary_all_2);
2114
2318
op->a[0] = Fail;
2115
2319
op->a[1] = Src;
2116
} else if (Size.type == TAG_i) {
2117
op->op = genop_i_bs_put_binary_imm_3;
2320
} else if (Size.type == TAG_i && stp->new_instructions) {
2321
op->op = genop_i_new_bs_put_binary_imm_3;
2119
2323
op->a[0] = Fail;
2120
2324
op->a[1].type = TAG_u;
2121
op->a[1].val = signed_val(Size.val) * Unit.val;
2325
op->a[1].val = Size.val * Unit.val;
2122
2326
op->a[2] = Src;
2124
op->op = genop_i_bs_put_binary_4;
2328
op->op = NEW_OR_OLD(genop_i_new_bs_put_binary_4,genop_i_bs_put_binary_4);
2126
2330
op->a[0] = Fail;
2127
2331
op->a[1] = Size;
2128
2332
op->a[2].type = TAG_u;
2129
op->a[2].val = (Unit.val << 3) | Flags.val;
2333
op->a[2].val = (Unit.val << 3) | (Flags.val & 7);
2130
2334
op->a[3] = Src;
2142
2346
NEW_GENOP(stp, op);
2144
2348
NATIVE_ENDIAN(Flags);
2145
if (Size.type == TAG_i && signed_val(Size.val) < 0) {
2349
if (Size.type == TAG_i && Size.val < 0) {
2146
2350
/* Negative size must fail */
2147
2351
op->op = genop_badarg_1;
2149
2353
op->a[0] = Fail;
2150
} else if (Size.type == TAG_i) {
2151
op->op = genop_i_bs_put_integer_imm_4;
2354
} else if (Size.type == TAG_i && stp->new_instructions) {
2355
op->op = genop_i_new_bs_put_integer_imm_4;
2153
2357
op->a[0] = Fail;
2154
2358
op->a[1].type = TAG_u;
2155
op->a[1].val = signed_val(Size.val) * Unit.val;
2359
op->a[1].val = Size.val * Unit.val;
2360
op->a[2].type = Flags.type;
2361
op->a[2].val = (Flags.val & 7);
2157
2362
op->a[3] = Src;
2159
op->op = genop_i_bs_put_integer_4;
2364
op->op = NEW_OR_OLD(genop_i_new_bs_put_integer_4,genop_i_bs_put_integer_4);
2161
2366
op->a[0] = Fail;
2162
2367
op->a[1] = Size;
2163
2368
op->a[2].type = TAG_u;
2164
op->a[2].val = (Unit.val << 3) | Flags.val;
2369
op->a[2].val = (Unit.val << 3) | (Flags.val & 7);
2165
2370
op->a[3] = Src;
2167
2372
op->next = NULL;
2176
2381
NEW_GENOP(stp, op);
2178
2383
NATIVE_ENDIAN(Flags);
2179
if (Size.type == TAG_i) {
2180
op->op = genop_i_bs_put_float_imm_4;
2384
if (Size.type == TAG_i && stp->new_instructions) {
2385
op->op = genop_i_new_bs_put_float_imm_4;
2182
2387
op->a[0] = Fail;
2183
2388
op->a[1].type = TAG_u;
2184
op->a[1].val = signed_val(Size.val) * Unit.val;
2389
op->a[1].val = Size.val * Unit.val;
2185
2390
op->a[2] = Flags;
2186
2391
op->a[3] = Src;
2188
op->op = genop_i_bs_put_float_4;
2393
op->op = NEW_OR_OLD(genop_i_new_bs_put_float_4,genop_i_bs_put_float_4);
2190
2395
op->a[0] = Fail;
2191
2396
op->a[1] = Size;
2192
2397
op->a[2].type = TAG_u;
2193
op->a[2].val = (Unit.val << 3) | Flags.val;
2398
op->a[2].val = (Unit.val << 3) | (Flags.val & 7);
2194
2399
op->a[3] = Src;
2196
2401
op->next = NULL;
2410
gen_get_float2(LoaderState* stp, GenOpArg Fail, GenOpArg Ms, GenOpArg Live,
2411
GenOpArg Size, GenOpArg Unit, GenOpArg Flags, GenOpArg Dst)
2416
NATIVE_ENDIAN(Flags);
2417
op->op = genop_i_bs_get_float2_6;
2423
op->a[4].type = TAG_u;
2424
op->a[4].val = (Unit.val << 3) | Flags.val;
2431
* Generate the fastest instruction for bs_skip_bits.
2435
gen_skip_bits2(LoaderState* stp, GenOpArg Fail, GenOpArg Ms,
2436
GenOpArg Size, GenOpArg Unit, GenOpArg Flags)
2440
NATIVE_ENDIAN(Flags);
2442
if (Size.type == TAG_a && Size.val == am_all) {
2443
op->op = genop_i_bs_skip_bits_all2_3;
2448
} else if (Size.type == TAG_i) {
2449
op->op = genop_i_bs_skip_bits_imm2_3;
2453
op->a[2].type = TAG_u;
2454
op->a[2].val = Size.val * Unit.val;
2456
op->op = genop_i_bs_skip_bits2_4;
2468
#if !defined(HEAP_FRAG_ELIM_TEST)
2470
* Old binary matching instructions - not allowed in the nofrag emulator.
2474
gen_get_integer(LoaderState* stp, GenOpArg Fail, GenOpArg Size, GenOpArg Unit,
2475
GenOpArg Flags, GenOpArg Dst)
2480
NATIVE_ENDIAN(Flags);
2481
op->op = genop_i_bs_get_integer_4;
2485
op->a[2].type = TAG_u;
2486
op->a[2].val = (Unit.val << 3) | Flags.val;
2493
gen_get_binary(LoaderState* stp, GenOpArg Fail, GenOpArg Size, GenOpArg Unit,
2494
GenOpArg Flags, GenOpArg Dst)
2499
NATIVE_ENDIAN(Flags);
2500
if (Size.type == TAG_a && Size.val == am_all) {
2501
op->op = genop_i_bs_get_binary_all_2;
2505
} else if (Size.type == TAG_i) {
2506
op->op = genop_i_bs_get_binary_imm_4;
2509
op->a[1].type = TAG_u;
2510
op->a[1].val = Size.val * Unit.val;
2514
op->op = genop_i_bs_get_binary_4;
2518
op->a[2].type = TAG_u;
2519
op->a[2].val = (Unit.val << 3) | Flags.val;
2205
2527
gen_get_float(LoaderState* stp, GenOpArg Fail, GenOpArg Size, GenOpArg Unit,
2206
2528
GenOpArg Flags, GenOpArg Dst)
2233
2551
NATIVE_ENDIAN(Flags);
2234
2552
NEW_GENOP(stp, op);
2235
2553
if (Size.type == TAG_a && Size.val == am_all) {
2236
if (Flags.val & BSF_ALIGNED) {
2237
op->op = genop_i_bs_skip_bits_all_aligned_0;
2240
op->op = genop_i_bs_skip_bits_all_1;
2554
op->op = genop_i_bs_skip_bits_all_1;
2244
2557
} else if (Size.type == TAG_i) {
2245
2558
op->op = genop_i_bs_skip_bits_imm_2;
2247
2560
op->a[0] = Fail;
2248
2561
op->a[1].type = TAG_u;
2249
op->a[1].val = signed_val(Size.val) * Unit.val;
2562
op->a[1].val = Size.val * Unit.val;
2251
2564
op->op = genop_i_bs_skip_bits_3;
2266
2620
gen_literal_timeout(LoaderState* stp, GenOpArg Fail, GenOpArg Time)
2271
2625
NEW_GENOP(stp, op);
2272
op->op = genop_wait_timeout_2;
2626
op->op = genop_i_wait_timeout_2;
2273
2627
op->next = NULL;
2275
2629
op->a[0] = Fail;
2276
2630
op->a[1].type = TAG_u;
2278
if (Time.type == TAG_i && (timeout = signed_val(Time.val)) >= 0) {
2632
if (Time.type == TAG_i && (timeout = Time.val) >= 0 &&
2634
(timeout >> 32) == 0
2279
2639
op->a[1].val = timeout;
2280
2641
} else if (Time.type == TAG_w) {
2281
2642
Eterm* bigp = stp->temp_heap + Time.val;
2282
2643
if (thing_arityval(*bigp) > 1 || BIG_SIGN(bigp)) {
2283
2644
op->op = genop_i_wait_error_0;
2286
ASSERT(sizeof(unsigned) == 4);
2288
op->a[1].val = (((unsigned) (((unsigned short *)bigp)[1])) << 16) |
2289
((unsigned short *)bigp)[0];
2647
(void) term_to_Uint(make_big(bigp), &op->a[1].val);
2292
2651
op->op = genop_i_wait_error_0;
2658
gen_literal_timeout_locked(LoaderState* stp, GenOpArg Fail, GenOpArg Time)
2664
op->op = genop_i_wait_timeout_locked_2;
2668
op->a[1].type = TAG_u;
2670
if (Time.type == TAG_i && (timeout = Time.val) >= 0 &&
2672
(timeout >> 32) == 0
2677
op->a[1].val = timeout;
2679
} else if (Time.type == TAG_w) {
2680
Eterm* bigp = stp->temp_heap + Time.val;
2681
if (thing_arityval(*bigp) > 1 || BIG_SIGN(bigp)) {
2682
op->op = genop_i_wait_error_locked_0;
2685
(void) term_to_Uint(make_big(bigp), &op->a[1].val);
2689
op->op = genop_i_wait_error_locked_0;
2299
2696
* Tag the list of values with tuple arity tags.
2691
3087
op->next = NULL;
2693
if (func.val == am_module_info && arity.val < 2) {
2694
NEW_GENOP(stp, op->next);
2696
op->op = arity.val == 0 ? genop_i_module_info_0_0 :
2697
genop_i_module_info_1_0;
3094
gen_func_info_mi(LoaderState* stp, GenOpArg mod,
3095
GenOpArg arity, GenOpArg label)
3101
fi->op = genop_i_func_info_4;
3103
fi->a[0].type = TAG_u; /* untagged Zero */
3106
fi->a[2].type = TAG_a;
3107
fi->a[2].val = am_module_info;
3111
op->op = genop_label_1;
3118
NEW_GENOP(stp, op->next);
3120
op->op = arity.val == 0 ? genop_i_module_info_0_0 :
3121
genop_i_module_info_1_0;
3129
#ifndef HEAP_FRAG_ELIM_TEST
2707
3131
gen_make_fun(LoaderState* stp, GenOpArg lbl, GenOpArg uniq, GenOpArg num_free)
3197
#if defined(HEAP_FRAG_ELIM_TEST)
3199
gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
3200
GenOpArg Src, GenOpArg Dst)
3206
op->op = genop_i_gc_bif1_5;
3209
op->a[1].type = TAG_u;
3210
bf = stp->import[Bif.val].bf;
3211
if (bf == length_1) {
3212
op->a[1].val = (Uint) (void *) erts_gc_length_1;
3213
} else if (bf == size_1) {
3214
op->a[1].val = (Uint) (void *) erts_gc_size_1;
3215
} else if (bf == abs_1) {
3216
op->a[1].val = (Uint) (void *) erts_gc_abs_1;
3217
} else if (bf == float_1) {
3218
op->a[1].val = (Uint) (void *) erts_gc_float_1;
3219
} else if (bf == round_1) {
3220
op->a[1].val = (Uint) (void *) erts_gc_round_1;
3221
} else if (bf == trunc_1) {
3222
op->a[1].val = (Uint) (void *) erts_gc_trunc_1;
2774
3236
* Freeze the code in memory, move the string table into place,
2868
3331
index = stp->bs_put_strings;
2869
3332
while (index != 0) {
2870
3333
Uint next = code[index];
2871
code[index] = BeamOpCode(op_bs_put_string_II);
3334
code[index] = BeamOpCode(op_i_bs_put_string_II);
3335
code[index+2] = (Uint) (str_table + code[index+2]);
3341
* Go through all i_new_bs_put_strings instructions, restore the pointer to
3342
* the instruction and convert string offsets to pointers (to the
3346
index = stp->new_bs_put_strings;
3347
while (index != 0) {
3348
Uint next = code[index];
3349
code[index] = BeamOpCode(op_i_new_bs_put_string_II);
2872
3350
code[index+2] = (Uint) (str_table + code[index+2]);
3592
#if defined(TOP_is_not_bif)
3593
case TOP_is_not_bif:
3598
* In debug build, the type must be 'u'.
3601
ASSERT(instr->a[ap].type == TAG_u);
3602
if (instr->a[ap].type != TAG_u) {
3605
i = instr->a[ap].val;
3608
* erlang:apply/2,3 are strange. They exist as (dummy) BIFs
3609
* so that they are included in the export table before
3610
* the erlang module is loaded. They also exist in the erlang
3611
* module as functions. When used in code, a special Beam
3612
* instruction is used.
3614
* Below we specially recognize erlang:apply/2,3 as special.
3615
* This is necessary because after setting a trace pattern on
3616
* them, you cannot no longer see from the export entry that
3619
if (i < st->num_imports) {
3620
if (st->import[i].bf != NULL ||
3621
(st->import[i].module == am_erlang &&
3622
st->import[i].function == am_apply &&
3623
(st->import[i].arity == 2 || st->import[i].arity == 3))) {
3114
3631
#if defined(TOP_is_func)
3115
3632
case TOP_is_func:
3652
case TOP_set_var_next_arg:
3136
3653
ASSERT(ap < instr->arity);
3138
3655
ASSERT(i < TE_MAX_VARS);
3139
3656
var[i].type = instr->a[ap].type;
3140
3657
var[i].val = instr->a[ap].val;
3143
3661
#if defined(TOP_rest_args)
3144
3662
case TOP_rest_args:
3146
var = erts_alloc(ERTS_ALC_T_LOADER_TMP,
3147
instr->arity * sizeof(GenOpArg));
3148
memcpy(var, def_vars, sizeof(def_vars));
3149
while (i < instr->arity) {
3150
var[i] = instr->a[i];
3665
var = erts_alloc(ERTS_ALC_T_LOADER_TMP,
3666
instr->arity * sizeof(GenOpArg));
3667
for (i = 0; i < n; i++) {
3668
var[i] = def_vars[i];
3670
while (i < instr->arity) {
3671
var[i] = instr->a[i];
3275
3797
load_printf(int line, LoaderState* context, char *fmt,...)
3279
char module_name[256]; /* Module name as string. */
3799
erts_dsprintf_buf_t *dsbufp;
3284
3802
if (is_non_value(context->module)) {
3285
3803
/* Suppressed by code:get_chunk/2 */
3807
dsbufp = erts_create_logger_dsbuf();
3809
erts_dsprintf(dsbufp, "%s(%d): Error loading ", __FILE__, line);
3811
if (is_atom(context->function))
3812
erts_dsprintf(dsbufp, "function %T:%T/%d", context->module,
3813
context->function, context->arity);
3815
erts_dsprintf(dsbufp, "module %T", context->module);
3818
erts_dsprintf(dsbufp, ": op %s", gen_opc[context->genop->op].name);
3820
if (context->specific_op != -1)
3821
erts_dsprintf(dsbufp, ": %s", opc[context->specific_op].sign);
3822
else if (context->genop) {
3824
for (i = 0; i < context->genop->arity; i++)
3825
erts_dsprintf(dsbufp, " %c",
3826
tag_to_letter[context->genop->a[i].type]);
3829
erts_dsprintf(dsbufp, ":\n ");
3289
3831
va_start(va, fmt);
3290
vsprintf(sbuf, fmt, va);
3832
erts_vdsprintf(dsbufp, fmt, va);
3293
sprintf(ep, "%s(%d): Error loading ", __FILE__, line);
3297
* Convert atom for module to a string.
3299
ap = atom_tab(atom_val(context->module));
3300
memcpy(module_name, ap->name, ap->len);
3301
module_name[ap->len] = '\0';
3303
if (is_atom(context->function)) {
3306
ap = atom_tab(atom_val(context->function));
3307
memcpy(function, ap->name, ap->len);
3308
function[ap->len] = '\0';
3309
sprintf(ep, "function %s:%s/%d", module_name, function, context->arity);
3311
sprintf(ep, "module %s", module_name);
3314
if (context->genop) {
3315
sprintf(ep, ": op %s", gen_opc[context->genop->op].name);
3318
if (context->specific_op != -1) {
3319
sprintf(ep, ": %s", opc[context->specific_op].sign);
3320
} else if (context->genop) {
3322
for (i = 0; i < context->genop->arity; i++) {
3323
sprintf(ep, " %c", tag_to_letter[context->genop->a[i].type]);
3329
sys_printf(CBUF, "%s:\n %s\n", error, sbuf);
3835
erts_dsprintf(dsbufp, "\n");
3331
sys_printf(CERR, "%s:\n %s\n", error, sbuf);
3837
erts_fprintf(stderr, "%s", dsbufp->str);
3333
send_error_to_logger(context->group_leader);
3839
erts_send_error_to_logger(context->group_leader, dsbufp);
3469
3975
arity = count/sizeof(Eterm);
3470
3976
hindex = TempAlloc(stp, arity+1);
3471
3977
hp = stp->temp_heap + hindex;
3472
*hp++ = neg ? make_neg_bignum_header(arity) : make_pos_bignum_header(arity);
3473
for (i = 0; i < arity; i++) {
3474
byte* bp = bigbuf + sizeof(Eterm)*i;
3475
((unsigned short *)hp)[0] = bp[0] | (bp[1] << 8);
3476
((unsigned short *)hp)[1] = bp[2] | (bp[3] << 8);
3477
if (sizeof(Eterm) == 8) {
3478
((unsigned short *)hp)[2] = bp[4] | (bp[5] << 8);
3479
((unsigned short *)hp)[3] = bp[6] | (bp[7] << 8);
3978
(void) bytes_to_big(bigbuf, count, neg, hp);
3484
3980
if (bigbuf != default_buf) {
3485
3981
erts_free(ERTS_ALC_T_LOADER_TMP, (void *) bigbuf);
3637
4141
return THE_NON_VALUE;
3639
4143
code = modp->code;
3640
for (i = code[MI_NUM_FUNCTIONS]-1; i >= 0 ; i--) {
4144
num_functions = code[MI_NUM_FUNCTIONS];
4145
hp = HAlloc(p, 5*num_functions);
4146
for (i = num_functions-1; i >= 0 ; i--) {
3641
4147
Eterm* func_info = (Eterm *) code[MI_FUNCTIONS+i];
3642
4148
Eterm name = func_info[3];
3643
4149
int arity = func_info[4];
3646
4152
ASSERT(is_atom(name));
3649
hp = HAlloc(p, need);
3652
4153
tuple = TUPLE2(hp, name, make_small(arity));
3654
4155
result = CONS(hp, tuple, result);
3692
4200
ASSERT(is_atom(name));
3693
4201
if (func_info[1] != 0) {
3694
Eterm addr = make_small_or_big(func_info[1], p);
3698
hp = HAlloc(p, need);
3701
tuple = TUPLE3(hp, name, make_small(arity), addr);
3703
result = CONS(hp, tuple, result);
4202
Eterm addr = erts_bld_uint(&hp, NULL, func_info[1]);
4203
tuple = erts_bld_tuple(&hp, NULL, 3, name, make_small(arity), addr);
4204
result = erts_bld_cons(&hp, NULL, tuple, result);
4207
HRelease(p, hp_end, hp);
3729
4228
if (is_not_atom(mod)) {
3730
4229
return THE_NON_VALUE;
3732
modp = erts_get_module(mod);
3734
return THE_NON_VALUE;
3737
for (i = code[MI_NUM_FUNCTIONS]-1; i >= 0 ; i--) {
3738
Eterm* func_info = (Eterm *) code[MI_FUNCTIONS+i];
3739
Eterm name = func_info[3];
3740
int arity = func_info[4];
3743
if (erts_find_function(mod, name, arity) != NULL) {
3744
ASSERT(is_atom(name));
4232
for (i = 0; i < export_list_size(); i++) {
4233
Export* ep = export_list(i);
4235
if (ep->code[0] == mod) {
4238
if (ep->address == ep->code+3 &&
4239
ep->code[3] == (Eterm) em_call_error_handler) {
4240
/* There is a call to the function, but it does not exist. */
3745
4244
if (hp == hend) {
3746
4245
int need = 10 * 5;
3747
4246
hp = HAlloc(p, need);
3748
4247
hend = hp + need;
3750
tuple = TUPLE2(hp, name, make_small(arity));
4249
tuple = TUPLE2(hp, ep->code[1], make_small(ep->code[2]));
3752
4251
result = CONS(hp, tuple, result);
4255
HRelease(p,hend,hp);
3921
4421
if (is_not_nil(Chunk)) {
3925
4424
if (!scan_iff_file(&state, &chunk, 1, 1)) {
4425
erts_free_aligned_binary_bytes(temp_alloc);
3926
4426
return am_undefined;
3928
sb = (ErlSubBin *) HAlloc(p, ERL_SUB_BIN_SIZE);
3929
GET_REAL_BIN(Bin, sb->orig, offset);
3930
sb->thing_word = HEADER_SUB_BIN;
3931
sb->size = state.chunks[0].size;
3932
sb->offs = offset + (state.chunks[0].start-start);
3933
return make_binary(sb);
3936
BIF_ERROR(p, BADARG);
4428
ERTS_GET_REAL_BIN(Bin, real_bin, offset, bitoffs, bitsize);
4430
res = new_binary(p, state.chunks[0].start, state.chunks[0].size);
4432
sb = (ErlSubBin *) HAlloc(p, ERL_SUB_BIN_SIZE);
4433
sb->thing_word = HEADER_SUB_BIN;
4434
sb->orig = real_bin;
4435
sb->size = state.chunks[0].size;
4438
sb->offs = offset + (state.chunks[0].start - start);
4439
res = make_binary(sb);
4441
erts_free_aligned_binary_bytes(temp_alloc);
3944
4450
code_module_md5_1(Process* p, Eterm Bin)
3946
4452
LoaderState state;
4453
byte* temp_alloc = NULL;
3949
if (is_not_binary(Bin)) {
4455
if ((state.file_p = erts_get_aligned_binary_bytes(Bin, &temp_alloc)) == NULL) {
3950
4456
BIF_ERROR(p, BADARG);
3952
4458
state.module = THE_NON_VALUE; /* Suppress diagnostiscs */
3953
4459
state.file_name = "IFF header for Beam file";
3954
GET_BINARY_BYTES(Bin, start);
3955
state.file_p = start;
3956
4460
state.file_left = binary_size(Bin);
3958
4462
if (!scan_iff_file(&state, chunk_types, NUM_CHUNK_TYPES, NUM_MANDATORY)) {
3959
4463
return am_undefined;
4465
erts_free_aligned_binary_bytes(temp_alloc);
3961
4466
return new_binary(p, state.mod_md5, sizeof(state.mod_md5));
4481
fp[5] = BeamOpCode(op_move_return_nr);
4482
hipe_mfa_save_orig_beam_op(mod, func, arity, fp+5);
3974
4485
fp[5] = OpCode;
3975
4486
return fp + WORDS_PER_FUNCTION;
3979
stub_init_state(LoaderState* stp, Eterm Bin)
3984
stp->file_name = "IFF header for Beam file";
3985
GET_BINARY_BYTES(Bin, start);
3986
stp->file_p = start;
3987
stp->file_left = binary_size(Bin);
3991
4490
stub_copy_info(LoaderState* stp,
3992
4491
int chunk, /* Chunk: ATTR_CHUNK or COMPILE_CHUNK */