dart-lang / sdk

The Dart SDK, including the VM, dart2js, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
9.99k stars 1.54k forks source link

[dart2wasm] Consider reusing short-lived locals in code generator #50560

Open osa1 opened 1 year ago

osa1 commented 1 year ago

Functions like CodeGenerator.makeList and Constants.instantiateConstant allocate locals that have very short lifetime. For example, here's a code that instantiateConstant generates:

(block
 (local.set $88 (i32.const 1))
 (local.set $87 (struct.new $type$60 (i32.const 232) (local.get $88))))

$88 is generated by instantiateConstant and it has no uses after this tiny block.

(In this particular case the local can be eliminated, but in general I think there will be a few instructions between the local.set and local.get)

binaryen can probably optimize this kind of trivial cases to use a shared local, but it will change a lot of other things as well which may make debugging more difficult.

I think we can easily reuse these short-lived locals and simplify generated code by maintaining a Map<ValueType, Set<Local>> state in DefinedFunction for locals that are known to be not used again, and add locals to the map with a new method void freeLocal(Local). addLocal would then use one of the available locals from the map when possible.

Functions like instantiateConstant and makeList would then free the locals they add when they are done. Relevant code in Constants would look like:

class Constants {
  ...
  ConstantInfo createConstant(
      Constant constant, w.RefType type, ConstantCodeGenerator generator,
      {bool lazy = false}) {
    assert(!type.nullable);
    if (lazy) {
      ...
      w.Local temp = function.addLocal(type);
      w.Instructions b2 = function.body;
      b2.local_tee(temp);
      b2.global_set(global);
      b2.local_get(temp);
      function.freeLocal(temp); // <--------- only new line needed
      b2.end();
      return ConstantInfo(constant, global, function);
    } else {
      ...
    }
  }
}

Seems like this could simplify generated code quite a bit with only one line added in a few places.

In cases where we think reusing a local will make debugging more difficult we can have a global parameter for disabling it, or add an optional argument to addLocal: addLocal(ValueType type, {bool forceFresh = false}).

askeksa-google commented 1 year ago

I have been contemplating something similar. A few thoughts:

osa1 commented 1 year ago

Another example of a very short lived local is in ConstructorInvocation compiler: https://github.com/dart-lang/sdk/blob/a464fc354beb0a2fee278612ccd7855071ede058/pkg/dart2wasm/lib/code_generator.dart#L1403-L1412

With this number of locals grow linearly with the constructor calls in the function. I actually see two locals introduced per constructor call, but I can't find where the other local is coming from.

This one when boxing a value creates a local to swap two values on stack: https://github.com/dart-lang/sdk/blob/a464fc354beb0a2fee278612ccd7855071ede058/pkg/dart2wasm/lib/translator.dart#L643-L646

osa1 commented 1 year ago

co19 has some tests with huge list literals, for example the test ListBase_class_A01_t06 uses this huge list: https://github.com/dart-lang/co19/blob/97d07c01fdf6becf1b7e780858427d2b184df18d/LibTest/core/List/sort_A01_t06.test.dart#L30-L31

Each element in this list literal generates 2 locals, which in total generates more locals in this test than V8 supports.

One of each of these locals is for boxing, in the same swap code shown above. I can't find where the other local is generated.

osa1 commented 1 year ago

Another example is computeRemainder. This function has 10 variable declarations (including loop variables and function arguments) but the generated Wasm has 241 locals.

