From cc7fc6b667453c35c76d0304590fa38a29819de4 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sat, 21 Feb 2026 17:03:00 -0600 Subject: [PATCH] fix inlining default params issue --- streamline.cm | 12 ++++++ vm_suite.ce | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/streamline.cm b/streamline.cm index 9e6883c4..86376382 100644 --- a/streamline.cm +++ b/streamline.cm @@ -2809,7 +2809,19 @@ var streamline = function(ir, log) { cont_label = label_prefix + "cont" // Build inlined body with remapping + // Unmapped params (e.g. caller passes 1 arg to a 2-param function) + // must be explicitly nulled. compress_slots may merge the fresh + // slot (base+j) with a previously-live slot that holds a non-null + // value, so the default-param jump_not_null preamble would skip + // the default assignment and use a stale value instead. inlined_body = [] + j = 0 + while (j <= callee_func.nr_args) { + if (!(j < length(arg_slots) && arg_slots[j] >= 0)) { + inlined_body[] = ["null", remap[j], 0, 0] + } + j = j + 1 + } k = 0 while (k < length(callee_func.instructions)) { cinstr = callee_func.instructions[k] diff --git a/vm_suite.ce b/vm_suite.ce index 15ba88c0..6e1605fc 100644 --- a/vm_suite.ce +++ b/vm_suite.ce @@ -3555,6 +3555,113 @@ run("inline map empty array", function() { if (length(result) != 0) fail("map of empty should be empty") }) +// ============================================================================ +// NUMERIC INTRINSIC CALLBACK INLINING +// ============================================================================ + +var mymap = function(arr, fn) { + var result = array(length(arr)) + var i = 0 + while (i < length(arr)) { + result[i] = fn(arr[i]) + i = i + 1 + } + return result +} + +var myfold = function(arr, fn) { + var acc = arr[0] + var i = 1 + while (i < length(arr)) { + acc = fn(acc, arr[i]) + i = i + 1 + } + return acc +} + +run("inline callback abs", function() { + var result = mymap([-3, 5, -1.5, 0], function(a) { return abs(a) }) + assert_eq(result[0], 3, "abs(-3)") + assert_eq(result[1], 5, "abs(5)") + assert_eq(result[2], 1.5, "abs(-1.5)") + assert_eq(result[3], 0, "abs(0)") +}) + +run("inline callback neg", function() { + var result = mymap([3, -5, 0, 1.5], function(a) { return neg(a) }) + assert_eq(result[0], -3, "neg(3)") + assert_eq(result[1], 5, "neg(-5)") + assert_eq(result[2], 0, "neg(0)") + assert_eq(result[3], -1.5, "neg(1.5)") +}) + +run("inline callback sign", function() { + var result = mymap([-7, 0, 42, -0.5], function(a) { return sign(a) }) + assert_eq(result[0], -1, "sign(-7)") + assert_eq(result[1], 0, "sign(0)") + assert_eq(result[2], 1, "sign(42)") + assert_eq(result[3], -1, "sign(-0.5)") +}) + +run("inline callback fraction", function() { + var result = mymap([3.75, -2.5, 5.0], function(a) { return fraction(a) }) + assert_eq(result[0], 0.75, "fraction(3.75)") + assert_eq(result[1], -0.5, "fraction(-2.5)") + assert_eq(result[2], 0, "fraction(5.0)") +}) + +run("inline callback floor", function() { + var result = mymap([3.7, -2.3, 5.0, 1.9], function(a) { return floor(a) }) + assert_eq(result[0], 3, "floor(3.7)") + assert_eq(result[1], -3, "floor(-2.3)") + assert_eq(result[2], 5, "floor(5.0)") + assert_eq(result[3], 1, "floor(1.9)") +}) + +run("inline callback ceiling", function() { + var result = mymap([3.2, -2.7, 5.0, 1.1], function(a) { return ceiling(a) }) + assert_eq(result[0], 4, "ceiling(3.2)") + assert_eq(result[1], -2, "ceiling(-2.7)") + assert_eq(result[2], 5, "ceiling(5.0)") + assert_eq(result[3], 2, "ceiling(1.1)") +}) + +run("inline callback round", function() { + var result = mymap([3.5, -2.5, 5.0, 1.4], function(a) { return round(a) }) + assert_eq(result[0], 4, "round(3.5)") + assert_eq(result[1], -3, "round(-2.5)") + assert_eq(result[2], 5, "round(5.0)") + assert_eq(result[3], 1, "round(1.4)") +}) + +run("inline callback trunc", function() { + var result = mymap([3.7, -2.3, 5.0, -1.9], function(a) { return trunc(a) }) + assert_eq(result[0], 3, "trunc(3.7)") + assert_eq(result[1], -2, "trunc(-2.3)") + assert_eq(result[2], 5, "trunc(5.0)") + assert_eq(result[3], -1, "trunc(-1.9)") +}) + +run("inline callback max", function() { + var result = myfold([3, 7, 2, 9, 1], function(a, b) { return max(a, b) }) + assert_eq(result, 9, "max reduce") +}) + +run("inline callback min", function() { + var result = myfold([3, 7, 2, 9, 1], function(a, b) { return min(a, b) }) + assert_eq(result, 1, "min reduce") +}) + +run("inline callback modulo", function() { + var result = myfold([17, 5], function(a, b) { return modulo(a, b) }) + assert_eq(result, 2, "modulo") +}) + +run("inline callback remainder", function() { + var result = myfold([-17, 5], function(a, b) { return remainder(a, b) }) + assert_eq(result, -2, "remainder") +}) + // ============================================================================ // STRING METHOD EDGE CASES // ============================================================================