static int avr_tbc_decode (const prog_char *data, UWORD length, ECTX context, WORDPTR memory, UWORD memory_size) { UWORD ws_size, vs_size; const prog_char *bytecode; WORDPTR ws, vs; avr_tenc_element_t element; int ret, memory_used; /* Decode the required elements */ if ((ret = load_uint (&data, &length, "ws U", &ws_size)) < 0) return ret; if ((ret = load_uint (&data, &length, "vs U", &vs_size)) < 0) return ret; if ((ret = avr_tenc_walk_to_element (data, &length, "bc B", &element)) < 0) return ret; bytecode = element.data.bytes; data = element.next; /* FIXME: check TLP is empty */ #if 0 /* Decode optional elements */ tbc->tlp = NULL; while (length > 0) { if (tenc_decode_element (data, &length, &element) < 0) return 0; /* ignore errors */ if (ids_match (element.id, "tlpL")) { tbc->tlp = decode_tlp (data, tbc->tlp, &element); } data = element.next; } #endif memory_used = tvm_ectx_layout ( context, memory, "", 0, ws_size, vs_size, &ws, &vs ); #ifdef DEBUG printf ("loaded program with ws_size=%d, vs_size=%d, memory_size=%d, used=%d\n", ws_size, vs_size, memory_size, memory_used); #endif /* Check we haven't exhausted memory. */ if (memory_used > memory_size) { terminate ("not enough RAM for program", NULL); } ret = tvm_ectx_install_tlp ( context, tvm_addr_from_progmem ((prog_void *) bytecode), ws, vs, "", 0, NULL ); return ret; }
ECTX allocate_ectx (bytecode_t *bc, const char *tlp, WORD *argv) { WORDPTR mem, vs, ws; WORD mem_len; ECTX vm; vm = (ECTX) malloc (sizeof (tvm_ectx_t)); if (vm == NULL) return NULL; tvm_ectx_init (&tvm, vm); add_system_functions (vm); install_sffi (vm); vm->ffi_table = bc->ffi_table; vm->ffi_table_length = bc->ffi_table_length; mem_len = tvm_ectx_memory_size ( vm, tlp, strlen (tlp), bc->tbc->ws, bc->tbc->vs ); mem = (WORDPTR) malloc (sizeof (WORD) * mem_len); if (mem == NULL) { free (vm); return NULL; } tvm_ectx_layout ( vm, mem, tlp, strlen (tlp), bc->tbc->ws, bc->tbc->vs, &ws, &vs ); /* Setup the type shadow before installing the TLP */ #ifdef TVM_TYPE_SHADOW vm->shadow_start = (unsigned int) mem; vm->shadow_end = vm->shadow_start + (mem_len << WSH); vm->type_store = malloc (mem_len); fill_type_shadow (vm, (BYTEPTR) vm->shadow_start, mem_len << WSH, STYPE_UNDEF); #endif if (tvm_ectx_install_tlp ( vm, bc->tbc->bytecode, ws, vs, tlp, strlen (tlp), argv )) { free (mem); free (vm); return NULL; } bc->refcount++; vm->priv.bytecode = bc; vm->priv.memory = mem; vm->priv.memory_length = mem_len; return vm; }