Numbers

Status: implemented

A number is written with JSON number syntax less its sign: an integer part, an optional fraction, an optional exponent. A leading - is not part of the literal but the unary minus applied to it, which is why - 42.5 is the same value written with a space.

export default [0, -42.5, 3e2, 1E-7];

A literal denotes the IEEE 754 double nearest its decimal value, as it does in JavaScript and in JSON.parse: digits beyond a double's precision round away, so 9007199254740993 is 9007199254740992; a literal too large for a double is Infinity (1e400); and one too small is 0 (1e-400), which is why -1e-400 is -0. A .json input reads its numbers the same way. An overflowed literal is an Infinity like any other, written as the word where a format has one and refused by a .json output (output).

A number may also be written in binary, as JavaScript writes it: 0b or 0B followed by one or more 0 or 1 digits. 0b101010 is 42; conversion rounds to the nearest double, as for decimal and hexadecimal literals. A binary literal has no fraction or exponent. Missing digits, other digits or a word directly after the literal are errors. The n suffix gives an exact bigint at any width: 0B101n is 5n. Outputs write the value in decimal; unary negation also preserves -0b0 as -0. A single _ may separate digits in decimal integer parts, fractions and exponents, and in binary or hexadecimal digits: 1_000, 1.2_5e1_0, 0b1010_0011, 0xFF_FF, and 1_000n. Separators do not change the value. Leading, trailing or repeated separators, separators next to a radix prefix, decimal point, exponent marker or sign, or bigint suffix, and separators after a leading decimal zero are errors.

A number may also be written in hexadecimal, as JavaScript writes it: 0x or 0X, then one or more digits 0–9, a–f or A–F. It denotes the double nearest the integer its digits spell, as a decimal literal does, so 0xFF is 255 and 0x20000000000001 is 9007199254740992. It has no fraction and no exponent: after 0x, e is a digit, so 0x10e1 is 4321, and a . after the digits is the next token, so 0x10.length is an access, as in JavaScript. 0x with no digit, and a word or a digit standing directly after the literal (0xg, 0x1g), are errors in both languages. The spelling is the source's and not the value's: every output writes 0xFF exactly as it writes 255 — 255 in the .js, DataJS, JSON and EDAG outputs, and the double's bits in .rs — as it writes a single-quoted string between double quotes, and two modules that differ only in it are one graph.

export default [0xFF, 0XfF, 0x10e1];

Otherwise the syntax is JSON's, so the other JavaScript spellings JSON leaves out are not recognized: no octal (0o7) prefix, no leading +, no leading decimal point (.5), and no trailing decimal point without a fractional digit (1.). The three numbers JSON cannot spell are written as the words JavaScript gives them — NaN, Infinity and -Infinity — exactly as DataJS writes them:

export default [NaN, Infinity, -Infinity];

NaN and Infinity are reserved words, like undefined: a module cannot bind or shadow them, so each denotes its value wherever a value stands. Array is reserved the same way, for a different reason: it denotes no value here, and is the one word the right side of instanceof may be (operators), so a module that could bind it would mean something else by it.

They still name a property, as every reserved word does: { NaN: 1 } and a.NaN are a key and an access, and mean the string "NaN", exactly as in JavaScript, where a property is named by an IdentifierName and a value by an IdentifierReference. -Infinity names nothing in either language: it is two tokens in both — the operator and the word — which no property name may be.

FunctionalScript has one NaN. IEEE 754 gives a NaN a sign and a payload, and a JavaScript program can read them — through a typed array or a DataView, which FunctionalScript has none of. Nothing else tells two NaNs apart: every operator, coercion and comparison treats each the same, Object.is included, and each is written as the word NaN. So a NaN's bits are not serializable data, hence not an observation and not a compatibility question (principles): every NaN is the one value, and a writer may spell them all as one — the Rust writer spells each as the quiet NaN with an empty payload.

The - is the unary minus operator (operators), the first operator the language had; ~, the bitwise not operator, !, the logical not operator, and typeof are the other prefixes — ~ Stage A of the same operators document, ! and typeof the rows admitted after both stages. None is part of the literal after it: -42.5 is the negation of 42.5, - 42.5 is the same value written with a space, and -NaN and -Infinity are values as JavaScript has them. Each binds looser than a property access or a call, as in JavaScript, so -1 .x is -(1 .x) and -1() is -(1()). What any of them takes is JavaScript's UnaryExpression, which an arrow function is not, so -(...a) => 1, ~(...a) => 1, !(...a) => 1 and typeof (...a) => 1 are syntax errors in both, and none stands immediately before ** — -2 ** 2 is refused, matching JavaScript, where (-2) ** 2 and -(2 ** 2) are the parenthesized readings — though either may stand right after it, as in JavaScript: 2 ** -2 is 2 ** (-2) and 2 ** ~2 is 2 ** (~2). Two adjacent - characters are the decrement operator, which the language has no rule for, so a negation of a negation is spaced, - -1, or grouped, -(-1). ~ and ! have no such token, in JavaScript or here, so ~~1 is two bitwise nots, the same as ~ ~1, and !!1 two logical nots. Operators has the rest of them.

