Comma

Status: implemented

sergey-shandar directed its implementation in the LLM working session before it began, and approved the design in #3075, as DESIGN.md §12 requires.

const assert = (...a) => a[0] ? undefined : (() => { throw a[1]; })();
export default (...a) => (assert(a[0] >= 0, "negative"), a[0] + 2);

(a, b) establishes a, then b, and is the value of b, a's value discarded, as in JavaScript. Any number of operands may be written, (a, b, c) being c with a and b established. In a pure language the one thing a discarded operand can do is fail, which makes the comma the assertion form: (assert(a >= 0), a + 2) is a + 2 where the assertion holds, and the assertion's failure where it does not. Asserts express internal contract breaches, not input validation: untrusted input is validated with values, a Result or a Nullable, since a program that throws on its input can be crashed by whoever supplies it.

The comma is written in parentheses, the one place it can be told from every other comma: an argument list, an array's items and an object's entries are lists, f(a, b) calling with two arguments and [a, b] holding two items, as in JavaScript. A group, (a, b), may stand wherever a value may, and takes steps and operators as a group does (grouping): (a, b).x reads x of b, and 1 + (a, 2) is 3. Inside the parentheses the operands are values, so a comma never holds what only a parameter list may: (a, b = 1), (a, ...b) and (a, b,) are refused at the =, the ... and the ). The comma JavaScript reads with no parentheses of its own — return a, b and throw a, b in a block, the condition of if (a, b), while and switch, a substitution ${a, b} and a computed key x[a, b] — is refused at the comma, and the parentheses are the spelling there too, if ((a, b)) (refused constructs).

A list in parentheses followed by => is a function's parameters, as in JavaScript, so (a, b) => a + b is the function and (a, b) the comma; the two agree up to the ), and what follows it decides. Each parameter is then a binding target (parameters), and (a, b + 1) => 1 is refused at the b.

The comma is the one operator that detaches a receiver. (o.m)(a) is the method call o.m(a) is (grouping), where (0, o.m)(a) reads o.m and calls the function it holds as a plain one — JavaScript's detached call, which a function of this language, using no this, answers as it answers the method call. The read is a read: (0, a.at)(0) reads a built-in prototype's member, and is refused at the key as a.at alone is (property access), where JavaScript would throw.

Every operand is an eager position, as a container's item is: a const reached through any of them counts as reached for what a module or a body anchors (the anchoring rule). The comma makes no EDAG node where it stands. Its value is its last operand's node, and each discarded operand that is code is anchored by the comma at the nearest block root — the module's, a function body's, or the lazy operand it stands in, so c && (assert(c), 1) establishes the assertion only where c is truthy. A discarded operand that is no code is dropped: a reference, a literal and a function compute nothing a later node reads, and a const a reference names is anchored by its scope where nothing else reaches it. A discarded comma is its operands, each discarded in turn, so ((a.x, () => 1), 2) drops the function as (a.x, () => 1, 2) does. So const a = []; const b = a; export default (b, a.length); is ['.', A, 'length'] with no comma, b being a's node, where const a = []; const b = a.x; export default (b, a.length); keeps [',', [['.', A, 'x'], ['.', A, 'length']]], b being a node of its own that the result does not reach (fjs/compiler/edag). The failure contract governs execution: each operand's success is established before the result is revealed, in no promised order beyond that.

The FunctionalScript writer, the .js output, spells a discarded operand as the const of the block it is anchored in, the form it writes every anchor in: export default (...a) => (a.x, a.y); comes back as export default (...$0)=>{const $1=$0.x;return $0.y;};, and (0, o.f)() as the read of o.f into a const and the call of that. Read back, that text is the graph it was written from.

Examples

The compiler demo offers the programs comma in module.f.js, each with its real output.

The demo on this page runs the assertion form above with every output fjs compile makes of it: the expression graph (EDAG), the Rust and the WebAssembly that Rust builds to. Its Run button calls the default export with 1 and with -1, as JavaScript and as WebAssembly, and shows what each call returned or threw.

Reference

Demo

In FunctionalScript

fjs compile accepts this module, and it runs as JavaScript and as WebAssembly alike.

A FunctionalScript module and what fjs compile makes of it: the expression graph it lowers to, the Rust it compiles to on the NaNVM runtime, and the WebAssembly that Rust builds to. Run calls its default export with 1, then -1, first as the JavaScript it already is and then as WebAssembly, and shows what each call returned or threw and how long one call takes, timed over 1000 calls.

FunctionalScript source:

/**
 * The comma operator's assertion form, the example of
 * [`README.md`](./README.md): `a[0] + 2`
 * where `a[0] >= 0` holds, and the assertion's failure where it does not.
 *
 * @module
 */

