Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

var_args 8 - verify signature during bytecode creation

* pitch a fit if get_params, get_results has a constant arg
* adjust argument type and const bits in singnature according to
  passed arguments
* create a constant FixedIntegerArray clone if SELF is constant



git-svn-id: https://svn.parrot.org/parrot/trunk@8351 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information...
commit 9822a2436c335b8015fef379481c642dd89efd94 1 parent 8760996
Leopold Toetsch authored
Showing with 101 additions and 4 deletions.
  1. +12 −1 classes/fixedintegerarray.pmc
  2. +59 −2 imcc/pbc.c
  3. +30 −1 t/op/calling.t
View
13 classes/fixedintegerarray.pmc
@@ -160,7 +160,18 @@ Creates and returns a copy of the array.
PMC* clone () {
INTVAL size;
- PMC * dest = pmc_new(INTERP, SELF->vtable->base_type);
+ PMC * dest;
+ /* a quick hack to create a clone in the constant PMC arena
+ * this is needed for the call signatures
+ *
+ * a better way would be probably to supply a flag to the clone
+ * vtable
+ */
+
+ if (PObj_constant_TEST(SELF))
+ dest = constant_pmc_new(INTERP, SELF->vtable->base_type);
+ else
+ dest = pmc_new(INTERP, SELF->vtable->base_type);
if (!PMC_data(SELF))
return dest;
View
61 imcc/pbc.c
@@ -1,6 +1,7 @@
#include "imc.h"
#include "pbc.h"
#include "parrot/packfile.h"
+#include "parrot/oplib/ops.h"
/*
* pbc.c
@@ -1026,6 +1027,56 @@ e_pbc_end_sub(Interp *interpreter, void *param, IMC_Unit * unit)
return 0;
}
+static void
+verify_signature(Interp *interpreter, Instruction *ins, opcode_t *pc)
+{
+ PMC *sig_arr = interpreter->code->const_table->constants[pc[-1]]->u.key;
+ INTVAL i, n, sig;
+ SymReg *r;
+ int no_consts, needed;
+ PMC *changed_sig = NULL;
+
+ assert(PObj_is_PMC_TEST(sig_arr));
+ assert(sig_arr->vtable->base_type == enum_class_FixedIntegerArray);
+ no_consts = (ins->opnum == PARROT_OP_get_results_pc ||
+ ins->opnum == PARROT_OP_get_params_pc);
+ n = VTABLE_elements(interpreter, sig_arr);
+ for (i = 0; i < n; ++i) {
+ r = ins->r[i + 1];
+ if (no_consts && (r->type & VTCONST))
+ IMCC_fatal(interpreter, 1, "e_pbc_emit: "
+ "constant argument '%s' in get param/result\n",
+ r->name);
+ sig = VTABLE_get_integer_keyed_int(interpreter, sig_arr, i);
+ if ((r->type & VTCONST) && !(sig & PARROT_ARG_CONSTANT)) {
+ if (!changed_sig)
+ changed_sig = VTABLE_clone(interpreter, sig_arr);
+ sig |= PARROT_ARG_CONSTANT;
+ VTABLE_set_integer_keyed_int(interpreter, changed_sig, i, sig);
+ }
+ switch (r->set) {
+ case 'I': needed = PARROT_ARG_INTVAL; break;
+ case 'S': needed = PARROT_ARG_STRING; break;
+ case 'P': needed = PARROT_ARG_PMC; break;
+ case 'N': needed = PARROT_ARG_FLOATVAL; break;
+ }
+ if (needed != (sig & PARROT_ARG_TYPE_MASK)) {
+ if (!changed_sig)
+ changed_sig = VTABLE_clone(interpreter, sig_arr);
+ sig &= ~PARROT_ARG_TYPE_MASK;
+ sig |= needed;
+ VTABLE_set_integer_keyed_int(interpreter, changed_sig, i, sig);
+ }
+ }
+ if (changed_sig) {
+ /* append PMC constant */
+ int k = PDB_extend_const_table(interpreter);
+ interpreter->code->const_table->constants[k]->type = PFC_PMC;
+ interpreter->code->const_table->constants[k]->u.key = changed_sig;
+ pc[-1] = k;
+ }
+}
+
/*
* now let the fun begin, actually emit code for one ins
*/
@@ -1193,13 +1244,19 @@ e_pbc_emit(Interp *interpreter, void *param, IMC_Unit * unit, Instruction * ins)
break;
}
}
- /* emit var_args part */
- for (; i < ins->opsize - 1; ++i) {
+ if (ins->opnum == PARROT_OP_set_args_pc ||
+ ins->opnum == PARROT_OP_get_results_pc ||
+ ins->opnum == PARROT_OP_get_params_pc ||
+ ins->opnum == PARROT_OP_set_returns_pc) {
+ verify_signature(interpreter, ins, pc);
+ /* emit var_args part */
+ for (; i < ins->opsize - 1; ++i) {
r = ins->r[i];
if (r->type & VT_CONSTP)
r = r->reg;
*pc++ = (opcode_t) r->color;
IMCC_debug(interpreter, DEBUG_PBC," %d", r->color);
+ }
}
IMCC_debug(interpreter, DEBUG_PBC, "\t%I\n", ins);
npc += ins->opsize;
View
31 t/op/calling.t
@@ -16,7 +16,7 @@ Tests Parrot calling conventions.
=cut
-use Parrot::Test tests => 6;
+use Parrot::Test tests => 7;
use Test::More;
# Test calling convention operations
@@ -230,3 +230,32 @@ CODE
back
OUTPUT
+output_is(<<'CODE', <<'OUTPUT', "call - i, ic, return i, ic - adjust sig");
+.pcc_sub main:
+ set I16, 77
+ set_args "(0, 0)", 42, I16
+ get_results "(0, 0)", I16, I17
+ find_name P1, "foo"
+ invokecc P1
+ print I16
+ print "\n"
+ print I17
+ print "\nback\n"
+ end
+.pcc_sub foo:
+ get_params "(0, 0)", I16, I17
+ print I16
+ print "\n"
+ print I17
+ print "\n"
+ set I16, 88
+ set_returns "(0, 0)", 99, I16
+ returncc
+CODE
+42
+77
+99
+88
+back
+OUTPUT
+
Please sign in to comment.
Something went wrong with that request. Please try again.