Author: leo
Date: Thu Aug 11 10:29:58 2005
New Revision: 8918
Modified:
branches/leo-ctx5/imcc/pcc.c
branches/leo-ctx5/ops/object.ops
branches/leo-ctx5/ops/ops.num
branches/leo-ctx5/t/pmc/io.t
branches/leo-ctx5/t/pmc/object-meths.t
branches/leo-ctx5/t/pmc/objects.t
Log:
Call opcode cleanup part 2
* make register usage of callmethod opcodes explicit
* please grep for callmethod in ops/object.ops or in the pod
* adjust some PASM test
* create the new ops for PIR, simplify pcc.c
Please make realclean ... and remove other existing PBCs
The same 2 stream tests are failing.
Modified: branches/leo-ctx5/imcc/pcc.c
==============================================================================
--- branches/leo-ctx5/imcc/pcc.c (original)
+++ branches/leo-ctx5/imcc/pcc.c Thu Aug 11 10:29:58 2005
@@ -247,16 +247,15 @@ insert_tail_call(Parrot_Interp interp, I
if (meth_call) {
s0 = s0 ? s0 : get_pasm_reg(interp, "S0");
- regs[0] = s0;
- ins = insINS(interp, unit, ins, "tailcallmethod", regs, 1);
+ regs[0] = sub->pcc_sub->object;
+ regs[1] = s0;
+ ins = insINS(interp, unit, ins, "tailcallmethod", regs, 2);
}
else {
regs[0] = sub->pcc_sub->sub;
ins = insINS(interp, unit, ins, "tailcall", regs, 1);
}
ins->type |= ITPCCSUB;
- ins->r[0]->pcc_sub = sub->pcc_sub;
- sub->pcc_sub = NULL;
}
/*
@@ -279,16 +278,12 @@ expand_pcc_sub_call(Parrot_Interp interp
if (sub->pcc_sub->object) {
meth_call = 1;
- /* set P2, obj */
- if (sub->pcc_sub->object->color != 2) {
+ if (sub->pcc_sub->object->set == 'S') {
+ /* XXX make a temp */
regs[0] = get_pasm_reg(interp, "P2");
regs[1] = sub->pcc_sub->object;
- if (regs[1]->set == 'S') {
- ins = insINS(interp, unit, ins, "getclass", regs, 2);
- sub->pcc_sub->object = regs[0];
- }
- else
- ins = insINS(interp, unit, ins, "set", regs, 2);
+ ins = insINS(interp, unit, ins, "getclass", regs, 2);
+ sub->pcc_sub->object = regs[0];
}
}
@@ -344,24 +339,12 @@ expand_pcc_sub_call(Parrot_Interp interp
ins = get_name;
}
- /*
- * setup P0, and P2, S0 if method
- *
- * Due to implicit call arguments (call opcodes that
- * either take a Sub/P0, method/S2, return continuation/P1,
- * object/P2 or not)
- * this is really a mess
- */
- arg = sub->pcc_sub->sub;
+ s0 = arg = sub->pcc_sub->sub;
if (meth_call) {
- /* set S0, meth */
- regs[0] = get_pasm_reg(interp, "S0");;
if (arg->set != 'P') {
- if ( (arg->type == VTIDENTIFIER ||
+ if ( !(arg->type == VTIDENTIFIER ||
arg->type == VTPASM ||
arg->type == VTREG))
- s0 = arg;
- else
s0 = mk_const(interp, str_dup(arg->name), 'S');
}
@@ -399,12 +382,17 @@ expand_pcc_sub_call(Parrot_Interp interp
}
else {
/* insert the call */
- if (meth_call && sub->pcc_sub->sub->set != 'P') {
- regs[0] = s0;
- n = 0;
- if (s0)
- n = 1;
- ins = insINS(interp, unit, ins, "callmethodcc" , regs, n);
+ if (meth_call) {
+ regs[0] = sub->pcc_sub->object;
+ regs[1] = s0;
+ arg = sub->pcc_sub->cc;
+ if (arg) {
+ regs[2] = arg;
+ ins = insINS(interp, unit, ins, "callmethod" , regs, 3);
+ }
+ else {
+ ins = insINS(interp, unit, ins, "callmethodcc" , regs, 2);
+ }
}
else {
regs[0] = sub->pcc_sub->sub;
Modified: branches/leo-ctx5/ops/object.ops
==============================================================================
--- branches/leo-ctx5/ops/object.ops (original)
+++ branches/leo-ctx5/ops/object.ops Thu Aug 11 10:29:58 2005
@@ -18,39 +18,31 @@ Parrot's library of object ops
=cut
-=item B<callmethod>()
+=item B<callmethodcc>(in PMC, in STR)
-=item B<callmethod>(in STR)
+Call method $2 with invocant $1 and generate a new return continuation.
+The invocant ($1) is used for method lookup. The object is passed as
+the first argument in B<set_args>.
-Call a method on an object. If a method name is provided, we find
-the PMC for the named method and put it into the sub/method slot.
-If no name is provided, then we assume that the method PMC and
-method name are already in their proper places. We assume that
-all other registers are correctly set up, as per the Parrot
-calling conventions.
Throws a Method_Not_Found_Exception for a non-existent method.
-=cut
+=item B<callmethodcc>(in PMC, in PMC)
-=item B<callmethodcc>()
+Like above but use the Sub object $2 as method.
-=item B<callmethodcc>(in STR)
+=item B<callmethod>(in PMC, in STR, in PMC)
-Make a method call, automatically generating a return continuation. If
-a method name is passed in we look up the method PMC for the object
-and put it in the method slot. If a method name isn't provided then we
-assume that things are already properly set up. Note that the return
-continuation is placed in P1.
-Throws a Method_Not_Found_Exception for a non-existent method.
+=item B<callmethod>(in PMC, in PMC, in PMC)
+
+Like above, but use continuation $3 instead of creating a new continuation.
=cut
-=item B<tailcallmethod> B<(unimplemented)>
+=item B<tailcallmethod>(in PMC, in STR)
-=item B<tailcallmethod>(in STR)
+=item B<tailcallmethod>(in PMC, in PMC)
-Make a tailcall to method $1. If no method name is given, we assume
-everything is already set up properly.
+Make a tailcall to method $2 with invocant $1.
=item B<fetchmethod>(out PMC, in PMC, in STR)
@@ -61,55 +53,55 @@ changes to the underlying classes where
=cut
-op callmethod() :object_base {
- PMC *method_pmc, *object;
+op callmethodcc(in PMC, in STR) :object_base {
opcode_t *dest;
- opcode_t *next = expr NEXT();
- STRING *meth = REG_STR(0);
+ PMC *method_pmc, *object;
+ opcode_t *next;
+ STRING *meth;
- object = REG_PMC(2);
+ object = $1;
+ meth = $2;
+ next = expr NEXT();
+ interpreter->current_object = object;
+ interpreter->current_cont = NEED_CONTINUATION;
+ interpreter->current_method = meth;
method_pmc = VTABLE_find_method(interpreter, object, meth);
if (!method_pmc) {
real_exception(interpreter, next, METH_NOT_FOUND,
"Method '%Ss' not found", meth);
}
- interpreter->current_object = object;
- interpreter->current_cont = NULL;
- interpreter->current_method = meth;
dest = (opcode_t *)VTABLE_invoke(interpreter, method_pmc, next);
goto ADDRESS(dest);
}
-op callmethod(in STR) :object_base {
- PMC *method_pmc, *object;
+op callmethodcc(in PMC, in PMC) :object_base {
opcode_t *dest;
- opcode_t *next = expr NEXT();
- STRING *meth = $1;
+ PMC *method_pmc, *object;
+ opcode_t *next;
- object = REG_PMC(2);
- method_pmc = VTABLE_find_method(interpreter, object, meth);
- if (!method_pmc) {
- real_exception(interpreter, next, METH_NOT_FOUND,
- "Method '%Ss' not found", meth);
- }
+ object = $1;
+ method_pmc = $2;
+ /* XXX should we check if object.can(method) */
+
+ next = expr NEXT();
interpreter->current_object = object;
- interpreter->current_cont = NULL;
- interpreter->current_method = meth;
+ interpreter->current_cont = NEED_CONTINUATION;
+ interpreter->current_method = VTABLE_get_string(interpreter, method_pmc);
dest = (opcode_t *)VTABLE_invoke(interpreter, method_pmc, next);
goto ADDRESS(dest);
}
-op callmethodcc() :object_base {
+op callmethod(in PMC, in STR, in PMC) :object_base {
opcode_t *dest;
PMC *method_pmc, *object;
- opcode_t *next = expr NEXT();
- STRING *meth = REG_STR(0);
+ opcode_t *next;
+ STRING *meth;
- object = REG_PMC(2);
- assert(!PMC_IS_NULL(object));
- assert(meth!=0);
+ object = $1;
+ meth = $2;
+ next = expr NEXT();
interpreter->current_object = object;
- interpreter->current_cont = NEED_CONTINUATION;
+ interpreter->current_cont = $3;
interpreter->current_method = meth;
method_pmc = VTABLE_find_method(interpreter, object, meth);
if (!method_pmc) {
@@ -120,38 +112,30 @@ op callmethodcc() :object_base {
goto ADDRESS(dest);
}
-op callmethodcc(in STR) :object_base {
+op callmethod(in PMC, in PMC, in PMC) :object_base {
opcode_t *dest;
PMC *method_pmc, *object;
opcode_t *next;
- STRING *meth;
- meth = $1;
- object = REG_PMC(2);
- if (Parrot_run_maybe_mmd_meth(interpreter, object, meth))
- goto NEXT();
+ object = $1;
+ method_pmc = $2;
next = expr NEXT();
interpreter->current_object = object;
- interpreter->current_cont = NEED_CONTINUATION;
- interpreter->current_method = meth;
- method_pmc = VTABLE_find_method(interpreter, object, meth);
- if (!method_pmc) {
- real_exception(interpreter, next, METH_NOT_FOUND,
- "Method '%Ss' not found", meth);
- }
+ interpreter->current_cont = $3;
+ interpreter->current_method = VTABLE_get_string(interpreter, method_pmc);
dest = (opcode_t *)VTABLE_invoke(interpreter, method_pmc, next);
goto ADDRESS(dest);
}
-op tailcallmethod(in STR) :object_base {
+op tailcallmethod(in PMC, in STR) :object_base {
opcode_t *dest;
PMC *method_pmc, *object;
opcode_t *next = expr NEXT();
STRING *meth;
- meth = $1;
- object = REG_PMC(2);
+ object = $1;
+ meth = $2;
interpreter->current_cont = CONTEXT(interpreter->ctx)->current_cont;
PObj_get_FLAGS(interpreter->current_cont) |= SUB_FLAG_TAILCALL;
interpreter->current_object = object;
@@ -164,6 +148,21 @@ op tailcallmethod(in STR) :object_base {
dest = (opcode_t *)VTABLE_invoke(interpreter, method_pmc, next);
goto ADDRESS(dest);
}
+
+op tailcallmethod(in PMC, in PMC) :object_base {
+ opcode_t *dest;
+ PMC *method_pmc, *object;
+ opcode_t *next = expr NEXT();
+
+ object = $1;
+ method_pmc = $2;
+ interpreter->current_cont = CONTEXT(interpreter->ctx)->current_cont;
+ PObj_get_FLAGS(interpreter->current_cont) |= SUB_FLAG_TAILCALL;
+ interpreter->current_object = object;
+ interpreter->current_method = VTABLE_get_string(interpreter, method_pmc);
+ dest = (opcode_t *)VTABLE_invoke(interpreter, method_pmc, next);
+ goto ADDRESS(dest);
+}
op fetchmethod(out PMC, in PMC, in STR) {
opcode_t *next = expr NEXT();
Modified: branches/leo-ctx5/ops/ops.num
==============================================================================
--- branches/leo-ctx5/ops/ops.num (original)
+++ branches/leo-ctx5/ops/ops.num Thu Aug 11 10:29:58 2005
@@ -143,12 +143,12 @@ bxors_s_s_s 112
bxors_s_s_sc 113
bxors_s_sc 114
bxors_s_sc_s 115
-callmethod 116
-callmethod_s 117
-callmethod_sc 118
-callmethodcc 119
-callmethodcc_s 120
-callmethodcc_sc 121
+callmethod_p_s_p 116
+callmethod_p_sc_p 117
+callmethod_p_p_p 118
+callmethodcc_p_s 119
+callmethodcc_p_sc 120
+callmethodcc_p_p 121
can_i_p_s 122
can_i_p_sc 123
ceil_i_n 124
@@ -1199,8 +1199,8 @@ sysinfo_i_ic 1168
sysinfo_s_i 1169
sysinfo_s_ic 1170
tailcall_p 1171
-tailcallmethod_s 1172
-tailcallmethod_sc 1173
+tailcallmethod_p_s 1172
+tailcallmethod_p_sc 1173
tan_n_n 1174
tan_n_nc 1175
tanh_n_n 1176
@@ -1349,3 +1349,4 @@ new_p_i_s 1318
new_p_ic_s 1319
new_p_i_sc 1320
new_p_ic_sc 1321
+tailcallmethod_p_p 1322
Modified: branches/leo-ctx5/t/pmc/io.t
==============================================================================
--- branches/leo-ctx5/t/pmc/io.t (original)
+++ branches/leo-ctx5/t/pmc/io.t Thu Aug 11 10:29:58 2005
@@ -382,7 +382,7 @@ output_is(<<'CODE', <<'OUTPUT', 'puts me
print "not "
ok1: print "ok 1\n"
set_args "(0,0)", P2, "ok 2\n"
- callmethod "puts"
+ callmethodcc P2, "puts"
end
CODE
ok 1
@@ -411,13 +411,12 @@ OUTPUT
output_is(<<'CODE', <<'OUTPUT', 'callmethod puts');
getstderr P2 # the object
set S0, "puts" # method
- set P5, P2 # first param
set S5, "ok 1\n" # 2nd param
set_args "(0,0)", P2, S5
- callmethod
+ callmethodcc P2, S0
set S5, "ok 2\n"
set_args "(0,0)", P2, S5
- callmethod
+ callmethodcc P2, S0
end
CODE
ok 1
Modified: branches/leo-ctx5/t/pmc/object-meths.t
==============================================================================
--- branches/leo-ctx5/t/pmc/object-meths.t (original)
+++ branches/leo-ctx5/t/pmc/object-meths.t Thu Aug 11 10:29:58 2005
@@ -22,7 +22,7 @@ use Test::More;
output_like(<<'CODE', <<'OUTPUT', "callmethod - unknown method");
newclass P2, "Foo"
set S0, "nada"
- callmethod
+ callmethodcc P2, S0
print "nope\n"
end
CODE
@@ -32,7 +32,7 @@ OUTPUT
output_like(<<'CODE', <<'OUTPUT', "callmethod (STR) - unknown method");
newclass P2, "Foo"
set S1, "nada"
- callmethod S1
+ callmethod P2, S1, P1
print "nope\n"
end
CODE
@@ -42,7 +42,7 @@ OUTPUT
output_like(<<'CODE', <<'OUTPUT', "callmethodcc - unknown method");
newclass P2, "Foo"
set S0, "nada"
- callmethodcc
+ callmethodcc P2, S0
print "nope\n"
end
CODE
@@ -52,7 +52,7 @@ OUTPUT
output_like(<<'CODE', <<'OUTPUT', "callmethodcc (STR) - unknown method");
newclass P2, "Foo"
set S1, "nada"
- callmethodcc S1
+ callmethodcc P2, S1
print "nope\n"
end
CODE
@@ -64,7 +64,7 @@ output_is(<<'CODE', <<'OUTPUT', "callmet
set S0, "meth"
print "main\n"
- callmethodcc
+ callmethodcc P2, S0
print "back\n"
end
@@ -459,8 +459,7 @@ eh:
print "in __init\n"
# raise an exception
- set S0, "qux"
- callmethodcc
+ callmethodcc self, "qux"
print "never\n"
returncc
@@ -479,13 +478,11 @@ output_is(<<'CODE', <<'OUTPUT', "fetchme
set S0, "meth"
fetchmethod P0, P2, S0
print "main\n"
- # P2, S0 are as in callmethod
- invokecc P0
+ callmethodcc P2, P0
print "back\n"
# check class
fetchmethod P0, P3, S0
- set P2, P3
- invokecc P0
+ callmethodcc P3, P0
print "back\n"
end
@@ -857,7 +854,7 @@ output_is(<<'CODE', <<'OUTPUT', "callmet
set S0, "meth"
print "main\n"
- callmethodcc
+ callmethodcc P2, S0
print "back\n"
end
@@ -917,9 +914,7 @@ pir_output_is(<<'CODE', <<'OUTPUT', "tai
n = getattribute self, "Foo\0n"
dec n
unless n goto done
- # XXX this is ugly
- P2 = self
- tailcallmethod "go"
+ tailcallmethod self, "go"
done:
.end
CODE
Modified: branches/leo-ctx5/t/pmc/objects.t
==============================================================================
--- branches/leo-ctx5/t/pmc/objects.t (original)
+++ branches/leo-ctx5/t/pmc/objects.t Thu Aug 11 10:29:58 2005
@@ -685,51 +685,49 @@ output_is(<<'CODE', <<'OUTPUT', "attribu
new P13, I1
# Foo and Bar have attribute accessor methods
- set S0, "Foo::set" # the meth s. pdd03
- set P2, P13 # the object s. pdd03
new P5, .String # set attribute values
set P5, "i\n" # attribute slots have reference semantics
set_args "(0,0)", P5, 0
get_results "()"
- callmethodcc "Foo::set"
+ callmethodcc P13, "Foo::set"
new P5, .String
set P5, "j\n"
set_args "(0,0)", P5, 1
get_results "()"
- callmethodcc "Foo::set"
+ callmethodcc P13,"Foo::set"
new P5, .String
set P5, "k\n"
set_args "(0,0)", P5, 0
get_results "()"
- callmethodcc "Bar::set"
+ callmethodcc P13,"Bar::set"
new P5, .String
set P5, "l\n"
set_args "(0,0)", P5, 1
get_results "()"
- callmethodcc "Bar::set"
+ callmethodcc P13,"Bar::set"
# now retrieve attributes
set_args "(0)", 0
get_results "(0)", P5
- callmethodcc "Foo::get"
+ callmethodcc P13,"Foo::get"
print P5 # return result
set_args "(0)", 1
get_results "(0)", P5
- callmethodcc "Foo::get"
+ callmethodcc P13,"Foo::get"
print P5
set_args "(0)", 0
get_results "(0)", P5
- callmethodcc "Bar::get"
+ callmethodcc P13,"Bar::get"
print P5 # return result
set_args "(0)", 1
get_results "(0)", P5
- callmethodcc "Bar::get"
+ callmethodcc P13,"Bar::get"
print P5
end
@@ -821,57 +819,57 @@ output_is(<<'CODE', <<'OUTPUT', "attribu
set P5, "i\n" # attribute slots have reference semantics
set_args "(0,0,0)", P5, "Foo", 0
get_results "()"
- callmethodcc "set"
+ callmethodcc P2, "set"
new P5, .String
set P5, "j\n"
set_args "(0,0,0)", P5, "Foo", 1
get_results "()"
- callmethodcc "set"
+ callmethodcc P2, "set"
new P5, .String
set P5, "k\n"
set_args "(0,0,0)", P5, "Bar", 0
get_results "()"
- callmethodcc "set"
+ callmethodcc P2, "set"
new P5, .String
set P5, "l\n"
set_args "(0,0,0)", P5, "Bar", 1
get_results "()"
- callmethodcc "set"
+ callmethodcc P2, "set"
new P5, .String
set P5, "m\n"
set_args "(0,0,0)", P5, "Bar", 2
get_results "()"
- callmethodcc "set"
+ callmethodcc P2, "set"
# now retrieve attributes
set_args "(0,0)", "Foo", 0
get_results "(0)", P5
- callmethodcc "get"
+ callmethodcc P2, "get"
print P5 # return result
set_args "(0,0)", "Foo", 1
get_results "(0)", P5
- callmethodcc "get"
+ callmethodcc P2, "get"
print P5
set_args "(0,0)", "Bar", 0
get_results "(0)", P5
- callmethodcc "get"
+ callmethodcc P2, "get"
print P5
set_args "(0,0)", "Bar", 1
get_results "(0)", P5
- callmethodcc "get"
+ callmethodcc P2, "get"
print P5
set_args "(0,0)", "Bar", 2
get_results "(0)", P5
- callmethodcc "get"
+ callmethodcc P2, "get"
print P5
end