/** @type {(...a: readonly unknown[]) => undefined} */
const assert = (...a) => a[0] ? undefined : (() => { throw a[1]; })();
/** @type {(...a: readonly number[]) => number} */
export default (...a) => (assert(a[0] >= 0, "negative"), a[0] + 2);

Expression graph (EDAG) that fjs compile lowers it to:

=>lengthframe 0body0=>,=>lengthbody0?:,anchorresult?:condthenelse.undefinedthrow()callee...frame 0[]+leftright.2.objidxrest0throwvalue[]01>="negative".objidxrest0.objidxrest1>=leftright.0.objidxrest0

The same graph, as fjs compile writes it to a .edag.data.js file:

const $0=["rest"];const $1=["rest"];export default ["{}",[[":","default",["=>",0,[["=>",0,[],["?:",[".",$0,0],["undefined"],["throw",[".",$0,1]]]]],[",",[["()",["frame",0],[[">=",[".",$1,0],0],"negative"]],["+",[".",$1,0],2]]]]]]];

Rust that fjs compile writes from it, on the NaNVM runtime:

// @generated by `fjs compile`. Do not edit: recompile the source module instead.

use nanvm_lib::vm::unstable::{f64_any, string_any, string_key};
use nanvm_lib::vm::{Any, Array, IStaticFunction, Nullish, ToAny, ToArray, ToObject};

#[rustfmt::skip]
#[allow(clippy::if_same_then_else)]
pub fn module<A: IStaticFunction>(_runtime: Any<A>) -> Result<Any<A>, Any<A>> {
    let _b6: Any<A> = A::static_function(|_self, _args| {
        let _b327: Any<A> = _args.rest(0).to_any();
        if Any::<A>::to_boolean((Any::dot(_b327.clone(), f64_any(0x0000000000000000)).end())?) { Ok(Nullish::Undefined.to_any()) } else { Err((Any::dot(_b327.clone(), f64_any(0x3ff0000000000000)).end())?) }
    }, 0, Array::default(), Some("(...$0)=>$0[0]?undefined:(()=>{throw $0[1];})()")).to_any();
    Ok([(string_key("default"), A::static_function(|_self, _args| {
        let _b768: Any<A> = _args.rest(0).to_any();
        let _b850: Any<A> = (Any::call(A::frame(_self)[0].clone(), [(Any::ge((Any::dot(_b768.clone(), f64_any(0x0000000000000000)).end())?, f64_any(0x0000000000000000)))?, string_any("negative")].to_array().to_any()))?;
        (Any::dot(_b768.clone(), f64_any(0x0000000000000000)).end())? + f64_any(0x4000000000000000)
    }, 0, [_b6.clone()].to_array(), Some("(...$1)=>{const $2=$0($1[0]>=0,\"negative\");return $1[0]+2;}")).to_any())].to_object().to_any())
}

