From 185e76653ed25db9cd40cc4c54f42d02b6c5eb78 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Wed, 15 Oct 2014 10:38:11 -0400 Subject: [PATCH] compiler: do the varargization in the ANodes Signed-off-by: Jean Privat --- src/compiler/abstract_compiler.nit | 92 +++++++++++++++++------------------- src/compiler/global_compiler.nit | 1 - src/compiler/separate_compiler.nit | 3 -- 3 files changed, 44 insertions(+), 52 deletions(-) diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 0a11d32..e83739d 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -1088,39 +1088,39 @@ abstract class AbstractCompilerVisitor fun native_array_def(pname: String, ret_type: nullable MType, arguments: Array[RuntimeVariable]) is abstract - # Transform varargs, in raw arguments, into a single argument of type `Array` - # Note: this method modify the given `args` - # If there is no vararg, then `args` is not modified. - fun varargize(mpropdef: MPropDef, msignature: MSignature, args: Array[RuntimeVariable]) + # Evaluate `args` as expressions in the call of `mpropdef` on `recv`. + # This method is used to manage varargs in signatures and returns the real array + # of runtime variables to use in the call. + fun varargize(mpropdef: MMethodDef, recv: RuntimeVariable, args: SequenceRead[AExpr]): Array[RuntimeVariable] do - var recv = args.first - var vararg_rank = msignature.vararg_rank - if vararg_rank >= 0 then - assert args.length >= msignature.arity + 1 # because of self - var rawargs = args - args = new Array[RuntimeVariable] - - args.add(rawargs.first) # recv + var msignature = mpropdef.new_msignature or else mpropdef.msignature.as(not null) + var res = new Array[RuntimeVariable] + res.add(recv) - for i in [0..vararg_rank[ do - args.add(rawargs[i+1]) - end - - var vararg_lastrank = vararg_rank + rawargs.length-1-msignature.arity - var vararg = new Array[RuntimeVariable] - for i in [vararg_rank..vararg_lastrank] do - vararg.add(rawargs[i+1]) - end + if args.is_empty then return res - var elttype = msignature.mparameters[vararg_rank].mtype - args.add(self.vararg_instance(mpropdef, recv, vararg, elttype)) + var vararg_rank = msignature.vararg_rank + var vararg_len = args.length - msignature.arity + if vararg_len < 0 then vararg_len = 0 - for i in [vararg_lastrank+1..rawargs.length-1[ do - args.add(rawargs[i+1]) + for i in [0..msignature.arity[ do + if i == vararg_rank then + var vararg = new Array[RuntimeVariable] + for j in [vararg_rank..vararg_rank+vararg_len] do + var e = self.expr(args[j], null) + vararg.add(e) + end + var elttype = msignature.mparameters[vararg_rank].mtype + var arg = self.vararg_instance(mpropdef, recv, vararg, elttype) + res.add(arg) + else + var j = i + if i > vararg_rank then j += vararg_len + var e = self.expr(args[j], null) + res.add(e) end - rawargs.clear - rawargs.add_all(args) end + return res end # Type handling @@ -2874,11 +2874,9 @@ redef class ASendExpr redef fun expr(v) do var recv = v.expr(self.n_expr, null) - var args = [recv] - for a in self.raw_arguments do - args.add(v.expr(a, null)) - end - return v.compile_callsite(self.callsite.as(not null), args) + var callsite = self.callsite.as(not null) + var args = v.varargize(callsite.mpropdef, recv, self.raw_arguments) + return v.compile_callsite(callsite, args) end end @@ -2886,13 +2884,12 @@ redef class ASendReassignFormExpr redef fun stmt(v) do var recv = v.expr(self.n_expr, null) - var args = [recv] - for a in self.raw_arguments do - args.add(v.expr(a, null)) - end + var callsite = self.callsite.as(not null) + var args = v.varargize(callsite.mpropdef, recv, self.raw_arguments) + var value = v.expr(self.n_value, null) - var left = v.compile_callsite(self.callsite.as(not null), args) + var left = v.compile_callsite(callsite, args) assert left != null var res = v.compile_callsite(self.reassign_callsite.as(not null), [left, value]) @@ -2907,14 +2904,12 @@ redef class ASuperExpr redef fun expr(v) do var recv = v.frame.arguments.first - var args = [recv] - for a in self.n_args.n_exprs do - args.add(v.expr(a, null)) - end var callsite = self.callsite if callsite != null then - # Add additionnals arguments for the super init call + var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs) + + # Add additional arguments for the super init call if args.length == 1 then for i in [0..callsite.msignature.arity[ do args.add(v.frame.arguments[i+1]) @@ -2925,12 +2920,14 @@ redef class ASuperExpr return res end + var mpropdef = self.mpropdef.as(not null) + var args = v.varargize(mpropdef, recv, self.n_args.n_exprs) if args.length == 1 then args = v.frame.arguments end # stantard call-next-method - return v.supercall(mpropdef.as(not null), recv.mtype.as(MClassType), args) + return v.supercall(mpropdef, recv.mtype.as(MClassType), args) end end @@ -2953,11 +2950,10 @@ redef class ANewExpr else recv = v.new_expr("({ctype})0/*special!*/", mtype) end - var args = [recv] - for a in self.n_args.n_exprs do - args.add(v.expr(a, null)) - end - var res2 = v.compile_callsite(self.callsite.as(not null), args) + + var callsite = self.callsite.as(not null) + var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs) + var res2 = v.compile_callsite(callsite, args) if res2 != null then #self.debug("got {res2} from {mproperty}. drop {recv}") return res2 diff --git a/src/compiler/global_compiler.nit b/src/compiler/global_compiler.nit index b8eef9b..4a4cbda 100644 --- a/src/compiler/global_compiler.nit +++ b/src/compiler/global_compiler.nit @@ -542,7 +542,6 @@ class GlobalCompilerVisitor var recv = get_recv(recv_type, args) if m.is_extern then recv = unbox_extern(recv, recv_type) var new_args = args.to_a - self.varargize(m, m.msignature.as(not null), new_args) new_args.first = recv return finalize_call(m, recv_type, new_args) end diff --git a/src/compiler/separate_compiler.nit b/src/compiler/separate_compiler.nit index 7eed804..3645f54 100644 --- a/src/compiler/separate_compiler.nit +++ b/src/compiler/separate_compiler.nit @@ -1068,7 +1068,6 @@ class SeparateCompilerVisitor var tgs = rta.live_targets(callsite) if tgs.length == 1 then # DIRECT CALL - self.varargize(mmethod.intro, mmethod.intro.msignature.as(not null), args) var res0 = before_send(mmethod, args) var res = call(tgs.first, tgs.first.mclassdef.bound_mtype, args) if res0 != null then @@ -1084,8 +1083,6 @@ class SeparateCompilerVisitor end redef fun send(mmethod, arguments) do - self.varargize(mmethod.intro, mmethod.intro.msignature.as(not null), arguments) - if arguments.first.mcasttype.ctype != "val*" then # In order to shortcut the primitive, we need to find the most specific method # Howverr, because of performance (no flattening), we always work on the realmainmodule -- 1.7.9.5