[svn:parrot] r47505 - in branches/dynop_mapping: include/parrot src
plobsing at svn.parrot.org
plobsing at svn.parrot.org
Wed Jun 9 08:35:08 UTC 2010
Author: plobsing
Date: Wed Jun 9 08:35:08 2010
New Revision: 47505
URL: https://trac.parrot.org/parrot/changeset/47505
Log:
implement bytecode packing/unpacking code to support per-segment mappings
Modified:
branches/dynop_mapping/include/parrot/packfile.h
branches/dynop_mapping/src/packfile.c
Modified: branches/dynop_mapping/include/parrot/packfile.h
==============================================================================
--- branches/dynop_mapping/include/parrot/packfile.h Wed Jun 9 08:22:20 2010 (r47504)
+++ branches/dynop_mapping/include/parrot/packfile.h Wed Jun 9 08:35:08 2010 (r47505)
@@ -250,16 +250,29 @@
opcode_t const_count;
PackFile_Constant **constants;
PackFile_ByteCode *code; /* where this segment belongs to */
-
PMC *string_hash; /* Hash for lookup strings and numbers */
} PackFile_ConstTable;
+typedef struct PackFile_ByteCode_OpMappingEntry {
+ op_lib_t *lib; /* library for this entry */
+ opcode_t n_ops; /* number of ops used */
+ opcode_t *lib_ops; /* indices of ops within the library */
+} PackFile_ByteCode_OpMappingEntry;
+
+typedef struct PackFile_ByteCode_OpMapping {
+ opcode_t n_libs; /* number of library entries */
+ PackFile_ByteCode_OpMappingEntry *libs; /* opcode libraries used by this segment */
+} PackFile_ByteCode_OpMapping;
+
struct PackFile_ByteCode {
- PackFile_Segment base;
- struct PackFile_Debug *debugs;
- PackFile_ConstTable *const_table;
- PackFile_FixupTable *fixups;
+ PackFile_Segment base;
+ struct PackFile_Debug *debugs;
+ PackFile_ConstTable *const_table;
+ PackFile_FixupTable *fixups;
struct PackFile_Annotations *annotations;
+ PackFile_ByteCode_OpMapping op_mapping; /* opcode mapping information */
+ size_t op_count; /* number of ops in the func table */
+ op_func_t *op_func_table; /* opcode dispatch table */
};
typedef struct PackFile_DebugFilenameMapping {
Modified: branches/dynop_mapping/src/packfile.c
==============================================================================
--- branches/dynop_mapping/src/packfile.c Wed Jun 9 08:22:20 2010 (r47504)
+++ branches/dynop_mapping/src/packfile.c Wed Jun 9 08:35:08 2010 (r47505)
@@ -25,15 +25,17 @@
*/
#include "parrot/parrot.h"
+#include "parrot/packfile.h"
#include "parrot/embed.h"
#include "parrot/extend.h"
-#include "parrot/packfile.h"
+#include "parrot/dynext.h"
#include "parrot/runcore_api.h"
#include "../compilers/imcc/imc.h"
#include "packfile.str"
#include "pmc/pmc_sub.h"
#include "pmc/pmc_key.h"
#include "pmc/pmc_callcontext.h"
+#include "pmc/pmc_parrotlibrary.h"
/* HEADERIZER HFILE: include/parrot/packfile.h */
@@ -55,6 +57,31 @@
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
+static opcode_t * byte_code_pack(PARROT_INTERP,
+ ARGMOD(PackFile_Segment *self),
+ ARGOUT(opcode_t *cursor))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ FUNC_MODIFIES(*self)
+ FUNC_MODIFIES(*cursor);
+
+static size_t byte_code_packed_size(SHIM_INTERP,
+ ARGIN(PackFile_Segment *self))
+ __attribute__nonnull__(2);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static opcode_t * byte_code_unpack(PARROT_INTERP,
+ ARGMOD(PackFile_Segment *self),
+ ARGIN(const opcode_t *cursor))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ FUNC_MODIFIES(*self);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
static PackFile_Constant * clone_constant(PARROT_INTERP,
ARGIN(PackFile_Constant *old_const))
__attribute__nonnull__(1)
@@ -352,6 +379,16 @@
, PARROT_ASSERT_ARG(self))
#define ASSERT_ARGS_byte_code_new __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_byte_code_pack __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(self) \
+ , PARROT_ASSERT_ARG(cursor))
+#define ASSERT_ARGS_byte_code_packed_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(self))
+#define ASSERT_ARGS_byte_code_unpack __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(self) \
+ , PARROT_ASSERT_ARG(cursor))
#define ASSERT_ARGS_clone_constant __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(old_const))
@@ -1619,7 +1656,8 @@
pf_register_standard_funcs(PARROT_INTERP, ARGMOD(PackFile *pf))
{
ASSERT_ARGS(pf_register_standard_funcs)
- PackFile_funcs dirf = {
+
+ static const PackFile_funcs dirf = {
directory_new,
directory_destroy,
directory_packed_size,
@@ -1628,7 +1666,7 @@
directory_dump
};
- PackFile_funcs defaultf = {
+ static const PackFile_funcs defaultf = {
PackFile_Segment_new,
(PackFile_Segment_destroy_func_t) NULLfunc,
(PackFile_Segment_packed_size_func_t) NULLfunc,
@@ -1637,7 +1675,7 @@
default_dump
};
- PackFile_funcs fixupf = {
+ static const PackFile_funcs fixupf = {
fixup_new,
fixup_destroy,
fixup_packed_size,
@@ -1646,7 +1684,7 @@
default_dump
};
- PackFile_funcs constf = {
+ static const PackFile_funcs constf = {
const_new,
const_destroy,
PackFile_ConstTable_pack_size,
@@ -1655,16 +1693,16 @@
default_dump
};
- PackFile_funcs bytef = {
+ static const PackFile_funcs bytef = {
byte_code_new,
byte_code_destroy,
- (PackFile_Segment_packed_size_func_t) NULLfunc,
- (PackFile_Segment_pack_func_t) NULLfunc,
- (PackFile_Segment_unpack_func_t) NULLfunc,
+ byte_code_packed_size,
+ byte_code_pack,
+ byte_code_unpack,
default_dump
};
- const PackFile_funcs debugf = {
+ static const PackFile_funcs debugf = {
pf_debug_new,
pf_debug_destroy,
pf_debug_packed_size,
@@ -1673,7 +1711,7 @@
pf_debug_dump
};
- const PackFile_funcs annotationf = {
+ static const PackFile_funcs annotationf = {
PackFile_Annotations_new,
PackFile_Annotations_destroy,
PackFile_Annotations_packed_size,
@@ -2582,9 +2620,16 @@
ASSERT_ARGS(byte_code_destroy)
PackFile_ByteCode * const byte_code = (PackFile_ByteCode *)self;
- byte_code->fixups = NULL;
- byte_code->const_table = NULL;
- byte_code->debugs = NULL;
+ if (byte_code->op_func_table)
+ mem_gc_free(interp, byte_code->op_func_table);
+ if (byte_code->op_mapping.libs)
+ mem_gc_free(interp, byte_code->op_mapping.libs);
+
+ byte_code->fixups = NULL;
+ byte_code->const_table = NULL;
+ byte_code->debugs = NULL;
+ byte_code->op_mapping.libs = NULL;
+ byte_code->op_func_table = NULL;
}
@@ -2610,6 +2655,139 @@
return (PackFile_Segment *) byte_code;
}
+static size_t
+byte_code_packed_size(SHIM_INTERP, ARGIN(PackFile_Segment *self))
+{
+ ASSERT_ARGS(byte_code_packed_size)
+ PackFile_ByteCode * const byte_code = (PackFile_ByteCode *)self;
+ size_t size;
+ int i;
+
+ size = 1; /* n_libs */
+
+ for (i = 0; i < byte_code->op_mapping.n_libs; i++) {
+ PackFile_ByteCode_OpMappingEntry * const entry = &byte_code->op_mapping.libs[i];
+
+ /* dynoplib data */
+ size += PF_size_cstring(entry->lib->name);
+ size += 3; /* major + minor + patch */
+
+ /* op entries */
+ size += 1; /* n_ops */
+ size += entry->n_ops; /* lib_ops */
+ }
+
+ return size;
+}
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static opcode_t *
+byte_code_pack(PARROT_INTERP, ARGMOD(PackFile_Segment *self), ARGOUT(opcode_t *cursor))
+{
+ ASSERT_ARGS(byte_code_pack)
+ PackFile_ByteCode * const byte_code = (PackFile_ByteCode *)self;
+ int i, j;
+
+ *cursor++ = byte_code->op_mapping.n_libs;
+
+ for (i = 0; i < byte_code->op_mapping.n_libs; i++) {
+ PackFile_ByteCode_OpMappingEntry * const entry = &byte_code->op_mapping.libs[i];
+
+ /* dynoplib data */
+ cursor = PF_store_cstring(cursor, entry->lib->name);
+ *cursor++ = entry->lib->major_version;
+ *cursor++ = entry->lib->minor_version;
+ *cursor++ = entry->lib->patch_version;
+
+ /* op entries */
+ *cursor++ = entry->n_ops;
+ for (j = 0; j < entry->n_ops; j++)
+ *cursor++ = entry->lib_ops[j];
+ }
+
+ return cursor;
+}
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static opcode_t *
+byte_code_unpack(PARROT_INTERP, ARGMOD(PackFile_Segment *self), ARGIN(const opcode_t *cursor))
+{
+ ASSERT_ARGS(byte_code_unpack)
+ PackFile_ByteCode * const byte_code = (PackFile_ByteCode *)self;
+ int i;
+
+ byte_code->op_count = 0;
+ byte_code->op_func_table = NULL;
+
+ byte_code->op_mapping.n_libs = PF_fetch_opcode(self->pf, &cursor);
+ byte_code->op_mapping.libs = mem_gc_allocate_n_zeroed_typed(interp,
+ byte_code->op_mapping.n_libs,
+ PackFile_ByteCode_OpMappingEntry);
+
+ for (i = 0; i < byte_code->op_mapping.n_libs; i++) {
+ PackFile_ByteCode_OpMappingEntry * const entry = &byte_code->op_mapping.libs[i];
+
+ /* dynoplib data */
+ {
+ char * const lib_name = PF_fetch_cstring(interp, self->pf, &cursor);
+ const opcode_t major = PF_fetch_opcode(self->pf, &cursor);
+ const opcode_t minor = PF_fetch_opcode(self->pf, &cursor);
+ const opcode_t patch = PF_fetch_opcode(self->pf, &cursor);
+ const PMC *lib_pmc = Parrot_load_lib(interp,
+ Parrot_str_new(interp, lib_name, 0),
+ NULL);
+
+ mem_gc_free(interp, lib_name);
+
+ {
+ /* XXX
+ * broken encapsulation => should make this data easier to access somehow
+ */
+ void *oplib_init;
+ op_lib_t *(*oplib_init_f)(PARROT_INTERP, long init);
+ GETATTR_ParrotLibrary_oplib_init(interp, lib_pmc, oplib_init);
+ oplib_init_f = D2FPTR(oplib_init);
+ entry->lib = oplib_init_f(interp, 1);
+ }
+
+ if (entry->lib->major_version != major
+ || entry->lib->minor_version != minor
+ || entry->lib->patch_version != patch)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
+ "Incompatible versions of `%s' library. Found %d.%d.%d but loaded %d.%d.%d",
+ entry->lib->name, major, minor, patch, entry->lib->major_version,
+ entry->lib->minor_version, entry->lib->patch_version);
+ }
+
+ /* op entries */
+ {
+ int j;
+ const int old_op_count = byte_code->op_count;
+ byte_code->op_count += entry->n_ops = PF_fetch_opcode(self->pf, &cursor);
+
+ if (!byte_code->op_func_table)
+ byte_code->op_func_table = mem_gc_allocate_n_typed(interp,
+ byte_code->op_count, op_func_t);
+ else
+ mem_gc_realloc_n_typed(interp, byte_code->op_func_table,
+ byte_code->op_count, op_func_t);
+
+ for (j = 0; j < entry->n_ops; j++) {
+ int op = PF_fetch_opcode(self->pf, &cursor);
+ if (0 < op || op < entry->lib->op_count)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "opcode index out of bounds on library `%s'. Found %d, expection 0 to %d.",
+ entry->lib->name, op, entry->lib->op_count);
+ entry->lib_ops[j] = op;
+ byte_code->op_func_table[old_op_count + j] = entry->lib->op_func_table[j];
+ }
+ }
+ }
+
+ return cursor;
+}
/*
More information about the parrot-commits
mailing list