diff --git a/js-assembler/assemble-helpers.rkt b/js-assembler/assemble-helpers.rkt index 5ed24e8..a501723 100644 --- a/js-assembler/assemble-helpers.rkt +++ b/js-assembler/assemble-helpers.rkt @@ -298,18 +298,24 @@ (: assemble-label (Label Blockht -> String)) (define (assemble-label a-label Blockht) - (let ([chunks - (regexp-split #rx"[^a-zA-Z0-9]+" - (symbol->string (Label-name a-label)))]) + (define a-block (hash-ref Blockht (Label-name a-label))) + (cond + [(block-looks-like-context-expected-values? a-block) + => (lambda (expected) + (format "RT.si_context_expected(~a)" expected))] + [else + (define chunks + (regexp-split #rx"[^a-zA-Z0-9]+" + (symbol->string (Label-name a-label)))) (cond - [(empty? chunks) - (error "impossible: empty label ~s" a-label)] - [(empty? (rest chunks)) - (string-append "_" (first chunks))] - [else - (string-append "_" - (first chunks) - (apply string-append (map string-titlecase (rest chunks))))]))) + [(empty? chunks) + (error "impossible: empty label ~s" a-label)] + [(empty? (rest chunks)) + (string-append "_" (first chunks))] + [else + (string-append "_" + (first chunks) + (apply string-append (map string-titlecase (rest chunks))))])])) diff --git a/js-assembler/assemble.rkt b/js-assembler/assemble.rkt index 1d7f071..a96bc19 100644 --- a/js-assembler/assemble.rkt +++ b/js-assembler/assemble.rkt @@ -139,10 +139,23 @@ EOF [(symbol? stmt) (next)] [(LinkedLabel? stmt) - ;; Setting up multiple-value-return - (fprintf op "~a.mvr=~a;\n" - (assemble-label (make-Label (LinkedLabel-label stmt)) blockht) - (assemble-label (make-Label (LinkedLabel-linked-to stmt)) blockht)) + ;; Setting up multiple-value-return. + ;; Optimization: in the most common case (expecting only one), we optimize away + ;; the assignment, because there's a distinguished instruction, and it's implied + ;; that if .mvr is missing, that the block only expects one. + (define linked-to-block (hash-ref blockht (LinkedLabel-linked-to stmt))) + (cond + [(block-looks-like-context-expected-values? linked-to-block) + => (lambda (expected) + (cond + [(= expected 1) + (void)] + [else + (fprintf op "~a.mvr=RT.si_context_expected(~a);\n" expected)]))] + [else + (fprintf op "~a.mvr=~a;\n" + (assemble-label (make-Label (LinkedLabel-label stmt)) blockht) + (assemble-label (make-Label (LinkedLabel-linked-to stmt)) blockht))]) (next)] [(DebugPrint? stmt) (next)] diff --git a/js-assembler/runtime-src/baselib-functions.js b/js-assembler/runtime-src/baselib-functions.js index 3cdb988..f77d278 100644 --- a/js-assembler/runtime-src/baselib-functions.js +++ b/js-assembler/runtime-src/baselib-functions.js @@ -72,12 +72,12 @@ return MACHINE.c.pop().label(MACHINE); } else if (returnArgs.length === 0) { MACHINE.a = 0; - return MACHINE.c.pop().label.mvr(MACHINE); + return (MACHINE.c.pop().label.mvr || plt.runtime.si_context_expected_1)(MACHINE); } else { MACHINE.a = returnArgs.length; MACHINE.v = returnArgs.shift(); MACHINE.e.push.apply(MACHINE.e, returnArgs.reverse()); - return MACHINE.c.pop().label.mvr(MACHINE); + return (MACHINE.c.pop().label.mvr || plt.runtime.si_context_expected_1)(MACHINE); } }; diff --git a/js-assembler/runtime-src/runtime.js b/js-assembler/runtime-src/runtime.js index 9cbce07..1a3e8e8 100644 --- a/js-assembler/runtime-src/runtime.js +++ b/js-assembler/runtime-src/runtime.js @@ -817,6 +817,7 @@ exports['getTracedCalleeKey'] = getTracedCalleeKey; exports['si_context_expected'] = si_context_expected; + exports['si_context_expected_1'] = si_context_expected_1; exports['checkClosureAndArity'] = checkClosureAndArity;