From 177cca2e0ad8752022c3322f537ee836598b342a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Wed, 10 Nov 2010 14:03:50 +0100
Subject: BEAM loader: Fix bug in handling of "rest" arguments

It would only really work in simple case like:

  select_val S=q Fail=f Size=u Rest=* => ...

where all operands for a single instruction where bound to
variables, and not for more complicated cases such as:

  i_put_tuple Dst Arity Puts=* | put PutSrc => ...
---
 erts/emulator/beam/beam_load.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 2f335faad0..feac89784b 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -3992,14 +3992,17 @@ transform_engine(LoaderState* st)
 	case TOP_rest_args:
 	    {
 		int n = *pc++;
+		int formal_arity = gen_opc[instr->op].arity;
+		int num_vars = n + (instr->arity - formal_arity);
+		int j = formal_arity;
+
 		var = erts_alloc(ERTS_ALC_T_LOADER_TMP,
-				 instr->arity * sizeof(GenOpArg));
+				 num_vars * sizeof(GenOpArg));
 		for (i = 0; i < n; i++) {
 		    var[i] = def_vars[i];
 		}
-		while (i < instr->arity) {
-		    var[i] = instr->a[i];
-		    i++;
+		while (i < num_vars) {
+		    var[i++] = instr->a[j++];
 		}
 	    }
 	    break;
-- 
cgit v1.2.3