Unoptimized Wasm for computeRemainder ```wast (func $BoxedDouble.computeRemainder (type $type$181) (param $0 f64) (param $1 f64) (result f64) (local $2 f64) (local $3 (ref $type$14)) (local $4 f64) (local $5 i64) (local $6 f64) (local $7 (ref $type$14)) (local $8 f64) (local $9 i64) (local $10 f64) (local $11 (ref $type$14)) (local $12 f64) (local $13 i64) (local $14 i64) (local $15 i64) (local $16 i64) (local $17 i64) (local $18 (ref $type$5)) (local $19 i64) (local $20 i64) (local $21 (ref $type$87)) (local $22 i64) (local $23 i64) (local $24 i64) (local $25 (ref $type$5)) (local $26 i64) (local $27 i64) (local $28 (ref $type$87)) (local $29 i64) (local $30 i64) (local $31 i64) (local $32 (ref $type$5)) (local $33 i64) (local $34 i64) (local $35 (ref $type$87)) (local $36 i64) (local $37 i64) (local $38 (ref $type$5)) (local $39 i64) (local $40 i64) (local $41 (ref $type$87)) (local $42 i64) (local $43 i64) (local $44 (ref $type$5)) (local $45 i64) (local $46 i64) (local $47 (ref $type$87)) (local $48 i64) (local $49 i64) (local $50 (ref $type$5)) (local $51 i64) (local $52 i64) (local $53 (ref $type$87)) (local $54 i64) (local $55 i64) (local $56 (ref $type$5)) (local $57 i64) (local $58 i64) (local $59 (ref $type$87)) (local $60 i64) (local $61 i64) (local $62 (ref $type$5)) (local $63 i64) (local $64 i64) (local $65 (ref $type$87)) (local $66 i64) (local $67 i64) (local $68 i64) (local $69 (ref $type$5)) (local $70 i64) (local $71 i64) (local $72 (ref $type$87)) (local $73 i64) (local $74 i64) (local $75 (ref $type$5)) (local $76 i64) (local $77 i64) (local $78 (ref $type$87)) (local $79 i64) (local $80 i64) (local $81 (ref $type$5)) (local $82 i64) (local $83 i64) (local $84 (ref $type$87)) (local $85 i64) (local $86 i64) (local $87 (ref $type$5)) (local $88 i64) (local $89 i64) (local $90 (ref $type$87)) (local $91 i64) (local $92 (ref $type$5)) (local $93 i64) (local $94 i64) (local $95 (ref $type$87)) (local $96 i64) (local $97 i64) (local $98 i64) (local $99 (ref $type$5)) (local $100 i64) (local $101 i64) (local $102 (ref $type$87)) (local $103 i64) (local $104 i64) (local $105 (ref $type$5)) (local $106 i64) (local $107 i64) (local $108 (ref $type$87)) (local $109 i64) (local $110 i64) (local $111 (ref $type$5)) (local $112 i64) (local $113 i64) (local $114 (ref $type$87)) (local $115 i64) (local $116 i64) (local $117 (ref $type$5)) (local $118 i64) (local $119 i64) (local $120 (ref $type$87)) (local $121 i64) (local $122 (ref $type$5)) (local $123 i64) (local $124 i64) (local $125 (ref $type$87)) (local $126 i64) (local $127 i64) (local $128 i64) (local $129 (ref $type$5)) (local $130 i64) (local $131 i64) (local $132 (ref $type$87)) (local $133 i64) (local $134 i64) (local $135 (ref $type$5)) (local $136 i64) (local $137 i64) (local $138 (ref $type$87)) (local $139 i64) (local $140 i64) (local $141 (ref $type$5)) (local $142 i64) (local $143 i64) (local $144 (ref $type$87)) (local $145 i64) (local $146 i64) (local $147 (ref $type$5)) (local $148 i64) (local $149 i64) (local $150 (ref $type$87)) (local $151 i64) (local $152 i64) (local $153 (ref $type$5)) (local $154 i64) (local $155 i64) (local $156 (ref $type$87)) (local $157 i64) (local $158 (ref $type$5)) (local $159 i64) (local $160 i64) (local $161 (ref $type$87)) (local $162 i64) (local $163 i64) (local $164 (ref $type$5)) (local $165 i64) (local $166 i64) (local $167 (ref $type$87)) (local $168 i64) (local $169 i64) (local $170 (ref $type$5)) (local $171 i64) (local $172 i64) (local $173 (ref $type$87)) (local $174 i64) (local $175 i64) (local $176 (ref $type$5)) (local $177 i64) (local $178 i64) (local $179 (ref $type$87)) (local $180 i64) (local $181 (ref $type$5)) (local $182 (ref $type$87)) (local $183 (ref $type$5)) (local $184 (ref $type$87)) (local $185 (ref $type$5)) (local $186 (ref $type$87)) (local $187 (ref $type$5)) (local $188 (ref $type$87)) (local $189 (ref $type$5)) (local $190 (ref $type$87)) (local $191 (ref $type$5)) (local $192 (ref $type$87)) (local $193 i64) (local $194 (ref $type$5)) (local $195 (ref $type$87)) (local $196 (ref $type$5)) (local $197 (ref $type$87)) (local $198 i64) (local $199 (ref $type$5)) (local $200 (ref $type$87)) (local $201 (ref $type$5)) (local $202 (ref $type$87)) (local $203 (ref $type$5)) (local $204 (ref $type$87)) (local $205 (ref $type$5)) (local $206 (ref $type$87)) (local $207 (ref $type$5)) (local $208 (ref $type$87)) (local $209 i64) (local $210 (ref $type$5)) (local $211 (ref $type$87)) (local $212 (ref $type$5)) (local $213 (ref $type$87)) (local $214 (ref $type$5)) (local $215 (ref $type$87)) (local $216 (ref $type$5)) (local $217 (ref $type$87)) (local $218 (ref $type$5)) (local $219 (ref $type$87)) (local $220 i64) (local $221 (ref $type$5)) (local $222 (ref $type$87)) (local $223 (ref $type$5)) (local $224 (ref $type$87)) (local $225 (ref $type$5)) (local $226 (ref $type$87)) (local $227 (ref $type$5)) (local $228 (ref $type$87)) (local $229 (ref $type$5)) (local $230 (ref $type$87)) (local $231 (ref $type$5)) (local $232 (ref $type$87)) (local $233 i64) (local $234 (ref $type$5)) (local $235 (ref $type$87)) (local $236 i64) (local $237 (ref $type$5)) (local $238 (ref $type$87)) (local $239 (ref $type$5)) (local $240 (ref $type$87)) (local $241 i64) (block $label$1 (block $label$2 (local.set $2 (local.get $0) ) (local.set $3 (struct.new $type$16 (i32.const 11) (local.get $2) ) ) (br_if $label$2 (block $label$3 (result i32) (local.set $4 (struct.get $type$16 1 (ref.cast $type$16 (local.get $3) ) ) ) (local.set $5 (i64.reinterpret_f64 (local.get $4) ) ) (br $label$3 (i64.eq (i64.and (local.get $5) (i64.or (i64.const 9218868437227405312) (i64.const 4503599627370495) ) ) (i64.const 9218868437227405312) ) ) ) ) (local.set $6 (local.get $0) ) (local.set $7 (struct.new $type$16 (i32.const 11) (local.get $6) ) ) (br_if $label$2 (block $label$5 (result i32) (local.set $8 (struct.get $type$16 1 (ref.cast $type$16 (local.get $7) ) ) ) (local.set $9 (i64.reinterpret_f64 (local.get $8) ) ) (br $label$5 (i64.gt_s (i64.and (local.get $9) (i64.or (i64.const 9218868437227405312) (i64.const 4503599627370495) ) ) (i64.const 9218868437227405312) ) ) ) ) (local.set $10 (local.get $1) ) (local.set $11 (struct.new $type$16 (i32.const 11) (local.get $10) ) ) (br_if $label$1 (i32.eqz (block $label$7 (result i32) (local.set $12 (struct.get $type$16 1 (ref.cast $type$16 (local.get $11) ) ) ) (local.set $13 (i64.reinterpret_f64 (local.get $12) ) ) (br $label$7 (i64.gt_s (i64.and (local.get $13) (i64.or (i64.const 9218868437227405312) (i64.const 4503599627370495) ) ) (i64.const 9218868437227405312) ) ) ) ) ) ) (return (f64.div (f64.mul (local.get $0) (local.get $1) ) (f64.mul (local.get $0) (local.get $1) ) ) ) ) (local.set $14 (i64.reinterpret_f64 (local.get $0) ) ) (local.set $15 (i64.reinterpret_f64 (local.get $1) ) ) (local.set $17 (i64.and (local.get $14) (i64.const 9218868437227405312) ) ) (local.set $18 (block (result (ref $type$5)) (local.set $181 (struct.new $type$5 (i32.const 9) (local.get $17) ) ) (local.set $19 (i64.const 52) ) (local.get $181) ) ) (local.set $16 (block $label$9 (result i64) (local.set $20 (struct.get $type$5 1 (local.get $18) ) ) (if (i64.lt_u (local.get $19) (i64.const 64) ) (br $label$9 (i64.shr_s (struct.get $type$5 1 (local.get $18) ) (local.get $19) ) ) ) (if (i64.lt_s (local.get $19) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $182 (local.tee $21 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $21) (i32.const 147) ) (local.set $22 (local.get $19) ) (local.get $182) ) (struct.new $type$5 (i32.const 9) (local.get $22) ) (ref.null none) ) (drop (call $Error._throw (local.get $21) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$9 (i64.shr_s (struct.get $type$5 1 (local.get $18) ) (i64.const 63) ) ) ) ) (local.set $24 (i64.and (local.get $15) (i64.const 9218868437227405312) ) ) (local.set $25 (block (result (ref $type$5)) (local.set $183 (struct.new $type$5 (i32.const 9) (local.get $24) ) ) (local.set $26 (i64.const 52) ) (local.get $183) ) ) (local.set $23 (block $label$13 (result i64) (local.set $27 (struct.get $type$5 1 (local.get $25) ) ) (if (i64.lt_u (local.get $26) (i64.const 64) ) (br $label$13 (i64.shr_s (struct.get $type$5 1 (local.get $25) ) (local.get $26) ) ) ) (if (i64.lt_s (local.get $26) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $184 (local.tee $28 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $28) (i32.const 147) ) (local.set $29 (local.get $26) ) (local.get $184) ) (struct.new $type$5 (i32.const 9) (local.get $29) ) (ref.null none) ) (drop (call $Error._throw (local.get $28) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$13 (i64.shr_s (struct.get $type$5 1 (local.get $25) ) (i64.const 63) ) ) ) ) (local.set $31 (local.get $14) ) (local.set $32 (block (result (ref $type$5)) (local.set $185 (struct.new $type$5 (i32.const 9) (local.get $31) ) ) (local.set $33 (i64.add (i64.const 11) (i64.const 52) ) ) (local.get $185) ) ) (local.set $30 (block $label$17 (result i64) (local.set $34 (struct.get $type$5 1 (local.get $32) ) ) (if (i64.lt_u (local.get $33) (i64.const 64) ) (br $label$17 (i64.shr_s (struct.get $type$5 1 (local.get $32) ) (local.get $33) ) ) ) (if (i64.lt_s (local.get $33) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $186 (local.tee $35 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $35) (i32.const 147) ) (local.set $36 (local.get $33) ) (local.get $186) ) (struct.new $type$5 (i32.const 9) (local.get $36) ) (ref.null none) ) (drop (call $Error._throw (local.get $35) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$17 (i64.shr_s (struct.get $type$5 1 (local.get $32) ) (i64.const 63) ) ) ) ) (local.set $37 (local.get $15) ) (local.set $38 (block (result (ref $type$5)) (local.set $187 (struct.new $type$5 (i32.const 9) (local.get $37) ) ) (local.set $39 (i64.const 1) ) (local.get $187) ) ) (if (i64.eq (block $label$21 (result i64) (local.set $40 (struct.get $type$5 1 (local.get $38) ) ) (if (i64.lt_u (local.get $39) (i64.const 64) ) (br $label$21 (i64.shl (struct.get $type$5 1 (local.get $38) ) (local.get $39) ) ) ) (if (i64.lt_s (local.get $39) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $188 (local.tee $41 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $41) (i32.const 147) ) (local.set $42 (local.get $39) ) (local.get $188) ) (struct.new $type$5 (i32.const 9) (local.get $42) ) (ref.null none) ) (drop (call $Error._throw (local.get $41) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$21 (i64.const 0) ) ) (i64.const 0) ) (return (f64.div (f64.mul (local.get $0) (local.get $1) ) (f64.mul (local.get $0) (local.get $1) ) ) ) ) (local.set $43 (local.get $14) ) (local.set $44 (block (result (ref $type$5)) (local.set $189 (struct.new $type$5 (i32.const 9) (local.get $43) ) ) (local.set $45 (i64.const 1) ) (local.get $189) ) ) (if (i64.le_u (block (result i64) (local.set $193 (block $label$26 (result i64) (local.set $46 (struct.get $type$5 1 (local.get $44) ) ) (if (i64.lt_u (local.get $45) (i64.const 64) ) (br $label$26 (i64.shl (struct.get $type$5 1 (local.get $44) ) (local.get $45) ) ) ) (if (i64.lt_s (local.get $45) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $190 (local.tee $47 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $47) (i32.const 147) ) (local.set $48 (local.get $45) ) (local.get $190) ) (struct.new $type$5 (i32.const 9) (local.get $48) ) (ref.null none) ) (drop (call $Error._throw (local.get $47) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$26 (i64.const 0) ) ) ) (local.set $49 (local.get $15) ) (local.set $50 (block (result (ref $type$5)) (local.set $191 (struct.new $type$5 (i32.const 9) (local.get $49) ) ) (local.set $51 (i64.const 1) ) (local.get $191) ) ) (local.get $193) ) (block $label$30 (result i64) (local.set $52 (struct.get $type$5 1 (local.get $50) ) ) (if (i64.lt_u (local.get $51) (i64.const 64) ) (br $label$30 (i64.shl (struct.get $type$5 1 (local.get $50) ) (local.get $51) ) ) ) (if (i64.lt_s (local.get $51) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $192 (local.tee $53 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $53) (i32.const 147) ) (local.set $54 (local.get $51) ) (local.get $192) ) (struct.new $type$5 (i32.const 9) (local.get $54) ) (ref.null none) ) (drop (call $Error._throw (local.get $53) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$30 (i64.const 0) ) ) ) (block (local.set $55 (local.get $14) ) (local.set $56 (block (result (ref $type$5)) (local.set $194 (struct.new $type$5 (i32.const 9) (local.get $55) ) ) (local.set $57 (i64.const 1) ) (local.get $194) ) ) (if (i64.eq (block (result i64) (local.set $198 (block $label$35 (result i64) (local.set $58 (struct.get $type$5 1 (local.get $56) ) ) (if (i64.lt_u (local.get $57) (i64.const 64) ) (br $label$35 (i64.shl (struct.get $type$5 1 (local.get $56) ) (local.get $57) ) ) ) (if (i64.lt_s (local.get $57) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $195 (local.tee $59 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $59) (i32.const 147) ) (local.set $60 (local.get $57) ) (local.get $195) ) (struct.new $type$5 (i32.const 9) (local.get $60) ) (ref.null none) ) (drop (call $Error._throw (local.get $59) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$35 (i64.const 0) ) ) ) (local.set $61 (local.get $15) ) (local.set $62 (block (result (ref $type$5)) (local.set $196 (struct.new $type$5 (i32.const 9) (local.get $61) ) ) (local.set $63 (i64.const 1) ) (local.get $196) ) ) (local.get $198) ) (block $label$39 (result i64) (local.set $64 (struct.get $type$5 1 (local.get $62) ) ) (if (i64.lt_u (local.get $63) (i64.const 64) ) (br $label$39 (i64.shl (struct.get $type$5 1 (local.get $62) ) (local.get $63) ) ) ) (if (i64.lt_s (local.get $63) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $197 (local.tee $65 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $65) (i32.const 147) ) (local.set $66 (local.get $63) ) (local.get $197) ) (struct.new $type$5 (i32.const 9) (local.get $66) ) (ref.null none) ) (drop (call $Error._throw (local.get $65) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$39 (i64.const 0) ) ) ) (return (f64.copysign (f64.const 0) (local.get $0) ) ) ) (return (local.get $0) ) ) ) (if (i64.eq (local.get $16) (i64.const 0) ) (block (local.set $68 (local.get $14) ) (local.set $69 (block (result (ref $type$5)) (local.set $199 (struct.new $type$5 (i32.const 9) (local.get $68) ) ) (local.set $70 (i64.const 12) ) (local.get $199) ) ) (local.set $67 (block $label$45 (result i64) (local.set $71 (struct.get $type$5 1 (local.get $69) ) ) (if (i64.lt_u (local.get $70) (i64.const 64) ) (br $label$45 (i64.shl (struct.get $type$5 1 (local.get $69) ) (local.get $70) ) ) ) (if (i64.lt_s (local.get $70) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $200 (local.tee $72 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $72) (i32.const 147) ) (local.set $73 (local.get $70) ) (local.get $200) ) (struct.new $type$5 (i32.const 9) (local.get $73) ) (ref.null none) ) (drop (call $Error._throw (local.get $72) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$45 (i64.const 0) ) ) ) (block $label$49 (loop $label$50 (local.set $74 (local.get $67) ) (local.set $75 (block (result (ref $type$5)) (local.set $201 (struct.new $type$5 (i32.const 9) (local.get $74) ) ) (local.set $76 (i64.const 63) ) (local.get $201) ) ) (br_if $label$49 (i32.eqz (i64.eq (block $label$51 (result i64) (local.set $77 (struct.get $type$5 1 (local.get $75) ) ) (if (i64.lt_u (local.get $76) (i64.const 64) ) (br $label$51 (i64.shr_s (struct.get $type$5 1 (local.get $75) ) (local.get $76) ) ) ) (if (i64.lt_s (local.get $76) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $202 (local.tee $78 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $78) (i32.const 147) ) (local.set $79 (local.get $76) ) (local.get $202) ) (struct.new $type$5 (i32.const 9) (local.get $79) ) (ref.null none) ) (drop (call $Error._throw (local.get $78) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$51 (i64.shr_s (struct.get $type$5 1 (local.get $75) ) (i64.const 63) ) ) ) (i64.const 0) ) ) ) (local.set $16 (i64.sub (local.get $16) (i64.const 1) ) ) (local.set $80 (local.get $67) ) (local.set $81 (block (result (ref $type$5)) (local.set $203 (struct.new $type$5 (i32.const 9) (local.get $80) ) ) (local.set $82 (i64.const 1) ) (local.get $203) ) ) (local.set $67 (block $label$55 (result i64) (local.set $83 (struct.get $type$5 1 (local.get $81) ) ) (if (i64.lt_u (local.get $82) (i64.const 64) ) (br $label$55 (i64.shl (struct.get $type$5 1 (local.get $81) ) (local.get $82) ) ) ) (if (i64.lt_s (local.get $82) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $204 (local.tee $84 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $84) (i32.const 147) ) (local.set $85 (local.get $82) ) (local.get $204) ) (struct.new $type$5 (i32.const 9) (local.get $85) ) (ref.null none) ) (drop (call $Error._throw (local.get $84) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$55 (i64.const 0) ) ) ) (br $label$50) ) ) (local.set $86 (local.get $14) ) (local.set $87 (block (result (ref $type$5)) (local.set $205 (struct.new $type$5 (i32.const 9) (local.get $86) ) ) (local.set $88 (i64.add (i64.mul (local.get $16) (i64.const -1) ) (i64.const 1) ) ) (local.get $205) ) ) (local.set $14 (block $label$59 (result i64) (local.set $89 (struct.get $type$5 1 (local.get $87) ) ) (if (i64.lt_u (local.get $88) (i64.const 64) ) (br $label$59 (i64.shl (struct.get $type$5 1 (local.get $87) ) (local.get $88) ) ) ) (if (i64.lt_s (local.get $88) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $206 (local.tee $90 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $90) (i32.const 147) ) (local.set $91 (local.get $88) ) (local.get $206) ) (struct.new $type$5 (i32.const 9) (local.get $91) ) (ref.null none) ) (drop (call $Error._throw (local.get $90) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$59 (i64.const 0) ) ) ) ) (block (local.set $14 (i64.and (local.get $14) (i64.const 4503599627370495) ) ) (local.set $14 (i64.or (block (result i64) (local.set $209 (local.get $14) ) (local.set $92 (block (result (ref $type$5)) (local.set $207 (global.get $global$12) ) (local.set $93 (i64.const 52) ) (local.get $207) ) ) (local.get $209) ) (block $label$64 (result i64) (local.set $94 (struct.get $type$5 1 (local.get $92) ) ) (if (i64.lt_u (local.get $93) (i64.const 64) ) (br $label$64 (i64.shl (struct.get $type$5 1 (local.get $92) ) (local.get $93) ) ) ) (if (i64.lt_s (local.get $93) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $208 (local.tee $95 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $95) (i32.const 147) ) (local.set $96 (local.get $93) ) (local.get $208) ) (struct.new $type$5 (i32.const 9) (local.get $96) ) (ref.null none) ) (drop (call $Error._throw (local.get $95) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$64 (i64.const 0) ) ) ) ) ) ) (if (i64.eq (local.get $23) (i64.const 0) ) (block (local.set $98 (local.get $15) ) (local.set $99 (block (result (ref $type$5)) (local.set $210 (struct.new $type$5 (i32.const 9) (local.get $98) ) ) (local.set $100 (i64.const 12) ) (local.get $210) ) ) (local.set $97 (block $label$69 (result i64) (local.set $101 (struct.get $type$5 1 (local.get $99) ) ) (if (i64.lt_u (local.get $100) (i64.const 64) ) (br $label$69 (i64.shl (struct.get $type$5 1 (local.get $99) ) (local.get $100) ) ) ) (if (i64.lt_s (local.get $100) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $211 (local.tee $102 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $102) (i32.const 147) ) (local.set $103 (local.get $100) ) (local.get $211) ) (struct.new $type$5 (i32.const 9) (local.get $103) ) (ref.null none) ) (drop (call $Error._throw (local.get $102) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$69 (i64.const 0) ) ) ) (block $label$73 (loop $label$74 (local.set $104 (local.get $97) ) (local.set $105 (block (result (ref $type$5)) (local.set $212 (struct.new $type$5 (i32.const 9) (local.get $104) ) ) (local.set $106 (i64.const 63) ) (local.get $212) ) ) (br_if $label$73 (i32.eqz (i64.eq (block $label$75 (result i64) (local.set $107 (struct.get $type$5 1 (local.get $105) ) ) (if (i64.lt_u (local.get $106) (i64.const 64) ) (br $label$75 (i64.shr_s (struct.get $type$5 1 (local.get $105) ) (local.get $106) ) ) ) (if (i64.lt_s (local.get $106) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $213 (local.tee $108 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $108) (i32.const 147) ) (local.set $109 (local.get $106) ) (local.get $213) ) (struct.new $type$5 (i32.const 9) (local.get $109) ) (ref.null none) ) (drop (call $Error._throw (local.get $108) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$75 (i64.shr_s (struct.get $type$5 1 (local.get $105) ) (i64.const 63) ) ) ) (i64.const 0) ) ) ) (local.set $23 (i64.sub (local.get $23) (i64.const 1) ) ) (local.set $110 (local.get $97) ) (local.set $111 (block (result (ref $type$5)) (local.set $214 (struct.new $type$5 (i32.const 9) (local.get $110) ) ) (local.set $112 (i64.const 1) ) (local.get $214) ) ) (local.set $97 (block $label$79 (result i64) (local.set $113 (struct.get $type$5 1 (local.get $111) ) ) (if (i64.lt_u (local.get $112) (i64.const 64) ) (br $label$79 (i64.shl (struct.get $type$5 1 (local.get $111) ) (local.get $112) ) ) ) (if (i64.lt_s (local.get $112) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $215 (local.tee $114 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $114) (i32.const 147) ) (local.set $115 (local.get $112) ) (local.get $215) ) (struct.new $type$5 (i32.const 9) (local.get $115) ) (ref.null none) ) (drop (call $Error._throw (local.get $114) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$79 (i64.const 0) ) ) ) (br $label$74) ) ) (local.set $116 (local.get $15) ) (local.set $117 (block (result (ref $type$5)) (local.set $216 (struct.new $type$5 (i32.const 9) (local.get $116) ) ) (local.set $118 (i64.add (i64.mul (local.get $23) (i64.const -1) ) (i64.const 1) ) ) (local.get $216) ) ) (local.set $15 (block $label$83 (result i64) (local.set $119 (struct.get $type$5 1 (local.get $117) ) ) (if (i64.lt_u (local.get $118) (i64.const 64) ) (br $label$83 (i64.shl (struct.get $type$5 1 (local.get $117) ) (local.get $118) ) ) ) (if (i64.lt_s (local.get $118) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $217 (local.tee $120 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $120) (i32.const 147) ) (local.set $121 (local.get $118) ) (local.get $217) ) (struct.new $type$5 (i32.const 9) (local.get $121) ) (ref.null none) ) (drop (call $Error._throw (local.get $120) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$83 (i64.const 0) ) ) ) ) (block (local.set $15 (i64.and (local.get $15) (i64.const 4503599627370495) ) ) (local.set $15 (i64.or (block (result i64) (local.set $220 (local.get $15) ) (local.set $122 (block (result (ref $type$5)) (local.set $218 (global.get $global$12) ) (local.set $123 (i64.const 52) ) (local.get $218) ) ) (local.get $220) ) (block $label$88 (result i64) (local.set $124 (struct.get $type$5 1 (local.get $122) ) ) (if (i64.lt_u (local.get $123) (i64.const 64) ) (br $label$88 (i64.shl (struct.get $type$5 1 (local.get $122) ) (local.get $123) ) ) ) (if (i64.lt_s (local.get $123) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $219 (local.tee $125 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $125) (i32.const 147) ) (local.set $126 (local.get $123) ) (local.get $219) ) (struct.new $type$5 (i32.const 9) (local.get $126) ) (ref.null none) ) (drop (call $Error._throw (local.get $125) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$88 (i64.const 0) ) ) ) ) ) ) (local.set $127 (i64.const 0) ) (block $label$92 (loop $label$93 (br_if $label$92 (i32.eqz (i64.gt_s (local.get $16) (local.get $23) ) ) ) (local.set $127 (i64.sub (local.get $14) (local.get $15) ) ) (local.set $128 (local.get $127) ) (local.set $129 (block (result (ref $type$5)) (local.set $221 (struct.new $type$5 (i32.const 9) (local.get $128) ) ) (local.set $130 (i64.const 63) ) (local.get $221) ) ) (if (i64.eq (block $label$94 (result i64) (local.set $131 (struct.get $type$5 1 (local.get $129) ) ) (if (i64.lt_u (local.get $130) (i64.const 64) ) (br $label$94 (i64.shr_s (struct.get $type$5 1 (local.get $129) ) (local.get $130) ) ) ) (if (i64.lt_s (local.get $130) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $222 (local.tee $132 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $132) (i32.const 147) ) (local.set $133 (local.get $130) ) (local.get $222) ) (struct.new $type$5 (i32.const 9) (local.get $133) ) (ref.null none) ) (drop (call $Error._throw (local.get $132) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$94 (i64.shr_s (struct.get $type$5 1 (local.get $129) ) (i64.const 63) ) ) ) (i64.const 0) ) (block (if (i64.eq (local.get $127) (i64.const 0) ) (return (f64.copysign (f64.const 0) (local.get $0) ) ) ) (local.set $14 (local.get $127) ) ) ) (local.set $134 (local.get $14) ) (local.set $135 (block (result (ref $type$5)) (local.set $223 (struct.new $type$5 (i32.const 9) (local.get $134) ) ) (local.set $136 (i64.const 1) ) (local.get $223) ) ) (local.set $14 (block $label$100 (result i64) (local.set $137 (struct.get $type$5 1 (local.get $135) ) ) (if (i64.lt_u (local.get $136) (i64.const 64) ) (br $label$100 (i64.shl (struct.get $type$5 1 (local.get $135) ) (local.get $136) ) ) ) (if (i64.lt_s (local.get $136) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $224 (local.tee $138 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $138) (i32.const 147) ) (local.set $139 (local.get $136) ) (local.get $224) ) (struct.new $type$5 (i32.const 9) (local.get $139) ) (ref.null none) ) (drop (call $Error._throw (local.get $138) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$100 (i64.const 0) ) ) ) (local.set $16 (i64.sub (local.get $16) (i64.const 1) ) ) (br $label$93) ) ) (local.set $127 (i64.sub (local.get $14) (local.get $15) ) ) (local.set $140 (local.get $127) ) (local.set $141 (block (result (ref $type$5)) (local.set $225 (struct.new $type$5 (i32.const 9) (local.get $140) ) ) (local.set $142 (i64.const 63) ) (local.get $225) ) ) (if (i64.eq (block $label$104 (result i64) (local.set $143 (struct.get $type$5 1 (local.get $141) ) ) (if (i64.lt_u (local.get $142) (i64.const 64) ) (br $label$104 (i64.shr_s (struct.get $type$5 1 (local.get $141) ) (local.get $142) ) ) ) (if (i64.lt_s (local.get $142) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $226 (local.tee $144 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $144) (i32.const 147) ) (local.set $145 (local.get $142) ) (local.get $226) ) (struct.new $type$5 (i32.const 9) (local.get $145) ) (ref.null none) ) (drop (call $Error._throw (local.get $144) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$104 (i64.shr_s (struct.get $type$5 1 (local.get $141) ) (i64.const 63) ) ) ) (i64.const 0) ) (block (if (i64.eq (local.get $127) (i64.const 0) ) (return (f64.copysign (f64.const 0) (local.get $0) ) ) ) (local.set $14 (local.get $127) ) ) ) (block $label$110 (loop $label$111 (local.set $146 (local.get $14) ) (local.set $147 (block (result (ref $type$5)) (local.set $227 (struct.new $type$5 (i32.const 9) (local.get $146) ) ) (local.set $148 (i64.const 52) ) (local.get $227) ) ) (br_if $label$110 (i32.eqz (i64.eq (block $label$112 (result i64) (local.set $149 (struct.get $type$5 1 (local.get $147) ) ) (if (i64.lt_u (local.get $148) (i64.const 64) ) (br $label$112 (i64.shr_s (struct.get $type$5 1 (local.get $147) ) (local.get $148) ) ) ) (if (i64.lt_s (local.get $148) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $228 (local.tee $150 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $150) (i32.const 147) ) (local.set $151 (local.get $148) ) (local.get $228) ) (struct.new $type$5 (i32.const 9) (local.get $151) ) (ref.null none) ) (drop (call $Error._throw (local.get $150) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$112 (i64.shr_s (struct.get $type$5 1 (local.get $147) ) (i64.const 63) ) ) ) (i64.const 0) ) ) ) (local.set $152 (local.get $14) ) (local.set $153 (block (result (ref $type$5)) (local.set $229 (struct.new $type$5 (i32.const 9) (local.get $152) ) ) (local.set $154 (i64.const 1) ) (local.get $229) ) ) (local.set $14 (block $label$116 (result i64) (local.set $155 (struct.get $type$5 1 (local.get $153) ) ) (if (i64.lt_u (local.get $154) (i64.const 64) ) (br $label$116 (i64.shl (struct.get $type$5 1 (local.get $153) ) (local.get $154) ) ) ) (if (i64.lt_s (local.get $154) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $230 (local.tee $156 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $156) (i32.const 147) ) (local.set $157 (local.get $154) ) (local.get $230) ) (struct.new $type$5 (i32.const 9) (local.get $157) ) (ref.null none) ) (drop (call $Error._throw (local.get $156) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$116 (i64.const 0) ) ) ) (local.set $16 (i64.sub (local.get $16) (i64.const 1) ) ) (br $label$111) ) ) (if (i64.gt_s (local.get $16) (i64.const 0) ) (block (local.set $14 (i64.sub (block (result i64) (local.set $233 (local.get $14) ) (local.set $158 (block (result (ref $type$5)) (local.set $231 (global.get $global$12) ) (local.set $159 (i64.const 52) ) (local.get $231) ) ) (local.get $233) ) (block $label$121 (result i64) (local.set $160 (struct.get $type$5 1 (local.get $158) ) ) (if (i64.lt_u (local.get $159) (i64.const 64) ) (br $label$121 (i64.shl (struct.get $type$5 1 (local.get $158) ) (local.get $159) ) ) ) (if (i64.lt_s (local.get $159) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $232 (local.tee $161 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $161) (i32.const 147) ) (local.set $162 (local.get $159) ) (local.get $232) ) (struct.new $type$5 (i32.const 9) (local.get $162) ) (ref.null none) ) (drop (call $Error._throw (local.get $161) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$121 (i64.const 0) ) ) ) ) (local.set $14 (i64.or (block (result i64) (local.set $236 (local.get $14) ) (local.set $163 (local.get $16) ) (local.set $164 (block (result (ref $type$5)) (local.set $234 (struct.new $type$5 (i32.const 9) (local.get $163) ) ) (local.set $165 (i64.const 52) ) (local.get $234) ) ) (local.get $236) ) (block $label$125 (result i64) (local.set $166 (struct.get $type$5 1 (local.get $164) ) ) (if (i64.lt_u (local.get $165) (i64.const 64) ) (br $label$125 (i64.shl (struct.get $type$5 1 (local.get $164) ) (local.get $165) ) ) ) (if (i64.lt_s (local.get $165) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $235 (local.tee $167 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $167) (i32.const 147) ) (local.set $168 (local.get $165) ) (local.get $235) ) (struct.new $type$5 (i32.const 9) (local.get $168) ) (ref.null none) ) (drop (call $Error._throw (local.get $167) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$125 (i64.const 0) ) ) ) ) ) (block (local.set $169 (local.get $14) ) (local.set $170 (block (result (ref $type$5)) (local.set $237 (struct.new $type$5 (i32.const 9) (local.get $169) ) ) (local.set $171 (i64.add (i64.mul (local.get $16) (i64.const -1) ) (i64.const 1) ) ) (local.get $237) ) ) (local.set $14 (block $label$130 (result i64) (local.set $172 (struct.get $type$5 1 (local.get $170) ) ) (if (i64.lt_u (local.get $171) (i64.const 64) ) (br $label$130 (i64.shr_s (struct.get $type$5 1 (local.get $170) ) (local.get $171) ) ) ) (if (i64.lt_s (local.get $171) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $238 (local.tee $173 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $173) (i32.const 147) ) (local.set $174 (local.get $171) ) (local.get $238) ) (struct.new $type$5 (i32.const 9) (local.get $174) ) (ref.null none) ) (drop (call $Error._throw (local.get $173) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$130 (i64.shr_s (struct.get $type$5 1 (local.get $170) ) (i64.const 63) ) ) ) ) ) ) (local.set $14 (i64.or (block (result i64) (local.set $241 (local.get $14) ) (local.set $175 (local.get $30) ) (local.set $176 (block (result (ref $type$5)) (local.set $239 (struct.new $type$5 (i32.const 9) (local.get $175) ) ) (local.set $177 (i64.const 63) ) (local.get $239) ) ) (local.get $241) ) (block $label$134 (result i64) (local.set $178 (struct.get $type$5 1 (local.get $176) ) ) (if (i64.lt_u (local.get $177) (i64.const 64) ) (br $label$134 (i64.shl (struct.get $type$5 1 (local.get $176) ) (local.get $177) ) ) ) (if (i64.lt_s (local.get $177) (i64.const 0) ) (block (call $ArgumentError. (block (result (ref $type$87)) (local.set $240 (local.tee $179 (struct.new_default $type$87) ) ) (struct.set $type$87 0 (local.get $179) (i32.const 147) ) (local.set $180 (local.get $177) ) (local.get $240) ) (struct.new $type$5 (i32.const 9) (local.get $180) ) (ref.null none) ) (drop (call $Error._throw (local.get $179) (call $StackTrace.current) ) ) (unreachable) ) ) (br $label$134 (i64.const 0) ) ) ) ) (return (f64.reinterpret_i64 (local.get $14) ) ) ) ```
Optimized Wasm for computeRemainder, inlined in BoxedDouble.modulo ```wast (func $BoxedDouble.modulo (type $type$133) (param $0 f64) (param $1 f64) (result f64) (local $2 i64) (local $3 i64) (local $4 i64) (local $5 i64) (local $6 i64) (local $7 i64) (local $8 (ref $type$105)) (local $9 (ref $type$105)) (if (result f64) (f64.eq (local.tee $0 (block $label$1 (result f64) (block $label$2 (block $label$3 (br_if $label$3 (i64.eq (i64.and (i64.reinterpret_f64 (local.get $0) ) (i64.const 9223372036854775807) ) (i64.const 9218868437227405312) ) ) (br_if $label$3 (i64.gt_u (i64.and (i64.reinterpret_f64 (local.get $0) ) (i64.const 9223372036854775807) ) (i64.const 9218868437227405312) ) ) (br_if $label$3 (i64.gt_u (i64.and (i64.reinterpret_f64 (local.get $1) ) (i64.const 9223372036854775807) ) (i64.const 9218868437227405312) ) ) (local.set $4 (i64.shr_u (i64.and (local.tee $2 (i64.reinterpret_f64 (local.get $0) ) ) (i64.const 9218868437227405312) ) (i64.const 52) ) ) (local.set $6 (i64.shr_u (i64.and (local.tee $5 (i64.reinterpret_f64 (local.get $1) ) ) (i64.const 9218868437227405312) ) (i64.const 52) ) ) (br_if $label$3 (i64.eqz (i64.shl (local.get $5) (i64.const 1) ) ) ) (if (i64.le_u (i64.shl (local.get $2) (i64.const 1) ) (i64.shl (local.get $5) (i64.const 1) ) ) (block (br_if $label$2 (i64.eq (i64.shl (local.get $2) (i64.const 1) ) (i64.shl (local.get $5) (i64.const 1) ) ) ) (br $label$1 (local.get $0) ) ) ) (local.set $7 (i64.shr_s (local.get $2) (i64.const 63) ) ) (local.set $2 (if (result i64) (i64.eqz (local.get $4) ) (block (result i64) (local.set $3 (i64.shl (local.get $2) (i64.const 12) ) ) (loop $label$6 (if (i64.eqz (i64.shr_s (local.get $3) (i64.const 63) ) ) (block (local.set $4 (i64.sub (local.get $4) (i64.const 1) ) ) (local.set $3 (i64.shl (local.get $3) (i64.const 1) ) ) (br $label$6) ) ) ) (block $label$8 (result i64) (drop (br_if $label$8 (i64.shl (local.get $2) (local.tee $2 (i64.sub (i64.const 1) (local.get $4) ) ) ) (i64.lt_u (local.get $2) (i64.const 64) ) ) ) (if (i64.lt_s (local.get $2) (i64.const 0) ) (block (struct.set $type$105 0 (local.tee $8 (struct.new_default $type$105) ) (i32.const 147) ) (struct.set $type$105 6 (local.get $8) (struct.new $type$3 (i32.const 9) (local.get $2) ) ) (struct.set $type$105 5 (local.get $8) (ref.null none) ) (struct.set $type$105 4 (local.get $8) (ref.null none) ) (struct.set $type$105 3 (local.get $8) (i32.const 0) ) (struct.set $type$105 2 (local.get $8) (ref.null none) ) (call $Error._throw (local.get $8) (call $StackTrace.current) ) (unreachable) ) ) (i64.const 0) ) ) (i64.or (i64.and (local.get $2) (i64.const 4503599627370495) ) (i64.const 4503599627370496) ) ) ) (block $label$11 (local.set $3 (if (result i64) (i64.eqz (local.get $6) ) (block (result i64) (local.set $3 (i64.shl (local.get $5) (i64.const 12) ) ) (loop $label$13 (if (i64.eqz (i64.shr_s (local.get $3) (i64.const 63) ) ) (block (local.set $6 (i64.sub (local.get $6) (i64.const 1) ) ) (local.set $3 (i64.shl (local.get $3) (i64.const 1) ) ) (br $label$13) ) ) ) (block $label$15 (result i64) (drop (br_if $label$15 (i64.shl (local.get $5) (local.tee $3 (i64.sub (i64.const 1) (local.get $6) ) ) ) (i64.lt_u (local.get $3) (i64.const 64) ) ) ) (br_if $label$11 (i64.lt_s (local.get $3) (i64.const 0) ) ) (i64.const 0) ) ) (i64.or (i64.and (local.get $5) (i64.const 4503599627370495) ) (i64.const 4503599627370496) ) ) ) (loop $label$17 (if (i64.gt_s (local.get $4) (local.get $6) ) (block (local.set $2 (i64.shl (if (result i64) (i64.eqz (i64.shr_s (local.tee $5 (i64.sub (local.get $2) (local.get $3) ) ) (i64.const 63) ) ) (block (result i64) (br_if $label$2 (i64.eqz (local.get $5) ) ) (local.get $5) ) (local.get $2) ) (i64.const 1) ) ) (local.set $4 (i64.sub (local.get $4) (i64.const 1) ) ) (br $label$17) ) ) ) (if (i64.eqz (i64.shr_s (local.tee $3 (i64.sub (local.get $2) (local.get $3) ) ) (i64.const 63) ) ) (block (br_if $label$2 (i64.eqz (local.get $3) ) ) (local.set $2 (local.get $3) ) ) ) (loop $label$22 (if (i64.eqz (i64.shr_s (local.get $2) (i64.const 52) ) ) (block (local.set $2 (i64.shl (local.get $2) (i64.const 1) ) ) (local.set $4 (i64.sub (local.get $4) (i64.const 1) ) ) (br $label$22) ) ) ) (br $label$1 (f64.reinterpret_i64 (i64.or (if (result i64) (i64.gt_s (local.get $4) (i64.const 0) ) (i64.or (i64.sub (local.get $2) (i64.const 4503599627370496) ) (i64.shl (local.get $4) (i64.const 52) ) ) (block $label$26 (result i64) (drop (br_if $label$26 (i64.shr_s (local.get $2) (local.tee $3 (i64.sub (i64.const 1) (local.get $4) ) ) ) (i64.lt_u (local.get $3) (i64.const 64) ) ) ) (br_if $label$11 (i64.lt_s (local.get $3) (i64.const 0) ) ) (i64.shr_s (local.get $2) (i64.const 63) ) ) ) (i64.shl (local.get $7) (i64.const 63) ) ) ) ) ) (struct.set $type$105 0 (local.tee $9 (struct.new_default $type$105) ) (i32.const 147) ) (struct.set $type$105 6 (local.get $9) (struct.new $type$3 (i32.const 9) (local.get $3) ) ) (struct.set $type$105 5 (local.get $9) (ref.null none) ) (struct.set $type$105 4 (local.get $9) (ref.null none) ) (struct.set $type$105 3 (local.get $9) (i32.const 0) ) (struct.set $type$105 2 (local.get $9) (ref.null none) ) (call $Error._throw (local.get $9) (call $StackTrace.current) ) (unreachable) ) (br $label$1 (f64.div (local.tee $0 (f64.mul (local.get $0) (local.get $1) ) ) (local.get $0) ) ) ) (f64.copysign (f64.const 0) (local.get $0) ) ) ) (f64.const 0) ) (f64.const 0) (if (result f64) (f64.lt (local.get $0) (f64.const 0) ) (select (f64.sub (local.get $0) (local.get $1) ) (f64.add (local.get $0) (local.get $1) ) (f64.gt (call $BoxedInt.toDouble (global.get $global$189) ) (local.get $1) ) ) (local.get $0) ) ) ) ```