A negative number is therefore an expression rather than a literal in the syntax. The graph is another matter: lowering folds a negation into a leaf when its operand lowers to a number or a bigint, since negating one is exact arithmetic, so the EDAG of -1 is the leaf -1 and not an operation. The operand is judged as lowered, not as written: a numeric literal, NaN or Infinity, a const holding a number or a bigint — a captured one included — and another folded negation all fold, so const a = 1; export default - -a; is the leaf 1, and its FunctionalScript output is export default 1;. An import of a number or a bigint folds too where it lowers to that value, which it does from a module that computes nothing but its default export, as a JSON document does; from any other module it lowers to that module's computation — its statement sequence, or a read of its export object when the module exports more than default — and stays an operation. A negation of anything else stays one too: of a string, a boolean, null, undefined or a container, since folding it would mean saying what that value converts to, and of an access, a parameter or a call, whose value lowering does not compute. No other operator folds, even over numbers: ~1 and 1 + 2 stay nodes, and -1 * 2 multiplies the leaf -1.

A .json or DataJS output computes a negation that survives lowering, using JavaScript's coercion rules. For a primitive, a bigint stays a bigint, and any other primitive converts to a number — -"2" is -2, -true is -1, -null and -"" are -0, and -undefined and -"abc" are NaN, which a .json output then has no spelling for. A negation of an array or an object first uses ToPrimitive: -[5] is -5 and -{} is NaN. Own valueOf or toString functions participate in that conversion and can fail. JSON then refuses a result such as NaN that it cannot represent; DataJS writes it. The EDAG and FunctionalScript outputs keep an unfolded negation as code (output).

Examples

The compiler demo has no programs for this page yet: its accepted and refused examples are a follow-up.

The demo on this page runs sample.f.js, this page's example as a function of one number — number literals: an integer, a fraction, and exponent forms — 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 0, 1, 2 and 3, as JavaScript and as WebAssembly, and shows what each call returned or threw.

export default (...a) => [0, -42.5, 3e2, 1E-7][Number(a[0])] * 2;

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 0, then 1, then 2, then 3, 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 example of [`README.md`](./README.md) (Numbers) as a function of one
 * number, for the page's WASM demo: number literals: an integer, a fraction,
 * and exponent forms.
 *
 * @module
 */

/** @type {(...a: readonly number[]) => unknown} */
export default (...a) => [0, -42.5, 3e2, 1E-7][Number(a[0])] * 2;

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

=>lengthbody0**leftright.2.objidx[]01230-42.53001e-7Numberoperand.objidxrest0

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

