struct Small_Object_Pool * make_bufferlike_pool(struct Parrot_Interp *interpreter, size_t buffer_size) { UINTVAL idx; UINTVAL num_old = interpreter->arena_base->num_sized; struct Small_Object_Pool **sized_pools = interpreter->arena_base->sized_header_pools; idx = (buffer_size - sizeof(Buffer)) / sizeof(void *); /* Expand the array of sized resource pools, if necessary */ if (num_old <= idx) { UINTVAL num_new = idx + 1; sized_pools = mem_sys_realloc(sized_pools, num_new * sizeof(void *)); memset(sized_pools + num_old, 0, sizeof(void *) * (num_new - num_old)); interpreter->arena_base->sized_header_pools = sized_pools; interpreter->arena_base->num_sized = num_new; } if (sized_pools[idx] == NULL) { sized_pools[idx] = new_bufferlike_pool(interpreter, buffer_size); } return sized_pools[idx]; }
INTVAL Parrot_Run_OS_Command_Argv(PARROT_INTERP, PMC *cmdargs) { DWORD status = 0; STARTUPINFO si; PROCESS_INFORMATION pi; int pmclen; int cmdlinelen = 1000; int cmdlinepos = 0; char *cmdline = (char *)mem_sys_allocate(cmdlinelen); int i; /* Ensure there's something in the PMC array. */ pmclen = VTABLE_elements(interp, cmdargs); if (pmclen == 0) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_NOSPAWN, "Empty argument array for spawnw"); /* Now build command line. */ for (i = 0; i < pmclen; i++) { STRING * const s = VTABLE_get_string_keyed_int(interp, cmdargs, i); char * const cs = Parrot_str_to_cstring(interp, s); if (cmdlinepos + (int)s->strlen + 3 > cmdlinelen) { cmdlinelen += s->strlen + 4; cmdline = (char *)mem_sys_realloc(cmdline, cmdlinelen); } strcpy(cmdline + cmdlinepos, "\""); strcpy(cmdline + cmdlinepos + 1, cs); strcpy(cmdline + cmdlinepos + 1 + s->strlen, "\" "); cmdlinepos += s->strlen + 3; } /* Start the child process. */ memset(&si, 0, sizeof (si)); si.cb = sizeof (si); memset(&pi, 0, sizeof (pi)); if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_NOSPAWN, "Can't spawn child process"); WaitForSingleObject(pi.hProcess, INFINITE); /* Get exit code. */ if (!GetExitCodeProcess(pi.hProcess, &status)) { Parrot_warn(interp, PARROT_WARNINGS_PLATFORM_FLAG, "Process completed: Failed to get exit code."); } /* Clean up. */ CloseHandle(pi.hProcess); CloseHandle(pi.hThread); mem_sys_free(cmdline); /* Return exit code left shifted by 8 for POSIX emulation. */ return status << 8; }
/* Registers a representation. It this is ever made public, it should first be * made thread-safe. */ static void register_repr(PARROT_INTERP, STRING *name, REPROps *repr) { INTVAL ID = num_reprs; num_reprs++; if (repr_registry) repr_registry = mem_sys_realloc(repr_registry, num_reprs * sizeof(REPROps *)); else repr_registry = mem_sys_allocate(num_reprs * sizeof(REPROps *)); repr_registry[ID] = repr; VTABLE_set_integer_keyed_str(interp, repr_name_to_id_map, name, ID); }
static void chartype_register(CHARTYPE *type) { if (type->index == -1) type->index = chartype_count; if (type->index >= chartype_count) { size_t old_size = chartype_count * sizeof(CHARTYPE *); size_t new_size = (type->index + 1) * sizeof(CHARTYPE *); chartype_array = mem_sys_realloc(chartype_array, new_size); memset((char *)chartype_array + old_size, 0, new_size - old_size); chartype_count = type->index + 1; } chartype_array[type->index] = type; }
/* Registers a representation. It this is ever made public, it should first be * made thread-safe. */ static void register_repr(PARROT_INTERP, STRING *name, REPROps *repr) { INTVAL ID = num_reprs; num_reprs++; if (repr_registry) repr_registry = mem_sys_realloc(repr_registry, num_reprs * sizeof(REPROps *)); else repr_registry = mem_sys_allocate(num_reprs * sizeof(REPROps *)); repr_registry[ID] = repr; VTABLE_set_integer_keyed_str(interp, repr_name_to_id_map, name, ID); repr->ID = ID; repr->name = name; if (!repr->attr_funcs) add_default_attr_funcs(interp, repr); if (!repr->box_funcs) add_default_box_funcs(interp, repr); if (!repr->idx_funcs) add_default_idx_funcs(interp, repr); }
struct PackFile * Parrot_readbc(struct Parrot_Interp *interpreter, const char *filename) { #if PARROT_HAS_HEADER_UNISTD off_t program_size, wanted; #else size_t program_size, wanted; #endif char *program_code; struct PackFile *pf; PMC * io = NULL; INTVAL is_mapped = 0; #ifdef PARROT_HAS_HEADER_SYSSTAT struct stat file_stat; #endif #ifdef PARROT_HAS_HEADER_SYSMMAN int fd = -1; #endif if (filename == NULL || strcmp(filename, "-") == 0) { /* read from STDIN */ io = PIO_STDIN(interpreter); /* read 1k at a time */ program_size = 0; } else { #ifdef PARROT_HAS_HEADER_SYSSTAT /* if we have stat(), get the actual file size so we can read it * in one chunk. */ if (stat(filename, &file_stat)) { PIO_eprintf(interpreter, "Parrot VM: Can't stat %s, code %i.\n", filename, errno); return NULL; } # ifndef PARROT_HAS_BROKEN_ISREG /* S_ISREG is strangely broken my lcc/linux install (though it did * once work */ if (!S_ISREG(file_stat.st_mode)) { PIO_eprintf(interpreter, "Parrot VM: %s is not a normal file.\n", filename); return NULL; } # endif /* PARROT_HAS_BROKEN_ISREG */ program_size = file_stat.st_size; #else /* PARROT_HAS_HEADER_SYSSTAT */ /* otherwise, we will read it 1k at a time */ program_size = 0; #endif /* PARROT_HAS_HEADER_SYSSTAT */ #ifndef PARROT_HAS_HEADER_SYSMMAN io = PIO_open(interpreter, NULL, filename, "<"); if (!io) { PIO_eprintf(interpreter, "Parrot VM: Can't open %s, code %i.\n", filename, errno); return NULL; } #else /* PARROT_HAS_HEADER_SYSMMAN */ /* the file wasn't from stdin, and we have mmap available- use it */ io = NULL; #endif /* PARROT_HAS_HEADER_SYSMMAN */ interpreter->current_file = string_make(interpreter, filename, strlen(filename), NULL, 0, NULL); } #ifdef PARROT_HAS_HEADER_SYSMMAN again: #endif /* if we've opened a file (or stdin) with PIO, read it in */ if (io != NULL) { size_t chunk_size; char *cursor; INTVAL read_result; chunk_size = program_size > 0 ? program_size : 1024; program_code = (char *)mem_sys_allocate(chunk_size); wanted = program_size; program_size = 0; if (!program_code) { /* Whoops, out of memory. */ PIO_eprintf(interpreter, "Parrot VM: Could not allocate buffer to read packfile from PIO.\n"); return NULL; } cursor = (char *)program_code; while ((read_result = PIO_read(interpreter, io, cursor, chunk_size)) > 0) { program_size += read_result; if (program_size == wanted) break; chunk_size = 1024; program_code = mem_sys_realloc(program_code, program_size + chunk_size); if (!program_code) { PIO_eprintf(interpreter, "Parrot VM: Could not reallocate buffer while reading packfile from PIO.\n"); return NULL; } cursor = (char *)program_code + program_size; } if (read_result < 0) { PIO_eprintf(interpreter, "Parrot VM: Problem reading packfile from PIO.\n"); return NULL; } PIO_close(interpreter, io); } else { /* if we've gotten here, we opted not to use PIO to read the file. * use mmap */ #ifdef PARROT_HAS_HEADER_SYSMMAN fd = open(filename, O_RDONLY | O_BINARY); if (!fd) { PIO_eprintf(interpreter, "Parrot VM: Can't open %s, code %i.\n", filename, errno); return NULL; } program_code = mmap(0, program_size, PROT_READ, MAP_SHARED, fd, (off_t)0); if (program_code == (void *)MAP_FAILED) { Parrot_warn(interpreter, PARROT_WARNINGS_IO_FLAG, "Parrot VM: Can't mmap file %s, code %i.\n", filename, errno); /* try again, now with IO reading the file */ io = PIO_open(interpreter, NULL, filename, "<"); if (!io) { PIO_eprintf(interpreter, "Parrot VM: Can't open %s, code %i.\n", filename, errno); return NULL; } goto again; } is_mapped = 1; #else /* PARROT_HAS_HEADER_SYSMMAN */ PIO_eprintf(interpreter, "Parrot VM: uncaught error occurred reading " "file or mmap not available.\n"); return NULL; #endif /* PARROT_HAS_HEADER_SYSMMAN */ } /* Now that we have the bytecode, let's unpack it. */ pf = PackFile_new(is_mapped); if (!PackFile_unpack (interpreter, pf, (opcode_t *)program_code, program_size)) { PIO_eprintf(interpreter, "Parrot VM: Can't unpack packfile %s.\n", filename); return NULL; } #ifdef PARROT_HAS_HEADER_SYSMMAN if (fd >= 0) { close(fd); /* the man page states, it's ok to close a mmaped file */ } #else /* XXX Parrot_exec uses this mem_sys_free(program_code); */ #endif return pf; }
PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL static STRING * to_encoding(PARROT_INTERP, ARGIN(STRING *src), ARGIN_NULLOK(STRING *dest)) { ASSERT_ARGS(to_encoding) #if PARROT_HAS_ICU UErrorCode err; int dest_len; UChar *p; #endif int src_len; int in_place = dest == NULL; STRING *result; if (src->encoding == Parrot_utf16_encoding_ptr || src->encoding == Parrot_ucs2_encoding_ptr) return in_place ? src : Parrot_str_copy(interp, src); /* * TODO adapt string creation functions */ src_len = src->strlen; if (in_place) { result = src; } else { result = dest; } if (!src_len) { result->charset = Parrot_unicode_charset_ptr; result->encoding = Parrot_ucs2_encoding_ptr; result->strlen = result->bufused = 0; return result; } /* u_strFromUTF8(UChar *dest, int32_t destCapacity, int32_t *pDestLength, const char *src, int32_t srcLength, UErrorCode *pErrorCode); */ #if PARROT_HAS_ICU if (in_place) { /* need intermediate memory */ p = (UChar *)mem_sys_allocate(src_len * sizeof (UChar)); } else { Parrot_gc_reallocate_string_storage(interp, dest, sizeof (UChar) * src_len); p = (UChar *)dest->strstart; } if (src->charset == Parrot_iso_8859_1_charset_ptr || src->charset == Parrot_ascii_charset_ptr) { for (dest_len = 0; dest_len < (int)src->strlen; ++dest_len) { p[dest_len] = (UChar)((unsigned char*)src->strstart)[dest_len]; } } else { err = U_ZERO_ERROR; u_strFromUTF8(p, src_len, &dest_len, src->strstart, src->bufused, &err); if (!U_SUCCESS(err)) { /* * have to resize - required len in UChars is in dest_len */ if (in_place) p = (UChar *)mem_sys_realloc(p, dest_len * sizeof (UChar)); else { result->bufused = dest_len * sizeof (UChar); Parrot_gc_reallocate_string_storage(interp, dest, sizeof (UChar) * dest_len); p = (UChar *)dest->strstart; } u_strFromUTF8(p, dest_len, &dest_len, src->strstart, src->bufused, &err); PARROT_ASSERT(U_SUCCESS(err)); } } result->bufused = dest_len * sizeof (UChar); if (in_place) { Parrot_gc_reallocate_string_storage(interp, src, src->bufused); memcpy(src->strstart, p, src->bufused); mem_sys_free(p); } result->charset = Parrot_unicode_charset_ptr; result->encoding = Parrot_utf16_encoding_ptr; result->strlen = src_len; /* downgrade if possible */ if (dest_len == (int)src->strlen) result->encoding = Parrot_ucs2_encoding_ptr; return result; #else Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR, "no ICU lib loaded"); #endif }