WebAssembly text (WAT) of the functions compiled from this source, without the NaNVM runtime:

  (func $nanvm_demos::samples::comma::module::<nanvm_lib::naive::Naive> (;653;) (type 1) (param i32 i32)
    (local i32 i32 i32 i32 i32)
    global.get $__stack_pointer
    i32.const 128
    i32.sub
    local.tee 2
    global.set $__stack_pointer
    local.get 2
    i32.const 0
    i32.store8 offset=64
    local.get 2
    i32.const 24
    i32.add
    local.get 2
    i32.const 64
    i32.add
    call $"<core::iter::adapters::GenericShunt<core::iter::adapters::map::Map<core::iter::sources::empty::Empty<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>, core::result::Result<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>, ()>::Ok>, core::result::Result<core::convert::Infallible, ()>> as alloc::rc::ToRcSlice<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>>::to_rc_slice"
    local.get 2
    local.get 2
    i32.load offset=28
    local.tee 3
    i32.store offset=84
    local.get 2
    local.get 2
    i32.load offset=24
    local.tee 4
    i32.store offset=80
    block ;; label = @1
      block ;; label = @2
        local.get 2
        i32.load8_u offset=64
        i32.const 1
        i32.ne
        br_if 0 (;@2;)
        local.get 4
        local.get 4
        i32.load
        i32.const -1
        i32.add
        local.tee 0
        i32.store
        local.get 0
        br_if 1 (;@1;)
        local.get 2
        i32.const 80
        i32.add
        call $"<alloc::rc::Rc<[nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>]>>::drop_slow"
        br 1 (;@1;)
      end
      local.get 4
      i32.eqz
      br_if 0 (;@1;)
      local.get 2
      i32.const 184
      i32.const 0
      local.get 4
      local.get 3
      i32.const 1066266
      i32.const 47
      call $<nanvm_lib::naive::function::Function>::new
      local.tee 4
      i32.store offset=36
      local.get 2
      i32.const 7
      i32.store8 offset=32
      local.get 2
      i32.const 0
      i32.store16 offset=60
      local.get 2
      i32.const 1066166
      i32.store offset=56
      local.get 2
      i32.const 1066159
      i32.store offset=52
      local.get 2
      i32.const 80
      i32.add
      local.get 2
      i32.const 52
      i32.add
      call $"core::iter::adapters::try_process::<core::iter::adapters::map::Map<core::str::iter::EncodeUtf16, core::result::Result<u16, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>::Ok>, u16, core::result::Result<core::convert::Infallible, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>, <core::result::Result<alloc::rc::Rc<[u16]>, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>> as core::iter::traits::collect::FromIterator<core::result::Result<u16, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>>>::from_iter<core::iter::adapters::map::Map<core::str::iter::EncodeUtf16, core::result::Result<u16, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>::Ok>>::{closure#0}, alloc::rc::Rc<[u16]>>"
      block ;; label = @2
        block ;; label = @3
          block ;; label = @4
            block ;; label = @5
              local.get 2
              i32.load8_u offset=80
              local.tee 3
              i32.const 255
              i32.ne
              br_if 0 (;@5;)
              local.get 2
              i32.load offset=88
              local.set 5
              local.get 2
              i32.load offset=84
              local.set 6
              local.get 4
              local.get 4
              i32.load
              i32.const 1
              i32.add
              local.tee 3
              i32.store
              local.get 3
              i32.eqz
              br_if 1 (;@4;)
              local.get 2
              i32.const 0
              i32.store8 offset=52
              local.get 2
              i64.const 0
              i64.store offset=96
              local.get 2
              local.get 4
              i32.store offset=92
              local.get 2
              i32.const 7
              i32.store8 offset=88
              local.get 2
              i64.const 4294967296
              i64.store offset=80
              local.get 2
              local.get 2
              i32.const 52
              i32.add
              i32.store offset=104
              local.get 2
              i32.const 16
              i32.add
              local.get 2
              i32.const 80
              i32.add
              call $"<core::iter::adapters::GenericShunt<core::iter::adapters::map::Map<core::array::iter::IntoIter<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>, 1>, core::result::Result<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>, ()>::Ok>, core::result::Result<core::convert::Infallible, ()>> as alloc::rc::ToRcSlice<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>>::to_rc_slice"
              local.get 2
              local.get 2
              i32.load offset=20
              local.tee 3
              i32.store offset=68
              local.get 2
              local.get 2
              i32.load offset=16
              local.tee 4
              i32.store offset=64
              block ;; label = @6
                local.get 2
                i32.load8_u offset=52
                i32.const 1
                i32.ne
                br_if 0 (;@6;)
                local.get 4
                local.get 4
                i32.load
                i32.const -1
                i32.add
                local.tee 0
                i32.store
                local.get 0
                br_if 4 (;@2;)
                local.get 2
                i32.const 64
                i32.add
                call $"<alloc::rc::Rc<[nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>]>>::drop_slow"
                br 4 (;@2;)
              end
              local.get 4
              i32.eqz
              br_if 3 (;@2;)
              i32.const 191
              i32.const 0
              local.get 4
              local.get 3
              i32.const 1066527
              i32.const 59
              call $<nanvm_lib::naive::function::Function>::new
              local.set 4
              local.get 2
              i32.const 0
              i32.store8 offset=52
              local.get 2
              local.get 4
              i32.store offset=100
              local.get 2
              i32.const 7
              i32.store8 offset=96
              local.get 2
              local.get 5
              i32.store offset=92
              local.get 2
              local.get 6
              i32.store offset=88
              local.get 2
              i64.const 4294967296
              i64.store offset=80
              local.get 2
              local.get 2
              i32.const 52
              i32.add
              i32.store offset=112
              local.get 2
              i32.const 8
              i32.add
              local.get 2
              i32.const 80
              i32.add
              call $"<core::iter::adapters::GenericShunt<core::iter::adapters::map::Map<core::array::iter::IntoIter<(nanvm_lib::vm::string::String<nanvm_lib::naive::Naive>, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>), 1>, core::result::Result<(nanvm_lib::vm::string::String<nanvm_lib::naive::Naive>, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>), ()>::Ok>, core::result::Result<core::convert::Infallible, ()>> as alloc::rc::ToRcSlice<(nanvm_lib::vm::string::String<nanvm_lib::naive::Naive>, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>)>>::to_rc_slice"
              local.get 2
              local.get 2
              i32.load offset=12
              local.tee 3
              i32.store offset=68
              local.get 2
              local.get 2
              i32.load offset=8
              local.tee 4
              i32.store offset=64
              block ;; label = @6
                local.get 2
                i32.load8_u offset=52
                i32.const 1
                i32.ne
                br_if 0 (;@6;)
                local.get 4
                local.get 4
                i32.load
                i32.const -1
                i32.add
                local.tee 0
                i32.store
                local.get 0
                br_if 3 (;@3;)
                local.get 2
                i32.const 64
                i32.add
                call $"<alloc::rc::Rc<[(nanvm_lib::vm::string::String<nanvm_lib::naive::Naive>, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>)]>>::drop_slow"
                br 3 (;@3;)
              end
              local.get 4
              i32.eqz
              br_if 2 (;@3;)
              local.get 0
              local.get 3
              i32.store offset=16
              local.get 0
              local.get 4
              i32.store offset=12
              local.get 0
              i32.const 5
              i32.store8 offset=8
              local.get 0
              i64.const 0
              i64.store
              local.get 2
              i32.const 32
              i32.add
              call $"#func639 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
              local.get 1
              call $"#func639 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
              local.get 2
              i32.const 128
              i32.add
              global.set $__stack_pointer
              return
            end
            local.get 2
            local.get 2
            i32.load8_u offset=83
            i32.store8 offset=67
            local.get 2
            local.get 2
            i32.load16_u offset=81 align=1
            i32.store16 offset=65 align=1
            local.get 2
            local.get 2
            i32.load offset=92
            i32.store offset=76
            local.get 2
            local.get 2
            i64.load offset=84 align=4
            i64.store offset=68 align=4
            local.get 2
            local.get 3
            i32.store8 offset=64
            i32.const 1065572
            i32.const 43
            local.get 2
            i32.const 64
            i32.add
            i32.const 1065556
            i32.const 1065616
            call $core::result::unwrap_failed
          end
          unreachable
        end
        i32.const 1057428
        i32.const 43
        local.get 2
        i32.const 127
        i32.add
        i32.const 1057412
        i32.const 1057472
        call $core::result::unwrap_failed
        unreachable
      end
      i32.const 1057428
      i32.const 43
      local.get 2
      i32.const 127
      i32.add
      i32.const 1057412
      i32.const 1057472
      call $core::result::unwrap_failed
      unreachable
    end
    i32.const 1057428
    i32.const 43
    local.get 2
    i32.const 127
    i32.add
    i32.const 1057412
    i32.const 1057472
    call $core::result::unwrap_failed
    unreachable
  )
  (func $"<nanvm_demos::samples::comma::module<nanvm_lib::naive::Naive>::{closure#1} as core::ops::function::FnOnce<(&nanvm_lib::naive::function::Function, nanvm_lib::vm::array::Array<nanvm_lib::naive::Naive>)>>::call_once" (;654;) (type 4) (param i32 i32 i32 i32)
    (local i32 i32 i64 i32)
    global.get $__stack_pointer
    i32.const 256
    i32.sub
    local.tee 4
    global.set $__stack_pointer
    local.get 1
    i32.load
    local.set 1
    local.get 4
    local.get 3
    i32.store offset=12
    local.get 4
    local.get 2
    i32.store offset=8
    local.get 2
    local.get 2
    i32.load
    i32.const 1
    i32.add
    local.tee 5
    i32.store
    block ;; label = @1
      local.get 5
      i32.eqz
      br_if 0 (;@1;)
      local.get 4
      local.get 3
      i32.store offset=24
      local.get 4
      local.get 2
      i32.store offset=20
      local.get 4
      i32.const 6
      i32.store8 offset=16
      block ;; label = @2
        block ;; label = @3
          block ;; label = @4
            local.get 1
            i32.load offset=16
            i32.eqz
            br_if 0 (;@4;)
            block ;; label = @5
              block ;; label = @6
                block ;; label = @7
                  block ;; label = @8
                    block ;; label = @9
                      block ;; label = @10
                        block ;; label = @11
                          block ;; label = @12
                            local.get 1
                            i32.load offset=12
                            local.tee 1
                            i32.load8_u offset=8
                            local.tee 5
                            br_table 6 (;@6;) 6 (;@6;) 0 (;@12;) 1 (;@11;) 2 (;@10;) 3 (;@9;) 4 (;@8;) 5 (;@7;) 6 (;@6;)
                          end
                          local.get 1
                          i64.load offset=16
                          local.set 6
                          br 9 (;@2;)
                        end
                        local.get 1
                        i32.load offset=12
                        local.tee 3
                        local.get 3
                        i32.load
                        i32.const 1
                        i32.add
                        local.tee 7
                        i32.store
                        local.get 7
                        i32.eqz
                        br_if 9 (;@1;)
                        br 7 (;@3;)
                      end
                      local.get 1
                      i32.load offset=12
                      local.tee 3
                      local.get 3
                      i32.load
                      i32.const 1
                      i32.add
                      local.tee 7
                      i32.store
                      local.get 7
                      i32.eqz
                      br_if 8 (;@1;)
                      local.get 1
                      i64.load8_u offset=20
                      i64.const 32
                      i64.shl
                      local.get 1
                      i64.load32_u offset=16
                      i64.or
                      local.set 6
                      br 7 (;@2;)
                    end
                    local.get 1
                    i32.load offset=12
                    local.tee 3
                    local.get 3
                    i32.load
                    i32.const 1
                    i32.add
                    local.tee 7
                    i32.store
                    local.get 7
                    br_if 5 (;@3;)
                    br 7 (;@1;)
                  end
                  local.get 1
                  i32.load offset=12
                  local.tee 3
                  local.get 3
                  i32.load
                  i32.const 1
                  i32.add
                  local.tee 7
                  i32.store
                  local.get 7
                  br_if 4 (;@3;)
                  br 6 (;@1;)
                end
                local.get 1
                i32.load offset=12
                local.tee 3
                local.get 3
                i32.load
                i32.const 1
                i32.add
                local.tee 1
                i32.store
                local.get 1
                i32.eqz
                br_if 5 (;@1;)
                br 1 (;@5;)
              end
              local.get 1
              i32.load8_u offset=9
              local.set 1
            end
            br 2 (;@2;)
          end
          i32.const 0
          i32.const 0
          i32.const 1063408
          call $core::panicking::panic_bounds_check
          unreachable
        end
        local.get 1
        i64.load32_u offset=16
        local.set 6
      end
      local.get 4
      local.get 6
      i64.store offset=96
      local.get 4
      local.get 3
      i32.store offset=92
      local.get 4
      local.get 1
      i32.store8 offset=89
      local.get 4
      local.get 5
      i32.store8 offset=88
      block ;; label = @2
        block ;; label = @3
          block ;; label = @4
            block ;; label = @5
              block ;; label = @6
                block ;; label = @7
                  block ;; label = @8
                    block ;; label = @9
                      block ;; label = @10
                        block ;; label = @11
                          local.get 4
                          i32.load8_u offset=16
                          local.tee 1
                          br_table 6 (;@5;) 6 (;@5;) 0 (;@11;) 1 (;@10;) 2 (;@9;) 3 (;@8;) 4 (;@7;) 5 (;@6;) 6 (;@5;)
                        end
                        local.get 4
                        i64.load offset=24
                        local.set 6
                        br 8 (;@2;)
                      end
                      local.get 4
                      i32.load offset=20
                      local.tee 3
                      local.get 3
                      i32.load
                      i32.const 1
                      i32.add
                      local.tee 5
                      i32.store
                      local.get 5
                      i32.eqz
                      br_if 8 (;@1;)
                      br 6 (;@3;)
                    end
                    local.get 4
                    i32.load offset=20
                    local.tee 3
                    local.get 3
                    i32.load
                    i32.const 1
                    i32.add
                    local.tee 5
                    i32.store
                    local.get 5
                    i32.eqz
                    br_if 7 (;@1;)
                    local.get 4
                    i64.load8_u offset=28
                    i64.const 32
                    i64.shl
                    local.get 4
                    i64.load32_u offset=24
                    i64.or
                    local.set 6
                    br 6 (;@2;)
                  end
                  local.get 4
                  i32.load offset=20
                  local.tee 3
                  local.get 3
                  i32.load
                  i32.const 1
                  i32.add
                  local.tee 5
                  i32.store
                  local.get 5
                  i32.eqz
                  br_if 6 (;@1;)
                  br 4 (;@3;)
                end
                local.get 4
                i32.load offset=20
                local.tee 3
                local.get 3
                i32.load
                i32.const 1
                i32.add
                local.tee 5
                i32.store
                local.get 5
                i32.eqz
                br_if 5 (;@1;)
                br 3 (;@3;)
              end
              local.get 4
              i32.load offset=20
              local.tee 3
              local.get 3
              i32.load
              i32.const 1
              i32.add
              local.tee 5
              i32.store
              local.get 5
              i32.eqz
              br_if 4 (;@1;)
              br 1 (;@4;)
            end
            local.get 4
            i32.load8_u offset=17
            local.set 5
          end
          br 1 (;@2;)
        end
        local.get 4
        i64.load32_u offset=24
        local.set 6
      end
      local.get 4
      local.get 6
      i64.store offset=144
      local.get 4
      local.get 3
      i32.store offset=140
      local.get 4
      local.get 5
      i32.store8 offset=137
      local.get 4
      local.get 1
      i32.store8 offset=136
      local.get 4
      i64.const 0
      i64.store offset=192
      local.get 4
      i32.const 2
      i32.store8 offset=184
      local.get 4
      i32.const 104
      i32.add
      local.get 4
      i32.const 136
      i32.add
      local.get 4
      i32.const 184
      i32.add
      call $<nanvm_lib::vm::lambda::member::Member<nanvm_lib::naive::Naive>>::new
      block ;; label = @2
        block ;; label = @3
          block ;; label = @4
            block ;; label = @5
              local.get 4
              i32.load8_u offset=104
              i32.const 255
              i32.ne
              br_if 0 (;@5;)
              local.get 0
              local.get 4
              i64.load offset=120
              i64.store offset=16
              local.get 0
              local.get 4
              i64.load offset=112
              i64.store offset=8
              local.get 0
              i64.const 1
              i64.store
              local.get 4
              i32.const 88
              i32.add
              call $"#func639 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
              br 1 (;@4;)
            end
            local.get 4
            local.get 4
            i64.load offset=128
            i64.store offset=208
            local.get 4
            local.get 4
            i64.load offset=120
            i64.store offset=200
            local.get 4
            local.get 4
            i64.load offset=112
            i64.store offset=192
            local.get 4
            local.get 4
            i64.load offset=104
            i64.store offset=184
            local.get 4
            i32.const 136
            i32.add
            local.get 4
            i32.const 184
            i32.add
            call $<nanvm_lib::vm::lambda::member::Member<nanvm_lib::naive::Naive>>::own
            block ;; label = @5
              block ;; label = @6
                local.get 4
                i32.load8_u offset=136
                i32.const 255
                i32.eq
                br_if 0 (;@6;)
                local.get 4
                local.get 4
                i64.load offset=144
                i64.store offset=80
                local.get 4
                local.get 4
                i64.load offset=136
                i64.store offset=72
                br 1 (;@5;)
              end
              local.get 4
              i32.const 256
              i32.store16 offset=72
            end
            local.get 4
            i32.const 184
            i32.add
            call $"#func562 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
            local.get 4
            i32.const 200
            i32.add
            call $"#func562 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
            local.get 4
            i64.const 0
            i64.store offset=144
            local.get 4
            i32.const 2
            i32.store8 offset=136
            local.get 4
            i32.const 184
            i32.add
            local.get 4
            i32.const 72
            i32.add
            local.get 4
            i32.const 136
            i32.add
            call $nanvm_lib::vm::any::relational::compare::<nanvm_lib::naive::Naive>
            local.get 4
            i32.load8_u offset=185
            local.set 3
            block ;; label = @5
              local.get 4
              i32.load8_u offset=184
              local.tee 1
              i32.const 255
              i32.eq
              br_if 0 (;@5;)
              local.get 0
              local.get 4
              i64.load offset=192 align=2
              i64.store offset=16 align=2
              local.get 0
              local.get 4
              i64.load offset=186 align=2
              i64.store offset=10 align=2
              local.get 0
              local.get 3
              i32.store8 offset=9
              local.get 0
              local.get 1
              i32.store8 offset=8
              local.get 0
              i64.const 1
              i64.store
              local.get 4
              i32.const 88
              i32.add
              call $"#func639 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
              br 1 (;@4;)
            end
            local.get 4
            i32.const 0
            i32.store16 offset=180
            local.get 4
            i32.const 1067702
            i32.store offset=176
            local.get 4
            i32.const 1067694
            i32.store offset=172
            local.get 4
            i32.const 184
            i32.add
            local.get 4
            i32.const 172
            i32.add
            call $"core::iter::adapters::try_process::<core::iter::adapters::map::Map<core::str::iter::EncodeUtf16, core::result::Result<u16, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>::Ok>, u16, core::result::Result<core::convert::Infallible, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>, <core::result::Result<alloc::rc::Rc<[u16]>, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>> as core::iter::traits::collect::FromIterator<core::result::Result<u16, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>>>::from_iter<core::iter::adapters::map::Map<core::str::iter::EncodeUtf16, core::result::Result<u16, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>::Ok>>::{closure#0}, alloc::rc::Rc<[u16]>>"
            block ;; label = @5
              block ;; label = @6
                block ;; label = @7
                  block ;; label = @8
                    local.get 4
                    i32.load8_u offset=184
                    local.tee 1
                    i32.const 255
                    i32.ne
                    br_if 0 (;@8;)
                    local.get 4
                    i64.load offset=188 align=4
                    local.set 6
                    local.get 4
                    i32.const 0
                    i32.store8 offset=172
                    local.get 4
                    local.get 6
                    i64.store offset=212 align=4
                    local.get 4
                    i32.const 3
                    i32.store8 offset=208
                    local.get 4
                    local.get 3
                    i32.const 255
                    i32.and
                    i32.const 254
                    i32.lt_u
                    i32.store8 offset=193
                    local.get 4
                    i64.const 8589934592
                    i64.store offset=184
                    local.get 4
                    local.get 4
                    i32.const 172
                    i32.add
                    i32.store offset=224
                    local.get 4
                    i32.const 1
                    i32.store8 offset=192
                    local.get 4
                    local.get 4
                    i32.const 184
                    i32.add
                    call $"<core::iter::adapters::GenericShunt<core::iter::adapters::map::Map<core::array::iter::IntoIter<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>, 2>, core::result::Result<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>, ()>::Ok>, core::result::Result<core::convert::Infallible, ()>> as alloc::rc::ToRcSlice<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>>::to_rc_slice"
                    local.get 4
                    local.get 4
                    i32.load offset=4
                    local.tee 5
                    i32.store offset=140
                    local.get 4
                    local.get 4
                    i32.load
                    local.tee 3
                    i32.store offset=136
                    block ;; label = @9
                      local.get 4
                      i32.load8_u offset=172
                      i32.const 1
                      i32.ne
                      br_if 0 (;@9;)
                      local.get 3
                      local.get 3
                      i32.load
                      i32.const -1
                      i32.add
                      local.tee 2
                      i32.store
                      local.get 2
                      br_if 4 (;@5;)
                      local.get 4
                      i32.const 136
                      i32.add
                      call $"<alloc::rc::Rc<[nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>]>>::drop_slow"
                      br 4 (;@5;)
                    end
                    local.get 3
                    i32.eqz
                    br_if 3 (;@5;)
                    local.get 4
                    i32.const 56
                    i32.add
                    local.set 1
                    local.get 4
                    local.get 5
                    i32.store offset=240
                    local.get 4
                    local.get 3
                    i32.store offset=236
                    local.get 4
                    i32.const 6
                    i32.store8 offset=232
                    local.get 4
                    i32.const 48
                    i32.add
                    local.get 4
                    i32.const 88
                    i32.add
                    local.get 4
                    i32.const 232
                    i32.add
                    call $<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>::call
                    block ;; label = @9
                      local.get 4
                      i64.load offset=48
                      i64.const 1
                      i64.ne
                      br_if 0 (;@9;)
                      local.get 0
                      i64.const 1
                      i64.store
                      local.get 0
                      local.get 1
                      i64.load offset=8
                      i64.store offset=16
                      local.get 0
                      local.get 1
                      i64.load
                      i64.store offset=8
                      br 5 (;@4;)
                    end
                    local.get 4
                    local.get 1
                    i64.load offset=8
                    i64.store offset=40
                    local.get 4
                    local.get 1
                    i64.load
                    i64.store offset=32
                    block ;; label = @9
                      block ;; label = @10
                        block ;; label = @11
                          block ;; label = @12
                            block ;; label = @13
                              block ;; label = @14
                                block ;; label = @15
                                  block ;; label = @16
                                    local.get 4
                                    i32.load8_u offset=16
                                    local.tee 1
                                    br_table 6 (;@10;) 6 (;@10;) 0 (;@16;) 1 (;@15;) 2 (;@14;) 3 (;@13;) 4 (;@12;) 5 (;@11;) 6 (;@10;)
                                  end
                                  local.get 4
                                  i64.load offset=24
                                  local.set 6
                                  br 9 (;@6;)
                                end
                                local.get 4
                                i32.load offset=20
                                local.tee 3
                                local.get 3
                                i32.load
                                i32.const 1
                                i32.add
                                local.tee 5
                                i32.store
                                local.get 5
                                i32.eqz
                                br_if 13 (;@1;)
                                br 7 (;@7;)
                              end
                              local.get 4
                              i32.load offset=20
                              local.tee 3
                              local.get 3
                              i32.load
                              i32.const 1
                              i32.add
                              local.tee 5
                              i32.store
                              local.get 5
                              i32.eqz
                              br_if 12 (;@1;)
                              local.get 4
                              i64.load8_u offset=28
                              i64.const 32
                              i64.shl
                              local.get 4
                              i64.load32_u offset=24
                              i64.or
                              local.set 6
                              br 7 (;@6;)
                            end
                            local.get 4
                            i32.load offset=20
                            local.tee 3
                            local.get 3
                            i32.load
                            i32.const 1
                            i32.add
                            local.tee 5
                            i32.store
                            local.get 5
                            i32.eqz
                            br_if 11 (;@1;)
                            br 5 (;@7;)
                          end
                          local.get 4
                          i32.load offset=20
                          local.tee 3
                          local.get 3
                          i32.load
                          i32.const 1
                          i32.add
                          local.tee 5
                          i32.store
                          local.get 5
                          i32.eqz
                          br_if 10 (;@1;)
                          br 4 (;@7;)
                        end
                        local.get 4
                        i32.load offset=20
                        local.tee 3
                        local.get 3
                        i32.load
                        i32.const 1
                        i32.add
                        local.tee 5
                        i32.store
                        local.get 5
                        i32.eqz
                        br_if 9 (;@1;)
                        br 1 (;@9;)
                      end
                      local.get 4
                      i32.load8_u offset=17
                      local.set 5
                    end
                    br 2 (;@6;)
                  end
                  local.get 4
                  local.get 4
                  i32.load8_u offset=187
                  i32.store8 offset=139
                  local.get 4
                  local.get 4
                  i32.load16_u offset=185 align=1
                  i32.store16 offset=137 align=1
                  local.get 4
                  local.get 4
                  i32.load offset=196
                  i32.store offset=148
                  local.get 4
                  local.get 4
                  i64.load offset=188 align=4
                  i64.store offset=140 align=4
                  local.get 4
                  local.get 1
                  i32.store8 offset=136
                  i32.const 1065572
                  i32.const 43
                  local.get 4
                  i32.const 136
                  i32.add
                  i32.const 1065556
                  i32.const 1065616
                  call $core::result::unwrap_failed
                  unreachable
                end
                local.get 4
                i64.load32_u offset=24
                local.set 6
              end
              local.get 4
              local.get 6
              i64.store offset=240
              local.get 4
              local.get 3
              i32.store offset=236
              local.get 4
              local.get 5
              i32.store8 offset=233
              local.get 4
              local.get 1
              i32.store8 offset=232
              local.get 4
              i64.const 0
              i64.store offset=192
              local.get 4
              i32.const 2
              i32.store8 offset=184
              local.get 4
              i32.const 136
              i32.add
              local.get 4
              i32.const 232
              i32.add
              local.get 4
              i32.const 184
              i32.add
              call $<nanvm_lib::vm::lambda::member::Member<nanvm_lib::naive::Naive>>::new
              block ;; label = @6
                local.get 4
                i32.load8_u offset=136
                i32.const 255
                i32.ne
                br_if 0 (;@6;)
                local.get 0
                local.get 4
                i64.load offset=152
                i64.store offset=16
                local.get 0
                local.get 4
                i64.load offset=144
                i64.store offset=8
                local.get 0
                i64.const 1
                i64.store
                local.get 4
                i32.const 32
                i32.add
                call $"#func639 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
                br 2 (;@4;)
              end
              local.get 4
              local.get 4
              i64.load offset=160
              i64.store offset=208
              local.get 4
              local.get 4
              i64.load offset=152
              i64.store offset=200
              local.get 4
              local.get 4
              i64.load offset=144
              i64.store offset=192
              local.get 4
              local.get 4
              i64.load offset=136
              i64.store offset=184
              local.get 4
              i32.const 232
              i32.add
              local.get 4
              i32.const 184
              i32.add
              call $<nanvm_lib::vm::lambda::member::Member<nanvm_lib::naive::Naive>>::own
              block ;; label = @6
                block ;; label = @7
                  local.get 4
                  i32.load8_u offset=232
                  i32.const 255
                  i32.eq
                  br_if 0 (;@7;)
                  local.get 4
                  local.get 4
                  i64.load offset=240
                  i64.store offset=96
                  local.get 4
                  local.get 4
                  i64.load offset=232
                  i64.store offset=88
                  br 1 (;@6;)
                end
                local.get 4
                i32.const 256
                i32.store16 offset=88
              end
              local.get 4
              i32.const 184
              i32.add
              call $"#func562 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
              local.get 4
              i32.const 200
              i32.add
              call $"#func562 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
              local.get 4
              i64.const 4611686018427387904
              i64.store offset=192
              local.get 4
              i32.const 2
              i32.store8 offset=184
              local.get 0
              local.get 4
              i32.const 88
              i32.add
              local.get 4
              i32.const 184
              i32.add
              call $"<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive> as core::ops::arith::Add>::add"
              local.get 4
              i32.const 32
              i32.add
              call $"#func639 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
              local.get 4
              i32.const 16
              i32.add
              call $"#func639 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
              local.get 2
              local.get 2
              i32.load
              i32.const -1
              i32.add
              local.tee 0
              i32.store
              local.get 0
              br_if 3 (;@2;)
              br 2 (;@3;)
            end
            i32.const 1057428
            i32.const 43
            local.get 4
            i32.const 255
            i32.add
            i32.const 1057412
            i32.const 1057472
            call $core::result::unwrap_failed
            unreachable
          end
          local.get 4
          i32.const 16
          i32.add
          call $"#func639 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
          local.get 2
          local.get 2
          i32.load
          i32.const -1
          i32.add
          local.tee 0
          i32.store
          local.get 0
          br_if 1 (;@2;)
        end
        local.get 4
        i32.const 8
        i32.add
        call $"<alloc::rc::Rc<[nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>]>>::drop_slow"
      end
      local.get 4
      i32.const 256
      i32.add
      global.set $__stack_pointer
      return
    end
    unreachable
  )

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs