From 96b1d2584a622b6ef8a9ed65daad4acffb00d1df Mon Sep 17 00:00:00 2001 From: Peter Bex
Date: Thu, 21 Nov 2019 17:06:26 +0100 Subject: [PATCH] Add new ##core#rest-length form which speeds up case-lambda A case-lambda form will simply expand into something like (lambda rest (case (length rest) ((0) zero-arg-case) ((1) one-arg-case) ...)) The length call is the only thing that is "special", as can be verified with a simple test case like this: (define foo (case-lambda ((x) (+ x 1)) ((x y) (* x y)))) (print (foo 1)) (print (foo 2 3)) --- NEWS | 2 +- c-backend.scm | 9 +++++++++ core.scm | 10 ++++++++-- optimizer.scm | 1 + 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index dde34053..477ffa40 100644 --- a/NEWS +++ b/NEWS @@ -38,7 +38,7 @@ - Inline files no longer refer to unexported foreign stub functions (fixes #1440, thanks to "megane"). - In some cases, rest argument lists do not need to be reified, which - should make using optional arguments faster (#1623). + should make using optional arguments and case-lambda faster (#1623). - Module system - Trying to export a foreign variable, define-inlined procedure or diff --git a/c-backend.scm b/c-backend.scm index 2af59829..ef8c12b1 100644 --- a/c-backend.scm +++ b/c-backend.scm @@ -199,6 +199,15 @@ (gen "C_rest_nullp(c," (+ depth n) ")") (gen "C_mk_bool(C_unfix(C_i_length(t" (sub1 n) ")) >= " depth ")")))) + ((##core#rest-length) + (let* ((n (lambda-literal-argument-count ll)) + (depth (second params)) + (have-av? (not (or (lambda-literal-customizable ll) + (lambda-literal-direct ll))))) + (if have-av? + (gen "C_fix(c - " (+ depth n) ")") + (gen "C_u_i_length(t" (sub1 n) ")")))) + ((##core#unbox) (gen "((C_word*)") (expr (car subs) i) diff --git a/core.scm b/core.scm index baeacb67..4623122b 100644 --- a/core.scm +++ b/core.scm @@ -180,7 +180,8 @@ ; [##core#switch {