Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

merge dynop_mapping branch

git-svn-id: https://svn.parrot.org/parrot/trunk@48412 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information...
commit 15e99572cbb6eb3baad027d2dd1975f300636478 1 parent bd2f553
@plobsing plobsing authored
Showing with 2,848 additions and 1,321 deletions.
  1. +1 −1  compilers/imcc/cfg.c
  2. +1 −0  compilers/imcc/imc.c
  3. +1 −1  compilers/imcc/instructions.c
  4. +23 −23 compilers/imcc/optimizer.c
  5. +96 −17 compilers/imcc/pbc.c
  6. +1 −1  compilers/imcc/pcc.c
  7. +8 −6 compilers/imcc/symreg.c
  8. +2 −2 compilers/imcc/unit.h
  9. +7 −3 compilers/opsc/src/Ops/Emitter.pm
  10. +3 −1 compilers/opsc/src/Ops/Trans/C.pm
  11. +1 −1  config/gen/config_h/config_h.in
  12. +1 −1  ext/nqp-rx/src/stage0/Regex-s0.pir
  13. +4 −5 include/parrot/call.h
  14. +11 −8 include/parrot/op.h
  15. +22 −6 include/parrot/packfile.h
  16. +1 −1  include/parrot/runcore_api.h
  17. +9 −6 src/debug.c
  18. +12 −5 src/embed.c
  19. +2,173 −1,086 src/ops/core_ops.c
  20. +263 −14 src/packfile.c
  21. +7 −7 src/pbc_dump.c
  22. +98 −30 src/pbc_merge.c
  23. +3 −29 src/pmc/opcode.pmc
  24. +64 −48 src/pmc/oplib.pmc
  25. +2 −1  src/pmc/sub.pmc
  26. +10 −4 src/runcore/main.c
  27. +1 −1  src/runcore/profiling.c
  28. +1 −1  src/runcore/trace.c
  29. +2 −2 src/sub.c
  30. BIN  t/examples/pir.t
  31. BIN  t/native_pbc/annotations.pbc
  32. BIN  t/native_pbc/integer.pbc
  33. BIN  t/native_pbc/integer_2.pbc
  34. BIN  t/native_pbc/number.pbc
  35. BIN  t/native_pbc/number_1.pbc
  36. BIN  t/native_pbc/number_2.pbc
  37. BIN  t/native_pbc/string.pbc
  38. BIN  t/native_pbc/string_1.pbc
  39. BIN  t/native_pbc/string_2.pbc
  40. +17 −9 t/pmc/oplib.t
  41. +3 −1 t/pmc/pmc.t
