int main(int argc, char **argv) { if (argc < 2) { printf("Need .beam file\n"); return EXIT_FAILURE; } MappedFile *mapped_file = mapped_file_open_beam(argv[1]); if (IS_NULL_PTR(mapped_file)) { return EXIT_FAILURE; } GlobalContext *glb = globalcontext_new(); const void *startup_beam; uint32_t startup_beam_size; const char *startup_module_name = argv[1]; if (avmpack_is_valid(mapped_file->mapped, mapped_file->size)) { glb->avmpack_data = mapped_file->mapped; glb->avmpack_platform_data = mapped_file; if (!avmpack_find_section_by_flag(mapped_file->mapped, 1, &startup_beam, &startup_beam_size, &startup_module_name)) { fprintf(stderr, "%s cannot be started.\n", argv[1]); mapped_file_close(mapped_file); return EXIT_FAILURE; } } else if (iff_is_valid_beam(mapped_file->mapped)) { glb->avmpack_data = NULL; glb->avmpack_platform_data = NULL; startup_beam = mapped_file->mapped; startup_beam_size = mapped_file->size; } else { fprintf(stderr, "%s is not a BEAM file.\n", argv[1]); mapped_file_close(mapped_file); return EXIT_FAILURE; } Module *mod = module_new_from_iff_binary(glb, startup_beam, startup_beam_size); if (IS_NULL_PTR(mod)) { fprintf(stderr, "Cannot load startup module: %s\n", startup_module_name); return EXIT_FAILURE; } globalcontext_insert_module_with_filename(glb, mod, startup_module_name); mod->module_platform_data = NULL; Context *ctx = context_new(glb); ctx->leader = 1; context_execute_loop(ctx, mod, "start", 0); printf("Return value: %lx\n", ctx->x[0]); context_destroy(ctx); globalcontext_destroy(glb); module_destroy(mod); mapped_file_close(mapped_file); return EXIT_SUCCESS; }
/* Open existing external memory list. */ static int em_list_open_existing(em_list_t *self) { mapped_file_t *mf; em_list_index_hdr_t *index_hdr; em_list_values_hdr_t *values_hdr; size_t pos; char *filename; const char *dirname = self->dirname; /* Open and verify "index.bin". */ filename = path_combine(dirname, "index.bin"); if((mf = mapped_file_open(filename)) == NULL) goto _err1; self->index = mf; index_hdr = mf->address; if(index_hdr->magic != MAGIC) goto _err2; /* Open and verify "values.bin". */ filename = path_combine(dirname, "values.bin"); if((mf = mapped_file_open(filename)) == NULL) goto _err2; self->values = mf; values_hdr = mf->address; pos = mapped_file_get_eof(mf); if(values_hdr->magic != MAGIC || mapped_file_seek(mf, pos, SEEK_SET) != 0) goto _err3; return 0; _err3: mapped_file_close(self->values); _err2: mapped_file_close(self->index); _err1: PyErr_SetString(PyExc_RuntimeError, "Cannot open EMList"); return -1; }
/* Synchronize and close an external memory list. */ static PyObject *em_list_close(em_list_t *self) { mapped_file_t *index = self->index; mapped_file_t *values = self->values; if(self->is_open) { /* Sync and close "index.bin". */ mapped_file_sync(index, 0, index->size); mapped_file_close(index); /* Sync and close "values.bin". */ mapped_file_sync(values, 0, values->size); mapped_file_truncate(values, mapped_file_get_eof(values)); mapped_file_close(values); PyMem_FREE(self->dirname); self->is_open = 0; } Py_RETURN_NONE; };
/* Create a new external memory list. */ static int em_list_create(em_list_t *self) { mapped_file_t *mf; em_list_index_hdr_t index_hdr; em_list_values_hdr_t values_hdr; size_t size; char *filename; const char *dirname = self->dirname; /* Compute initial external memory list index size. */ size = EM_LIST_E2S(0); /* Create directory to hold external memory list files. */ if(mk_dir(dirname) != 0) goto _err1; /* Create "index.bin" and write file header. */ filename = path_combine(dirname, "index.bin"); if((mf = mapped_file_create(filename, size)) == NULL) goto _err2; index_hdr.magic = MAGIC; index_hdr.used = 0; index_hdr.capacity = 0; mapped_file_write(mf, &index_hdr, sizeof(em_list_index_hdr_t)); self->index = mf; /* Create "values.bin" and write file header. */ filename = path_combine(dirname, "values.bin"); if((mf = mapped_file_create(filename, size)) == NULL) goto _err3; values_hdr.magic = MAGIC; mapped_file_write(mf, &values_hdr, sizeof(em_list_values_hdr_t)); self->values = mf; return 0; _err3: mapped_file_unlink(self->index); mapped_file_close(self->index); _err2: rm_dir(dirname); _err1: PyErr_SetString(PyExc_RuntimeError, "Cannot open EMList"); return -1; }
int test_modules_execution() { struct Test *test = tests; if (chdir("erlang_tests")) { return EXIT_FAILURE; } do { printf("-- EXECUTING TEST: %s\n", test->test_file); MappedFile *beam_file = mapped_file_open_beam(test->test_file); assert(beam_file != NULL); GlobalContext *glb = globalcontext_new(); glb->avmpack_data = NULL; glb->avmpack_platform_data = NULL; Module *mod = module_new_from_iff_binary(glb, beam_file->mapped, beam_file->size); if (IS_NULL_PTR(mod)) { fprintf(stderr, "Cannot load startup module: %s\n", test->test_file); test++; continue; } globalcontext_insert_module_with_filename(glb, mod, test->test_file); Context *ctx = context_new(glb); ctx->leader = 1; context_execute_loop(ctx, mod, "start", 0); int32_t value = term_to_int32(ctx->x[0]); if (value != test->expected_value) { fprintf(stderr, "\x1b[1;31mFailed test module %s, got value: %i\x1b[0m\n", test->test_file, value); } context_destroy(ctx); globalcontext_destroy(glb); module_destroy(mod); mapped_file_close(beam_file); test++; } while (test->test_file); return EXIT_SUCCESS; }
static int em_list_resize(em_list_t *self) { size_t capacity, new_capacity, new_size; char *filename; mapped_file_t *mf; em_list_index_hdr_t *index_hdr, *new_index_hdr; /* Get a reference to the current index file header. */ index_hdr = (em_list_index_hdr_t *)self->index->address; /* Compute new capacity and size in bytes and check for overflows. */ capacity = index_hdr->capacity; if(capacity == 0) new_capacity = 1; else new_capacity = capacity << 1; new_size = EM_LIST_E2S(new_capacity); if(new_capacity < capacity || new_size < new_capacity) { PyErr_SetString(PyExc_RuntimeError, "Integer overflow while resizing EMList"); goto _err1; } msgf("EMList: Resizing"); filename = path_combine(self->dirname, "index.bin.1"); if((mf = mapped_file_create(filename, new_size)) == NULL) goto _err1; /* Copy old entries to the new external memory list. */ memcpy(mf->address, self->index->address, EM_LIST_E2S(capacity)); msgf("EMList: Resize successful"); filename = path_combine(self->dirname, "index.bin.0"); if(mapped_file_rename(self->index, filename) != 0) { PyErr_SetString(PyExc_RuntimeError, "Cannot rename old EMList index file"); goto _err2; } filename = path_combine(self->dirname, "index.bin"); if(mapped_file_rename(mf, filename) != 0) { PyErr_SetString(PyExc_RuntimeError, "Cannot rename new EMList index file"); goto _err2; } /* Populate new index file header. */ new_index_hdr = (em_list_index_hdr_t *)mf->address; new_index_hdr->magic = MAGIC; new_index_hdr->used = index_hdr->used; new_index_hdr->capacity = new_capacity; mapped_file_unlink(self->index); mapped_file_close(self->index); self->index = mf; return 0; _err2: mapped_file_unlink(mf); mapped_file_close(mf); _err1: return -1; }