From b7ef21950bca527937a4930809fe7a25635dda8d Mon Sep 17 00:00:00 2001 From: Max Graey Date: Sat, 7 Apr 2018 19:59:26 +0300 Subject: [PATCH] Add String#repeat method (#67) --- std/assembly.d.ts | 2 + std/assembly/string.ts | 52 +- std/portable.d.ts | 5 + tests/compiler/std/array-access.optimized.wat | 2 +- tests/compiler/std/array-access.untouched.wat | 2 +- tests/compiler/std/string.optimized.wat | 433 ++++++++++++++++- tests/compiler/std/string.ts | 12 +- tests/compiler/std/string.untouched.wat | 451 ++++++++++++++++-- 8 files changed, 897 insertions(+), 62 deletions(-) diff --git a/std/assembly.d.ts b/std/assembly.d.ts index c335239e..13d5e1f3 100644 --- a/std/assembly.d.ts +++ b/std/assembly.d.ts @@ -373,6 +373,8 @@ declare class String { trim(): string; trimLeft(): string; trimRight(): string; + repeat(count?: i32): string; + toString(): string; } /** Class for representing a runtime error. Base class of all errors. */ diff --git a/std/assembly/string.ts b/std/assembly/string.ts index 26ad66cd..e8ca36b7 100644 --- a/std/assembly/string.ts +++ b/std/assembly/string.ts @@ -111,7 +111,7 @@ export class String { @operator("==") private static __eq(left: String, right: String): bool { if (left === right) return true; - if (left === null) return right === null; + if (left === null) return right === null; if (right === null) return false; var leftLength = left.length; @@ -131,7 +131,7 @@ export class String { @operator(">") private static __gt(left: String, right: String): bool { - if (left === null || right === null) return false; + if (left === right || left === null || right === null) return false; var leftLength = left.length; var rightLength = right.length; @@ -149,8 +149,9 @@ export class String { @operator(">=") private static __gte(left: String, right: String): bool { - if (left === null) return right === null; - else if (right === null) return false; + if (left === right) return true; + if (left === null) return right === null; + if (right === null) return false; var leftLength = left.length; var rightLength = right.length; @@ -168,7 +169,7 @@ export class String { @operator("<") private static __lt(left: String, right: String): bool { - if (left === null || right === null) return false; + if (left === right || left === null || right === null) return false; var leftLength = left.length; var rightLength = right.length; @@ -186,8 +187,9 @@ export class String { @operator("<=") private static __lte(left: String, right: String): bool { - if (left === null) return right === null; - else if (right === null) return false; + if (left === right) return true; + if (left === null) return right === null; + if (right === null) return false; var leftLength = left.length; var rightLength = right.length; @@ -231,6 +233,7 @@ export class String { startsWith(searchString: String, position: i32 = 0): bool { assert(this !== null); if (searchString === null) searchString = changetype("null"); + var pos: isize = position; var len: isize = this.length; var start: isize = min(max(pos, 0), len); @@ -292,6 +295,7 @@ export class String { trim(): String { assert(this !== null); var length: usize = this.length; + while ( length && isWhiteSpaceOrLineTerminator( @@ -377,6 +381,40 @@ export class String { ); return out; } + + repeat(count: i32 = 0): String { + assert(this !== null); + var length = this.length; + + // Most browsers can't handle strings 1 << 28 chars or longer + if (count < 0 || length * count > (1 << 28)) { + throw new RangeError("Invalid count value"); + } + + if (count === 0 || !length) return EMPTY; + if (count === 1) return this; + + var result = allocate(length * count); + var strLen = length << 1; + + /* + * TODO possible improvments: reuse existing result for exponentially concats like: + * 'a' + 'a' => 'aa' + 'aa' => 'aaaa' + 'aaaa' etc + */ + for (let offset = 0, len = strLen * count; offset < len; offset += strLen) { + move_memory( + changetype(result) + HEADER_SIZE + offset, + changetype(this) + HEADER_SIZE, + strLen + ); + } + + return result; + } + + toString(): String { + return this; + } } export function parseInt(str: String, radix: i32 = 0): f64 { diff --git a/std/portable.d.ts b/std/portable.d.ts index a8396a25..68f8ffd6 100644 --- a/std/portable.d.ts +++ b/std/portable.d.ts @@ -247,12 +247,16 @@ declare class Float32Array extends Array {} declare class Float64Array extends Array {} declare class String { + static fromCharCode(ls: i32, hs?: i32): string; static fromCharCodes(arr: u16[]): string; static fromCodePoint(cp: i32): string; static fromCodePoints(arr: i32[]): string; + readonly length: i32; + private constructor(); + indexOf(subject: string, position?: i32): i32; includes(other: string): bool; lastIndexOf(subject: string, position?: i32): i32; @@ -262,6 +266,7 @@ declare class String { startsWith(subject: string): bool; endsWith(subject: string): bool; replace(search: string, replacement: string): string; + repeat(count?: i32): string; toString(): string; } diff --git a/tests/compiler/std/array-access.optimized.wat b/tests/compiler/std/array-access.optimized.wat index 9c49d99c..c206cc2a 100644 --- a/tests/compiler/std/array-access.optimized.wat +++ b/tests/compiler/std/array-access.optimized.wat @@ -125,7 +125,7 @@ (call $abort (i32.const 0) (i32.const 8) - (i32.const 232) + (i32.const 234) (i32.const 4) ) (unreachable) diff --git a/tests/compiler/std/array-access.untouched.wat b/tests/compiler/std/array-access.untouched.wat index 0c6cadd4..9a2b8ca4 100644 --- a/tests/compiler/std/array-access.untouched.wat +++ b/tests/compiler/std/array-access.untouched.wat @@ -195,7 +195,7 @@ (call $abort (i32.const 0) (i32.const 8) - (i32.const 232) + (i32.const 234) (i32.const 4) ) (unreachable) diff --git a/tests/compiler/std/string.optimized.wat b/tests/compiler/std/string.optimized.wat index 09b61a09..2a27e5a8 100644 --- a/tests/compiler/std/string.optimized.wat +++ b/tests/compiler/std/string.optimized.wat @@ -15,7 +15,7 @@ (global $std/string/nullStr (mut i32) (i32.const 0)) (global $argumentCount (mut i32) (i32.const 0)) (global $std/string/c (mut i32) (i32.const 0)) - (global $HEAP_BASE i32 (i32.const 436)) + (global $HEAP_BASE i32 (i32.const 520)) (memory $0 1) (data (i32.const 4) "\10\00\00\00h\00i\00,\00 \00I\00\'\00m\00 \00a\00 \00s\00t\00r\00i\00n\00g") (data (i32.const 40) "\0d\00\00\00s\00t\00d\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s") @@ -45,6 +45,11 @@ (data (i32.const 404) "\02\00\00\00a\00a") (data (i32.const 412) "\03\00\00\00a\00b\00c") (data (i32.const 424) "\03\00\00\001\002\003") + (data (i32.const 436) "\03\00\00\00a\00a\00a") + (data (i32.const 448) "\08\00\00\00a\00b\00a\00b\00a\00b\00a\00b") + (data (i32.const 468) "\05\00\00\00a\00a\00a\00a\00a") + (data (i32.const 484) "\06\00\00\00a\00a\00a\00a\00a\00a") + (data (i32.const 500) "\07\00\00\00a\00a\00a\00a\00a\00a\00a") (export "getString" (func $std/string/getString)) (export "memory" (memory $0)) (start $start) @@ -156,7 +161,7 @@ (call $abort (i32.const 0) (i32.const 72) - (i32.const 232) + (i32.const 234) (i32.const 4) ) (unreachable) @@ -376,7 +381,7 @@ (call $abort (i32.const 0) (i32.const 72) - (i32.const 211) + (i32.const 213) (i32.const 4) ) (unreachable) @@ -1087,7 +1092,7 @@ (call $abort (i32.const 0) (i32.const 72) - (i32.const 431) + (i32.const 469) (i32.const 10) ) (unreachable) @@ -3352,8 +3357,20 @@ (i32.and (if (result i32) (tee_local $2 - (i32.eqz - (get_local $0) + (i32.and + (if (result i32) + (tee_local $2 + (i32.eq + (get_local $0) + (get_local $1) + ) + ) + (get_local $2) + (i32.eqz + (get_local $0) + ) + ) + (i32.const 1) ) ) (get_local $2) @@ -3421,14 +3438,17 @@ (local $2 i32) (local $3 i32) (if - (get_local $0) - (if - (i32.eqz - (get_local $1) - ) - (return - (i32.const 0) - ) + (i32.eq + (get_local $0) + (get_local $1) + ) + (return + (i32.const 1) + ) + ) + (if + (i32.eqz + (get_local $0) ) (return (i32.eqz @@ -3436,6 +3456,14 @@ ) ) ) + (if + (i32.eqz + (get_local $1) + ) + (return + (i32.const 0) + ) + ) (set_local $2 (i32.load (get_local $1) @@ -3495,8 +3523,20 @@ (i32.and (if (result i32) (tee_local $2 - (i32.eqz - (get_local $0) + (i32.and + (if (result i32) + (tee_local $2 + (i32.eq + (get_local $0) + (get_local $1) + ) + ) + (get_local $2) + (i32.eqz + (get_local $0) + ) + ) + (i32.const 1) ) ) (get_local $2) @@ -3564,14 +3604,17 @@ (local $2 i32) (local $3 i32) (if - (get_local $0) - (if - (i32.eqz - (get_local $1) - ) - (return - (i32.const 0) - ) + (i32.eq + (get_local $0) + (get_local $1) + ) + (return + (i32.const 1) + ) + ) + (if + (i32.eqz + (get_local $0) ) (return (i32.eqz @@ -3579,6 +3622,14 @@ ) ) ) + (if + (i32.eqz + (get_local $1) + ) + (return + (i32.const 0) + ) + ) (set_local $2 (i32.load (get_local $0) @@ -3631,7 +3682,154 @@ (i32.const 0) ) ) - (func $start (; 28 ;) (type $v) + (func $~lib/string/String#repeat (; 28 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (if + (i32.eqz + (get_local $0) + ) + (block + (call $abort + (i32.const 0) + (i32.const 72) + (i32.const 386) + (i32.const 4) + ) + (unreachable) + ) + ) + (set_local $3 + (i32.load + (get_local $0) + ) + ) + (if + (i32.and + (if (result i32) + (tee_local $2 + (i32.lt_s + (get_local $1) + (i32.const 0) + ) + ) + (get_local $2) + (i32.gt_s + (i32.mul + (get_local $3) + (get_local $1) + ) + (i32.const 268435456) + ) + ) + (i32.const 1) + ) + (unreachable) + ) + (if + (i32.and + (if (result i32) + (tee_local $2 + (i32.eqz + (get_local $1) + ) + ) + (get_local $2) + (i32.eqz + (get_local $3) + ) + ) + (i32.const 1) + ) + (return + (i32.const 332) + ) + ) + (if + (i32.eq + (get_local $1) + (i32.const 1) + ) + (return + (get_local $0) + ) + ) + (set_local $4 + (call $~lib/internal/string/allocate + (i32.mul + (get_local $3) + (get_local $1) + ) + ) + ) + (set_local $2 + (i32.const 0) + ) + (set_local $1 + (i32.mul + (tee_local $3 + (i32.shl + (get_local $3) + (i32.const 1) + ) + ) + (get_local $1) + ) + ) + (loop $continue|0 + (if + (i32.lt_s + (get_local $2) + (get_local $1) + ) + (block + (call $~lib/memory/move_memory + (i32.add + (i32.add + (get_local $4) + (i32.const 4) + ) + (get_local $2) + ) + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $3) + ) + (set_local $2 + (i32.add + (get_local $2) + (get_local $3) + ) + ) + (br $continue|0) + ) + ) + ) + (get_local $4) + ) + (func $~lib/string/String#repeat|trampoline (; 29 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (block $1of1 + (block $0of1 + (block $oob + (br_table $0of1 $1of1 $oob + (get_global $argumentCount) + ) + ) + (unreachable) + ) + (set_local $1 + (i32.const 0) + ) + ) + (call $~lib/string/String#repeat + (get_local $0) + (get_local $1) + ) + ) + (func $start (; 30 ;) (type $v) (set_global $~lib/allocator/arena/startOffset (i32.and (i32.add @@ -4446,5 +4644,190 @@ (unreachable) ) ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 332) + (i32.const 100) + ) + (i32.const 332) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 66) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (block (result i32) + (set_global $argumentCount + (i32.const 0) + ) + (call $~lib/string/String#repeat|trampoline + (i32.const 316) + (i32.const 0) + ) + ) + (i32.const 332) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 67) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 1) + ) + (i32.const 316) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 68) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 2) + ) + (i32.const 404) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 69) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 3) + ) + (i32.const 436) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 70) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 388) + (i32.const 4) + ) + (i32.const 448) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 71) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 5) + ) + (i32.const 468) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 72) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 6) + ) + (i32.const 484) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 73) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 7) + ) + (i32.const 500) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 74) + (i32.const 0) + ) + (unreachable) + ) + ) ) ) diff --git a/tests/compiler/std/string.ts b/tests/compiler/std/string.ts index 868ab063..a014aebb 100644 --- a/tests/compiler/std/string.ts +++ b/tests/compiler/std/string.ts @@ -3,7 +3,7 @@ import "allocator/arena"; // preliminary var str: string = "hi, I'm a string"; -var nullStr: String; +var nullStr: string; // exactly once in static memory assert(changetype(str) == changetype("hi, I'm a string")); @@ -62,3 +62,13 @@ assert("" >= ""); assert("" <= ""); assert("123".length == 3); + +assert("".repeat(100) == ""); +assert("a".repeat() == ""); +assert("a".repeat(1) == "a"); +assert("a".repeat(2) == "aa"); +assert("a".repeat(3) == "aaa"); +assert("ab".repeat(4) == "abababab"); +assert("a".repeat(5) == "aaaaa"); +assert("a".repeat(6) == "aaaaaa"); +assert("a".repeat(7) == "aaaaaaa"); diff --git a/tests/compiler/std/string.untouched.wat b/tests/compiler/std/string.untouched.wat index 417d6dc8..3bd4382a 100644 --- a/tests/compiler/std/string.untouched.wat +++ b/tests/compiler/std/string.untouched.wat @@ -47,7 +47,7 @@ (global $~lib/internal/string/CharCode.z i32 (i32.const 122)) (global $~lib/internal/string/EMPTY i32 (i32.const 332)) (global $std/string/c (mut i32) (i32.const 0)) - (global $HEAP_BASE i32 (i32.const 436)) + (global $HEAP_BASE i32 (i32.const 520)) (memory $0 1) (data (i32.const 4) "\10\00\00\00h\00i\00,\00 \00I\00\'\00m\00 \00a\00 \00s\00t\00r\00i\00n\00g\00") (data (i32.const 40) "\0d\00\00\00s\00t\00d\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s\00") @@ -78,6 +78,11 @@ (data (i32.const 404) "\02\00\00\00a\00a\00") (data (i32.const 412) "\03\00\00\00a\00b\00c\00") (data (i32.const 424) "\03\00\00\001\002\003\00") + (data (i32.const 436) "\03\00\00\00a\00a\00a\00") + (data (i32.const 448) "\08\00\00\00a\00b\00a\00b\00a\00b\00a\00b\00") + (data (i32.const 468) "\05\00\00\00a\00a\00a\00a\00a\00") + (data (i32.const 484) "\06\00\00\00a\00a\00a\00a\00a\00a\00") + (data (i32.const 500) "\07\00\00\00a\00a\00a\00a\00a\00a\00a\00") (export "getString" (func $std/string/getString)) (export "memory" (memory $0)) (start $start) @@ -206,7 +211,7 @@ (call $abort (i32.const 0) (i32.const 72) - (i32.const 232) + (i32.const 234) (i32.const 4) ) (unreachable) @@ -464,7 +469,7 @@ (call $abort (i32.const 0) (i32.const 72) - (i32.const 211) + (i32.const 213) (i32.const 4) ) (unreachable) @@ -1266,7 +1271,7 @@ (call $abort (i32.const 0) (i32.const 72) - (i32.const 431) + (i32.const 469) (i32.const 10) ) (unreachable) @@ -3851,9 +3856,21 @@ (i32.and (if (result i32) (tee_local $2 - (i32.eq - (get_local $0) - (i32.const 0) + (i32.and + (if (result i32) + (tee_local $2 + (i32.eq + (get_local $0) + (get_local $1) + ) + ) + (get_local $2) + (i32.eq + (get_local $0) + (i32.const 0) + ) + ) + (i32.const 1) ) ) (get_local $2) @@ -3934,6 +3951,15 @@ (local $4 i32) (local $5 i32) (local $6 i32) + (if + (i32.eq + (get_local $0) + (get_local $1) + ) + (return + (i32.const 1) + ) + ) (if (i32.eq (get_local $0) @@ -3945,14 +3971,14 @@ (i32.const 0) ) ) - (if - (i32.eq - (get_local $1) - (i32.const 0) - ) - (return - (i32.const 0) - ) + ) + (if + (i32.eq + (get_local $1) + (i32.const 0) + ) + (return + (i32.const 0) ) ) (set_local $2 @@ -4027,9 +4053,21 @@ (i32.and (if (result i32) (tee_local $2 - (i32.eq - (get_local $0) - (i32.const 0) + (i32.and + (if (result i32) + (tee_local $2 + (i32.eq + (get_local $0) + (get_local $1) + ) + ) + (get_local $2) + (i32.eq + (get_local $0) + (i32.const 0) + ) + ) + (i32.const 1) ) ) (get_local $2) @@ -4110,6 +4148,15 @@ (local $4 i32) (local $5 i32) (local $6 i32) + (if + (i32.eq + (get_local $0) + (get_local $1) + ) + (return + (i32.const 1) + ) + ) (if (i32.eq (get_local $0) @@ -4121,14 +4168,14 @@ (i32.const 0) ) ) - (if - (i32.eq - (get_local $1) - (i32.const 0) - ) - (return - (i32.const 0) - ) + ) + (if + (i32.eq + (get_local $1) + (i32.const 0) + ) + (return + (i32.const 0) ) ) (set_local $2 @@ -4193,7 +4240,172 @@ ) ) ) - (func $start (; 28 ;) (type $v) + (func $~lib/string/String#repeat (; 28 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (if + (i32.eqz + (i32.ne + (get_local $0) + (i32.const 0) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 72) + (i32.const 386) + (i32.const 4) + ) + (unreachable) + ) + ) + (set_local $2 + (i32.load + (get_local $0) + ) + ) + (if + (i32.and + (if (result i32) + (tee_local $3 + (i32.lt_s + (get_local $1) + (i32.const 0) + ) + ) + (get_local $3) + (i32.gt_s + (i32.mul + (get_local $2) + (get_local $1) + ) + (i32.shl + (i32.const 1) + (i32.const 28) + ) + ) + ) + (i32.const 1) + ) + (unreachable) + ) + (if + (i32.and + (if (result i32) + (tee_local $3 + (i32.eq + (get_local $1) + (i32.const 0) + ) + ) + (get_local $3) + (i32.eqz + (get_local $2) + ) + ) + (i32.const 1) + ) + (return + (i32.const 332) + ) + ) + (if + (i32.eq + (get_local $1) + (i32.const 1) + ) + (return + (get_local $0) + ) + ) + (set_local $4 + (call $~lib/internal/string/allocate + (i32.mul + (get_local $2) + (get_local $1) + ) + ) + ) + (set_local $5 + (i32.shl + (get_local $2) + (i32.const 1) + ) + ) + (block $break|0 + (block + (set_local $3 + (i32.const 0) + ) + (set_local $6 + (i32.mul + (get_local $5) + (get_local $1) + ) + ) + ) + (loop $continue|0 + (if + (i32.lt_s + (get_local $3) + (get_local $6) + ) + (block + (block + (call $~lib/memory/move_memory + (i32.add + (i32.add + (get_local $4) + (i32.const 4) + ) + (get_local $3) + ) + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $5) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (get_local $5) + ) + ) + (br $continue|0) + ) + ) + ) + ) + (return + (get_local $4) + ) + ) + (func $~lib/string/String#repeat|trampoline (; 29 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32) + (block $1of1 + (block $0of1 + (block $oob + (br_table $0of1 $1of1 $oob + (get_global $argumentCount) + ) + ) + (unreachable) + ) + (set_local $1 + (i32.const 0) + ) + ) + (call $~lib/string/String#repeat + (get_local $0) + (get_local $1) + ) + ) + (func $start (; 30 ;) (type $v) (set_global $~lib/allocator/arena/startOffset (i32.and (i32.add @@ -5077,5 +5289,190 @@ (unreachable) ) ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 332) + (i32.const 100) + ) + (i32.const 332) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 66) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (block (result i32) + (set_global $argumentCount + (i32.const 0) + ) + (call $~lib/string/String#repeat|trampoline + (i32.const 316) + (i32.const 0) + ) + ) + (i32.const 332) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 67) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 1) + ) + (i32.const 316) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 68) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 2) + ) + (i32.const 404) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 69) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 3) + ) + (i32.const 436) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 70) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 388) + (i32.const 4) + ) + (i32.const 448) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 71) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 5) + ) + (i32.const 468) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 72) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 6) + ) + (i32.const 484) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 73) + (i32.const 0) + ) + (unreachable) + ) + ) + (if + (i32.eqz + (call $~lib/string/String.__eq + (call $~lib/string/String#repeat + (i32.const 316) + (i32.const 7) + ) + (i32.const 500) + ) + ) + (block + (call $abort + (i32.const 0) + (i32.const 40) + (i32.const 74) + (i32.const 0) + ) + (unreachable) + ) + ) ) )