export default ["{}",[[":","default",["=>",0,[],["*",[".",["[]",[0,-42.5,300,1e-7]],["Number",[".",["rest"],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_key};
use nanvm_lib::vm::{Any, Array, IStaticFunction, ToAny, ToArray, ToObject};

#[rustfmt::skip]
#[allow(clippy::if_same_then_else)]
pub fn module<A: IStaticFunction>(_runtime: Any<A>) -> Result<Any<A>, Any<A>> {
    Ok([(string_key("default"), A::static_function(|_self, _args| {
        let _b264: Any<A> = _args.rest(0).to_any();
        (Any::dot([f64_any(0x0000000000000000), f64_any(0xc045400000000000), f64_any(0x4072c00000000000), f64_any(0x3e7ad7f29abcaf48)].to_array().to_any(), (Any::number((Any::dot(_b264.clone(), f64_any(0x0000000000000000)).end())?))?).end())? * f64_any(0x4000000000000000)
    }, 0, Array::default(), Some("(...$0)=>[0,-42.5,300,1e-7][Number($0[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::numbers::module::<nanvm_lib::naive::Naive> (;481;) (type 1) (param i32 i32)
    (local i32 i32 i32 i32 i32)
    global.get $__stack_pointer
    i32.const 96
    i32.sub
    local.tee 2
    global.set $__stack_pointer
    local.get 2
    i32.const 0
    i32.store16 offset=28
    local.get 2
    i32.const 1063531
    i32.store offset=24
    local.get 2
    i32.const 1063524
    i32.store offset=20
    local.get 2
    i32.const 48
    i32.add
    local.get 2
    i32.const 20
    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 = @1
      block ;; label = @2
        block ;; label = @3
          local.get 2
          i32.load8_u offset=48
          local.tee 3
          i32.const 255
          i32.ne
          br_if 0 (;@3;)
          local.get 2
          i32.load offset=56
          local.set 4
          local.get 2
          i32.load offset=52
          local.set 5
          local.get 2
          i32.const 0
          i32.store8 offset=32
          local.get 2
          i32.const 8
          i32.add
          local.get 2
          i32.const 32
          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=12
          local.tee 6
          i32.store offset=52
          local.get 2
          local.get 2
          i32.load offset=8
          local.tee 3
          i32.store offset=48
          block ;; label = @4
            local.get 2
            i32.load8_u offset=32
            i32.const 1
            i32.ne
            br_if 0 (;@4;)
            local.get 3
            local.get 3
            i32.load
            i32.const -1
            i32.add
            local.tee 0
            i32.store
            local.get 0
            br_if 3 (;@1;)
            local.get 2
            i32.const 48
            i32.add
            call $"<alloc::rc::Rc<[nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>]>>::drop_slow"
            br 3 (;@1;)
          end
          local.get 3
          i32.eqz
          br_if 2 (;@1;)
          i32.const 116
          i32.const 0
          local.get 3
          local.get 6
          i32.const 1063531
          i32.const 44
          call $<nanvm_lib::naive::function::Function>::new
          local.set 3
          local.get 2
          i32.const 0
          i32.store8 offset=20
          local.get 2
          local.get 3
          i32.store offset=68
          local.get 2
          i32.const 7
          i32.store8 offset=64
          local.get 2
          local.get 4
          i32.store offset=60
          local.get 2
          local.get 5
          i32.store offset=56
          local.get 2
          i64.const 4294967296
          i64.store offset=48
          local.get 2
          local.get 2
          i32.const 20
          i32.add
          i32.store offset=80
          local.get 2
          local.get 2
          i32.const 48
          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=4
          local.tee 4
          i32.store offset=36
          local.get 2
          local.get 2
          i32.load
          local.tee 3
          i32.store offset=32
          block ;; label = @4
            local.get 2
            i32.load8_u offset=20
            i32.const 1
            i32.ne
            br_if 0 (;@4;)
            local.get 3
            local.get 3
            i32.load
            i32.const -1
            i32.add
            local.tee 0
            i32.store
            local.get 0
            br_if 2 (;@2;)
            local.get 2
            i32.const 32
            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 2 (;@2;)
          end
          local.get 3
          i32.eqz
          br_if 1 (;@2;)
          local.get 0
          local.get 4
          i32.store offset=16
          local.get 0
          local.get 3
          i32.store offset=12
          local.get 0
          i32.const 5
          i32.store8 offset=8
          local.get 0
          i64.const 0
          i64.store
          local.get 1
          call $"#func480 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
          local.get 2
          i32.const 96
          i32.add
          global.set $__stack_pointer
          return
        end
        local.get 2
        local.get 2
        i32.load8_u offset=51
        i32.store8 offset=35
        local.get 2
        local.get 2
        i32.load16_u offset=49 align=1
        i32.store16 offset=33 align=1
        local.get 2
        local.get 2
        i32.load offset=60
        i32.store offset=44
        local.get 2
        local.get 2
        i64.load offset=52 align=4
        i64.store offset=36 align=4
        local.get 2
        local.get 3
        i32.store8 offset=32
        i32.const 1065572
        i32.const 43
        local.get 2
        i32.const 32
        i32.add
        i32.const 1065556
        i32.const 1065616
        call $core::result::unwrap_failed
        unreachable
      end
      i32.const 1057428
      i32.const 43
      local.get 2
      i32.const 95
      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 95
    i32.add
    i32.const 1057412
    i32.const 1057472
    call $core::result::unwrap_failed
    unreachable
  )
  (func $"<nanvm_demos::samples::numbers::module<nanvm_lib::naive::Naive>::{closure#0} as core::ops::function::FnOnce<(&nanvm_lib::naive::function::Function, nanvm_lib::vm::array::Array<nanvm_lib::naive::Naive>)>>::call_once" (;482;) (type 4) (param i32 i32 i32 i32)
    (local i32 i32 i32 f64)
    global.get $__stack_pointer
    i32.const 256
    i32.sub
    local.tee 4
    global.set $__stack_pointer
    local.get 4
    local.get 3
    i32.store offset=20
    local.get 4
    local.get 2
    i32.store offset=16
    local.get 2
    local.get 2
    i32.load
    i32.const 1
    i32.add
    local.tee 5
    i32.store
    block ;; label = @1
      block ;; label = @2
        block ;; label = @3
          block ;; label = @4
            local.get 5
            i32.eqz
            br_if 0 (;@4;)
            local.get 4
            local.get 3
            i32.store offset=32
            local.get 4
            local.get 2
            i32.store offset=28
            local.get 4
            i32.const 6
            i32.store8 offset=24
            local.get 4
            i32.const 0
            i32.store8 offset=88
            local.get 4
            i64.const 4502148214488346440
            i64.store offset=216
            local.get 4
            i32.const 2
            i32.store8 offset=208
            local.get 4
            i64.const 4643985272004935680
            i64.store offset=200
            local.get 4
            i32.const 2
            i32.store8 offset=192
            local.get 4
            i64.const -4592193876290174976
            i64.store offset=184
            local.get 4
            i32.const 2
            i32.store8 offset=176
            local.get 4
            i64.const 0
            i64.store offset=168
            local.get 4
            i32.const 2
            i32.store8 offset=160
            local.get 4
            i64.const 17179869184
            i64.store offset=152
            local.get 4
            local.get 4
            i32.const 88
            i32.add
            i32.store offset=224
            local.get 4
            i32.const 8
            i32.add
            local.get 4
            i32.const 152
            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>, 4>, 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=12
            local.tee 6
            i32.store offset=124
            local.get 4
            local.get 4
            i32.load offset=8
            local.tee 5
            i32.store offset=120
            block ;; label = @5
              local.get 4
              i32.load8_u offset=88
              i32.const 1
              i32.ne
              br_if 0 (;@5;)
              local.get 5
              local.get 5
              i32.load
              i32.const -1
              i32.add
              local.tee 2
              i32.store
              local.get 2
              br_if 4 (;@1;)
              local.get 4
              i32.const 120
              i32.add
              call $"<alloc::rc::Rc<[nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>]>>::drop_slow"
              br 4 (;@1;)
            end
            local.get 5
            i32.eqz
            br_if 3 (;@1;)
            local.get 4
            local.get 6
            i32.store offset=240
            local.get 4
            local.get 5
            i32.store offset=236
            local.get 4
            i32.const 6
            i32.store8 offset=232
            local.get 2
            local.get 2
            i32.load
            i32.const 1
            i32.add
            local.tee 5
            i32.store
            local.get 5
            i32.eqz
            br_if 0 (;@4;)
            local.get 4
            local.get 2
            i32.store offset=124
            local.get 4
            i32.const 6
            i32.store8 offset=120
            local.get 4
            local.get 3
            i64.extend_i32_u
            i64.store offset=128
            local.get 4
            i64.const 0
            i64.store offset=160
            local.get 4
            i32.const 2
            i32.store8 offset=152
            local.get 4
            i32.const 88
            i32.add
            local.get 4
            i32.const 120
            i32.add
            local.get 4
            i32.const 152
            i32.add
            call $<nanvm_lib::vm::lambda::member::Member<nanvm_lib::naive::Naive>>::new
            block ;; label = @5
              block ;; label = @6
                local.get 4
                i32.load8_u offset=88
                i32.const 255
                i32.ne
                br_if 0 (;@6;)
                local.get 0
                local.get 4
                i64.load offset=104
                i64.store offset=16
                local.get 0
                local.get 4
                i64.load offset=96
                i64.store offset=8
                local.get 0
                i64.const 1
                i64.store
                local.get 4
                i32.const 232
                i32.add
                call $"#func480 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
                br 1 (;@5;)
              end
              local.get 4
              local.get 4
              i64.load offset=112
              i64.store offset=176
              local.get 4
              local.get 4
              i64.load offset=104
              i64.store offset=168
              local.get 4
              local.get 4
              i64.load offset=96
              i64.store offset=160
              local.get 4
              local.get 4
              i64.load offset=88
              i64.store offset=152
              local.get 4
              i32.const 120
              i32.add
              local.get 4
              i32.const 152
              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=120
                  i32.const 255
                  i32.eq
                  br_if 0 (;@7;)
                  local.get 4
                  local.get 4
                  i64.load offset=128
                  i64.store offset=48
                  local.get 4
                  local.get 4
                  i64.load offset=120
                  i64.store offset=40
                  br 1 (;@6;)
                end
                local.get 4
                i32.const 256
                i32.store16 offset=40
              end
              local.get 4
              i32.const 152
              i32.add
              call $"#func562 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
              local.get 4
              i32.const 168
              i32.add
              call $"#func562 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
              local.get 4
              i32.const 152
              i32.add
              local.get 4
              i32.const 40
              i32.add
              call $<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>::to_numeric
              local.get 4
              f64.load offset=168
              local.set 7
              local.get 4
              i32.load offset=164
              local.set 3
              local.get 4
              i32.load offset=160
              local.set 5
              block ;; label = @6
                local.get 4
                i32.load offset=152
                br_if 0 (;@6;)
                block ;; label = @7
                  local.get 5
                  i32.const 1
                  i32.ne
                  br_if 0 (;@7;)
                  local.get 4
                  local.get 7
                  f64.store offset=156 align=4
                  local.get 4
                  local.get 3
                  i32.store offset=152
                  local.get 4
                  i32.const 152
                  i32.add
                  call $<nanvm_lib::vm::bigint::BigInt<nanvm_lib::naive::Naive>>::to_number
                  local.set 7
                  local.get 3
                  local.get 3
                  i32.load
                  i32.const -1
                  i32.add
                  local.tee 5
                  i32.store
                  local.get 5
                  br_if 0 (;@7;)
                  local.get 4
                  i32.const 152
                  i32.add
                  call $"<alloc::rc::Rc<[u64]>>::drop_slow"
                end
                local.get 4
                local.get 7
                f64.store offset=64
                local.get 4
                i32.const 2
                i32.store offset=56
                local.get 4
                i32.const 120
                i32.add
                local.get 4
                i32.const 232
                i32.add
                local.get 4
                i32.const 56
                i32.add
                call $<nanvm_lib::vm::lambda::member::Member<nanvm_lib::naive::Naive>>::new
                block ;; label = @7
                  local.get 4
                  i32.load8_u offset=120
                  i32.const 255
                  i32.ne
                  br_if 0 (;@7;)
                  local.get 0
                  local.get 4
                  i64.load offset=136
                  i64.store offset=16
                  local.get 0
                  local.get 4
                  i64.load offset=128
                  i64.store offset=8
                  local.get 0
                  i64.const 1
                  i64.store
                  br 2 (;@5;)
                end
                local.get 4
                local.get 4
                i64.load offset=144
                i64.store offset=176
                local.get 4
                local.get 4
                i64.load offset=136
                i64.store offset=168
                local.get 4
                local.get 4
                i64.load offset=128
                i64.store offset=160
                local.get 4
                local.get 4
                i64.load offset=120
                i64.store offset=152
                local.get 4
                i32.const 232
                i32.add
                local.get 4
                i32.const 152
                i32.add
                call $<nanvm_lib::vm::lambda::member::Member<nanvm_lib::naive::Naive>>::own
                block ;; label = @7
                  block ;; label = @8
                    local.get 4
                    i32.load8_u offset=232
                    i32.const 255
                    i32.eq
                    br_if 0 (;@8;)
                    local.get 4
                    local.get 4
                    i64.load offset=240
                    i64.store offset=80
                    local.get 4
                    local.get 4
                    i64.load offset=232
                    i64.store offset=72
                    br 1 (;@7;)
                  end
                  local.get 4
                  i32.const 256
                  i32.store16 offset=72
                end
                local.get 4
                i32.const 152
                i32.add
                call $"#func562 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
                local.get 4
                i32.const 168
                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=160
                local.get 4
                i32.const 2
                i32.store8 offset=152
                local.get 0
                local.get 4
                i32.const 72
                i32.add
                local.get 4
                i32.const 152
                i32.add
                call $"<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>::numeric_op::<<nanvm_lib::vm::numeric::Numeric<nanvm_lib::naive::Naive> as core::ops::arith::Mul>::mul>"
                local.get 4
                i32.const 24
                i32.add
                call $"#func480 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
                local.get 2
                local.get 2
                i32.load
                i32.const -1
                i32.add
                local.tee 3
                i32.store
                local.get 3
                br_if 4 (;@2;)
                br 3 (;@3;)
              end
              local.get 0
              local.get 7
              f64.store offset=16
              local.get 0
              local.get 3
              i32.store offset=12
              local.get 0
              local.get 5
              i32.store offset=8
              local.get 0
              i64.const 1
              i64.store
              local.get 4
              i32.const 232
              i32.add
              call $"#func480 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
            end
            local.get 4
            i32.const 24
            i32.add
            call $"#func480 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
            local.get 2
            local.get 2
            i32.load
            i32.const -1
            i32.add
            local.tee 3
            i32.store
            local.get 3
            i32.eqz
            br_if 1 (;@3;)
            br 2 (;@2;)
          end
          unreachable
        end
        local.get 4
        i32.const 16
        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
    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
  )

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs