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. An octal literal uses 0o or 0O followed by one or more digits 0–7. 0o17 and 0O17 are 15; 0o17n and 0O17n are the exact bigint 15n. The existing radix rules apply: separators may occur between digits, and no fraction or exponent belongs to the literal. Numbers round to the nearest double; BigInts keep every digit. Unary negation preserves -0o0 as -0. Missing digits, digits 8 or 9, misplaced separators and an identifier immediately after a literal are errors. Legacy leading-zero spellings such as 017 and 08 remain rejected, as in strict JavaScript modules. JSON and DataJS retain their own numeric grammars.

The language designer sergey-shandar approved explicit octal literals in the working session, under DESIGN.md §12.

A single _ may separate digits in decimal integer parts, fractions and exponents, and in binary, octal or hexadecimal digits: 1_000, 1.2_5e1_0, 0b1010_0011, 0o7_7, 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> (;477;) (type 1) (param i32 i32)
    (local i32 i32 i32 i32 i32 i32 i32)
    global.get $__stack_pointer
    i32.const 112
    i32.sub
    local.tee 2
    global.set $__stack_pointer
    local.get 2
    i32.const 255
    i32.store8 offset=40
    local.get 2
    i32.const 0
    i32.store16 offset=72
    local.get 2
    i32.const 1064225
    i32.store offset=68
    local.get 2
    i32.const 1064218
    i32.store offset=64
    local.get 2
    local.get 2
    i32.const 40
    i32.add
    i32.store offset=76
    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::str::iter::EncodeUtf16, core::result::Result<u16, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>::Ok>, core::result::Result<core::convert::Infallible, nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>> as alloc::rc::ToRcSlice<u16>>::to_rc_slice"
    local.get 2
    local.get 2
    i32.load offset=28
    local.tee 3
    i32.store offset=60
    local.get 2
    local.get 2
    i32.load offset=24
    local.tee 4
    i32.store offset=56
    block ;; label = @1
      local.get 2
      i32.load8_u offset=40
      local.tee 5
      i32.const 255
      i32.eq
      br_if 0 (;@1;)
      local.get 2
      i32.load offset=44
      local.set 0
      local.get 2
      i32.load offset=48
      local.set 3
      local.get 2
      i32.load offset=52
      local.set 1
      local.get 2
      i32.load16_u offset=41 align=1
      local.set 6
      local.get 2
      i32.load8_u offset=43
      local.set 7
      local.get 4
      local.get 4
      i32.load
      i32.const -1
      i32.add
      local.tee 8
      i32.store
      local.get 2
      local.get 7
      i32.store8 offset=38
      local.get 2
      local.get 6
      i32.store16 offset=36
      block ;; label = @2
        local.get 8
        br_if 0 (;@2;)
        local.get 2
        i32.const 56
        i32.add
        call $"<alloc::rc::Rc<[u16]>>::drop_slow"
      end
      local.get 2
      local.get 5
      i32.store8 offset=64
      local.get 2
      local.get 2
      i32.load16_u offset=36
      i32.store16 offset=65 align=1
      local.get 2
      local.get 2
      i32.load8_u offset=38
      i32.store8 offset=67
      local.get 2
      local.get 1
      i32.store offset=76
      local.get 2
      local.get 3
      i32.store offset=72
      local.get 2
      local.get 0
      i32.store offset=68
      i32.const 1057960
      i32.const 43
      local.get 2
      i32.const 64
      i32.add
      i32.const 1057944
      i32.const 1058004
      call $core::result::unwrap_failed
      unreachable
    end
    local.get 2
    i32.const 0
    i32.store8 offset=40
    local.get 2
    i32.const 16
    i32.add
    local.get 2
    i32.const 40
    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=20
    local.tee 6
    i32.store offset=68
    local.get 2
    local.get 2
    i32.load offset=16
    local.tee 5
    i32.store offset=64
    block ;; label = @1
      block ;; label = @2
        local.get 2
        i32.load8_u offset=40
        i32.const 1
        i32.ne
        br_if 0 (;@2;)
        local.get 5
        local.get 5
        i32.load
        i32.const -1
        i32.add
        local.tee 0
        i32.store
        local.get 0
        br_if 1 (;@1;)
        local.get 2
        i32.const 64
        i32.add
        call $"<alloc::rc::Rc<[nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>]>>::drop_slow"
        br 1 (;@1;)
      end
      local.get 5
      i32.eqz
      br_if 0 (;@1;)
      i32.const 111
      i32.const 0
      local.get 5
      local.get 6
      i32.const 1064225
      i32.const 44
      call $"<nanvm_lib::naive::Naive as nanvm_lib::vm::internal::IVm>::static_function"
      local.set 5
      local.get 2
      i32.const 0
      i32.store8 offset=56
      local.get 2
      local.get 5
      i32.store offset=84
      local.get 2
      i32.const 7
      i32.store8 offset=80
      local.get 2
      local.get 3
      i32.store offset=76
      local.get 2
      local.get 4
      i32.store offset=72
      local.get 2
      i64.const 4294967296
      i64.store offset=64
      local.get 2
      local.get 2
      i32.const 56
      i32.add
      i32.store offset=96
      local.get 2
      i32.const 8
      i32.add
      local.get 2
      i32.const 64
      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 4
      i32.store offset=44
      local.get 2
      local.get 2
      i32.load offset=8
      local.tee 5
      i32.store offset=40
      block ;; label = @2
        block ;; label = @3
          local.get 2
          i32.load8_u offset=56
          i32.const 1
          i32.ne
          br_if 0 (;@3;)
          local.get 5
          local.get 5
          i32.load
          i32.const -1
          i32.add
          local.tee 0
          i32.store
          local.get 0
          br_if 1 (;@2;)
          local.get 2
          i32.const 40
          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 1 (;@2;)
        end
        local.get 5
        i32.eqz
        br_if 0 (;@2;)
        local.get 0
        local.get 4
        i32.store offset=16
        local.get 0
        local.get 5
        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 $"#func476 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
        local.get 2
        i32.const 112
        i32.add
        global.set $__stack_pointer
        return
      end
      i32.const 1064316
      i32.const 43
      local.get 2
      i32.const 111
      i32.add
      i32.const 1064300
      i32.const 1064360
      call $core::result::unwrap_failed
      unreachable
    end
    i32.const 1064316
    i32.const 43
    local.get 2
    i32.const 111
    i32.add
    i32.const 1064300
    i32.const 1064360
    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" (;478;) (type 4) (param i32 i32 i32 i32)
    (local i32 i32 i32)
    global.get $__stack_pointer
    i32.const 272
    i32.sub
    local.tee 4
    global.set $__stack_pointer
    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
      block ;; label = @2
        local.get 5
        i32.eqz
        br_if 0 (;@2;)
        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
        local.get 4
        i32.const 0
        i32.store8 offset=104
        local.get 4
        i64.const 4502148214488346440
        i64.store offset=232
        local.get 4
        i32.const 2
        i32.store8 offset=224
        local.get 4
        i64.const 4643985272004935680
        i64.store offset=216
        local.get 4
        i32.const 2
        i32.store8 offset=208
        local.get 4
        i64.const -4592193876290174976
        i64.store offset=200
        local.get 4
        i32.const 2
        i32.store8 offset=192
        local.get 4
        i64.const 0
        i64.store offset=184
        local.get 4
        i32.const 2
        i32.store8 offset=176
        local.get 4
        i64.const 17179869184
        i64.store offset=168
        local.get 4
        local.get 4
        i32.const 104
        i32.add
        i32.store offset=240
        local.get 4
        local.get 4
        i32.const 168
        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=4
        local.tee 6
        i32.store offset=140
        local.get 4
        local.get 4
        i32.load
        local.tee 5
        i32.store offset=136
        block ;; label = @3
          local.get 4
          i32.load8_u offset=104
          i32.const 1
          i32.ne
          br_if 0 (;@3;)
          local.get 5
          local.get 5
          i32.load
          i32.const -1
          i32.add
          local.tee 2
          i32.store
          local.get 2
          br_if 2 (;@1;)
          local.get 4
          i32.const 136
          i32.add
          call $"<alloc::rc::Rc<[nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>]>>::drop_slow"
          br 2 (;@1;)
        end
        local.get 5
        i32.eqz
        br_if 1 (;@1;)
        local.get 4
        local.get 6
        i32.store offset=256
        local.get 4
        local.get 5
        i32.store offset=252
        local.get 4
        i32.const 6
        i32.store8 offset=248
        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 (;@2;)
        local.get 4
        local.get 2
        i32.store offset=140
        local.get 4
        i32.const 6
        i32.store8 offset=136
        local.get 4
        local.get 3
        i64.extend_i32_u
        i64.store offset=144
        local.get 4
        i64.const 0
        i64.store offset=176
        local.get 4
        i32.const 2
        i32.store8 offset=168
        local.get 4
        i32.const 104
        i32.add
        local.get 4
        i32.const 136
        i32.add
        local.get 4
        i32.const 168
        i32.add
        call $<nanvm_lib::vm::lambda::member::Member<nanvm_lib::naive::Naive>>::new
        block ;; label = @3
          block ;; label = @4
            block ;; label = @5
              block ;; label = @6
                block ;; label = @7
                  local.get 4
                  i32.load8_u offset=104
                  i32.const 255
                  i32.ne
                  br_if 0 (;@7;)
                  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 248
                  i32.add
                  call $"#func476 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
                  br 1 (;@6;)
                end
                local.get 4
                local.get 4
                i64.load offset=128
                i64.store offset=192
                local.get 4
                local.get 4
                i64.load offset=120
                i64.store offset=184
                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
                i32.const 136
                i32.add
                local.get 4
                i32.const 168
                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=136
                    i32.const 255
                    i32.eq
                    br_if 0 (;@8;)
                    local.get 4
                    local.get 4
                    i64.load offset=144
                    i64.store offset=64
                    local.get 4
                    local.get 4
                    i64.load offset=136
                    i64.store offset=56
                    br 1 (;@7;)
                  end
                  local.get 4
                  i32.const 256
                  i32.store16 offset=56
                end
                local.get 4
                i32.const 40
                i32.add
                local.set 3
                local.get 4
                i32.const 168
                i32.add
                call $"#func693 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
                local.get 4
                i32.const 184
                i32.add
                call $"#func693 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
                local.get 4
                i32.const 32
                i32.add
                local.get 4
                i32.const 56
                i32.add
                call $<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>::number
                block ;; label = @7
                  local.get 4
                  i64.load offset=32
                  i64.const 1
                  i64.ne
                  br_if 0 (;@7;)
                  local.get 0
                  i64.const 1
                  i64.store
                  local.get 0
                  local.get 3
                  i64.load offset=8
                  i64.store offset=16
                  local.get 0
                  local.get 3
                  i64.load
                  i64.store offset=8
                  local.get 4
                  i32.const 248
                  i32.add
                  call $"#func476 core::ptr::drop_glue::<nanvm_lib::vm::any::Any<nanvm_lib::naive::Naive>>"
                  br 1 (;@6;)
                end
                local.get 4
                local.get 3
                i64.load offset=8
                i64.store offset=80
                local.get 4
                local.get 3
                i64.load
                i64.store offset=72
                local.get 4
                i32.const 136
                i32.add
                local.get 4
                i32.const 248
                i32.add
                local.get 4
                i32.const 72
                i32.add
                call $<nanvm_lib::vm::lambda::member::Member<nanvm_lib::naive::Naive>>::new
                local.get 4
                i32.load8_u offset=136
                i32.const 255
                i32.ne
                br_if 1 (;@5;)
                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
              end
              local.get 4
              i32.const 16
              i32.add
              call $"#func476 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 3
              i32.store
              local.get 3
              i32.eqz
              br_if 1 (;@4;)
              br 2 (;@3;)
            end
            local.get 4
            local.get 4
            i64.load offset=160
            i64.store offset=192
            local.get 4
            local.get 4
            i64.load offset=152
            i64.store offset=184
            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
            i32.const 248
            i32.add
            local.get 4
            i32.const 168
            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=248
                i32.const 255
                i32.eq
                br_if 0 (;@6;)
                local.get 4
                local.get 4
                i64.load offset=256
                i64.store offset=96
                local.get 4
                local.get 4
                i64.load offset=248
                i64.store offset=88
                br 1 (;@5;)
              end
              local.get 4
              i32.const 256
              i32.store16 offset=88
            end
            local.get 4
            i32.const 168
            i32.add
            call $"#func693 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
            local.get 4
            i32.const 184
            i32.add
            call $"#func693 core::ptr::drop_glue::<nanvm_lib::vm::unpacked::Unpacked<nanvm_lib::naive::Naive>>"
            local.get 4
            i64.const 4611686018427387904
            i64.store offset=176
            local.get 4
            i32.const 2
            i32.store8 offset=168
            local.get 0
            local.get 4
            i32.const 88
            i32.add
            local.get 4
            i32.const 168
            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 16
            i32.add
            call $"#func476 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 3
            i32.store
            local.get 3
            br_if 1 (;@3;)
          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 272
        i32.add
        global.set $__stack_pointer
        return
      end
      unreachable
    end
    i32.const 1064316
    i32.const 43
    local.get 4
    i32.const 271
    i32.add
    i32.const 1064300
    i32.const 1064360
    call $core::result::unwrap_failed
    unreachable
  )

Emergent Testing

Idle. Press Run to start the suite.

  • ./proof.f.mjs