View
2  compilers/imcc/cfg.c
@@ -463,7 +463,7 @@ bb_findadd_edge(PARROT_INTERP, ARGMOD(IMC_Unit *unit), ARGIN(Basic_block *from),
if (r && (r->type & VTADDRESS) && r->first_ins)
bb_add_edge(interp, unit, from, unit->bb_list[r->first_ins->bbindex]);
else {
- IMCC_debug(interp, DEBUG_CFG, "register branch %I ", from->end);
+ IMCC_debug(interp, DEBUG_CFG, "register branch %d ", from->end);
for (ins = from->end; ins; ins = ins->prev) {
if ((ins->type & ITBRANCH)
&& STREQ(ins->opname, "set_addr")
View
1  compilers/imcc/imc.c
@@ -97,6 +97,7 @@ imc_compile_all_units(PARROT_INTERP)
}
IMCC_INFO(interp)->imc_units = NULL;
+ IMCC_INFO(interp)->cur_unit = NULL;
IMCC_INFO(interp)->last_unit = NULL;
}
View
2  compilers/imcc/instructions.c
@@ -826,7 +826,7 @@ emit_flush(PARROT_INTERP, ARGIN_NULLOK(void *param), ARGIN(IMC_Unit *unit))
(emitters[emitter]).new_sub(interp, param, unit);
for (ins = unit->instructions; ins; ins = ins->next) {
- IMCC_debug(interp, DEBUG_IMC, "emit %I\n", ins);
+ IMCC_debug(interp, DEBUG_IMC, "emit %d\n", ins);
(emitters[emitter]).emit(interp, param, unit, ins);
}
View
46 compilers/imcc/optimizer.c
@@ -461,12 +461,12 @@ strength_reduce(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
ins->opnum == PARROT_OP_mul_n_nc_n) &&
(ins->symregs[0] == ins->symregs[1] ||
ins->symregs[0] == ins->symregs[2]))) {
- IMCC_debug(interp, DEBUG_OPT1, "opt1 %I => ", ins);
+ IMCC_debug(interp, DEBUG_OPT1, "opt1 %d => ", ins);
if (ins->symregs[0] == ins->symregs[1]) {
ins->symregs[1] = ins->symregs[2];
}
tmp = INS(interp, unit, ins->opname, "", ins->symregs, 2, 0, 0);
- IMCC_debug(interp, DEBUG_OPT1, "%I\n", tmp);
+ IMCC_debug(interp, DEBUG_OPT1, "%d\n", tmp);
subst_ins(unit, ins, tmp, 1);
ins = tmp;
changes = 1;
@@ -497,7 +497,7 @@ strength_reduce(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
ins->opnum == PARROT_OP_div_n_nc ||
ins->opnum == PARROT_OP_fdiv_n_nc) &&
atof(ins->symregs[1]->name) == 1.0)) {
- IMCC_debug(interp, DEBUG_OPT1, "opt1 %I => ", ins);
+ IMCC_debug(interp, DEBUG_OPT1, "opt1 %d => ", ins);
ins = delete_ins(unit, ins);
if (ins)
ins = ins->prev ? ins->prev : unit->instructions;
@@ -519,7 +519,7 @@ strength_reduce(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
|| ((ins->opnum == PARROT_OP_add_n_nc ||
ins->opnum == PARROT_OP_sub_n_nc) &&
atof(ins->symregs[1]->name) == 1.0)) {
- IMCC_debug(interp, DEBUG_OPT1, "opt1 %I => ", ins);
+ IMCC_debug(interp, DEBUG_OPT1, "opt1 %d => ", ins);
--ins->symregs[1]->use_count;
if (ins->opnum == PARROT_OP_add_i_ic ||
ins->opnum == PARROT_OP_add_n_nc)
@@ -527,7 +527,7 @@ strength_reduce(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
else
tmp = INS(interp, unit, "dec", "", ins->symregs, 1, 0, 0);
subst_ins(unit, ins, tmp, 1);
- IMCC_debug(interp, DEBUG_OPT1, "%I\n", tmp);
+ IMCC_debug(interp, DEBUG_OPT1, "%d\n", tmp);
ins = tmp;
changes = 1;
continue;
@@ -570,7 +570,7 @@ strength_reduce(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
atof(ins->symregs[2]->name) == 1.0)
|| (ins->opnum == PARROT_OP_mul_n_nc_n &&
atof(ins->symregs[1]->name) == 1.0)) {
- IMCC_debug(interp, DEBUG_OPT1, "opt1 %I => ", ins);
+ IMCC_debug(interp, DEBUG_OPT1, "opt1 %d => ", ins);
if (ins->symregs[1]->type == VTCONST) {
--ins->symregs[1]->use_count;
ins->symregs[1] = ins->symregs[2];
@@ -579,7 +579,7 @@ strength_reduce(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
--ins->symregs[2]->use_count;
}
tmp = INS(interp, unit, "set", "", ins->symregs, 2, 0, 0);
- IMCC_debug(interp, DEBUG_OPT1, "%I\n", tmp);
+ IMCC_debug(interp, DEBUG_OPT1, "%d\n", tmp);
subst_ins(unit, ins, tmp, 1);
ins = tmp;
changes = 1;
@@ -600,14 +600,14 @@ strength_reduce(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
|| ((ins->opnum == PARROT_OP_mul_n_nc_n ||
ins->opnum == PARROT_OP_mul_n_nc) &&
(f = atof(ins->symregs[1]->name), FLOAT_IS_ZERO(f)))) {
- IMCC_debug(interp, DEBUG_OPT1, "opt1 %I => ", ins);
+ IMCC_debug(interp, DEBUG_OPT1, "opt1 %d => ", ins);
r = mk_const(interp, "0", ins->symregs[0]->set);
--ins->symregs[1]->use_count;
if (ins->opsize == 4)
--ins->symregs[2]->use_count;
ins->symregs[1] = r;
tmp = INS(interp, unit, "set", "", ins->symregs, 2, 0, 0);
- IMCC_debug(interp, DEBUG_OPT1, "%I\n", tmp);
+ IMCC_debug(interp, DEBUG_OPT1, "%d\n", tmp);
subst_ins(unit, ins, tmp, 1);
ins = tmp;
changes = 1;
@@ -621,11 +621,11 @@ strength_reduce(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
|| (ins->opnum == PARROT_OP_set_n_nc &&
(f = atof(ins->symregs[1]->name), FLOAT_IS_ZERO(f)) &&
ins->symregs[1]->name[0] != '-')) {
- IMCC_debug(interp, DEBUG_OPT1, "opt1 %I => ", ins);
+ IMCC_debug(interp, DEBUG_OPT1, "opt1 %d => ", ins);
--ins->symregs[1]->use_count;
tmp = INS(interp, unit, "null", "", ins->symregs, 1, 0, 0);
subst_ins(unit, ins, tmp, 1);
- IMCC_debug(interp, DEBUG_OPT1, "%I\n", tmp);
+ IMCC_debug(interp, DEBUG_OPT1, "%d\n", tmp);
ins = tmp;
changes = 1;
continue;
@@ -677,7 +677,7 @@ constant_propagation(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
Instruction *ins2;
IMCC_debug(interp, DEBUG_OPT2,
- "propagating constant %I => \n", ins);
+ "propagating constant %d => \n", ins);
for (ins2 = ins->next; ins2; ins2 = ins2->next) {
int i;
if (ins2->bbindex != ins->bbindex)
@@ -694,7 +694,7 @@ constant_propagation(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
SymReg *old;
IMCC_debug(interp, DEBUG_OPT2,
- "\tpropagating into %I register %i",
+ "\tpropagating into %d register %i",
ins2, i);
old = ins2->symregs[i];
ins2->symregs[i] = c;
@@ -708,7 +708,7 @@ constant_propagation(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
subst_ins(unit, ins2, tmp, 1);
any = 1;
IMCC_debug(interp, DEBUG_OPT2,
- " reduced to %I\n", tmp);
+ " reduced to %d\n", tmp);
ins2 = prev->next;
}
}
@@ -726,7 +726,7 @@ constant_propagation(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
ins2->opnum = op;
any = 1;
IMCC_debug(interp, DEBUG_OPT2,
- " -> %I\n", ins2);
+ " -> %d\n", ins2);
}
}
}
@@ -777,7 +777,7 @@ IMCC_subst_constants_umix(PARROT_INTERP, ARGMOD(IMC_Unit *unit), ARGIN(const cha
strcpy(b, r[1]->name);
r[1] = mk_const(interp, b, 'N');
tmp = INS(interp, unit, name, "", r, 2, 0, 0);
- IMCC_debug(interp, DEBUG_OPT1, "%I\n", tmp);
+ IMCC_debug(interp, DEBUG_OPT1, "%d\n", tmp);
}
}
return tmp;
@@ -1067,7 +1067,7 @@ IMCC_subst_constants(PARROT_INTERP, ARGMOD(IMC_Unit *unit), ARGIN(const char *na
tmp = INS(interp, unit, "set", "", r, 2, 0, 0);
}
if (tmp) {
- IMCC_debug(interp, DEBUG_OPT1, "%I\n", tmp);
+ IMCC_debug(interp, DEBUG_OPT1, "%d\n", tmp);
}
*ok = 1;
return tmp;
@@ -1116,7 +1116,7 @@ branch_branch(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
!STREQ(next->symregs[0]->name, get_branch_reg(ins)->name)) {
const int regno = get_branch_regno(ins);
IMCC_debug(interp, DEBUG_OPT1,
- "found branch to branch '%s' %I\n",
+ "found branch to branch '%s' %d\n",
r->first_ins->symregs[0]->name, next);
unit->ostat.branch_branch++;
if (regno < 0)
@@ -1209,7 +1209,7 @@ branch_reorg(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
start->prev = ins;
IMCC_debug(interp, DEBUG_OPT1,
- "found branch to reorganize '%s' %I\n",
+ "found branch to reorganize '%s' %d\n",
r->first_ins->symregs[0]->name, ins);
/* unconditional jump can be eliminated */
@@ -1507,7 +1507,7 @@ dead_code_remove(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
for (ins = bb->start; ins && ins->bbindex == bbi;) {
IMCC_debug(interp, DEBUG_OPT1,
- "\tins deleted (dead block) %I\n", ins);
+ "\tins deleted (dead block) %d\n", ins);
ins = delete_ins(unit, ins);
unit->ostat.deleted_ins++;
changed++;
@@ -1525,7 +1525,7 @@ dead_code_remove(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
if ((last->type & IF_goto) && !(ins->type & ITLABEL) &&
STREQ(last->opname, "branch")) {
IMCC_debug(interp, DEBUG_OPT1,
- "unreachable ins deleted (after branch) %I\n", ins);
+ "unreachable ins deleted (after branch) %d\n", ins);
ins = delete_ins(unit, ins);
unit->ostat.deleted_ins++;
changed++;
@@ -1538,7 +1538,7 @@ dead_code_remove(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
if (ins && last && (last->type & IF_goto) && (ins->type & ITLABEL) &&
STREQ(last->opname, "branch") &&
STREQ(last->symregs[0]->name, ins->symregs[0]->name)) {
- IMCC_debug(interp, DEBUG_OPT1, "dead branch deleted %I\n", ins);
+ IMCC_debug(interp, DEBUG_OPT1, "dead branch deleted %d\n", ins);
ins = delete_ins(unit, last);
unit->ostat.deleted_ins++;
changed++;
@@ -1572,7 +1572,7 @@ used_once(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
if (ins->symregs) {
SymReg * const r = ins->symregs[0];
if (r && (r->use_count == 1 && r->lhs_use_count == 1)) {
- IMCC_debug(interp, DEBUG_OPT2, "used once '%I' deleted\n", ins);
+ IMCC_debug(interp, DEBUG_OPT2, "used once '%d' deleted\n", ins);
ins = delete_ins(unit, ins);
/* find previous instruction or first instruction of this CU
View
113 compilers/imcc/pbc.c
@@ -666,7 +666,7 @@ get_code_size(PARROT_INTERP, ARGIN(const IMC_Unit *unit), ARGOUT(size_t *src_lin
(*src_lines)++;
if (ins->opnum < 0)
IMCC_fatal(interp, 1, "get_code_size: "
- "no opnum ins#%d %I\n",
+ "no opnum ins#%d %d\n",
ins->index, ins);
if (ins->opnum == PARROT_OP_set_p_pc) {
@@ -691,6 +691,85 @@ get_code_size(PARROT_INTERP, ARGIN(const IMC_Unit *unit), ARGOUT(size_t *src_lin
/*
+=item C<opcode_t bytecode_map_op(PARROT_INTERP, opcode_t op)>
+
+Lookup the mapping of an op for the current bytecode segment or make one if
+none exists.
+
+=cut
+
+*/
+
+static
+opcode_t
+bytecode_map_op(PARROT_INTERP, opcode_t op) {
+ int i;
+ op_info_t *info = &interp->op_info_table[op];
+ op_lib_t *lib = info->lib;
+ op_func_t op_func = interp->op_func_table[op];
+ PackFile_ByteCode *bc = interp->code;
+ PackFile_ByteCode_OpMappingEntry *om;
+
+ for (i = 0; i < bc->op_mapping.n_libs; i++) {
+ if (lib == bc->op_mapping.libs[i].lib) {
+ om = &bc->op_mapping.libs[i];
+ goto found_lib;
+ }
+ }
+
+ /* library not yet mapped */
+ bc->op_mapping.n_libs++;
+ bc->op_mapping.libs = mem_gc_realloc_n_typed_zeroed(interp, bc->op_mapping.libs,
+ bc->op_mapping.n_libs, bc->op_mapping.n_libs - 1,
+ PackFile_ByteCode_OpMappingEntry);
+
+ /* initialize a new lib entry */
+ om = &bc->op_mapping.libs[bc->op_mapping.n_libs - 1];
+ om->lib = lib;
+ om->n_ops = 0;
+ om->lib_ops = mem_gc_allocate_n_zeroed_typed(interp, 0, opcode_t);
+ om->table_ops = mem_gc_allocate_n_zeroed_typed(interp, 0, opcode_t);
+
+ found_lib:
+ for (i = 0; i < om->n_ops; i++) {
+ if (bc->op_func_table[om->table_ops[i]] == op_func)
+ return om->table_ops[i];
+ }
+
+ /* op not yet mapped */
+ bc->op_count++;
+ bc->op_func_table =
+ mem_gc_realloc_n_typed_zeroed(interp, bc->op_func_table, bc->op_count, bc->op_count,
+ op_func_t);
+ bc->op_func_table[bc->op_count - 1] = op_func;
+ bc->op_info_table =
+ mem_gc_realloc_n_typed_zeroed(interp, bc->op_info_table, bc->op_count, bc->op_count,
+ op_info_t *);
+ bc->op_info_table[bc->op_count - 1] = info;
+
+ /* initialize new op mapping */
+ om->n_ops++;
+
+ om->lib_ops =
+ mem_gc_realloc_n_typed_zeroed(interp, om->lib_ops, om->n_ops, om->n_ops - 1, opcode_t);
+ for (i = 0; i < lib->op_count; i++) {
+ if (lib->op_func_table[i] == op_func) {
+ om->lib_ops[om->n_ops - 1] = i;
+ break;
+ }
+ }
+ PARROT_ASSERT(om->lib_ops[om->n_ops - 1] || !i);
+
+ om->table_ops =
+ mem_gc_realloc_n_typed_zeroed(interp, om->table_ops, om->n_ops, om->n_ops - 1, opcode_t);
+ om->table_ops[om->n_ops - 1] = bc->op_count - 1;
+
+ return bc->op_count - 1;
+}
+
+
+/*
+
=item C<static subs_t * find_global_label(PARROT_INTERP, const char *name, const
subs_t *sym, int *pc)>
@@ -836,7 +915,7 @@ fixup_globals(PARROT_INTERP)
const int op = interp->op_lib->op_code(interp, "find_sub_not_null_p_sc", 1);
PARROT_ASSERT(op);
- interp->code->base.data[addr] = op;
+ interp->code->base.data[addr] = bytecode_map_op(interp, op);
if (nam->color < 0)
nam->color = add_const_str(interp, IMCC_string_from_reg(interp, nam));
@@ -1437,7 +1516,7 @@ add_const_pmc_sub(PARROT_INTERP, ARGMOD(SymReg *r), size_t offs, size_t end)
sub->namespace_name = ns_pmc;
sub->start_offs = offs;
sub->end_offs = end;
- sub->HLL_id = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp));
+ sub->HLL_id = unit->hll_id;
for (i = 0; i < 4; ++i)
sub->n_regs_used[i] = unit->n_regs_used[i];
@@ -1643,22 +1722,20 @@ build_key(PARROT_INTERP, ARGIN(SymReg *key_reg))
for (key_length = 0; reg ; reg = reg->nextkey, key_length++) {
SymReg *r = reg;
- int type;
if (key_length >= MAX_KEY_LEN)
IMCC_fatal(interp, 1, "build_key:"
"Key too long, increase MAX_KEY_LEN.\n");
- /* if key is a register, the original sym is in r->reg */
- type = r->type;
-
- if (r->reg)
- r = r->reg;
-
- switch (type) {
+ switch (r->type) {
case VTIDENTIFIER: /* P[S0] */
case VTPASM: /* P[S0] */
case VTREG: /* P[S0] */
+
+ /* if key is a register, the original sym is in r->reg */
+ if (r->reg)
+ r = r->reg;
+
if (r->set == 'I')
*pc++ = PARROT_ARG_I; /* register type */
else if (r->set == 'S')
@@ -1678,7 +1755,9 @@ build_key(PARROT_INTERP, ARGIN(SymReg *key_reg))
" keypart reg %s %c%d\n",
r->name, r->set, (int)r->color);
break;
+
case VT_CONSTP:
+ r = r->reg;
case VTCONST:
case VTCONST|VT_ENCODED:
switch (r->set) {
@@ -1711,7 +1790,7 @@ build_key(PARROT_INTERP, ARGIN(SymReg *key_reg))
break;
default:
IMCC_fatal(interp, 1, "build_key: "
- "unknown type 0x%x on %s\n", type, r->name);
+ "unknown type 0x%x on %s\n", r->type, r->name);
}
}
@@ -1969,7 +2048,7 @@ add_1_const(PARROT_INTERP, ARGMOD(SymReg *r))
SymReg *key = r;
for (r = r->nextkey; r; r = r->nextkey)
- if (r->type & VTCONST)
+ if (r->type & (VTCONST|VT_CONSTP))
add_1_const(interp, r);
build_key(interp, key);
}
@@ -2351,15 +2430,15 @@ e_pbc_emit(PARROT_INTERP, SHIM(void *param), ARGIN(const IMC_Unit *unit),
op = (opcode_t)ins->opnum;
- /* Start generating the bytecode */
- *(IMCC_INFO(interp)->pc)++ = op;
-
/* Get the info for that opcode */
op_info = &interp->op_info_table[op];
IMCC_debug(interp, DEBUG_PBC, "%d %s", IMCC_INFO(interp)->npc,
op_info->full_name);
+ /* Start generating the bytecode */
+ *(IMCC_INFO(interp)->pc)++ = bytecode_map_op(interp, op);
+
for (i = 0; i < op_info->op_count-1; i++) {
switch (op_info->types[i]) {
case PARROT_ARG_IC:
@@ -2429,7 +2508,7 @@ e_pbc_emit(PARROT_INTERP, SHIM(void *param), ARGIN(const IMC_Unit *unit),
}
}
- IMCC_debug(interp, DEBUG_PBC, "\t%I\n", ins);
+ IMCC_debug(interp, DEBUG_PBC, "\t%d\n", ins);
IMCC_INFO(interp)->npc += ins->opsize;
}
View
2  compilers/imcc/pcc.c
@@ -471,7 +471,7 @@ expand_pcc_sub(PARROT_INTERP, ARGMOD(IMC_Unit *unit), ARGIN(Instruction *ins))
tmp = INS(interp, unit, "returncc", NULL, regs, 0, 0, 0);
}
- IMCC_debug(interp, DEBUG_IMC, "add sub ret - %I\n", tmp);
+ IMCC_debug(interp, DEBUG_IMC, "add sub ret - %d\n", tmp);
insert_ins(unit, unit->last_ins, tmp);
}
}
View
14 compilers/imcc/symreg.c
@@ -298,7 +298,7 @@ SymReg *
mk_symreg(PARROT_INTERP, ARGIN(const char *name), int t)
{
ASSERT_ARGS(mk_symreg)
- IMC_Unit * const unit = IMCC_INFO(interp)->last_unit;
+ IMC_Unit * const unit = IMCC_INFO(interp)->cur_unit;
/* Check for the condition that fires up a segfault in TT #162 */
PARROT_ASSERT(unit != NULL);
@@ -393,7 +393,7 @@ SymReg *
mk_pcc_sub(PARROT_INTERP, ARGIN(const char *name), int proto)
{
ASSERT_ARGS(mk_pcc_sub)
- IMC_Unit * const unit = IMCC_INFO(interp)->last_unit;
+ IMC_Unit * const unit = IMCC_INFO(interp)->cur_unit;
SymReg * const r = _mk_symreg(interp, &unit->hash, name, proto);
r->type = VT_PCC_SUB;
@@ -407,7 +407,7 @@ mk_pcc_sub(PARROT_INTERP, ARGIN(const char *name), int proto)
=item C<void add_namespace(PARROT_INTERP, IMC_Unit *unit)>
-Add the current namespace to a sub declaration.
+Add the current namespace (and HLL id) to a sub declaration.
=cut
@@ -419,6 +419,8 @@ add_namespace(PARROT_INTERP, ARGMOD(IMC_Unit *unit))
ASSERT_ARGS(add_namespace)
SymReg * const ns = IMCC_INFO(interp)->cur_namespace;
+ unit->hll_id = Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp));
+
if (!ns)
return;
@@ -647,7 +649,7 @@ mk_ident(PARROT_INTERP, ARGIN(const char *name), int t)
{
ASSERT_ARGS(mk_ident)
char * const fullname = _mk_fullname(interp, IMCC_INFO(interp)->namespace_stack, name);
- SymReg *r = get_sym_by_name(&(IMCC_INFO(interp)->last_unit->hash), name);
+ SymReg *r = get_sym_by_name(&(IMCC_INFO(interp)->cur_unit->hash), name);
if (r && r->set != t)
IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
"syntax error, duplicated IDENTIFIER '%s'\n", fullname);
@@ -1075,7 +1077,7 @@ SymReg *
mk_local_label(PARROT_INTERP, ARGIN(const char *name))
{
ASSERT_ARGS(mk_local_label)
- IMC_Unit * const unit = IMCC_INFO(interp)->last_unit;
+ IMC_Unit * const unit = IMCC_INFO(interp)->cur_unit;
return _mk_address(interp, &unit->hash, name, U_add_uniq_label);
}
@@ -1096,7 +1098,7 @@ SymReg *
mk_label_address(PARROT_INTERP, ARGIN(const char *name))
{
ASSERT_ARGS(mk_label_address)
- IMC_Unit * const unit = IMCC_INFO(interp)->last_unit;
+ IMC_Unit * const unit = IMCC_INFO(interp)->cur_unit;
return _mk_address(interp, &unit->hash, name, U_add_once);
}
View
4 compilers/imcc/unit.h
@@ -69,8 +69,8 @@ struct IMC_Unit {
char *vtable_name; /* vtable name, if any */
char *method_name; /* method name, if any */
char *ns_entry_name; /* ns entry name, if any */
- char *instance_of; /* PMC or class this is an instance of
- * if any */
+ char *instance_of; /* PMC or class this is an instance of if any */
+ INTVAL hll_id; /* HLL ID for this sub */
SymReg *subid; /* Unique subroutine id */
struct imcc_ostat ostat;
View
10 compilers/opsc/src/Ops/Emitter.pm
@@ -217,6 +217,9 @@ method _emit_source_preamble($fh) {
{self.trans.defines(self)}
+/* XXX should be static, but C++ doesn't want to play ball */
+extern op_lib_t {self.bs}op_lib;
+
|);
$fh.print(self.ops_file.preamble);
@@ -230,9 +233,10 @@ method _emit_op_lib_descriptor($fh) {
** op lib descriptor:
*/
-static op_lib_t | ~ self.bs ~ q|op_lib = {| ~ qq|
- "{self.base}", /* name */
- "{self.suffix}", /* suffix */
+/* XXX should be static, but C++ doesn't want to play ball */
+op_lib_t | ~ self.bs ~ q|op_lib = {| ~ qq|
+ "{self.base}_ops", /* name */
+ "{self.suffix}", /* suffix */
$core_type, /* core_type = PARROT_XX_CORE */
0, /* flags */
{self.ops_file.version_major}, /* major_version */
View
4 compilers/opsc/src/Ops/Trans/C.pm
@@ -180,6 +180,7 @@ static op_info_t {self.op_info($emitter)}[{self<num_entries>}] = | ~ q|{
|);
my $index := 0;
+ my $op_lib_ref := '&' ~ $emitter.bs() ~ 'op_lib';
for $emitter.ops_file.ops -> $op {
my $type := sprintf( "PARROT_%s_OP", uc($op.type ?? 'INLINE' !! 'FUNCTION') );
@@ -218,7 +219,8 @@ static op_info_t {self.op_info($emitter)}[{self<num_entries>}] = | ~ q|{
$arg_count,
$arg_types,
$arg_dirs,
- $labels
+ $labels,
+ $op_lib_ref
| ~ '},
',
);
View
2  config/gen/config_h/config_h.in
@@ -150,7 +150,7 @@ typedef void DPOINTER;
#define PARROT_@jitcpu@ 1
/* Oplib and dynamic ops related. */
-#define PARROT_CORE_OPLIB_NAME "core"
+#define PARROT_CORE_OPLIB_NAME "core_ops"
#define PARROT_CORE_OPLIB_INIT Parrot_DynOp_core_@MAJOR@_@MINOR@_@PATCH@
/* ICU. */
View
2  ext/nqp-rx/src/stage0/Regex-s0.pir
@@ -2122,7 +2122,7 @@ An alternate dump output for a Match object and all of its subcaptures.
# vim: expandtab shiftwidth=4 ft=pir:
### .include 'src/PAST/Regex.pir'
-# $Id: Regex.pir 41578 2009-09-30 14:45:23Z pmichaud $
+# $Id$
=head1 NAME
View
9 include/parrot/call.h
@@ -302,12 +302,11 @@ void Parrot_pcc_split_signature_string(
PARROT_ASSERT((sig)->vtable->base_type == enum_class_FixedIntegerArray); \
} while (0)
-/* XXX Remove interp from this */
#define ADD_OP_VAR_PART(interp, seg, pc, n) do { \
- if (*(pc) == PARROT_OP_set_args_pc \
- || *(pc) == PARROT_OP_get_results_pc \
- || *(pc) == PARROT_OP_get_params_pc \
- || *(pc) == PARROT_OP_set_returns_pc) { \
+ if (OPCODE_IS((interp), (seg), *(pc), PARROT_OP_set_args_pc) \
+ || OPCODE_IS((interp), (seg), *(pc), PARROT_OP_get_results_pc) \
+ || OPCODE_IS((interp), (seg), *(pc), PARROT_OP_get_params_pc) \
+ || OPCODE_IS((interp), (seg), *(pc), PARROT_OP_set_returns_pc)) { \
PMC * const sig = (seg)->const_table->constants[(pc)[1]].u.key; \
(n) += VTABLE_elements((interp), sig); \
} \
View
19 include/parrot/op.h
@@ -67,16 +67,19 @@ typedef opcode_t *(*op_func_t)(opcode_t *, PARROT_INTERP);
*/
typedef struct op_info_t {
- const char *name;
- const char *full_name;
- const char *func_name;
- unsigned short jump;
- short op_count; /* Includes opcode as one arg */
- arg_type_t types[PARROT_MAX_ARGS]; /* arg_type_t, 0 = 1st arg */
- arg_dir_t dirs[PARROT_MAX_ARGS]; /* arg_dir_t 0 = 1st arg */
- char labels[PARROT_MAX_ARGS]; /* 0/1 0 = 1st arg */
+ const char *name;
+ const char *full_name;
+ const char *func_name;
+ unsigned short jump;
+ short op_count; /* Includes opcode as one arg */
+ arg_type_t types[PARROT_MAX_ARGS]; /* arg_type_t, 0 = 1st arg */
+ arg_dir_t dirs[PARROT_MAX_ARGS]; /* arg_dir_t 0 = 1st arg */
+ char labels[PARROT_MAX_ARGS]; /* 0/1 0 = 1st arg */
+ struct op_lib_t *lib;
} op_info_t;
+#define OPCODE_IS(interp, seg, opnum, global_opnum) \
+ ((seg)->op_func_table[(opnum)] == (interp)->op_func_table[(global_opnum)])
#endif /* PARROT_OP_H_GUARD */
View
28 include/parrot/packfile.h
@@ -263,16 +263,32 @@ typedef struct PackFile_ConstTable {
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 */
+ opcode_t *table_ops; /* indices of ops within the op table */
+} 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;
- struct PackFile_Annotations *annotations;
+ 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 */
+ op_func_t *save_func_table; /* for when we hijack op_func_table */
+ op_info_t **op_info_table;
};
typedef struct PackFile_DebugFilenameMapping {
View
2  include/parrot/runcore_api.h
@@ -15,7 +15,7 @@ typedef struct runcore_t Parrot_runcore_t;
#include "parrot/parrot.h"
#include "parrot/op.h"
-# define DO_OP(PC, INTERP) ((PC) = (((INTERP)->op_func_table)[*(PC)])((PC), (INTERP)))
+# define DO_OP(PC, INTERP) ((PC) = (((INTERP)->code->op_func_table)[*(PC)])((PC), (INTERP)))
typedef opcode_t * (*runcore_runops_fn_type) (PARROT_INTERP, ARGIN(Parrot_runcore_t *), ARGIN(opcode_t *pc));
typedef void (*runcore_destroy_fn_type)(PARROT_INTERP, ARGIN(Parrot_runcore_t *));
View
15 src/debug.c
@@ -2452,13 +2452,15 @@ PDB_disassemble_op(PARROT_INTERP, ARGOUT(char *dest), size_t space,
one fixed parameter (the signature vector), plus a varying number of
registers/constants. For each arg/return, we show the register and its
flags using PIR syntax. */
- if (*(op) == PARROT_OP_set_args_pc || *(op) == PARROT_OP_set_returns_pc)
+ if (OPCODE_IS(interp, interp->code, *(op), PARROT_OP_set_args_pc)
+ || OPCODE_IS(interp, interp->code, *(op), PARROT_OP_set_returns_pc))
specialop = 1;
/* if it's a retrieving op, specialop = 2, so that later a :flat flag
* can be changed into a :slurpy flag. See flag handling below.
*/
- if (*(op) == PARROT_OP_get_results_pc || *(op) == PARROT_OP_get_params_pc)
+ if (OPCODE_IS(interp, interp->code, *(op), PARROT_OP_get_results_pc)
+ || OPCODE_IS(interp, interp->code, *(op), PARROT_OP_get_params_pc))
specialop = 2;
if (specialop > 0) {
@@ -2593,14 +2595,14 @@ PDB_disassemble(PARROT_INTERP, SHIM(const char *command))
}
size = PDB_disassemble_op(interp, pfile->source + pfile->size,
- space, &interp->op_info_table[*pc], pc, pfile, NULL, 1);
+ space, interp->code->op_info_table[*pc], pc, pfile, NULL, 1);
space -= size;
pfile->size += size;
pfile->source[pfile->size - 1] = '\n';
/* Store the opcode of this line */
pline->opcode = pc;
- n = interp->op_info_table[*pc].op_count;
+ n = interp->code->op_info_table[*pc]->op_count;
ADD_OP_VAR_PART(interp, interp->code, pc, n);
pc += n;
@@ -2797,7 +2799,8 @@ PDB_load_source(PARROT_INTERP, ARGIN(const char *command))
pfile->line = pline;
pline->number = 1;
- PARROT_ASSERT(interp->op_info_table);
+ PARROT_ASSERT(interp->code);
+ PARROT_ASSERT(interp->code->op_info_table);
PARROT_ASSERT(pc);
while ((c = fgetc(file)) != EOF) {
@@ -2817,7 +2820,7 @@ PDB_load_source(PARROT_INTERP, ARGIN(const char *command))
PDB_line_t *newline = mem_gc_allocate_zeroed_typed(interp, PDB_line_t);
if (PDB_hasinstruction(pfile->source + pline->source_offset)) {
- size_t n = interp->op_info_table[*pc].op_count;
+ size_t n = interp->code->op_info_table[*pc]->op_count;
pline->opcode = pc;
ADD_OP_VAR_PART(interp, interp->code, pc, n);
pc += n;
View
17 src/embed.c
@@ -1079,16 +1079,23 @@ Parrot_run_native(PARROT_INTERP, native_func_t func)
{
ASSERT_ARGS(Parrot_run_native)
PackFile * const pf = PackFile_new(interp, 0);
- static opcode_t program_code[2];
+ static opcode_t program_code[2] = {
+ 0, /* enternative */
+ 1 /* end */
+ };
+
+ static op_func_t op_func_table[2];
+ op_func_table[0] = interp->op_func_table[ interp->op_lib->op_code(interp, "enternative", 0) ];
+ op_func_table[1] = interp->op_func_table[ interp->op_lib->op_code(interp, "end", 0) ];
- program_code[0] = interp->op_lib->op_code(interp, "enternative", 0);
- program_code[1] = 0; /* end */
pf->cur_cs = (PackFile_ByteCode *)
(pf->PackFuncs[PF_BYTEC_SEG].new_seg)(interp, pf,
Parrot_str_new_constant(interp, "code"), 1);
- pf->cur_cs->base.data = program_code;
- pf->cur_cs->base.size = 2;
+ pf->cur_cs->base.data = program_code;
+ pf->cur_cs->base.size = 2;
+ pf->cur_cs->op_func_table = op_func_table;
+ /* TODO fill out cur_cs with op_mapping */
Parrot_pbc_load(interp, pf);
View
3,259 src/ops/core_ops.c
2,173 additions, 1,086 deletions not shown
View
277 src/packfile.c
@@ -25,15 +25,18 @@ about the structure of the frozen bytecode.
*/
#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"
+#include "parrot/oplib/core_ops.h"
/* HEADERIZER HFILE: include/parrot/packfile.h */
@@ -53,6 +56,31 @@ static PackFile_Segment * byte_code_new(PARROT_INTERP,
SHIM(int add))
__attribute__nonnull__(1);
+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 const 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);
+
static void clone_constant(PARROT_INTERP,
ARGIN(PackFile_Constant *old_const),
ARGMOD(PackFile_Constant *new_const))
@@ -353,6 +381,16 @@ static int sub_pragma(PARROT_INTERP,
, 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) \
@@ -1626,7 +1664,8 @@ static void
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,
@@ -1635,7 +1674,7 @@ pf_register_standard_funcs(PARROT_INTERP, ARGMOD(PackFile *pf))
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,
@@ -1644,7 +1683,7 @@ pf_register_standard_funcs(PARROT_INTERP, ARGMOD(PackFile *pf))
default_dump
};
- PackFile_funcs fixupf = {
+ static const PackFile_funcs fixupf = {
fixup_new,
fixup_destroy,
fixup_packed_size,
@@ -1653,7 +1692,7 @@ pf_register_standard_funcs(PARROT_INTERP, ARGMOD(PackFile *pf))
default_dump
};
- PackFile_funcs constf = {
+ static const PackFile_funcs constf = {
const_new,
const_destroy,
PackFile_ConstTable_pack_size,
@@ -1662,16 +1701,16 @@ pf_register_standard_funcs(PARROT_INTERP, ARGMOD(PackFile *pf))
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,
@@ -1680,7 +1719,7 @@ pf_register_standard_funcs(PARROT_INTERP, ARGMOD(PackFile *pf))
pf_debug_dump
};
- const PackFile_funcs annotationf = {
+ static const PackFile_funcs annotationf = {
PackFile_Annotations_new,
PackFile_Annotations_destroy,
PackFile_Annotations_packed_size,
@@ -2589,9 +2628,19 @@ byte_code_destroy(PARROT_INTERP, ARGMOD(PackFile_Segment *self))
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_info_table)
+ mem_gc_free(interp, byte_code->op_info_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;
+ byte_code->op_info_table = NULL;
}
@@ -2617,6 +2666,206 @@ byte_code_new(PARROT_INTERP, SHIM(PackFile *pf), SHIM(STRING *name), SHIM(int ad
return (PackFile_Segment *) byte_code;
}
+/*
+
+=item C<static size_t byte_code_packed_size(PARROT_INTERP, PackFile_Segment
+*self)>
+
+Computes the size in multiples of C<opcode_t> required to store the passed
+C<PackFile_ByteCode>.
+
+=cut
+
+*/
+
+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 = 2; /* op_count + 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 * 2; /* lib_ops and table_ops */
+ }
+
+ return size;
+}
+
+/*
+
+=item C<static opcode_t * byte_code_pack(PARROT_INTERP, PackFile_Segment *self,
+opcode_t *cursor)>
+
+Stores the passed C<PackFile_ByteCode> segment in bytecode.
+
+=cut
+
+*/
+
+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_count;
+ *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->table_ops[j];
+ *cursor++ = entry->lib_ops[j];
+ }
+ }
+
+ return cursor;
+}
+
+/*
+
+=item C<static const opcode_t * byte_code_unpack(PARROT_INTERP, PackFile_Segment
+*self, const opcode_t *cursor)>
+
+Unpacks a bytecode segment into the passed C<PackFile_ByteCode>.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static const 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;
+ int total_ops = 0;
+
+ byte_code->op_count = PF_fetch_opcode(self->pf, &cursor);
+ byte_code->op_func_table = mem_gc_allocate_n_zeroed_typed(interp,
+ byte_code->op_count, op_func_t);
+ byte_code->op_info_table = mem_gc_allocate_n_zeroed_typed(interp,
+ byte_code->op_count, op_info_t *);
+
+
+ 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);
+
+ /* XXX
+ * broken encapsulation => should make this data easier to access somehow
+ */
+ if (STREQ(lib_name, PARROT_CORE_OPLIB_NAME)) {
+ entry->lib = PARROT_CORE_OPLIB_INIT(interp, 1);
+ }
+ else {
+ PMC *lib_pmc = Parrot_load_lib(interp,
+ Parrot_str_new(interp, lib_name, 0),
+ NULL);
+ typedef op_lib_t *(*oplib_init_t)(PARROT_INTERP, long init);
+ void *oplib_init;
+ oplib_init_t oplib_init_f;
+ if (!VTABLE_get_bool(interp, lib_pmc))
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
+ "Could not load oplib `%s'", lib_name);
+ GETATTR_ParrotLibrary_oplib_init(interp, lib_pmc, oplib_init);
+ oplib_init_f = (oplib_init_t)D2FPTR(oplib_init);
+ entry->lib = oplib_init_f(interp, 1);
+ }
+
+
+ mem_gc_free(interp, lib_name);
+
+ 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' oplib. 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;
+ total_ops += entry->n_ops = PF_fetch_opcode(self->pf, &cursor);
+
+ entry->table_ops = mem_gc_allocate_n_zeroed_typed(interp,
+ entry->n_ops, opcode_t);
+ entry->lib_ops = mem_gc_allocate_n_zeroed_typed(interp,
+ entry->n_ops, opcode_t);
+
+ for (j = 0; j < entry->n_ops; j++) {
+ opcode_t idx = PF_fetch_opcode(self->pf, &cursor);
+ opcode_t 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, expected 0 to %d.",
+ entry->lib->name, op, entry->lib->op_count - 1);
+
+ if (0 > idx || idx >= byte_code->op_count)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "op table index out of bounds for entry from library `%s'."
+ " Found %d, expected 0 to %d",
+ entry->lib->name, idx, byte_code->op_count - 1);
+
+ if (byte_code->op_func_table[idx])
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "duplicate entries in optable");
+
+ entry->table_ops[j] = idx;
+ entry->lib_ops[j] = op;
+ byte_code->op_func_table[idx] = entry->lib->op_func_table[op];
+ byte_code->op_info_table[idx] = &entry->lib->op_info_table[op];
+ }
+ }
+ }
+
+ if (total_ops != byte_code->op_count)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "wrong number of ops decoded for optable. Decoded %d, but expected %d",
+ total_ops, byte_code->op_count);
+
+ return cursor;
+}
/*
View
14 src/pbc_dump.c
@@ -118,7 +118,7 @@ disas_dump(PARROT_INTERP, const PackFile_Segment *self)
while (pc < self->data + self->size) {
/* n can't be const; the ADD_OP_VAR_PART macro increments it */
- size_t n = (size_t)interp->op_info_table[*pc].op_count;
+ size_t n = (size_t)interp->code->op_info_table[*pc]->op_count;
size_t i;
/* trace_op_dump(interp, self->pf->src, pc); */
@@ -131,7 +131,7 @@ disas_dump(PARROT_INTERP, const PackFile_Segment *self)
Parrot_io_printf(interp, " ");
Parrot_io_printf(interp, "%s\n",
- interp->op_info_table[*pc].full_name);
+ interp->code->op_info_table[*pc]->full_name);
ADD_OP_VAR_PART(interp, interp->code, pc, n);
pc += n;
@@ -159,16 +159,16 @@ nums_dump(PARROT_INTERP, const PackFile_Segment *self)
const PackFile_Segment *debug = PackFile_find_segment(interp,
self->dir, debug_name, 1);
- const opcode_t * pc = self->data;
- const opcode_t * debug_ops = debug->data;
- const op_info_t * const op_info = interp->op_info_table;
+ opcode_t * pc = self->data;
+ opcode_t * debug_ops = debug->data;
+ op_info_t ** const op_info = interp->code->op_info_table;
while (pc < self->data + self->size) {
/* n can't be const; the ADD_OP_VAR_PART macro increments it */
- size_t n = (size_t)op_info[*pc].op_count;
+ size_t n = (size_t)op_info[*pc]->op_count;
Parrot_io_printf(interp, " %04x: %s\n",
- *(debug_ops++), op_info[*pc].full_name);
+ *(debug_ops++), op_info[*pc]->full_name);
ADD_OP_VAR_PART(interp, interp->code, pc, n);
pc += n;
View
128 src/pbc_merge.c
@@ -64,6 +64,16 @@ PARROT_DOES_NOT_RETURN
static void help(PARROT_INTERP)
__attribute__nonnull__(1);
+static void pbc_fixup_bytecode(PARROT_INTERP,
+ ARGMOD(pbc_merge_input **inputs),
+ int num_inputs,
+ ARGMOD(PackFile_ByteCode *bc))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(4)
+ FUNC_MODIFIES(*inputs)
+ FUNC_MODIFIES(*bc);
+
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
static PackFile* pbc_merge_begin(PARROT_INTERP,
@@ -100,16 +110,6 @@ static PackFile_ConstTable* pbc_merge_constants(PARROT_INTERP,
FUNC_MODIFIES(*pf)
FUNC_MODIFIES(*bc);
-static void pbc_merge_ctpointers(PARROT_INTERP,
- ARGMOD(pbc_merge_input **inputs),
- int num_inputs,
- ARGMOD(PackFile_ByteCode *bc))
- __attribute__nonnull__(1)
- __attribute__nonnull__(2)
- __attribute__nonnull__(4)
- FUNC_MODIFIES(*inputs)
- FUNC_MODIFIES(*bc);
-
static void pbc_merge_debugs(PARROT_INTERP,
ARGMOD(pbc_merge_input **inputs),
int num_inputs,
@@ -149,6 +149,10 @@ static void pbc_merge_write(PARROT_INTERP,
#define ASSERT_ARGS_help __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_pbc_fixup_bytecode __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(inputs) \
+ , PARROT_ASSERT_ARG(bc))
#define ASSERT_ARGS_pbc_merge_begin __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(inputs))
@@ -161,10 +165,6 @@ static void pbc_merge_write(PARROT_INTERP,
, PARROT_ASSERT_ARG(inputs) \
, PARROT_ASSERT_ARG(pf) \
, PARROT_ASSERT_ARG(bc))
-#define ASSERT_ARGS_pbc_merge_ctpointers __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp) \
- , PARROT_ASSERT_ARG(inputs) \
- , PARROT_ASSERT_ARG(bc))
#define ASSERT_ARGS_pbc_merge_debugs __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(inputs) \
@@ -601,7 +601,6 @@ pbc_merge_debugs(PARROT_INTERP, ARGMOD(pbc_merge_input **inputs),
/* Create merged debug segment. Replace created data and mappings
with merged ones we have created. */
debug_seg = Parrot_new_debug_seg(interp, bc, num_lines);
- PackFile_add_segment(interp, &pf->directory, (PackFile_Segment*)debug_seg);
mem_gc_free(interp, debug_seg->base.data);
debug_seg->base.data = lines;
mem_gc_free(interp, debug_seg->mappings);
@@ -610,23 +609,90 @@ pbc_merge_debugs(PARROT_INTERP, ARGMOD(pbc_merge_input **inputs),
debug_seg->num_mappings = num_mappings;
}
+
+static opcode_t
+bytecode_remap_op(PARROT_INTERP, PackFile *pf, opcode_t op) {
+ int i;
+ op_info_t *info = pf->cur_cs->op_info_table[op];
+ op_lib_t *lib = info->lib;
+ op_func_t op_func = pf->cur_cs->op_func_table[op];
+ PackFile_ByteCode *bc = interp->code;
+ PackFile_ByteCode_OpMappingEntry *om;
+
+ for (i = 0; i < bc->op_mapping.n_libs; i++) {
+ if (lib == bc->op_mapping.libs[i].lib) {
+ om = &bc->op_mapping.libs[i];
+ goto found_lib;
+ }
+ }
+
+ /* library not yet mapped */
+ bc->op_mapping.n_libs++;
+ bc->op_mapping.libs = mem_gc_realloc_n_typed_zeroed(interp, bc->op_mapping.libs,
+ bc->op_mapping.n_libs, bc->op_mapping.n_libs - 1,
+ PackFile_ByteCode_OpMappingEntry);
+
+ /* initialize a new lib entry */
+ om = &bc->op_mapping.libs[bc->op_mapping.n_libs - 1];
+ om->lib = lib;
+ om->n_ops = 0;
+ om->lib_ops = mem_gc_allocate_n_zeroed_typed(interp, 0, opcode_t);
+ om->table_ops = mem_gc_allocate_n_zeroed_typed(interp, 0, opcode_t);
+
+ found_lib:
+ for (i = 0; i < om->n_ops; i++) {
+ if (bc->op_func_table[om->table_ops[i]] == op_func)
+ return om->table_ops[i];
+ }
+
+ /* op not yet mapped */
+ bc->op_count++;
+ bc->op_func_table =
+ mem_gc_realloc_n_typed_zeroed(interp, bc->op_func_table, bc->op_count, bc->op_count,
+ op_func_t);
+ bc->op_func_table[bc->op_count - 1] = op_func;
+ bc->op_info_table =
+ mem_gc_realloc_n_typed_zeroed(interp, bc->op_info_table, bc->op_count, bc->op_count,
+ op_info_t *);
+ bc->op_info_table[bc->op_count - 1] = info;
+
+ /* initialize new op mapping */
+ om->n_ops++;
+
+ om->lib_ops =
+ mem_gc_realloc_n_typed_zeroed(interp, om->lib_ops, om->n_ops, om->n_ops - 1, opcode_t);
+ for (i = 0; i < lib->op_count; i++) {
+ if (lib->op_func_table[i] == op_func) {
+ om->lib_ops[om->n_ops - 1] = i;
+ break;
+ }
+ }
+ PARROT_ASSERT(om->lib_ops[om->n_ops - 1] || !i);
+
+ om->table_ops =
+ mem_gc_realloc_n_typed_zeroed(interp, om->table_ops, om->n_ops, om->n_ops - 1, opcode_t);
+ om->table_ops[om->n_ops - 1] = bc->op_count - 1;
+
+ return bc->op_count - 1;
+}
+
/*
-=item C<static void pbc_merge_ctpointers(PARROT_INTERP, pbc_merge_input
-**inputs, int num_inputs, PackFile_ByteCode *bc)>
+=item C<static void pbc_fixup_bytecode(PARROT_INTERP, pbc_merge_input **inputs,
+int num_inputs, PackFile_ByteCode *bc)>
-This function corrects the pointers into the constants table found in the
-bytecode.
+Fixup bytecode. This includes correcting pointers into the constant table
+and updating the ops mapping.
=cut
*/
static void
-pbc_merge_ctpointers(PARROT_INTERP, ARGMOD(pbc_merge_input **inputs),
+pbc_fixup_bytecode(PARROT_INTERP, ARGMOD(pbc_merge_input **inputs),
int num_inputs, ARGMOD(PackFile_ByteCode *bc))
{
- ASSERT_ARGS(pbc_merge_ctpointers)
+ ASSERT_ARGS(pbc_fixup_bytecode)
int cur_arg;
opcode_t *op_ptr;
opcode_t *ops = bc->base.data;
@@ -637,15 +703,16 @@ pbc_merge_ctpointers(PARROT_INTERP, ARGMOD(pbc_merge_input **inputs),
while (cur_op < (opcode_t)bc->base.size) {
op_info_t *op;
opcode_t op_num;
+ op_func_t op_func;
/* Keep track of the current input file. */
if (cur_input + 1 < num_inputs &&
cur_op >= inputs[cur_input + 1]->code_start)
++cur_input;
- /* Get info about this op and jump over it. */
- op_num = ops[cur_op];
- op = &interp->op_info_table[op_num];
+ /* Get info about this op, remap it, and jump over it. */
+ op_num = ops[cur_op] = bytecode_remap_op(interp, inputs[cur_input]->pf, ops[cur_op]);
+ op = bc->op_info_table[op_num];
op_ptr = ops + cur_op;
++cur_op;
@@ -669,10 +736,11 @@ pbc_merge_ctpointers(PARROT_INTERP, ARGMOD(pbc_merge_input **inputs),
}
/* Handle special case variable argument opcodes. */
- if (op_num == PARROT_OP_set_args_pc ||
- op_num == PARROT_OP_get_results_pc ||
- op_num == PARROT_OP_get_params_pc ||
- op_num == PARROT_OP_set_returns_pc) {
+ op_func = interp->code->op_func_table[op_num];
+ if (op_func == interp->op_func_table[PARROT_OP_set_args_pc] ||
+ op_func == interp->op_func_table[PARROT_OP_get_results_pc] ||
+ op_func == interp->op_func_table[PARROT_OP_get_params_pc] ||
+ op_func == interp->op_func_table[PARROT_OP_set_returns_pc]) {
/* Get the signature. */
PMC * const sig = bc->const_table->constants[op_ptr[1]].u.key;
@@ -739,7 +807,7 @@ pbc_merge_begin(PARROT_INTERP, ARGMOD(pbc_merge_input **inputs), int num_inputs)
}
/* Merge the various stuff. */
- bc = pbc_merge_bytecode(interp, inputs, num_inputs, merged);
+ bc = interp->code = pbc_merge_bytecode(interp, inputs, num_inputs, merged);
ct = pbc_merge_constants(interp, inputs, num_inputs, merged, bc);
UNUSED(ct);
@@ -747,7 +815,7 @@ pbc_merge_begin(PARROT_INTERP, ARGMOD(pbc_merge_input **inputs), int num_inputs)
pbc_merge_debugs(interp, inputs, num_inputs, merged, bc);
/* Walk bytecode and fix ops that reference the constants table. */
- pbc_merge_ctpointers(interp, inputs, num_inputs, bc);
+ pbc_fixup_bytecode(interp, inputs, num_inputs, bc);
for (i = 0; i < num_inputs; ++i) {
mem_gc_free(interp, inputs[i]->const_map);
View
32 src/pmc/opcode.pmc
@@ -23,19 +23,12 @@ Implements opcode VTABLEs.
pmclass Opcode auto_attrs {
ATTR op_info_t *info;
ATTR INTVAL op_number;
- ATTR STRING *full_name_cache;
VTABLE void init() {
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"Opcode must be created from OpLib.");
}
- VTABLE void mark() {
- Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
- if (attrs->full_name_cache)
- Parrot_gc_mark_STRING_alive(INTERP, attrs->full_name_cache);
- }
-
VTABLE void set_pointer(void *i) {
Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
if (attrs->info)
@@ -44,16 +37,6 @@ pmclass Opcode auto_attrs {
attrs->info = (op_info_t *)i;
}
- VTABLE void set_string_native(STRING *name) {
- char * const cstr = Parrot_str_to_cstring(INTERP, name);
- const INTVAL num = INTERP->op_lib->op_code(INTERP, cstr, 1);
- Parrot_str_free_cstring(cstr);
- if (num == -1)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
- "Opcode: Opcode %S not found", name);
- VTABLE_set_integer_native(INTERP, SELF, num);
- }
-
VTABLE INTVAL get_integer() {
Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
if (!attrs->info)
@@ -62,27 +45,18 @@ pmclass Opcode auto_attrs {
}
VTABLE void set_integer_native(INTVAL value) {
- const INTVAL opcount = INTERP->op_lib->op_count;
Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
if (attrs->info)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
"Opcode has already been initialized");
- if (value >= opcount || value < 0)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
- "Opcode: Opcode index %d out of bounds", value);
- attrs->info = &(INTERP->op_info_table[value]);
attrs->op_number = value;
}
VTABLE STRING* get_string() {
Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
- if (attrs->full_name_cache == NULL) {
- const char * const name = attrs->info->full_name;
- const INTVAL len = strlen(name);
- STRING * const newstr = Parrot_str_new(INTERP, name, len);
- attrs->full_name_cache = newstr;
- }
- return attrs->full_name_cache;
+ const char * const name = attrs->info->full_name;
+ const INTVAL len = strlen(name);
+ return Parrot_str_new(INTERP, name, len);
}
VTABLE INTVAL elements() {
View
112 src/pmc/oplib.pmc
@@ -15,51 +15,59 @@ Implements oplib VTABLEs.
*/
#include "parrot/parrot.h"
+#include "parrot/oplib/core_ops.h"
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
-/* TODO: Since Opcode PMCs are essentially read-only after initialization
- here, we should cache them. A FixedPMCArray would be okay, an
- INTVAL->PMC HASH might be better, since it's unlikely that we will
- need to cache even a majority of the ~1300 ops. */
-static PMC *OPLIB_PMC_INSTANCE;
-static PMC *OPLIB_OPCODE_CACHE;
-pmclass OpLib singleton {
- void class_init() {
- OPLIB_PMC_INSTANCE = NULL;
- OPLIB_OPCODE_CACHE = NULL;
- }
+pmclass OpLib auto_attrs {
+ ATTR op_lib_t *oplib;
- VTABLE void *get_pointer() {
- return OPLIB_PMC_INSTANCE;
+ VTABLE void init() {
+ Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
+ "OpLib must be initialized with an oplib name");
}
- VTABLE void set_pointer(void *ptr) {
- OPLIB_PMC_INSTANCE = (PMC *)ptr;
- }
+ VTABLE void init_pmc(PMC *name_pmc) {
+ STRING *name = VTABLE_get_string(INTERP, name_pmc);
+ char *name_cstr = Parrot_str_to_cstring(INTERP, name);
+ op_lib_t *oplib = NULL;
+ int i;
- VTABLE void init() {
- if (OPLIB_OPCODE_CACHE == NULL) {
- OPLIB_OPCODE_CACHE = Parrot_pmc_new(INTERP, enum_class_Hash);
- Parrot_pmc_gc_register(INTERP, OPLIB_OPCODE_CACHE);
+ if (STREQ(name_cstr, PARROT_CORE_OPLIB_NAME)) {
+ oplib = PARROT_CORE_OPLIB_INIT(INTERP, 1);
}
- PObj_custom_mark_SET(SELF);
- }
+ else {
+ for (i = 0; i < INTERP->n_libs; i++) {
+ if (STREQ(name_cstr, INTERP->all_op_libs[i]->name)) {
+ oplib = INTERP->all_op_libs[i];
+ break;
+ }
+ }
+ }
+
+ Parrot_str_free_cstring(name_cstr);
- VTABLE void mark() {
- if (OPLIB_OPCODE_CACHE != NULL)
- Parrot_gc_mark_PMC_alive(INTERP, OPLIB_OPCODE_CACHE);
+ if (!oplib)
+ Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_LIBRARY_NOT_LOADED,
+ "Could not find oplib `%S'", name);
+
+ SET_ATTR_oplib(INTERP, SELF, oplib);
}
/* Look up an opnumber given the name of the op. First we look for the
specific name, then the more general short name. */
VTABLE INTVAL get_integer_keyed_str(STRING *name) {
- char * const cstr = Parrot_str_to_cstring(INTERP, name);
- INTVAL num = INTERP->op_lib->op_code(INTERP, cstr, 1);
+ op_lib_t *oplib;
+ char * const cstr = Parrot_str_to_cstring(INTERP, name);
+ INTVAL num;
+
+ GET_ATTR_oplib(INTERP, SELF, oplib);
+ num = oplib->op_code(INTERP, cstr, 1);
if (num == -1)
- num = INTERP->op_lib->op_code(INTERP, cstr, 0);
+ num = oplib->op_code(INTERP, cstr, 0);
+
Parrot_str_free_cstring(cstr);
return num;
}
@@ -70,17 +78,11 @@ pmclass OpLib singleton {
}
VTABLE PMC* get_pmc_keyed_str(STRING *name) {
- if (VTABLE_defined_keyed_str(INTERP, OPLIB_OPCODE_CACHE, name)) {
- PMC * const op = VTABLE_get_pmc_keyed_str(INTERP, OPLIB_OPCODE_CACHE, name);
- return op;
- }
- else {
- PMC * const op = Parrot_pmc_new_noinit(INTERP, enum_class_Opcode);
- VTABLE_set_string_native(INTERP, op, name);
- PObj_custom_mark_SET(op);
- VTABLE_set_pmc_keyed_str(INTERP, OPLIB_OPCODE_CACHE, name, op);
- return op;
- }
+ const INTVAL num = STATICSELF.get_integer_keyed_str(name);
+ if (num == -1)
+ Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+ "Opcode: Opcode %S not found", name);
+ return STATICSELF.get_pmc_keyed_int(num);
}
VTABLE PMC* get_pmc_keyed(PMC *key) {
@@ -89,18 +91,29 @@ pmclass OpLib singleton {
}
VTABLE PMC* get_pmc_keyed_int(INTVAL value) {
- if ((UINTVAL)value >= INTERP->op_lib->op_count)
+ op_lib_t *oplib;
+ GET_ATTR_oplib(INTERP, SELF, oplib);
+ if ((UINTVAL)value >= oplib->op_count ||
+ value < 0) {
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
- "OpLib: Opcode index %d out of bounds", value);
+ "OpLib `%s': Opcode index %d out of bounds", oplib->name, value);
+ }
else {
- const char * const name = INTERP->op_info_table[value].full_name;
- STRING * const newstr = Parrot_str_new(INTERP, name, 0);
- return VTABLE_get_pmc_keyed_str(INTERP, SELF, newstr);
+ PMC * const op = Parrot_pmc_new_noinit(INTERP, enum_class_Opcode);
+ VTABLE_set_integer_native(INTERP, op, value);
+ VTABLE_set_pointer(INTERP, op, &oplib->op_info_table[value]);
+ return op;
}
}
VTABLE INTVAL elements() {
- return INTERP->op_lib->op_count;
+ op_lib_t *oplib;
+ GET_ATTR_oplib(INTERP, SELF, oplib);
+ return oplib->op_count;
+ }
+
+ VTABLE INTVAL get_integer() {
+ return STATICSELF.elements();
}
VTABLE INTVAL get_integer() {
@@ -110,11 +123,14 @@ pmclass OpLib singleton {
METHOD op_family(STRING *shortname)
{
char * const sname = Parrot_str_to_cstring(INTERP, shortname);
- const op_lib_t * const op_lib = INTERP->op_lib;
- const op_info_t * const table = op_lib->op_info_table;
+ op_lib_t *oplib;
+ op_info_t *table;
PMC *result = PMCNULL;
UINTVAL i;
- for (i = 0; i < op_lib->op_count; ++i) {
+
+ GET_ATTR_oplib(INTERP, SELF, oplib);
+ table = oplib->op_info_table;
+ for (i = 0; i < oplib->op_count; ++i) {
if (strcmp(table[i].name, sname) == 0) {
if (PMC_IS_NULL(result))
result = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
View
3  src/pmc/sub.pmc
@@ -871,7 +871,8 @@ The number of optional named arguments
Parrot_sub_arginfo);
/* If the first instruction is a get_params... */
- if (*pc == PARROT_OP_get_params_pc) {
+ if (sub->seg->op_func_table[*pc]
+ == interp->op_func_table[PARROT_OP_get_params_pc]) {
/* Get the signature (the next thing in the bytecode). */
PMC * const sig = PF_CONST(sub->seg, *(++pc)).u.key;
View
14 src/runcore/main.c
@@ -520,9 +520,11 @@ void
disable_event_checking(PARROT_INTERP)
{
ASSERT_ARGS(disable_event_checking)
+ PackFile_ByteCode *cs = interp->code;
/* restore func table */
- PARROT_ASSERT(interp->save_func_table);
- notify_func_table(interp, interp->save_func_table, 0);
+ PARROT_ASSERT(cs->save_func_table);
+ cs->op_func_table = cs->save_func_table;
+ cs->save_func_table = NULL;
}
@@ -546,8 +548,12 @@ void
enable_event_checking(PARROT_INTERP)
{
ASSERT_ARGS(enable_event_checking)
- /* put table in place */
- notify_func_table(interp, interp->evc_func_table, 1);
+ PackFile_ByteCode *cs = interp->code;
+ /* only save if we're not already event checking */
+ if (cs->save_func_table == NULL)
+ cs->save_func_table = cs->op_func_table;
+ /* put evc table in place */
+ cs->op_func_table = interp->evc_func_table;
}
View
2  src/runcore/profiling.c
@@ -459,7 +459,7 @@ ARGIN(opcode_t *pc))
pprof_data[PPROF_DATA_TIME] = op_time;
}
pprof_data[PPROF_DATA_LINE] = preop_line;
- pprof_data[PPROF_DATA_OPNAME] = (PPROF_DATA)(interp->op_info_table)[*preop_pc].name;
+ pprof_data[PPROF_DATA_OPNAME] = (PPROF_DATA)(interp->code->op_info_table)[*preop_pc]->name;
runcore->output_fn(runcore, pprof_data, PPROF_LINE_OP);
}
View
2  src/runcore/trace.c
@@ -297,7 +297,7 @@ trace_op_dump(PARROT_INTERP,
{
ASSERT_ARGS(trace_op_dump)
Interp * const debugger = debugger_or_interp(interp);
- op_info_t * const info = &interp->op_info_table[*pc];
+ op_info_t * const info = interp->code->op_info_table[*pc];
PMC *sig = PMCNULL;
INTVAL n = info->op_count;
INTVAL s = 1;
View
4 src/sub.c
@@ -182,7 +182,7 @@ Parrot_Context_get_info(PARROT_INTERP, ARGIN(PMC *ctx),
if (!debug)
return 0;
for (i = n = 0; n < sub->seg->base.size; ++i) {
- op_info_t * const op_info = &interp->op_info_table[*pc];
+ op_info_t * const op_info = sub->seg->op_info_table[*pc];
opcode_t var_args = 0;
if (i >= debug->base.size)
@@ -234,7 +234,7 @@ Parrot_Sub_get_line_from_pc(PARROT_INTERP, ARGIN_NULLOK(PMC *subpmc), ARGIN_NULL
current_annotation = pc - base_pc;
for (i = op = 0; op < debug_size; ++i) {
- op_info_t * const op_info = &interp->op_info_table[*base_pc];
+ op_info_t * const op_info = interp->code->op_info_table[*base_pc];
opcode_t var_args = 0;
if (i >= debug_size)
View
BIN  t/examples/pir.t
Binary file not shown
View
BIN  t/native_pbc/annotations.pbc
Binary file not shown
View
BIN  t/native_pbc/integer.pbc
Binary file not shown
View
BIN  t/native_pbc/integer_2.pbc
Binary file not shown
View
BIN  t/native_pbc/number.pbc
Binary file not shown
View
BIN  t/native_pbc/number_1.pbc
Binary file not shown
View
BIN  t/native_pbc/number_2.pbc
Binary file not shown
View
BIN  t/native_pbc/string.pbc
Binary file not shown
View
BIN  t/native_pbc/string_1.pbc
Binary file not shown
View
BIN  t/native_pbc/string_2.pbc
Binary file not shown
View
26 t/pmc/oplib.t
@@ -37,15 +37,17 @@ t/pmc/oplib.t - OpLib PMC
.end
.sub new_oplib
- $P0 = new ['OpLib']
- $I0 = isnull $P0
+ $P0 = box "core_ops"
+ $P1 = new ['OpLib'], $P0
+ $I0 = isnull $P1
nok($I0, "new OpLib")
.end
.sub check_elements
.local pmc oplib, op, eh
.local int n, i
- oplib = new ['OpLib']
+ $P0 = box "core_ops"
+ oplib = new ['OpLib'], $P0
n = elements oplib
i = n - 1
op = oplib[i]
@@ -66,14 +68,16 @@ t/pmc/oplib.t - OpLib PMC
.end
.sub getint_end
- $P0 = new ['OpLib']
+ $P0 = box 'core_ops'
+ $P0 = new ['OpLib'], $P0
$I1 = $P0[TESTED_OP]
$I0 = isne $I1, -1
ok($I0, "got end opcode")
.end
.sub getint_no_opcode
- $P0 = new ['OpLib']
+ $P0 = box 'core_ops'
+ $P0 = new ['OpLib'], $P0
$I1 = $P0[TESTED_NOSUCHOP]
$I0 = iseq $I1, -1
ok($I0, "get non existent opcode fails")
@@ -81,7 +85,8 @@ t/pmc/oplib.t - OpLib PMC
.sub getop_end
.local pmc oplib, op, op2, name
- oplib = new ['OpLib']
+ $P0 = box 'core_ops'
+ oplib = new ['OpLib'], $P0
# Using a string constant
op = oplib[TESTED_OP]
@@ -99,7 +104,8 @@ t/pmc/oplib.t - OpLib PMC
is($I0, 0, "got end opcode data keyed pmc")
$I0 = issame op, op2
- ok($I0, "got same result from both ways")
+ $S0 = "Implement cacheing, Opcode.is_same, or change comparison"
+ todo($I0, "got same result from both ways", $S0)
$I1 = op
$I0 = oplib[TESTED_OP]
@@ -110,7 +116,8 @@ t/pmc/oplib.t - OpLib PMC
.end
.sub family_end
- $P0 = new ['OpLib']
+ $P0 = box 'core_ops'
+ $P0 = new ['OpLib'], $P0
$P1 = $P0.'op_family'(TESTED_OP)
$I0 = isnull $P1
dec $I0
@@ -121,7 +128,8 @@ done:
.end
.sub family_no_opcode
- $P0 = new ['OpLib']
+ $P0 = box 'core_ops'
+ $P0 = new ['OpLib'], $P0
$P1 = $P0.'op_family'(TESTED_NOSUCHOP)
$I0 = isnull $P1
ok($I0, "non existent opcode family is null")
View
4 t/pmc/pmc.t
@@ -51,7 +51,9 @@ OUTPUT
my $checkTypes;
my %types_we_cant_test
= map { $_ => 1; } ( # These require initializers.
- qw(default Null Iterator ArrayIterator HashIterator StringIterator OrderedHashIterator Enumerate ParrotObject ParrotThread BigInt LexInfo LexPad Object Handle Opcode),
+ qw(default Null Iterator ArrayIterator HashIterator StringIterator
+ OrderedHashIterator Enumerate ParrotObject ParrotThread BigInt LexInfo
+ LexPad Object Handle Opcode OpLib),
# Instances of these appear to have other types.
qw(PMCProxy Class) );
Please sign in to comment.
Something went wrong with that request. Please try again.