Update binary expression inference, see #35; Update dependencies

This commit is contained in:
dcodeIO 2018-03-01 19:42:07 +01:00
parent 02dce5a518
commit 4633fdab96
26 changed files with 6342 additions and 3057 deletions

8
dist/asc.js vendored

File diff suppressed because one or more lines are too long

1
dist/asc.js.map vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -27,10 +27,12 @@ export function step(): void {
load<u8>(yp1 * w + xm1) + load<u8>(yp1 * w + x) + load<u8>(yp1 * w + xp1) load<u8>(yp1 * w + xm1) + load<u8>(yp1 * w + x) + load<u8>(yp1 * w + xp1)
); );
if (load<u8>(y * w + x)) { if (load<u8>(y * w + x)) {
if (n < 2 || n > 3) if (n < 2 || n > 3) {
store<u8>(s + y * w + x, 0); store<u8>(s + y * w + x, 0);
} else if (n == 3) }
} else if (n == 3) {
store<u8>(s + y * w + x, 1); store<u8>(s + y * w + x, 1);
}
} }
} }
} }

View File

@ -320,31 +320,31 @@
(i32.const 0) (i32.const 0)
) )
) )
;;@ assembly/game-of-life.ts:32:13 ;;@ assembly/game-of-life.ts:33:13
(if (if
;;@ assembly/game-of-life.ts:32:17 ;;@ assembly/game-of-life.ts:33:17
(i32.eq (i32.eq
(get_local $2) (get_local $2)
;;@ assembly/game-of-life.ts:32:22 ;;@ assembly/game-of-life.ts:33:22
(i32.const 3) (i32.const 3)
) )
;;@ assembly/game-of-life.ts:33:8 ;;@ assembly/game-of-life.ts:34:8
(i32.store8 (i32.store8
;;@ assembly/game-of-life.ts:33:18 ;;@ assembly/game-of-life.ts:34:18
(i32.add (i32.add
(i32.add (i32.add
(get_global $assembly/game-of-life/s) (get_global $assembly/game-of-life/s)
;;@ assembly/game-of-life.ts:33:22 ;;@ assembly/game-of-life.ts:34:22
(i32.mul (i32.mul
(get_local $0) (get_local $0)
;;@ assembly/game-of-life.ts:33:26 ;;@ assembly/game-of-life.ts:34:26
(get_global $assembly/game-of-life/w) (get_global $assembly/game-of-life/w)
) )
) )
;;@ assembly/game-of-life.ts:33:30 ;;@ assembly/game-of-life.ts:34:30
(get_local $1) (get_local $1)
) )
;;@ assembly/game-of-life.ts:33:33 ;;@ assembly/game-of-life.ts:34:33
(i32.const 1) (i32.const 1)
) )
) )

View File

@ -316,15 +316,12 @@
;;@ assembly/game-of-life.ts:30:12 ;;@ assembly/game-of-life.ts:30:12
(i32.and (i32.and
(if (result i32) (if (result i32)
(i32.ne (tee_local $9
(tee_local $9 (i32.lt_s
(i32.lt_s (get_local $8)
(get_local $8) ;;@ assembly/game-of-life.ts:30:16
;;@ assembly/game-of-life.ts:30:16 (i32.const 2)
(i32.const 2)
)
) )
(i32.const 0)
) )
(get_local $9) (get_local $9)
;;@ assembly/game-of-life.ts:30:21 ;;@ assembly/game-of-life.ts:30:21
@ -356,31 +353,31 @@
(i32.const 0) (i32.const 0)
) )
) )
;;@ assembly/game-of-life.ts:32:13 ;;@ assembly/game-of-life.ts:33:13
(if (if
;;@ assembly/game-of-life.ts:32:17 ;;@ assembly/game-of-life.ts:33:17
(i32.eq (i32.eq
(get_local $8) (get_local $8)
;;@ assembly/game-of-life.ts:32:22 ;;@ assembly/game-of-life.ts:33:22
(i32.const 3) (i32.const 3)
) )
;;@ assembly/game-of-life.ts:33:8 ;;@ assembly/game-of-life.ts:34:8
(i32.store8 (i32.store8
;;@ assembly/game-of-life.ts:33:18 ;;@ assembly/game-of-life.ts:34:18
(i32.add (i32.add
(i32.add (i32.add
(get_global $assembly/game-of-life/s) (get_global $assembly/game-of-life/s)
;;@ assembly/game-of-life.ts:33:22 ;;@ assembly/game-of-life.ts:34:22
(i32.mul (i32.mul
(get_local $2) (get_local $2)
;;@ assembly/game-of-life.ts:33:26 ;;@ assembly/game-of-life.ts:34:26
(get_global $assembly/game-of-life/w) (get_global $assembly/game-of-life/w)
) )
) )
;;@ assembly/game-of-life.ts:33:30 ;;@ assembly/game-of-life.ts:34:30
(get_local $5) (get_local $5)
) )
;;@ assembly/game-of-life.ts:33:33 ;;@ assembly/game-of-life.ts:34:33
(i32.const 1) (i32.const 1)
) )
) )

View File

@ -40,8 +40,9 @@ var offset: usize = 0;
export function decode(length: usize): void { export function decode(length: usize): void {
offset = 0; offset = 0;
while (offset < length) while (offset < length) {
decodeValue(); decodeValue();
}
assert(offset == length); assert(offset == length);
} }
@ -85,8 +86,9 @@ function decodeValue(): void {
case Token.ARRAY: case Token.ARRAY:
pson.onArray(size = readVarint32()); pson.onArray(size = readVarint32());
while (size--) while (size--) {
decodeValue(); decodeValue();
}
break; break;
case Token.INTEGER: case Token.INTEGER:
@ -126,8 +128,9 @@ function decodeValue(): void {
break; break;
default: // small integer? default: // small integer?
if (token > Token.MAX) if (token > <u32>Token.MAX) {
throw new Error("unexpected token"); throw new Error("unexpected token");
}
pson.onInteger((token >> 1) ^ -(token & 1)); pson.onInteger((token >> 1) ^ -(token & 1));
break; break;
} }

View File

@ -32,11 +32,11 @@
(local $1 i32) (local $1 i32)
(local $2 i32) (local $2 i32)
(loop $continue|0 (loop $continue|0
;;@ assembly/pson.ts:141:4 ;;@ assembly/pson.ts:144:4
(set_local $0 (set_local $0
(i32.or (i32.or
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:140:21 ;;@ assembly/pson.ts:143:21
(block (result i32) (block (result i32)
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
@ -46,20 +46,20 @@
(i32.const 1) (i32.const 1)
) )
) )
;;@ assembly/pson.ts:141:13 ;;@ assembly/pson.ts:144:13
(i32.shl (i32.shl
(i32.and (i32.and
;;@ assembly/pson.ts:140:4 ;;@ assembly/pson.ts:143:4
(tee_local $2 (tee_local $2
;;@ assembly/pson.ts:140:12 ;;@ assembly/pson.ts:143:12
(i32.load8_u (i32.load8_u
(get_local $0) (get_local $0)
) )
) )
;;@ assembly/pson.ts:141:23 ;;@ assembly/pson.ts:144:23
(i32.const 127) (i32.const 127)
) )
;;@ assembly/pson.ts:141:37 ;;@ assembly/pson.ts:144:37
(block (result i32) (block (result i32)
(set_local $1 (set_local $1
(i32.add (i32.add
@ -69,10 +69,10 @@
(i32.const 1) (i32.const 1)
) )
) )
;;@ assembly/pson.ts:141:32 ;;@ assembly/pson.ts:144:32
(i32.mul (i32.mul
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:141:33 ;;@ assembly/pson.ts:144:33
(i32.const 7) (i32.const 7)
) )
) )
@ -82,14 +82,14 @@
) )
(br_if $continue|0 (br_if $continue|0
(i32.and (i32.and
;;@ assembly/pson.ts:142:11 ;;@ assembly/pson.ts:145:11
(get_local $2) (get_local $2)
;;@ assembly/pson.ts:142:15 ;;@ assembly/pson.ts:145:15
(i32.const 128) (i32.const 128)
) )
) )
) )
;;@ assembly/pson.ts:143:9 ;;@ assembly/pson.ts:146:9
(get_local $0) (get_local $0)
) )
(func $assembly/pson/readVarint64 (; 16 ;) (type $I) (result i64) (func $assembly/pson/readVarint64 (; 16 ;) (type $I) (result i64)
@ -97,11 +97,11 @@
(local $1 i32) (local $1 i32)
(local $2 i64) (local $2 i64)
(loop $continue|0 (loop $continue|0
;;@ assembly/pson.ts:151:4 ;;@ assembly/pson.ts:154:4
(set_local $0 (set_local $0
(i64.or (i64.or
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:150:21 ;;@ assembly/pson.ts:153:21
(block (result i64) (block (result i64)
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
@ -114,31 +114,31 @@
(set_local $2 (set_local $2
(i64.add (i64.add
(tee_local $0 (tee_local $0
;;@ assembly/pson.ts:151:37 ;;@ assembly/pson.ts:154:37
(get_local $2) (get_local $2)
) )
(i64.const 1) (i64.const 1)
) )
) )
;;@ assembly/pson.ts:151:13 ;;@ assembly/pson.ts:154:13
(i64.shl (i64.shl
(i64.extend_u/i32 (i64.extend_u/i32
(i32.and (i32.and
;;@ assembly/pson.ts:150:4 ;;@ assembly/pson.ts:153:4
(tee_local $1 (tee_local $1
;;@ assembly/pson.ts:150:12 ;;@ assembly/pson.ts:153:12
(i32.load8_u (i32.load8_u
(get_local $1) (get_local $1)
) )
) )
;;@ assembly/pson.ts:151:23 ;;@ assembly/pson.ts:154:23
(i32.const 127) (i32.const 127)
) )
) )
;;@ assembly/pson.ts:151:32 ;;@ assembly/pson.ts:154:32
(i64.mul (i64.mul
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:151:33 ;;@ assembly/pson.ts:154:33
(i64.const 7) (i64.const 7)
) )
) )
@ -147,21 +147,21 @@
) )
(br_if $continue|0 (br_if $continue|0
(i32.and (i32.and
;;@ assembly/pson.ts:152:11 ;;@ assembly/pson.ts:155:11
(get_local $1) (get_local $1)
;;@ assembly/pson.ts:152:15 ;;@ assembly/pson.ts:155:15
(i32.const 128) (i32.const 128)
) )
) )
) )
;;@ assembly/pson.ts:153:9 ;;@ assembly/pson.ts:156:9
(get_local $0) (get_local $0)
) )
(func $assembly/pson/decodeValue (; 17 ;) (type $v) (func $assembly/pson/decodeValue (; 17 ;) (type $v)
(local $0 i32) (local $0 i32)
(local $1 i32) (local $1 i32)
(local $2 i64) (local $2 i64)
;;@ assembly/pson.ts:52:2 ;;@ assembly/pson.ts:53:2
(block $break|0 (block $break|0
(block $case16|0 (block $case16|0
(block $case15|0 (block $case15|0
@ -183,7 +183,7 @@
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
(tee_local $1 (tee_local $1
;;@ assembly/pson.ts:49:28 ;;@ assembly/pson.ts:50:28
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
) )
(i32.const 1) (i32.const 1)
@ -192,9 +192,9 @@
(br_table $case0|0 $case1|0 $case2|0 $case3|0 $case4|0 $case5|0 $case6|0 $case7|0 $case8|0 $case9|0 $case10|0 $case11|0 $case12|0 $tablify|0 (br_table $case0|0 $case1|0 $case2|0 $case3|0 $case4|0 $case5|0 $case6|0 $case7|0 $case8|0 $case9|0 $case10|0 $case11|0 $case12|0 $tablify|0
(i32.sub (i32.sub
(tee_local $1 (tee_local $1
;;@ assembly/pson.ts:49:2 ;;@ assembly/pson.ts:50:2
(tee_local $0 (tee_local $0
;;@ assembly/pson.ts:49:19 ;;@ assembly/pson.ts:50:19
(i32.load8_u (i32.load8_u
(get_local $1) (get_local $1)
) )
@ -208,12 +208,12 @@
(i32.or (i32.or
(i32.eq (i32.eq
(get_local $1) (get_local $1)
;;@ assembly/pson.ts:117:9 ;;@ assembly/pson.ts:119:9
(i32.const 253) (i32.const 253)
) )
(i32.eq (i32.eq
(get_local $1) (get_local $1)
;;@ assembly/pson.ts:118:9 ;;@ assembly/pson.ts:120:9
(i32.const 254) (i32.const 254)
) )
) )
@ -221,53 +221,53 @@
(br_if $case15|0 (br_if $case15|0
(i32.eq (i32.eq
(get_local $1) (get_local $1)
;;@ assembly/pson.ts:122:9 ;;@ assembly/pson.ts:124:9
(i32.const 255) (i32.const 255)
) )
) )
(br $case16|0) (br $case16|0)
) )
;;@ assembly/pson.ts:55:11 ;;@ assembly/pson.ts:56:11
(call $assembly/pson/pson.onNull) (call $assembly/pson/pson.onNull)
;;@ assembly/pson.ts:56:6 ;;@ assembly/pson.ts:57:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:59:11 ;;@ assembly/pson.ts:60:11
(call $assembly/pson/pson.onTrue) (call $assembly/pson/pson.onTrue)
;;@ assembly/pson.ts:60:6 ;;@ assembly/pson.ts:61:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:63:11 ;;@ assembly/pson.ts:64:11
(call $assembly/pson/pson.onFalse) (call $assembly/pson/pson.onFalse)
;;@ assembly/pson.ts:64:6 ;;@ assembly/pson.ts:65:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:67:11 ;;@ assembly/pson.ts:68:11
(call $assembly/pson/pson.onEObject) (call $assembly/pson/pson.onEObject)
;;@ assembly/pson.ts:68:6 ;;@ assembly/pson.ts:69:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:71:11 ;;@ assembly/pson.ts:72:11
(call $assembly/pson/pson.onEArray) (call $assembly/pson/pson.onEArray)
;;@ assembly/pson.ts:72:6 ;;@ assembly/pson.ts:73:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:75:11 ;;@ assembly/pson.ts:76:11
(call $assembly/pson/pson.onEString) (call $assembly/pson/pson.onEString)
;;@ assembly/pson.ts:76:6 ;;@ assembly/pson.ts:77:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:79:11 ;;@ assembly/pson.ts:80:11
(call $assembly/pson/pson.onObject (call $assembly/pson/pson.onObject
;;@ assembly/pson.ts:79:20 ;;@ assembly/pson.ts:80:20
(tee_local $0 (tee_local $0
;;@ assembly/pson.ts:79:27 ;;@ assembly/pson.ts:80:27
(call $assembly/pson/readVarint32) (call $assembly/pson/readVarint32)
) )
) )
(loop $continue|1 (loop $continue|1
(if (if
;;@ assembly/pson.ts:80:13 ;;@ assembly/pson.ts:81:13
(block (result i32) (block (result i32)
(set_local $0 (set_local $0
(i32.sub (i32.sub
@ -280,28 +280,28 @@
(get_local $1) (get_local $1)
) )
(block (block
;;@ assembly/pson.ts:81:8
(call $assembly/pson/decodeValue)
;;@ assembly/pson.ts:82:8 ;;@ assembly/pson.ts:82:8
(call $assembly/pson/decodeValue) (call $assembly/pson/decodeValue)
;;@ assembly/pson.ts:83:8
(call $assembly/pson/decodeValue)
(br $continue|1) (br $continue|1)
) )
) )
) )
;;@ assembly/pson.ts:84:6 ;;@ assembly/pson.ts:85:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:87:11 ;;@ assembly/pson.ts:88:11
(call $assembly/pson/pson.onArray (call $assembly/pson/pson.onArray
;;@ assembly/pson.ts:87:19 ;;@ assembly/pson.ts:88:19
(tee_local $0 (tee_local $0
;;@ assembly/pson.ts:87:26 ;;@ assembly/pson.ts:88:26
(call $assembly/pson/readVarint32) (call $assembly/pson/readVarint32)
) )
) )
(loop $continue|2 (loop $continue|2
(if (if
;;@ assembly/pson.ts:88:13 ;;@ assembly/pson.ts:89:13
(block (result i32) (block (result i32)
(set_local $0 (set_local $0
(i32.sub (i32.sub
@ -314,204 +314,204 @@
(get_local $1) (get_local $1)
) )
(block (block
;;@ assembly/pson.ts:89:8 ;;@ assembly/pson.ts:90:8
(call $assembly/pson/decodeValue) (call $assembly/pson/decodeValue)
(br $continue|2) (br $continue|2)
) )
) )
) )
;;@ assembly/pson.ts:90:6 ;;@ assembly/pson.ts:92:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:93:11 ;;@ assembly/pson.ts:95:11
(call $assembly/pson/pson.onInteger (call $assembly/pson/pson.onInteger
;;@ assembly/pson.ts:93:21 ;;@ assembly/pson.ts:95:21
(i32.xor (i32.xor
(i32.shr_u (i32.shr_u
;;@ assembly/pson.ts:93:22 ;;@ assembly/pson.ts:95:22
(tee_local $0 (tee_local $0
;;@ assembly/pson.ts:93:30 ;;@ assembly/pson.ts:95:30
(call $assembly/pson/readVarint32) (call $assembly/pson/readVarint32)
) )
;;@ assembly/pson.ts:93:49 ;;@ assembly/pson.ts:95:49
(i32.const 1) (i32.const 1)
) )
;;@ assembly/pson.ts:93:54 ;;@ assembly/pson.ts:95:54
(i32.sub (i32.sub
(i32.const 0) (i32.const 0)
;;@ assembly/pson.ts:93:55 ;;@ assembly/pson.ts:95:55
(i32.and (i32.and
;;@ assembly/pson.ts:93:56 ;;@ assembly/pson.ts:95:56
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:93:63 ;;@ assembly/pson.ts:95:63
(i32.const 1) (i32.const 1)
) )
) )
) )
) )
;;@ assembly/pson.ts:94:6 ;;@ assembly/pson.ts:96:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:98:11 ;;@ assembly/pson.ts:100:11
(call $assembly/pson/pson.onLong (call $assembly/pson/pson.onLong
;;@ assembly/pson.ts:98:18 ;;@ assembly/pson.ts:100:18
(i32.wrap/i64 (i32.wrap/i64
;;@ assembly/pson.ts:97:6 ;;@ assembly/pson.ts:99:6
(tee_local $2 (tee_local $2
;;@ assembly/pson.ts:97:13 ;;@ assembly/pson.ts:99:13
(i64.xor (i64.xor
(i64.shr_u (i64.shr_u
;;@ assembly/pson.ts:97:14 ;;@ assembly/pson.ts:99:14
(tee_local $2 (tee_local $2
;;@ assembly/pson.ts:97:22 ;;@ assembly/pson.ts:99:22
(call $assembly/pson/readVarint64) (call $assembly/pson/readVarint64)
) )
;;@ assembly/pson.ts:97:41 ;;@ assembly/pson.ts:99:41
(i64.const 1) (i64.const 1)
) )
;;@ assembly/pson.ts:97:46 ;;@ assembly/pson.ts:99:46
(i64.sub (i64.sub
(i64.const 0) (i64.const 0)
;;@ assembly/pson.ts:97:47 ;;@ assembly/pson.ts:99:47
(i64.and (i64.and
;;@ assembly/pson.ts:97:48 ;;@ assembly/pson.ts:99:48
(get_local $2) (get_local $2)
;;@ assembly/pson.ts:97:55 ;;@ assembly/pson.ts:99:55
(i64.const 1) (i64.const 1)
) )
) )
) )
) )
) )
;;@ assembly/pson.ts:98:29 ;;@ assembly/pson.ts:100:29
(i32.wrap/i64 (i32.wrap/i64
;;@ assembly/pson.ts:98:35 ;;@ assembly/pson.ts:100:35
(i64.shr_u (i64.shr_u
(get_local $2) (get_local $2)
;;@ assembly/pson.ts:98:44 ;;@ assembly/pson.ts:100:44
(i64.const 32) (i64.const 32)
) )
) )
) )
;;@ assembly/pson.ts:99:6 ;;@ assembly/pson.ts:101:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:102:11 ;;@ assembly/pson.ts:104:11
(call $assembly/pson/pson.onFloat (call $assembly/pson/pson.onFloat
;;@ assembly/pson.ts:102:19 ;;@ assembly/pson.ts:104:19
(f32.load (f32.load
;;@ assembly/pson.ts:102:29 ;;@ assembly/pson.ts:104:29
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
) )
) )
;;@ assembly/pson.ts:103:6 ;;@ assembly/pson.ts:105:6
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:103:16 ;;@ assembly/pson.ts:105:16
(i32.const 4) (i32.const 4)
) )
) )
;;@ assembly/pson.ts:104:6 ;;@ assembly/pson.ts:106:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:107:11 ;;@ assembly/pson.ts:109:11
(call $assembly/pson/pson.onDouble (call $assembly/pson/pson.onDouble
;;@ assembly/pson.ts:107:20 ;;@ assembly/pson.ts:109:20
(f64.load (f64.load
;;@ assembly/pson.ts:107:30 ;;@ assembly/pson.ts:109:30
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
) )
) )
;;@ assembly/pson.ts:108:6 ;;@ assembly/pson.ts:110:6
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:108:16 ;;@ assembly/pson.ts:110:16
(i32.const 8) (i32.const 8)
) )
) )
;;@ assembly/pson.ts:109:6 ;;@ assembly/pson.ts:111:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:112:6 ;;@ assembly/pson.ts:114:6
(set_local $0 (set_local $0
;;@ assembly/pson.ts:112:13 ;;@ assembly/pson.ts:114:13
(call $assembly/pson/readVarint32) (call $assembly/pson/readVarint32)
) )
;;@ assembly/pson.ts:113:11 ;;@ assembly/pson.ts:115:11
(call $assembly/pson/pson.onString (call $assembly/pson/pson.onString
;;@ assembly/pson.ts:113:20 ;;@ assembly/pson.ts:115:20
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:113:28 ;;@ assembly/pson.ts:115:28
(get_local $0) (get_local $0)
) )
;;@ assembly/pson.ts:114:6 ;;@ assembly/pson.ts:116:6
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:114:16 ;;@ assembly/pson.ts:116:16
(get_local $0) (get_local $0)
) )
) )
;;@ assembly/pson.ts:115:6 ;;@ assembly/pson.ts:117:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:120:6 ;;@ assembly/pson.ts:122:6
(unreachable) (unreachable)
) )
;;@ assembly/pson.ts:123:6 ;;@ assembly/pson.ts:125:6
(set_local $0 (set_local $0
;;@ assembly/pson.ts:123:13 ;;@ assembly/pson.ts:125:13
(call $assembly/pson/readVarint32) (call $assembly/pson/readVarint32)
) )
;;@ assembly/pson.ts:124:11 ;;@ assembly/pson.ts:126:11
(call $assembly/pson/pson.onBinary (call $assembly/pson/pson.onBinary
;;@ assembly/pson.ts:124:20 ;;@ assembly/pson.ts:126:20
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:124:28 ;;@ assembly/pson.ts:126:28
(get_local $0) (get_local $0)
) )
;;@ assembly/pson.ts:125:6 ;;@ assembly/pson.ts:127:6
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:125:16 ;;@ assembly/pson.ts:127:16
(get_local $0) (get_local $0)
) )
) )
;;@ assembly/pson.ts:126:6 ;;@ assembly/pson.ts:128:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:129:6 ;;@ assembly/pson.ts:131:6
(if (if
;;@ assembly/pson.ts:129:10 ;;@ assembly/pson.ts:131:10
(i32.gt_u (i32.gt_u
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:129:18 ;;@ assembly/pson.ts:131:18
(i32.const 239) (i32.const 239)
) )
;;@ assembly/pson.ts:130:8 ;;@ assembly/pson.ts:132:8
(unreachable) (unreachable)
) )
;;@ assembly/pson.ts:131:11 ;;@ assembly/pson.ts:134:11
(call $assembly/pson/pson.onInteger (call $assembly/pson/pson.onInteger
;;@ assembly/pson.ts:131:21 ;;@ assembly/pson.ts:134:21
(i32.xor (i32.xor
(i32.shr_u (i32.shr_u
;;@ assembly/pson.ts:131:22 ;;@ assembly/pson.ts:134:22
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:131:31 ;;@ assembly/pson.ts:134:31
(i32.const 1) (i32.const 1)
) )
;;@ assembly/pson.ts:131:36 ;;@ assembly/pson.ts:134:36
(i32.sub (i32.sub
(i32.const 0) (i32.const 0)
;;@ assembly/pson.ts:131:37 ;;@ assembly/pson.ts:134:37
(i32.and (i32.and
;;@ assembly/pson.ts:131:38 ;;@ assembly/pson.ts:134:38
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:131:46 ;;@ assembly/pson.ts:134:46
(i32.const 1) (i32.const 1)
) )
) )
@ -540,19 +540,19 @@
) )
) )
) )
;;@ assembly/pson.ts:45:2 ;;@ assembly/pson.ts:46:2
(if (if
;;@ assembly/pson.ts:45:9 ;;@ assembly/pson.ts:46:9
(i32.ne (i32.ne
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:45:19 ;;@ assembly/pson.ts:46:19
(get_local $0) (get_local $0)
) )
(block (block
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 45) (i32.const 46)
(i32.const 2) (i32.const 2)
) )
(unreachable) (unreachable)

View File

@ -51,26 +51,26 @@
(local $1 i32) (local $1 i32)
(local $2 i32) (local $2 i32)
(local $3 i32) (local $3 i32)
;;@ assembly/pson.ts:137:2 ;;@ assembly/pson.ts:140:2
(set_local $0 (set_local $0
;;@ assembly/pson.ts:137:19 ;;@ assembly/pson.ts:140:19
(i32.const 0) (i32.const 0)
) )
;;@ assembly/pson.ts:138:2 ;;@ assembly/pson.ts:141:2
(set_local $1 (set_local $1
;;@ assembly/pson.ts:138:19 ;;@ assembly/pson.ts:141:19
(i32.const 0) (i32.const 0)
) )
;;@ assembly/pson.ts:139:2 ;;@ assembly/pson.ts:142:2
(block $break|0 (block $break|0
(loop $continue|0 (loop $continue|0
;;@ assembly/pson.ts:139:5 ;;@ assembly/pson.ts:142:5
(block (block
;;@ assembly/pson.ts:140:4 ;;@ assembly/pson.ts:143:4
(set_local $3 (set_local $3
;;@ assembly/pson.ts:140:12 ;;@ assembly/pson.ts:143:12
(i32.load8_u (i32.load8_u
;;@ assembly/pson.ts:140:21 ;;@ assembly/pson.ts:143:21
(block (result i32) (block (result i32)
(set_local $2 (set_local $2
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
@ -85,26 +85,26 @@
) )
) )
) )
;;@ assembly/pson.ts:141:4 ;;@ assembly/pson.ts:144:4
(set_local $0 (set_local $0
(i32.or (i32.or
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:141:13 ;;@ assembly/pson.ts:144:13
(i32.shl (i32.shl
(i32.and (i32.and
(i32.and (i32.and
;;@ assembly/pson.ts:141:19 ;;@ assembly/pson.ts:144:19
(get_local $3) (get_local $3)
;;@ assembly/pson.ts:141:23 ;;@ assembly/pson.ts:144:23
(i32.const 127) (i32.const 127)
) )
(i32.const 255) (i32.const 255)
) )
;;@ assembly/pson.ts:141:32 ;;@ assembly/pson.ts:144:32
(i32.mul (i32.mul
;;@ assembly/pson.ts:141:33 ;;@ assembly/pson.ts:144:33
(i32.const 7) (i32.const 7)
;;@ assembly/pson.ts:141:37 ;;@ assembly/pson.ts:144:37
(block (result i32) (block (result i32)
(set_local $2 (set_local $2
(get_local $1) (get_local $1)
@ -123,11 +123,11 @@
) )
) )
(br_if $continue|0 (br_if $continue|0
;;@ assembly/pson.ts:142:11 ;;@ assembly/pson.ts:145:11
(i32.and (i32.and
(i32.and (i32.and
(get_local $3) (get_local $3)
;;@ assembly/pson.ts:142:15 ;;@ assembly/pson.ts:145:15
(i32.const 128) (i32.const 128)
) )
(i32.const 255) (i32.const 255)
@ -135,7 +135,7 @@
) )
) )
) )
;;@ assembly/pson.ts:143:9 ;;@ assembly/pson.ts:146:9
(return (return
(get_local $0) (get_local $0)
) )
@ -146,26 +146,26 @@
(local $2 i32) (local $2 i32)
(local $3 i32) (local $3 i32)
(local $4 i64) (local $4 i64)
;;@ assembly/pson.ts:147:2 ;;@ assembly/pson.ts:150:2
(set_local $0 (set_local $0
;;@ assembly/pson.ts:147:19 ;;@ assembly/pson.ts:150:19
(i64.const 0) (i64.const 0)
) )
;;@ assembly/pson.ts:148:2 ;;@ assembly/pson.ts:151:2
(set_local $1 (set_local $1
;;@ assembly/pson.ts:148:19 ;;@ assembly/pson.ts:151:19
(i64.const 0) (i64.const 0)
) )
;;@ assembly/pson.ts:149:2 ;;@ assembly/pson.ts:152:2
(block $break|0 (block $break|0
(loop $continue|0 (loop $continue|0
;;@ assembly/pson.ts:149:5 ;;@ assembly/pson.ts:152:5
(block (block
;;@ assembly/pson.ts:150:4 ;;@ assembly/pson.ts:153:4
(set_local $3 (set_local $3
;;@ assembly/pson.ts:150:12 ;;@ assembly/pson.ts:153:12
(i32.load8_u (i32.load8_u
;;@ assembly/pson.ts:150:21 ;;@ assembly/pson.ts:153:21
(block (result i32) (block (result i32)
(set_local $2 (set_local $2
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
@ -180,28 +180,28 @@
) )
) )
) )
;;@ assembly/pson.ts:151:4 ;;@ assembly/pson.ts:154:4
(set_local $0 (set_local $0
(i64.or (i64.or
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:151:13 ;;@ assembly/pson.ts:154:13
(i64.shl (i64.shl
(i64.extend_u/i32 (i64.extend_u/i32
;;@ assembly/pson.ts:151:19 ;;@ assembly/pson.ts:154:19
(i32.and (i32.and
(i32.and (i32.and
(get_local $3) (get_local $3)
;;@ assembly/pson.ts:151:23 ;;@ assembly/pson.ts:154:23
(i32.const 127) (i32.const 127)
) )
(i32.const 255) (i32.const 255)
) )
) )
;;@ assembly/pson.ts:151:32 ;;@ assembly/pson.ts:154:32
(i64.mul (i64.mul
;;@ assembly/pson.ts:151:33 ;;@ assembly/pson.ts:154:33
(i64.const 7) (i64.const 7)
;;@ assembly/pson.ts:151:37 ;;@ assembly/pson.ts:154:37
(block (result i64) (block (result i64)
(set_local $4 (set_local $4
(get_local $1) (get_local $1)
@ -220,11 +220,11 @@
) )
) )
(br_if $continue|0 (br_if $continue|0
;;@ assembly/pson.ts:152:11 ;;@ assembly/pson.ts:155:11
(i32.and (i32.and
(i32.and (i32.and
(get_local $3) (get_local $3)
;;@ assembly/pson.ts:152:15 ;;@ assembly/pson.ts:155:15
(i32.const 128) (i32.const 128)
) )
(i32.const 255) (i32.const 255)
@ -232,7 +232,7 @@
) )
) )
) )
;;@ assembly/pson.ts:153:9 ;;@ assembly/pson.ts:156:9
(return (return
(get_local $0) (get_local $0)
) )
@ -242,11 +242,11 @@
(local $1 i32) (local $1 i32)
(local $2 i32) (local $2 i32)
(local $3 i64) (local $3 i64)
;;@ assembly/pson.ts:49:2 ;;@ assembly/pson.ts:50:2
(set_local $1 (set_local $1
;;@ assembly/pson.ts:49:19 ;;@ assembly/pson.ts:50:19
(i32.load8_u (i32.load8_u
;;@ assembly/pson.ts:49:28 ;;@ assembly/pson.ts:50:28
(block (result i32) (block (result i32)
(set_local $0 (set_local $0
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
@ -261,11 +261,11 @@
) )
) )
) )
;;@ assembly/pson.ts:50:2
(nop)
;;@ assembly/pson.ts:51:2 ;;@ assembly/pson.ts:51:2
(nop) (nop)
;;@ assembly/pson.ts:52:2 ;;@ assembly/pson.ts:52:2
(nop)
;;@ assembly/pson.ts:53:2
(block $break|0 (block $break|0
(block $case16|0 (block $case16|0
(block $case15|0 (block $case15|0
@ -285,166 +285,166 @@
(block $case1|0 (block $case1|0
(block $case0|0 (block $case0|0
(set_local $0 (set_local $0
;;@ assembly/pson.ts:52:10 ;;@ assembly/pson.ts:53:10
(get_local $1) (get_local $1)
) )
(br_if $case0|0 (br_if $case0|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:54:9 ;;@ assembly/pson.ts:55:9
(i32.const 240) (i32.const 240)
) )
) )
(br_if $case1|0 (br_if $case1|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:58:9 ;;@ assembly/pson.ts:59:9
(i32.const 241) (i32.const 241)
) )
) )
(br_if $case2|0 (br_if $case2|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:62:9 ;;@ assembly/pson.ts:63:9
(i32.const 242) (i32.const 242)
) )
) )
(br_if $case3|0 (br_if $case3|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:66:9 ;;@ assembly/pson.ts:67:9
(i32.const 243) (i32.const 243)
) )
) )
(br_if $case4|0 (br_if $case4|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:70:9 ;;@ assembly/pson.ts:71:9
(i32.const 244) (i32.const 244)
) )
) )
(br_if $case5|0 (br_if $case5|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:74:9 ;;@ assembly/pson.ts:75:9
(i32.const 245) (i32.const 245)
) )
) )
(br_if $case6|0 (br_if $case6|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:78:9 ;;@ assembly/pson.ts:79:9
(i32.const 246) (i32.const 246)
) )
) )
(br_if $case7|0 (br_if $case7|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:86:9 ;;@ assembly/pson.ts:87:9
(i32.const 247) (i32.const 247)
) )
) )
(br_if $case8|0 (br_if $case8|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:92:9 ;;@ assembly/pson.ts:94:9
(i32.const 248) (i32.const 248)
) )
) )
(br_if $case9|0 (br_if $case9|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:96:9 ;;@ assembly/pson.ts:98:9
(i32.const 249) (i32.const 249)
) )
) )
(br_if $case10|0 (br_if $case10|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:101:9 ;;@ assembly/pson.ts:103:9
(i32.const 250) (i32.const 250)
) )
) )
(br_if $case11|0 (br_if $case11|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:106:9 ;;@ assembly/pson.ts:108:9
(i32.const 251) (i32.const 251)
) )
) )
(br_if $case12|0 (br_if $case12|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:111:9 ;;@ assembly/pson.ts:113:9
(i32.const 252) (i32.const 252)
) )
) )
(br_if $case13|0 (br_if $case13|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:117:9 ;;@ assembly/pson.ts:119:9
(i32.const 253) (i32.const 253)
) )
) )
(br_if $case14|0 (br_if $case14|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:118:9 ;;@ assembly/pson.ts:120:9
(i32.const 254) (i32.const 254)
) )
) )
(br_if $case15|0 (br_if $case15|0
(i32.eq (i32.eq
(get_local $0) (get_local $0)
;;@ assembly/pson.ts:122:9 ;;@ assembly/pson.ts:124:9
(i32.const 255) (i32.const 255)
) )
) )
(br $case16|0) (br $case16|0)
) )
;;@ assembly/pson.ts:55:11 ;;@ assembly/pson.ts:56:11
(call $assembly/pson/pson.onNull) (call $assembly/pson/pson.onNull)
;;@ assembly/pson.ts:56:6 ;;@ assembly/pson.ts:57:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:59:11 ;;@ assembly/pson.ts:60:11
(call $assembly/pson/pson.onTrue) (call $assembly/pson/pson.onTrue)
;;@ assembly/pson.ts:60:6 ;;@ assembly/pson.ts:61:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:63:11 ;;@ assembly/pson.ts:64:11
(call $assembly/pson/pson.onFalse) (call $assembly/pson/pson.onFalse)
;;@ assembly/pson.ts:64:6 ;;@ assembly/pson.ts:65:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:67:11 ;;@ assembly/pson.ts:68:11
(call $assembly/pson/pson.onEObject) (call $assembly/pson/pson.onEObject)
;;@ assembly/pson.ts:68:6 ;;@ assembly/pson.ts:69:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:71:11 ;;@ assembly/pson.ts:72:11
(call $assembly/pson/pson.onEArray) (call $assembly/pson/pson.onEArray)
;;@ assembly/pson.ts:72:6 ;;@ assembly/pson.ts:73:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:75:11 ;;@ assembly/pson.ts:76:11
(call $assembly/pson/pson.onEString) (call $assembly/pson/pson.onEString)
;;@ assembly/pson.ts:76:6 ;;@ assembly/pson.ts:77:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:79:11 ;;@ assembly/pson.ts:80:11
(call $assembly/pson/pson.onObject (call $assembly/pson/pson.onObject
;;@ assembly/pson.ts:79:20 ;;@ assembly/pson.ts:80:20
(tee_local $2 (tee_local $2
;;@ assembly/pson.ts:79:27 ;;@ assembly/pson.ts:80:27
(call $assembly/pson/readVarint32) (call $assembly/pson/readVarint32)
) )
) )
;;@ assembly/pson.ts:80:6 ;;@ assembly/pson.ts:81:6
(block $break|1 (block $break|1
(loop $continue|1 (loop $continue|1
(if (if
;;@ assembly/pson.ts:80:13 ;;@ assembly/pson.ts:81:13
(block (result i32) (block (result i32)
(set_local $0 (set_local $0
(get_local $2) (get_local $2)
@ -459,32 +459,32 @@
) )
(block (block
(block (block
;;@ assembly/pson.ts:81:8
(call $assembly/pson/decodeValue)
;;@ assembly/pson.ts:82:8 ;;@ assembly/pson.ts:82:8
(call $assembly/pson/decodeValue) (call $assembly/pson/decodeValue)
;;@ assembly/pson.ts:83:8
(call $assembly/pson/decodeValue)
) )
(br $continue|1) (br $continue|1)
) )
) )
) )
) )
;;@ assembly/pson.ts:84:6 ;;@ assembly/pson.ts:85:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:87:11 ;;@ assembly/pson.ts:88:11
(call $assembly/pson/pson.onArray (call $assembly/pson/pson.onArray
;;@ assembly/pson.ts:87:19 ;;@ assembly/pson.ts:88:19
(tee_local $2 (tee_local $2
;;@ assembly/pson.ts:87:26 ;;@ assembly/pson.ts:88:26
(call $assembly/pson/readVarint32) (call $assembly/pson/readVarint32)
) )
) )
;;@ assembly/pson.ts:88:6 ;;@ assembly/pson.ts:89:6
(block $break|2 (block $break|2
(loop $continue|2 (loop $continue|2
(if (if
;;@ assembly/pson.ts:88:13 ;;@ assembly/pson.ts:89:13
(block (result i32) (block (result i32)
(set_local $0 (set_local $0
(get_local $2) (get_local $2)
@ -498,213 +498,215 @@
(get_local $0) (get_local $0)
) )
(block (block
;;@ assembly/pson.ts:89:8 (block
(call $assembly/pson/decodeValue) ;;@ assembly/pson.ts:90:8
(call $assembly/pson/decodeValue)
)
(br $continue|2) (br $continue|2)
) )
) )
) )
) )
;;@ assembly/pson.ts:90:6 ;;@ assembly/pson.ts:92:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:93:11 ;;@ assembly/pson.ts:95:11
(call $assembly/pson/pson.onInteger (call $assembly/pson/pson.onInteger
;;@ assembly/pson.ts:93:21 ;;@ assembly/pson.ts:95:21
(i32.xor (i32.xor
(i32.shr_u (i32.shr_u
;;@ assembly/pson.ts:93:22 ;;@ assembly/pson.ts:95:22
(tee_local $2 (tee_local $2
;;@ assembly/pson.ts:93:30 ;;@ assembly/pson.ts:95:30
(call $assembly/pson/readVarint32) (call $assembly/pson/readVarint32)
) )
;;@ assembly/pson.ts:93:49 ;;@ assembly/pson.ts:95:49
(i32.const 1) (i32.const 1)
) )
;;@ assembly/pson.ts:93:54 ;;@ assembly/pson.ts:95:54
(i32.sub (i32.sub
(i32.const 0) (i32.const 0)
;;@ assembly/pson.ts:93:55 ;;@ assembly/pson.ts:95:55
(i32.and (i32.and
;;@ assembly/pson.ts:93:56 ;;@ assembly/pson.ts:95:56
(get_local $2) (get_local $2)
;;@ assembly/pson.ts:93:63 ;;@ assembly/pson.ts:95:63
(i32.const 1) (i32.const 1)
) )
) )
) )
) )
;;@ assembly/pson.ts:94:6 ;;@ assembly/pson.ts:96:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:97:6 ;;@ assembly/pson.ts:99:6
(set_local $3 (set_local $3
;;@ assembly/pson.ts:97:13 ;;@ assembly/pson.ts:99:13
(i64.xor (i64.xor
(i64.shr_u (i64.shr_u
;;@ assembly/pson.ts:97:14 ;;@ assembly/pson.ts:99:14
(tee_local $3 (tee_local $3
;;@ assembly/pson.ts:97:22 ;;@ assembly/pson.ts:99:22
(call $assembly/pson/readVarint64) (call $assembly/pson/readVarint64)
) )
;;@ assembly/pson.ts:97:41 ;;@ assembly/pson.ts:99:41
(i64.const 1) (i64.const 1)
) )
;;@ assembly/pson.ts:97:46 ;;@ assembly/pson.ts:99:46
(i64.sub (i64.sub
(i64.const 0) (i64.const 0)
;;@ assembly/pson.ts:97:47 ;;@ assembly/pson.ts:99:47
(i64.and (i64.and
;;@ assembly/pson.ts:97:48 ;;@ assembly/pson.ts:99:48
(get_local $3) (get_local $3)
;;@ assembly/pson.ts:97:55 ;;@ assembly/pson.ts:99:55
(i64.const 1) (i64.const 1)
) )
) )
) )
) )
;;@ assembly/pson.ts:98:11 ;;@ assembly/pson.ts:100:11
(call $assembly/pson/pson.onLong (call $assembly/pson/pson.onLong
;;@ assembly/pson.ts:98:18 ;;@ assembly/pson.ts:100:18
(i32.wrap/i64 (i32.wrap/i64
(get_local $3) (get_local $3)
) )
;;@ assembly/pson.ts:98:29 ;;@ assembly/pson.ts:100:29
(i32.wrap/i64 (i32.wrap/i64
;;@ assembly/pson.ts:98:35 ;;@ assembly/pson.ts:100:35
(i64.shr_u (i64.shr_u
(get_local $3) (get_local $3)
;;@ assembly/pson.ts:98:44 ;;@ assembly/pson.ts:100:44
(i64.const 32) (i64.const 32)
) )
) )
) )
;;@ assembly/pson.ts:99:6 ;;@ assembly/pson.ts:101:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:102:11 ;;@ assembly/pson.ts:104:11
(call $assembly/pson/pson.onFloat (call $assembly/pson/pson.onFloat
;;@ assembly/pson.ts:102:19 ;;@ assembly/pson.ts:104:19
(f32.load (f32.load
;;@ assembly/pson.ts:102:29 ;;@ assembly/pson.ts:104:29
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
) )
) )
;;@ assembly/pson.ts:103:6 ;;@ assembly/pson.ts:105:6
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:103:16 ;;@ assembly/pson.ts:105:16
(i32.const 4) (i32.const 4)
) )
) )
;;@ assembly/pson.ts:104:6 ;;@ assembly/pson.ts:106:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:107:11 ;;@ assembly/pson.ts:109:11
(call $assembly/pson/pson.onDouble (call $assembly/pson/pson.onDouble
;;@ assembly/pson.ts:107:20 ;;@ assembly/pson.ts:109:20
(f64.load (f64.load
;;@ assembly/pson.ts:107:30 ;;@ assembly/pson.ts:109:30
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
) )
) )
;;@ assembly/pson.ts:108:6 ;;@ assembly/pson.ts:110:6
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:108:16 ;;@ assembly/pson.ts:110:16
(i32.const 8) (i32.const 8)
) )
) )
;;@ assembly/pson.ts:109:6 ;;@ assembly/pson.ts:111:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:112:6 ;;@ assembly/pson.ts:114:6
(set_local $2 (set_local $2
;;@ assembly/pson.ts:112:13 ;;@ assembly/pson.ts:114:13
(call $assembly/pson/readVarint32) (call $assembly/pson/readVarint32)
) )
;;@ assembly/pson.ts:113:11 ;;@ assembly/pson.ts:115:11
(call $assembly/pson/pson.onString (call $assembly/pson/pson.onString
;;@ assembly/pson.ts:113:20 ;;@ assembly/pson.ts:115:20
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:113:28 ;;@ assembly/pson.ts:115:28
(get_local $2) (get_local $2)
) )
;;@ assembly/pson.ts:114:6 ;;@ assembly/pson.ts:116:6
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:114:16 ;;@ assembly/pson.ts:116:16
(get_local $2) (get_local $2)
) )
) )
;;@ assembly/pson.ts:115:6 ;;@ assembly/pson.ts:117:6
(br $break|0) (br $break|0)
) )
) )
;;@ assembly/pson.ts:120:6 ;;@ assembly/pson.ts:122:6
(unreachable) (unreachable)
) )
;;@ assembly/pson.ts:123:6 ;;@ assembly/pson.ts:125:6
(set_local $2 (set_local $2
;;@ assembly/pson.ts:123:13 ;;@ assembly/pson.ts:125:13
(call $assembly/pson/readVarint32) (call $assembly/pson/readVarint32)
) )
;;@ assembly/pson.ts:124:11 ;;@ assembly/pson.ts:126:11
(call $assembly/pson/pson.onBinary (call $assembly/pson/pson.onBinary
;;@ assembly/pson.ts:124:20 ;;@ assembly/pson.ts:126:20
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:124:28 ;;@ assembly/pson.ts:126:28
(get_local $2) (get_local $2)
) )
;;@ assembly/pson.ts:125:6 ;;@ assembly/pson.ts:127:6
(set_global $assembly/pson/offset (set_global $assembly/pson/offset
(i32.add (i32.add
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:125:16 ;;@ assembly/pson.ts:127:16
(get_local $2) (get_local $2)
) )
) )
;;@ assembly/pson.ts:126:6 ;;@ assembly/pson.ts:128:6
(br $break|0) (br $break|0)
) )
;;@ assembly/pson.ts:129:6 ;;@ assembly/pson.ts:131:6
(if (if
;;@ assembly/pson.ts:129:10 ;;@ assembly/pson.ts:131:10
(i32.gt_u (i32.gt_u
(get_local $1) (get_local $1)
;;@ assembly/pson.ts:129:18 ;;@ assembly/pson.ts:131:18
(i32.const 239) (i32.const 239)
) )
;;@ assembly/pson.ts:130:8 ;;@ assembly/pson.ts:132:8
(unreachable) (unreachable)
) )
;;@ assembly/pson.ts:131:11 ;;@ assembly/pson.ts:134:11
(call $assembly/pson/pson.onInteger (call $assembly/pson/pson.onInteger
;;@ assembly/pson.ts:131:21 ;;@ assembly/pson.ts:134:21
(i32.xor (i32.xor
(i32.shr_u (i32.shr_u
;;@ assembly/pson.ts:131:22 ;;@ assembly/pson.ts:134:22
(get_local $1) (get_local $1)
;;@ assembly/pson.ts:131:31 ;;@ assembly/pson.ts:134:31
(i32.const 1) (i32.const 1)
) )
;;@ assembly/pson.ts:131:36 ;;@ assembly/pson.ts:134:36
(i32.sub (i32.sub
(i32.const 0) (i32.const 0)
;;@ assembly/pson.ts:131:37 ;;@ assembly/pson.ts:134:37
(i32.and (i32.and
;;@ assembly/pson.ts:131:38 ;;@ assembly/pson.ts:134:38
(get_local $1) (get_local $1)
;;@ assembly/pson.ts:131:46 ;;@ assembly/pson.ts:134:46
(i32.const 1) (i32.const 1)
) )
) )
) )
) )
;;@ assembly/pson.ts:132:6 ;;@ assembly/pson.ts:135:6
(br $break|0) (br $break|0)
) )
) )
@ -725,20 +727,22 @@
(get_local $0) (get_local $0)
) )
(block (block
;;@ assembly/pson.ts:44:4 (block
(call $assembly/pson/decodeValue) ;;@ assembly/pson.ts:44:4
(call $assembly/pson/decodeValue)
)
(br $continue|0) (br $continue|0)
) )
) )
) )
) )
;;@ assembly/pson.ts:45:2 ;;@ assembly/pson.ts:46:2
(if (if
(i32.eqz (i32.eqz
;;@ assembly/pson.ts:45:9 ;;@ assembly/pson.ts:46:9
(i32.eq (i32.eq
(get_global $assembly/pson/offset) (get_global $assembly/pson/offset)
;;@ assembly/pson.ts:45:19 ;;@ assembly/pson.ts:46:19
(get_local $0) (get_local $0)
) )
) )
@ -746,7 +750,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 45) (i32.const 46)
(i32.const 2) (i32.const 2)
) )
(unreachable) (unreachable)

View File

@ -214,18 +214,22 @@ class Control {
* garbage for the next cycle. * garbage for the next cycle.
*/ */
collect(): void { collect(): void {
if (this.state == IDLE) if (this.state == IDLE) {
this.step(); this.step();
while (this.state != IDLE) }
while (this.state != IDLE) {
this.step(); this.step();
}
} }
/** Informs the GC of a referred object during the mark phase. */ /** Informs the GC of a referred object during the mark phase. */
visit(obj: ObjectHeader): void { visit(obj: ObjectHeader): void {
if (this.state == SWEEP) if (this.state == SWEEP) {
return; return;
if (obj.color == this.white) }
if (obj.color == this.white) {
this.makeGray(obj); this.makeGray(obj);
}
} }
makeGray(obj: ObjectHeader): void { makeGray(obj: ObjectHeader): void {

5178
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,11 +11,11 @@
"url": "https://github.com/AssemblyScript/assemblyscript/issues" "url": "https://github.com/AssemblyScript/assemblyscript/issues"
}, },
"dependencies": { "dependencies": {
"binaryen": "44.0.0-nightly.20180224", "binaryen": "44.0.0-nightly.20180301",
"glob": "^7.1.2", "glob": "^7.1.2",
"long": "^4.0.0", "long": "^4.0.0",
"minimist": "^1.2.0", "minimist": "^1.2.0",
"ts-node": "^5.0.0" "ts-node": "^5.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^9.4.6", "@types/node": "^9.4.6",
@ -24,10 +24,11 @@
"chalk": "^2.3.1", "chalk": "^2.3.1",
"diff": "^3.4.0", "diff": "^3.4.0",
"source-map-support": "^0.5.3", "source-map-support": "^0.5.3",
"ts-loader": "^3.5.0", "ts-loader": "^4.0.0",
"tslint": "^5.9.1", "tslint": "^5.9.1",
"typescript": "^2.7.2", "typescript": "^2.7.2",
"webpack": "^3.11.0" "webpack": "^4.0.1",
"webpack-cli": "^2.0.9"
}, },
"main": "index.js", "main": "index.js",
"types": "index.d.ts", "types": "index.d.ts",

5
scripts/build.js Normal file
View File

@ -0,0 +1,5 @@
const webpack = require("webpack");
webpack(require("../webpack.config.js"), (err, stats) => {
if (err) throw err;
});

View File

@ -1563,13 +1563,14 @@ export function compileCall(
if (offset < 0) { // reported in evaluateConstantOffset if (offset < 0) { // reported in evaluateConstantOffset
return module.createUnreachable(); return module.createUnreachable();
} }
compiler.currentType = typeArguments[0];
return module.createLoad( return module.createLoad(
typeArguments[0].byteSize, typeArguments[0].byteSize,
typeArguments[0].is(TypeFlags.SIGNED | TypeFlags.INTEGER), typeArguments[0].is(TypeFlags.SIGNED | TypeFlags.INTEGER),
arg0, arg0,
typeArguments[0].is(TypeFlags.INTEGER) && typeArguments[0].is(TypeFlags.INTEGER) &&
contextualType.is(TypeFlags.INTEGER) && contextualType.is(TypeFlags.INTEGER) &&
contextualType.size >= typeArguments[0].size contextualType.size > typeArguments[0].size
? (compiler.currentType = contextualType).toNativeType() ? (compiler.currentType = contextualType).toNativeType()
: (compiler.currentType = typeArguments[0]).toNativeType(), : (compiler.currentType = typeArguments[0]).toNativeType(),
offset offset
@ -1896,7 +1897,7 @@ export function compileCall(
} }
arg0 = compiler.compileExpression(operands[0], typeArguments[0]); arg0 = compiler.compileExpression(operands[0], typeArguments[0]);
} else { } else {
arg0 = compiler.compileExpression(operands[0], Type.i32, ConversionKind.NONE); arg0 = compiler.compileExpressionRetainType(operands[0], Type.i32);
} }
type = compiler.currentType; type = compiler.currentType;

View File

@ -529,7 +529,7 @@ export class Compiler extends DiagnosticEmitter {
var initializeInStart = false; var initializeInStart = false;
if (global.is(ElementFlags.INLINED)) { if (global.is(ElementFlags.INLINED)) {
initExpr = this.compileInlineConstant(global, global.type); initExpr = this.compileInlineConstant(global, global.type, true);
} else { } else {
if (declaration.initializer) { if (declaration.initializer) {
if (!initExpr) { if (!initExpr) {
@ -1662,11 +1662,20 @@ export class Compiler extends DiagnosticEmitter {
// expressions // expressions
/** Compiles an inlined constant value of a variable-like element. */ /**
compileInlineConstant(element: VariableLikeElement, contextualType: Type): ExpressionRef { * Compiles the value of an inlined constant element.
* @param retainType If true, the annotated type of the constant is retained. Otherwise, the value
* is precomputed according to context.
*/
compileInlineConstant(
element: VariableLikeElement,
contextualType: Type,
retainType: bool
): ExpressionRef {
assert(element.is(ElementFlags.INLINED)); assert(element.is(ElementFlags.INLINED));
switch ( switch (
!retainType &&
element.type.is(TypeFlags.INTEGER) && element.type.is(TypeFlags.INTEGER) &&
contextualType.is(TypeFlags.INTEGER) && contextualType.is(TypeFlags.INTEGER) &&
element.type.size < contextualType.size element.type.size < contextualType.size
@ -1773,7 +1782,11 @@ export class Compiler extends DiagnosticEmitter {
case NodeKind.NULL: case NodeKind.NULL:
case NodeKind.THIS: case NodeKind.THIS:
case NodeKind.TRUE: case NodeKind.TRUE:
expr = this.compileIdentifierExpression(<IdentifierExpression>expression, contextualType); expr = this.compileIdentifierExpression(
<IdentifierExpression>expression,
contextualType,
conversionKind == ConversionKind.NONE // retain type of inlined constants
);
break; break;
case NodeKind.LITERAL: case NodeKind.LITERAL:
@ -1789,7 +1802,11 @@ export class Compiler extends DiagnosticEmitter {
break; break;
case NodeKind.PROPERTYACCESS: case NodeKind.PROPERTYACCESS:
expr = this.compilePropertyAccessExpression(<PropertyAccessExpression>expression, contextualType); expr = this.compilePropertyAccessExpression(
<PropertyAccessExpression>expression,
contextualType,
conversionKind == ConversionKind.NONE // retain type of inlined constants
);
break; break;
case NodeKind.TERNARY: case NodeKind.TERNARY:
@ -1817,6 +1834,17 @@ export class Compiler extends DiagnosticEmitter {
return expr; return expr;
} }
compileExpressionRetainType(expression: Expression, contextualType: Type, wrapSmallIntegers: bool = true) {
return this.compileExpression(
expression,
contextualType == Type.void
? Type.i32
: contextualType,
ConversionKind.NONE,
wrapSmallIntegers
);
}
precomputeExpression( precomputeExpression(
expression: Expression, expression: Expression,
contextualType: Type, contextualType: Type,
@ -1877,9 +1905,6 @@ export class Compiler extends DiagnosticEmitter {
); );
} }
var mod = this.module;
var losesInformation = false;
if (fromType.is(TypeFlags.FLOAT)) { if (fromType.is(TypeFlags.FLOAT)) {
// float to float // float to float
@ -1888,39 +1913,37 @@ export class Compiler extends DiagnosticEmitter {
// f32 to f64 // f32 to f64
if (toType.kind == TypeKind.F64) { if (toType.kind == TypeKind.F64) {
expr = mod.createUnary(UnaryOp.PromoteF32, expr); expr = this.module.createUnary(UnaryOp.PromoteF32, expr);
} }
// otherwise f32 to f32 // otherwise f32 to f32
// f64 to f32 // f64 to f32
} else if (toType.kind == TypeKind.F32) { } else if (toType.kind == TypeKind.F32) {
losesInformation = true; expr = this.module.createUnary(UnaryOp.DemoteF64, expr);
expr = mod.createUnary(UnaryOp.DemoteF64, expr);
} }
// otherwise f64 to f64 // otherwise f64 to f64
// float to int // float to int
} else if (toType.is(TypeFlags.INTEGER)) { } else if (toType.is(TypeFlags.INTEGER)) {
losesInformation = true;
// f32 to int // f32 to int
if (fromType.kind == TypeKind.F32) { if (fromType.kind == TypeKind.F32) {
if (toType.is(TypeFlags.SIGNED)) { if (toType.is(TypeFlags.SIGNED)) {
if (toType.is(TypeFlags.LONG)) { if (toType.is(TypeFlags.LONG)) {
expr = mod.createUnary(UnaryOp.TruncF32ToI64, expr); expr = this.module.createUnary(UnaryOp.TruncF32ToI64, expr);
} else { } else {
expr = mod.createUnary(UnaryOp.TruncF32ToI32, expr); expr = this.module.createUnary(UnaryOp.TruncF32ToI32, expr);
if (toType.is(TypeFlags.SMALL)) { if (toType.is(TypeFlags.SMALL)) {
expr = makeSmallIntegerWrap(expr, toType, this.module); expr = makeSmallIntegerWrap(expr, toType, this.module);
} }
} }
} else { } else {
if (toType.is(TypeFlags.LONG)) { if (toType.is(TypeFlags.LONG)) {
expr = mod.createUnary(UnaryOp.TruncF32ToU64, expr); expr = this.module.createUnary(UnaryOp.TruncF32ToU64, expr);
} else { } else {
expr = mod.createUnary(UnaryOp.TruncF32ToU32, expr); expr = this.module.createUnary(UnaryOp.TruncF32ToU32, expr);
if (toType.is(TypeFlags.SMALL)) { if (toType.is(TypeFlags.SMALL)) {
expr = makeSmallIntegerWrap(expr, toType, this.module); expr = makeSmallIntegerWrap(expr, toType, this.module);
} }
@ -1931,18 +1954,18 @@ export class Compiler extends DiagnosticEmitter {
} else { } else {
if (toType.is(TypeFlags.SIGNED)) { if (toType.is(TypeFlags.SIGNED)) {
if (toType.is(TypeFlags.LONG)) { if (toType.is(TypeFlags.LONG)) {
expr = mod.createUnary(UnaryOp.TruncF64ToI64, expr); expr = this.module.createUnary(UnaryOp.TruncF64ToI64, expr);
} else { } else {
expr = mod.createUnary(UnaryOp.TruncF64ToI32, expr); expr = this.module.createUnary(UnaryOp.TruncF64ToI32, expr);
if (toType.is(TypeFlags.SMALL)) { if (toType.is(TypeFlags.SMALL)) {
expr = makeSmallIntegerWrap(expr, toType, this.module); expr = makeSmallIntegerWrap(expr, toType, this.module);
} }
} }
} else { } else {
if (toType.is(TypeFlags.LONG)) { if (toType.is(TypeFlags.LONG)) {
expr = mod.createUnary(UnaryOp.TruncF64ToU64, expr); expr = this.module.createUnary(UnaryOp.TruncF64ToU64, expr);
} else { } else {
expr = mod.createUnary(UnaryOp.TruncF64ToU32, expr); expr = this.module.createUnary(UnaryOp.TruncF64ToU32, expr);
if (toType.is(TypeFlags.SMALL)) { if (toType.is(TypeFlags.SMALL)) {
expr = makeSmallIntegerWrap(expr, toType, this.module); expr = makeSmallIntegerWrap(expr, toType, this.module);
} }
@ -1962,16 +1985,14 @@ export class Compiler extends DiagnosticEmitter {
// int to f32 // int to f32
if (toType.kind == TypeKind.F32) { if (toType.kind == TypeKind.F32) {
if (fromType.is(TypeFlags.LONG)) { if (fromType.is(TypeFlags.LONG)) {
losesInformation = true; expr = this.module.createUnary(
expr = mod.createUnary(
fromType.is(TypeFlags.SIGNED) fromType.is(TypeFlags.SIGNED)
? UnaryOp.ConvertI64ToF32 ? UnaryOp.ConvertI64ToF32
: UnaryOp.ConvertU64ToF32, : UnaryOp.ConvertU64ToF32,
expr expr
); );
} else { } else {
losesInformation = !fromType.is(TypeFlags.SMALL); expr = this.module.createUnary(
expr = mod.createUnary(
fromType.is(TypeFlags.SIGNED) fromType.is(TypeFlags.SIGNED)
? UnaryOp.ConvertI32ToF32 ? UnaryOp.ConvertI32ToF32
: UnaryOp.ConvertU32ToF32, : UnaryOp.ConvertU32ToF32,
@ -1982,15 +2003,14 @@ export class Compiler extends DiagnosticEmitter {
// int to f64 // int to f64
} else { } else {
if (fromType.is(TypeFlags.LONG)) { if (fromType.is(TypeFlags.LONG)) {
losesInformation = true; expr = this.module.createUnary(
expr = mod.createUnary(
fromType.is(TypeFlags.SIGNED) fromType.is(TypeFlags.SIGNED)
? UnaryOp.ConvertI64ToF64 ? UnaryOp.ConvertI64ToF64
: UnaryOp.ConvertU64ToF64, : UnaryOp.ConvertU64ToF64,
expr expr
); );
} else { } else {
expr = mod.createUnary( expr = this.module.createUnary(
fromType.is(TypeFlags.SIGNED) fromType.is(TypeFlags.SIGNED)
? UnaryOp.ConvertI32ToF64 ? UnaryOp.ConvertI32ToF64
: UnaryOp.ConvertU32ToF64, : UnaryOp.ConvertU32ToF64,
@ -2005,8 +2025,7 @@ export class Compiler extends DiagnosticEmitter {
// i64 to i32 // i64 to i32
if (!toType.is(TypeFlags.LONG)) { if (!toType.is(TypeFlags.LONG)) {
losesInformation = true; expr = this.module.createUnary(UnaryOp.WrapI64, expr); // discards upper bits
expr = mod.createUnary(UnaryOp.WrapI64, expr); // discards upper bits
if (toType.is(TypeFlags.SMALL)) { if (toType.is(TypeFlags.SMALL)) {
expr = makeSmallIntegerWrap(expr, toType, this.module); expr = makeSmallIntegerWrap(expr, toType, this.module);
} }
@ -2014,7 +2033,7 @@ export class Compiler extends DiagnosticEmitter {
// i32 to i64 // i32 to i64
} else if (toType.is(TypeFlags.LONG)) { } else if (toType.is(TypeFlags.LONG)) {
expr = mod.createUnary(toType.is(TypeFlags.SIGNED) ? UnaryOp.ExtendI32 : UnaryOp.ExtendU32, expr); expr = this.module.createUnary(toType.is(TypeFlags.SIGNED) ? UnaryOp.ExtendI32 : UnaryOp.ExtendU32, expr);
// i32 or smaller to even smaller or same size int with change of sign // i32 or smaller to even smaller or same size int with change of sign
} else if ( } else if (
@ -2027,26 +2046,16 @@ export class Compiler extends DiagnosticEmitter {
) )
) )
) { ) {
losesInformation = true;
expr = makeSmallIntegerWrap(expr, toType, this.module); expr = makeSmallIntegerWrap(expr, toType, this.module);
} }
// otherwise (smaller) i32/u32 to (same size) i32/u32 // otherwise (smaller) i32/u32 to (same size) i32/u32
} }
this.currentType = toType;
return expr; return expr;
} }
/** Computes the common compatible type of two types. Returns `null` if incompatible. */
computeCommonType(leftType: Type, rightType: Type): Type | null {
if (leftType.isAssignableTo(rightType)) {
return rightType;
} else if (rightType.isAssignableTo(leftType)) {
return leftType;
}
return null;
}
compileAssertionExpression(expression: AssertionExpression, contextualType: Type): ExpressionRef { compileAssertionExpression(expression: AssertionExpression, contextualType: Type): ExpressionRef {
var toType = this.program.resolveType( // reports var toType = this.program.resolveType( // reports
expression.toType, expression.toType,
@ -2061,43 +2070,15 @@ export class Compiler extends DiagnosticEmitter {
contextualType: Type, contextualType: Type,
wrapSmallIntegers: bool = true wrapSmallIntegers: bool = true
): ExpressionRef { ): ExpressionRef {
var left: ExpressionRef; var left: ExpressionRef;
var leftType: Type;
var right: ExpressionRef; var right: ExpressionRef;
var rightType: Type;
// TODO: Currently, the common type of any binary expression is the first operand's type. This var commonType: Type | null;
// differs from C and other languages where comparing an int to a long, in this order, upcasts
// left to a long before comparison, instead of failing when trying to downcast right to an int.
// NOTE that if we change the current behaviour, some examples, tests and wiki pages will have
// to be updated, while compound binary operations must retain the previous behavior.
// var left = this.compileExpression(
// expression.left,
// contextualType == Type.void
// ? Type.i32
// : contextualType,
// ConversionKind.NONE
// );
// var leftType = this.currentType;
// var right = this.compileExpression(
// expression.right,
// leftType,
// ConversionKind.NONE
// );
// var rightType = this.currentType;
// var commonType = this.computeCommonType(leftType, rightType);
// if (!commonType) {
// this.error(
// DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
// expression.range,
// Token.operatorToString(expression.operator), leftType.toString(), rightType.toString()
// );
// this.currentType = contextualType;
// return this.module.createUnreachable();
// }
var condition: ExpressionRef; var condition: ExpressionRef;
var expr: ExpressionRef; var expr: ExpressionRef;
var compound = false; var compound = false;
var possiblyOverflows = false; var possiblyOverflows = false;
var tempLocal: Local | null = null; var tempLocal: Local | null = null;
@ -2105,16 +2086,23 @@ export class Compiler extends DiagnosticEmitter {
switch (expression.operator) { switch (expression.operator) {
case Token.LESSTHAN: case Token.LESSTHAN:
left = this.compileExpression( left = this.compileExpressionRetainType(expression.left, contextualType);
expression.left, leftType = this.currentType;
contextualType == Type.void right = this.compileExpressionRetainType(expression.right, leftType);
? Type.i32 rightType = this.currentType;
: contextualType, if (commonType = Type.commonCompatible(leftType, rightType, true)) {
ConversionKind.NONE left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
); right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
right = this.compileExpression(expression.right, this.currentType); } else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, "<", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
switch (this.currentType.kind) { switch (commonType.kind) {
case TypeKind.I8: case TypeKind.I8:
case TypeKind.I16: case TypeKind.I16:
@ -2177,16 +2165,23 @@ export class Compiler extends DiagnosticEmitter {
break; break;
case Token.GREATERTHAN: case Token.GREATERTHAN:
left = this.compileExpression( left = this.compileExpressionRetainType(expression.left, contextualType);
expression.left, leftType = this.currentType;
contextualType == Type.void right = this.compileExpressionRetainType(expression.right, leftType);
? Type.i32 rightType = this.currentType;
: contextualType, if (commonType = Type.commonCompatible(leftType, rightType, true)) {
ConversionKind.NONE left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
); right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
right = this.compileExpression(expression.right, this.currentType); } else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, ">", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
switch (this.currentType.kind) { switch (commonType.kind) {
case TypeKind.I8: case TypeKind.I8:
case TypeKind.I16: case TypeKind.I16:
@ -2249,16 +2244,23 @@ export class Compiler extends DiagnosticEmitter {
break; break;
case Token.LESSTHAN_EQUALS: case Token.LESSTHAN_EQUALS:
left = this.compileExpression( left = this.compileExpressionRetainType(expression.left, contextualType);
expression.left, leftType = this.currentType;
contextualType == Type.void right = this.compileExpressionRetainType(expression.right, leftType);
? Type.i32 rightType = this.currentType;
: contextualType, if (commonType = Type.commonCompatible(leftType, rightType, true)) {
ConversionKind.NONE left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
); right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
right = this.compileExpression(expression.right, this.currentType); } else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, "<=", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
switch (this.currentType.kind) { switch (commonType.kind) {
case TypeKind.I8: case TypeKind.I8:
case TypeKind.I16: case TypeKind.I16:
@ -2321,16 +2323,23 @@ export class Compiler extends DiagnosticEmitter {
break; break;
case Token.GREATERTHAN_EQUALS: case Token.GREATERTHAN_EQUALS:
left = this.compileExpression( left = this.compileExpressionRetainType(expression.left, contextualType);
expression.left, leftType = this.currentType;
contextualType == Type.void right = this.compileExpressionRetainType(expression.right, leftType);
? Type.i32 rightType = this.currentType;
: contextualType, if (commonType = Type.commonCompatible(leftType, rightType, true)) {
ConversionKind.NONE left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
); right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
right = this.compileExpression(expression.right, this.currentType); } else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, ">=", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
switch (this.currentType.kind) { switch (commonType.kind) {
case TypeKind.I8: case TypeKind.I8:
case TypeKind.I16: case TypeKind.I16:
@ -2400,16 +2409,23 @@ export class Compiler extends DiagnosticEmitter {
// checking for a possible use of unary EQZ. while the most classic of all optimizations, // checking for a possible use of unary EQZ. while the most classic of all optimizations,
// that's not what the source told us to do. for reference, `!left` emits unary EQZ. // that's not what the source told us to do. for reference, `!left` emits unary EQZ.
left = this.compileExpression( left = this.compileExpressionRetainType(expression.left, contextualType);
expression.left, leftType = this.currentType;
contextualType == Type.void right = this.compileExpressionRetainType(expression.right, leftType);
? Type.i32 rightType = this.currentType;
: contextualType, if (commonType = Type.commonCompatible(leftType, rightType, false)) {
ConversionKind.NONE left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
); right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
right = this.compileExpression(expression.right, this.currentType); } else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, Token.operatorToString(expression.operator), leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
switch (this.currentType.kind) { switch (commonType.kind) {
case TypeKind.I8: case TypeKind.I8:
case TypeKind.I16: case TypeKind.I16:
@ -2459,16 +2475,23 @@ export class Compiler extends DiagnosticEmitter {
case Token.EXCLAMATION_EQUALS_EQUALS: case Token.EXCLAMATION_EQUALS_EQUALS:
// TODO? // TODO?
case Token.EXCLAMATION_EQUALS: case Token.EXCLAMATION_EQUALS:
left = this.compileExpression( left = this.compileExpressionRetainType(expression.left, contextualType);
expression.left, leftType = this.currentType;
contextualType == Type.void right = this.compileExpressionRetainType(expression.right, leftType);
? Type.i32 rightType = this.currentType;
: contextualType, if (commonType = Type.commonCompatible(leftType, rightType, false)) {
ConversionKind.NONE left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
); right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
right = this.compileExpression(expression.right, this.currentType); } else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, Token.operatorToString(expression.operator), leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
switch (this.currentType.kind) { switch (commonType.kind) {
case TypeKind.I8: case TypeKind.I8:
case TypeKind.I16: case TypeKind.I16:
@ -2521,20 +2544,38 @@ export class Compiler extends DiagnosticEmitter {
case Token.PLUS_EQUALS: case Token.PLUS_EQUALS:
compound = true; compound = true;
case Token.PLUS: case Token.PLUS:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32
: contextualType,
ConversionKind.NONE,
false // retains low bits of small integers false // retains low bits of small integers
); );
right = this.compileExpression( if (compound) {
expression.right, right = this.compileExpression(
this.currentType, expression.right,
ConversionKind.IMPLICIT, this.currentType,
false // ^ ConversionKind.IMPLICIT,
); false // ^
);
} else {
leftType = this.currentType;
right = this.compileExpressionRetainType(
expression.right,
leftType,
false // ^
);
rightType = this.currentType;
if (commonType = Type.commonCompatible(leftType, rightType, false)) {
left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
} else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, "+", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
}
switch (this.currentType.kind) { switch (this.currentType.kind) {
@ -2582,20 +2623,38 @@ export class Compiler extends DiagnosticEmitter {
case Token.MINUS_EQUALS: case Token.MINUS_EQUALS:
compound = true; compound = true;
case Token.MINUS: case Token.MINUS:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32
: contextualType,
ConversionKind.NONE,
false // retains low bits of small integers false // retains low bits of small integers
); );
right = this.compileExpression( if (compound) {
expression.right, right = this.compileExpression(
this.currentType, expression.right,
ConversionKind.IMPLICIT, this.currentType,
false // ^ ConversionKind.IMPLICIT,
); false // ^
);
} else {
leftType = this.currentType;
right = this.compileExpressionRetainType(
expression.right,
leftType,
false // ^
);
rightType = this.currentType;
if (commonType = Type.commonCompatible(leftType, rightType, false)) {
left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
} else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, "-", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
}
switch (this.currentType.kind) { switch (this.currentType.kind) {
@ -2647,20 +2706,38 @@ export class Compiler extends DiagnosticEmitter {
case Token.ASTERISK_EQUALS: case Token.ASTERISK_EQUALS:
compound = true; compound = true;
case Token.ASTERISK: case Token.ASTERISK:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32
: contextualType,
ConversionKind.NONE,
false // retains low bits of small integers false // retains low bits of small integers
); );
right = this.compileExpression( if (compound) {
expression.right, right = this.compileExpression(
this.currentType, expression.right,
ConversionKind.IMPLICIT, this.currentType,
false // ^ ConversionKind.IMPLICIT,
); false // ^
);
} else {
leftType = this.currentType;
right = this.compileExpressionRetainType(
expression.right,
leftType,
false // ^
);
rightType = this.currentType;
if (commonType = Type.commonCompatible(leftType, rightType, false)) {
left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
} else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, "*", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
}
switch (this.currentType.kind) { switch (this.currentType.kind) {
@ -2713,20 +2790,38 @@ export class Compiler extends DiagnosticEmitter {
case Token.SLASH_EQUALS: case Token.SLASH_EQUALS:
compound = true; compound = true;
case Token.SLASH: case Token.SLASH:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32
: contextualType,
ConversionKind.NONE,
true // TODO: when can division remain unwrapped? does it overflow? true // TODO: when can division remain unwrapped? does it overflow?
); );
right = this.compileExpression( if (compound) {
expression.right, right = this.compileExpression(
this.currentType, expression.right,
ConversionKind.IMPLICIT, this.currentType,
true // ^ ConversionKind.IMPLICIT,
); false // ^
);
} else {
leftType = this.currentType;
right = this.compileExpressionRetainType(
expression.right,
leftType,
false // ^
);
rightType = this.currentType;
if (commonType = Type.commonCompatible(leftType, rightType, false)) {
left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
} else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, "/", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
}
switch (this.currentType.kind) { switch (this.currentType.kind) {
@ -2794,20 +2889,38 @@ export class Compiler extends DiagnosticEmitter {
case Token.PERCENT_EQUALS: case Token.PERCENT_EQUALS:
compound = true; compound = true;
case Token.PERCENT: case Token.PERCENT:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32 true // TODO: when can remainder remain unwrapped? does it overflow?
: contextualType,
ConversionKind.NONE,
true // TODO: when can remainder remain unwrapped? may it overflow?
);
right = this.compileExpression(
expression.right,
this.currentType,
ConversionKind.IMPLICIT,
true // ^
); );
if (compound) {
right = this.compileExpression(
expression.right,
this.currentType,
ConversionKind.IMPLICIT,
false // ^
);
} else {
leftType = this.currentType;
right = this.compileExpressionRetainType(
expression.right,
leftType,
false // ^
);
rightType = this.currentType;
if (commonType = Type.commonCompatible(leftType, rightType, false)) {
left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
} else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, "%", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
}
switch (this.currentType.kind) { switch (this.currentType.kind) {
@ -2875,14 +2988,9 @@ export class Compiler extends DiagnosticEmitter {
case Token.LESSTHAN_LESSTHAN_EQUALS: case Token.LESSTHAN_LESSTHAN_EQUALS:
compound = true; compound = true;
case Token.LESSTHAN_LESSTHAN: case Token.LESSTHAN_LESSTHAN:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32
: contextualType.is(TypeFlags.FLOAT)
? Type.i64
: contextualType,
ConversionKind.NONE,
false // retains low bits of small integers false // retains low bits of small integers
); );
right = this.compileExpression( right = this.compileExpression(
@ -2933,14 +3041,9 @@ export class Compiler extends DiagnosticEmitter {
case Token.GREATERTHAN_GREATERTHAN_EQUALS: case Token.GREATERTHAN_GREATERTHAN_EQUALS:
compound = true; compound = true;
case Token.GREATERTHAN_GREATERTHAN: case Token.GREATERTHAN_GREATERTHAN:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32
: contextualType.is(TypeFlags.FLOAT)
? Type.i64
: contextualType,
ConversionKind.NONE,
true // must wrap small integers true // must wrap small integers
); );
right = this.compileExpression( right = this.compileExpression(
@ -3006,14 +3109,9 @@ export class Compiler extends DiagnosticEmitter {
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN_EQUALS: case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN_EQUALS:
compound = true; compound = true;
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN: case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32
: contextualType == Type.void
? Type.u64
: contextualType,
ConversionKind.NONE,
true // modifies low bits of small integers if unsigned true // modifies low bits of small integers if unsigned
); );
right = this.compileExpression( right = this.compileExpression(
@ -3063,22 +3161,38 @@ export class Compiler extends DiagnosticEmitter {
case Token.AMPERSAND_EQUALS: case Token.AMPERSAND_EQUALS:
compound = true; compound = true;
case Token.AMPERSAND: case Token.AMPERSAND:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32
: contextualType.is(TypeFlags.FLOAT)
? Type.i64
: contextualType,
ConversionKind.NONE,
false // retains low bits of small integers false // retains low bits of small integers
); );
right = this.compileExpression( if (compound) {
expression.right, right = this.compileExpression(
this.currentType, expression.right,
ConversionKind.IMPLICIT, this.currentType,
false // ^ ConversionKind.IMPLICIT,
); false // ^
);
} else {
leftType = this.currentType;
right = this.compileExpressionRetainType(
expression.right,
leftType,
false // ^
);
rightType = this.currentType;
if (commonType = Type.commonCompatible(leftType, rightType, false)) {
left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
} else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, "&", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
}
switch (this.currentType.kind) { switch (this.currentType.kind) {
@ -3121,22 +3235,38 @@ export class Compiler extends DiagnosticEmitter {
case Token.BAR_EQUALS: case Token.BAR_EQUALS:
compound = true; compound = true;
case Token.BAR: case Token.BAR:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32
: contextualType.is(TypeFlags.FLOAT)
? Type.i64
: contextualType,
ConversionKind.NONE,
false // retains low bits of small integers false // retains low bits of small integers
); );
right = this.compileExpression( if (compound) {
expression.right, right = this.compileExpression(
this.currentType, expression.right,
ConversionKind.IMPLICIT, this.currentType,
false // ^ ConversionKind.IMPLICIT,
); false // ^
);
} else {
leftType = this.currentType;
right = this.compileExpressionRetainType(
expression.right,
leftType,
false // ^
);
rightType = this.currentType;
if (commonType = Type.commonCompatible(leftType, rightType, false)) {
left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
} else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, "|", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
}
switch (this.currentType.kind) { switch (this.currentType.kind) {
@ -3179,22 +3309,38 @@ export class Compiler extends DiagnosticEmitter {
case Token.CARET_EQUALS: case Token.CARET_EQUALS:
compound = true; compound = true;
case Token.CARET: case Token.CARET:
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType,
? Type.i32
: contextualType.is(TypeFlags.FLOAT)
? Type.i64
: contextualType,
ConversionKind.NONE,
false // retains low bits of small integers false // retains low bits of small integers
); );
right = this.compileExpression( if (compound) {
expression.right, right = this.compileExpression(
this.currentType, expression.right,
ConversionKind.IMPLICIT, this.currentType,
false // ^ ConversionKind.IMPLICIT,
); false // ^
);
} else {
leftType = this.currentType;
right = this.compileExpressionRetainType(
expression.right,
leftType,
false // ^
);
rightType = this.currentType;
if (commonType = Type.commonCompatible(leftType, rightType, false)) {
left = this.convertExpression(left, leftType, commonType, ConversionKind.IMPLICIT, expression.left);
right = this.convertExpression(right, rightType, commonType, ConversionKind.IMPLICIT, expression.right);
} else {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, "^", leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return this.module.createUnreachable();
}
}
switch (this.currentType.kind) { switch (this.currentType.kind) {
@ -3237,12 +3383,9 @@ export class Compiler extends DiagnosticEmitter {
// logical (no overloading) // logical (no overloading)
case Token.AMPERSAND_AMPERSAND: // left && right case Token.AMPERSAND_AMPERSAND: // left && right
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType
? Type.i32
: contextualType,
ConversionKind.NONE
); );
right = this.compileExpression( right = this.compileExpression(
expression.right, expression.right,
@ -3286,12 +3429,9 @@ export class Compiler extends DiagnosticEmitter {
break; break;
case Token.BAR_BAR: // left || right case Token.BAR_BAR: // left || right
left = this.compileExpression( left = this.compileExpressionRetainType(
expression.left, expression.left,
contextualType == Type.void contextualType
? Type.i32
: contextualType,
ConversionKind.NONE
); );
right = this.compileExpression( right = this.compileExpression(
expression.right, expression.right,
@ -3884,7 +4024,16 @@ export class Compiler extends DiagnosticEmitter {
return this.module.createI32(index); return this.module.createI32(index);
} }
compileIdentifierExpression(expression: IdentifierExpression, contextualType: Type): ExpressionRef { /**
* Compiles an identifier in the specified context.
* @param retainConstantType Retains the type of inlined constants if `true`, otherwise
* precomputes them according to context.
*/
compileIdentifierExpression(
expression: IdentifierExpression,
contextualType: Type,
retainConstantType: bool
): ExpressionRef {
// check special keywords first // check special keywords first
switch (expression.kind) { switch (expression.kind) {
@ -3948,7 +4097,7 @@ export class Compiler extends DiagnosticEmitter {
case ElementKind.LOCAL: case ElementKind.LOCAL:
if ((<Local>element).is(ElementFlags.INLINED)) { if ((<Local>element).is(ElementFlags.INLINED)) {
return this.compileInlineConstant(<Local>element, contextualType); return this.compileInlineConstant(<Local>element, contextualType, retainConstantType);
} }
assert((<Local>element).index >= 0); assert((<Local>element).index >= 0);
this.currentType = (<Local>element).type; this.currentType = (<Local>element).type;
@ -3963,7 +4112,7 @@ export class Compiler extends DiagnosticEmitter {
} }
assert((<Global>element).type != Type.void); assert((<Global>element).type != Type.void);
if ((<Global>element).is(ElementFlags.INLINED)) { if ((<Global>element).is(ElementFlags.INLINED)) {
return this.compileInlineConstant(<Global>element, contextualType); return this.compileInlineConstant(<Global>element, contextualType, retainConstantType);
} }
this.currentType = (<Global>element).type; this.currentType = (<Global>element).type;
return this.module.createGetGlobal((<Global>element).internalName, this.currentType.toNativeType()); return this.module.createGetGlobal((<Global>element).internalName, this.currentType.toNativeType());
@ -4323,7 +4472,16 @@ export class Compiler extends DiagnosticEmitter {
return this.compileExpression(expression.expression, contextualType, ConversionKind.NONE); return this.compileExpression(expression.expression, contextualType, ConversionKind.NONE);
} }
compilePropertyAccessExpression(propertyAccess: PropertyAccessExpression, contextualType: Type): ExpressionRef { /**
* Compiles a property access in the specified context.
* @param retainConstantType Retains the type of inlined constants if `true`, otherwise
* precomputes them according to context.
*/
compilePropertyAccessExpression(
propertyAccess: PropertyAccessExpression,
contextualType: Type,
retainConstantType: bool
): ExpressionRef {
var resolved = this.program.resolvePropertyAccess(propertyAccess, this.currentFunction); // reports var resolved = this.program.resolvePropertyAccess(propertyAccess, this.currentFunction); // reports
if (!resolved) return this.module.createUnreachable(); if (!resolved) return this.module.createUnreachable();
@ -4340,7 +4498,7 @@ export class Compiler extends DiagnosticEmitter {
} }
assert((<Global>element).type != Type.void); assert((<Global>element).type != Type.void);
if ((<Global>element).is(ElementFlags.INLINED)) { if ((<Global>element).is(ElementFlags.INLINED)) {
return this.compileInlineConstant(<Global>element, contextualType); return this.compileInlineConstant(<Global>element, contextualType, retainConstantType);
} }
this.currentType = (<Global>element).type; this.currentType = (<Global>element).type;
return this.module.createGetGlobal((<Global>element).internalName, this.currentType.toNativeType()); return this.module.createGetGlobal((<Global>element).internalName, this.currentType.toNativeType());

View File

@ -114,7 +114,7 @@ export class Type {
/** Composes a class type from this type and a class. */ /** Composes a class type from this type and a class. */
asClass(classType: Class): Type { asClass(classType: Class): Type {
assert(this.kind == TypeKind.USIZE); assert(this.kind == TypeKind.USIZE && !this.classType);
var ret = new Type(this.kind, this.flags & ~TypeFlags.VALUE | TypeFlags.REFERENCE, this.size); var ret = new Type(this.kind, this.flags & ~TypeFlags.VALUE | TypeFlags.REFERENCE, this.size);
ret.classType = classType; ret.classType = classType;
return ret; return ret;
@ -122,26 +122,26 @@ export class Type {
/** Composes a function type from this type and a function. */ /** Composes a function type from this type and a function. */
asFunction(functionType: Function): Type { asFunction(functionType: Function): Type {
assert(this.kind == TypeKind.U32 && !this.isReference); assert(this.kind == TypeKind.U32 && !this.functionType);
var ret = new Type(this.kind, this.flags & ~TypeFlags.VALUE | TypeFlags.REFERENCE, this.size); var ret = new Type(this.kind, this.flags & ~TypeFlags.VALUE | TypeFlags.REFERENCE, this.size);
ret.functionType = functionType; ret.functionType = functionType;
return ret; return ret;
} }
/** Composes the respective nullable type of this type. */ /** Composes the respective nullable type of this type. */
asNullable(): Type | null { asNullable(): Type {
assert(this.kind == TypeKind.USIZE); assert(this.isReference);
if (!this.nullableType) { if (!this.nullableType) {
assert(!this.is(TypeFlags.NULLABLE) && this.isReference); assert(!this.is(TypeFlags.NULLABLE));
this.nullableType = new Type(this.kind, this.flags | TypeFlags.NULLABLE, this.size); this.nullableType = new Type(this.kind, this.flags | TypeFlags.NULLABLE, this.size);
this.nullableType.classType = this.classType; this.nullableType.classType = this.classType; // either a class reference
this.nullableType.functionType = this.functionType; this.nullableType.functionType = this.functionType; // or a function reference
} }
return this.nullableType; return this.nullableType;
} }
/** Tests if a value of this type is assignable to a target of the specified type. */ /** Tests if a value of this type is assignable to a target of the specified type. */
isAssignableTo(target: Type): bool { isAssignableTo(target: Type, signednessIsImportant: bool = false): bool {
var currentClass: Class | null; var currentClass: Class | null;
var targetClass: Class | null; var targetClass: Class | null;
var currentFunction: Function | null; var currentFunction: Function | null;
@ -159,177 +159,35 @@ export class Type {
} }
} }
} else if (!target.isReference) { } else if (!target.isReference) {
switch (this.kind) { if (this.is(TypeFlags.INTEGER)) {
if (target.is(TypeFlags.INTEGER)) {
case TypeKind.I8: if (!signednessIsImportant || this.is(TypeFlags.SIGNED) == target.is(TypeFlags.SIGNED)) {
switch (target.kind) { return this.size <= target.size;
case TypeKind.I8: // same
case TypeKind.I16: // larger
case TypeKind.I32: // larger
case TypeKind.I64: // larger
case TypeKind.ISIZE: // larger
case TypeKind.U8: // signed to unsigned
case TypeKind.U16: // larger
case TypeKind.U32: // larger
case TypeKind.U64: // larger
case TypeKind.USIZE: // larger
case TypeKind.F32: // safe
case TypeKind.F64: // safe
return true;
} }
break; } else if (target.kind == TypeKind.F32) {
return this.size <= 23; // mantissa bits
case TypeKind.I16: } else if (target.kind == TypeKind.F64) {
switch (target.kind) { return this.size <= 52; // ^
case TypeKind.I16: // same }
case TypeKind.I32: // larger } else if (this.is(TypeFlags.FLOAT)) {
case TypeKind.I64: // larger if (target.is(TypeFlags.FLOAT)) {
case TypeKind.ISIZE: // larger return this.size <= target.size;
case TypeKind.U16: // signed to unsigned }
case TypeKind.U32: // larger
case TypeKind.U64: // larger
case TypeKind.USIZE: // larger
case TypeKind.F32: // safe
case TypeKind.F64: // safe
return true;
}
break;
case TypeKind.I32:
switch (target.kind) {
case TypeKind.I32: // same
case TypeKind.I64: // larger
case TypeKind.ISIZE: // same or larger
case TypeKind.U32: // signed to unsigned
case TypeKind.U64: // larger
case TypeKind.USIZE: // signed to unsigned or larger
case TypeKind.F64: // safe
return true;
}
break;
case TypeKind.I64:
switch (target.kind) {
case TypeKind.I64: // same
case TypeKind.U64: // signed to unsigned
return true;
case TypeKind.ISIZE: // possibly same
case TypeKind.USIZE: // possibly signed to unsigned
return target.size == 64;
}
break;
case TypeKind.ISIZE:
switch (target.kind) {
case TypeKind.I32: // possibly same
case TypeKind.U32: // possibly signed to unsigned
return this.size == 32;
case TypeKind.I64: // same or larger
case TypeKind.ISIZE: // same
case TypeKind.U64: // signed to unsigned or larger
case TypeKind.USIZE: // signed to unsigned
return true;
case TypeKind.F64: // possibly safe
return target.size == 32;
}
break;
case TypeKind.U8:
switch (target.kind) {
case TypeKind.I16: // larger
case TypeKind.I32: // larger
case TypeKind.I64: // larger
case TypeKind.ISIZE: // larger
case TypeKind.U8: // same
case TypeKind.U16: // larger
case TypeKind.U32: // larger
case TypeKind.U64: // larger
case TypeKind.USIZE: // larger
case TypeKind.F32: // safe
case TypeKind.F64: // safe
return true;
}
break;
case TypeKind.U16:
switch (target.kind) {
case TypeKind.I32: // larger
case TypeKind.I64: // larger
case TypeKind.ISIZE: // larger
case TypeKind.U16: // same
case TypeKind.U32: // larger
case TypeKind.U64: // larger
case TypeKind.USIZE: // larger
case TypeKind.F32: // safe
case TypeKind.F64: // safe
return true;
}
break;
case TypeKind.U32:
switch (target.kind) {
case TypeKind.I64: // larger
case TypeKind.U32: // same
case TypeKind.U64: // larger
case TypeKind.USIZE: // same or larger
case TypeKind.F64: // safe
return true;
}
break;
case TypeKind.U64:
switch (target.kind) {
case TypeKind.U64: // same
return true;
case TypeKind.USIZE: // possibly same
return target.size == 64;
}
break;
case TypeKind.USIZE:
switch (target.kind) {
case TypeKind.U32: // possibly same
return this.size == 32;
case TypeKind.U64: // same or larger
case TypeKind.USIZE: // same
return true;
case TypeKind.F64: // possibly safe
return target.size == 32;
}
break;
case TypeKind.BOOL:
switch (target.kind) {
case TypeKind.I8: // larger
case TypeKind.I16: // larger
case TypeKind.I32: // larger
case TypeKind.I64: // larger
case TypeKind.ISIZE: // larger
case TypeKind.U8: // larger
case TypeKind.U16: // larger
case TypeKind.U32: // larger
case TypeKind.U64: // larger
case TypeKind.USIZE: // larger
case TypeKind.BOOL: // same
return true;
}
break;
case TypeKind.F32:
switch (target.kind) {
case TypeKind.F32: // same
case TypeKind.F64: // larger
return true;
}
break;
case TypeKind.F64:
return target.kind == TypeKind.F64;
} }
} }
return false; return false;
} }
/** Determines the common compatible type of two types, if any. */
static commonCompatible(left: Type, right: Type, signednessIsImportant: bool): Type | null {
if (right.isAssignableTo(left, signednessIsImportant)) {
return left;
} else if (left.isAssignableTo(right, signednessIsImportant)) {
return right;
}
return null;
}
/** Converts this type to its TypeScript representation. */ /** Converts this type to its TypeScript representation. */
toString(kindOnly: bool = false): string { toString(kindOnly: bool = false): string {
switch (this.kind) { switch (this.kind) {

View File

@ -41,7 +41,7 @@ export class Array<T> {
@operator("[]") @operator("[]")
private __get(index: i32): T { private __get(index: i32): T {
if (<u32>index >= this.__capacity) { if (<u32>index >= <u32>this.__capacity) {
throw new Error("Index out of bounds"); // return changetype<T>(0) ? throw new Error("Index out of bounds"); // return changetype<T>(0) ?
} }
return load<T>(this.__memory + <usize>index * sizeof<T>()); return load<T>(this.__memory + <usize>index * sizeof<T>());
@ -62,7 +62,7 @@ export class Array<T> {
if (fromIndex < 0) { if (fromIndex < 0) {
fromIndex = this.__length + fromIndex; fromIndex = this.__length + fromIndex;
} }
while (<u32>fromIndex < this.__length) { while (<u32>fromIndex < <u32>this.__length) {
if (load<T>(this.__memory + <usize>fromIndex * sizeof<T>()) == searchElement) { if (load<T>(this.__memory + <usize>fromIndex * sizeof<T>()) == searchElement) {
return fromIndex; return fromIndex;
} }

View File

@ -185,8 +185,8 @@ export { usize };
@builtin @builtin
declare function bool(value: void): bool; declare function bool(value: void): bool;
namespace bool { namespace bool {
export const MIN_VALUE: bool = 0; export const MIN_VALUE: bool = false;
export const MAX_VALUE: bool = 1; export const MAX_VALUE: bool = true;
} }
export { bool }; export { bool };

View File

@ -13,13 +13,13 @@ function allocate(length: i32): String {
export class String { export class String {
readonly length: i32; readonly length: i32; // capped to [0, 0x7fffffff]
@operator("[]") @operator("[]")
charAt(pos: i32): String { charAt(pos: i32): String {
assert(this != null); assert(this != null);
if (<u32>pos >= this.length) { if (<u32>pos >= <u32>this.length) {
return EMPTY; return EMPTY;
} }
@ -37,7 +37,7 @@ export class String {
charCodeAt(pos: i32): i32 { charCodeAt(pos: i32): i32 {
assert(this != null); assert(this != null);
if (<u32>pos >= this.length) { if (<u32>pos >= <u32>this.length) {
return -1; // (NaN) return -1; // (NaN)
} }
return load<u16>( return load<u16>(
@ -48,7 +48,7 @@ export class String {
codePointAt(pos: i32): i32 { codePointAt(pos: i32): i32 {
assert(this != null); assert(this != null);
if (<u32>pos >= this.length) { if (<u32>pos >= <u32>this.length) {
return -1; // (undefined) return -1; // (undefined)
} }
var first = <i32>load<u16>( var first = <i32>load<u16>(

View File

@ -171,7 +171,7 @@ function update_max_ptr(new_value: usize): i32 {
// if (brk(new_value)) { // if (brk(new_value)) {
// return 0; // return 0;
// } // }
var oldPages = current_memory(); var oldPages = <u32>current_memory();
var newPages = <u32>(((new_value + 0xffff) & ~0xffff) >> 16); var newPages = <u32>(((new_value + 0xffff) & ~0xffff) >> 16);
assert(newPages > oldPages); assert(newPages > oldPages);
if (grow_memory(newPages - oldPages) < 0) { if (grow_memory(newPages - oldPages) < 0) {

View File

@ -927,15 +927,12 @@
;;@ assembly/buddy.ts:400:10 ;;@ assembly/buddy.ts:400:10
(i32.and (i32.and
(if (result i32) (if (result i32)
(i32.ne (tee_local $7
(tee_local $7 (i32.ne
(i32.ne (get_local $2)
(get_local $2) ;;@ assembly/buddy.ts:400:20
;;@ assembly/buddy.ts:400:20 (get_global $assembly/buddy/bucket_limit)
(get_global $assembly/buddy/bucket_limit)
)
) )
(i32.const 0)
) )
(get_local $7) (get_local $7)
;;@ assembly/buddy.ts:400:36 ;;@ assembly/buddy.ts:400:36
@ -1245,14 +1242,11 @@
(if (if
;;@ assembly/buddy.ts:514:8 ;;@ assembly/buddy.ts:514:8
(if (result i32) (if (result i32)
(i32.ne (tee_local $3
(tee_local $3 (call $assembly/buddy/parent_is_split
(call $assembly/buddy/parent_is_split ;;@ assembly/buddy.ts:514:24
;;@ assembly/buddy.ts:514:24 (get_local $2)
(get_local $2)
)
) )
(i32.const 0)
) )
(get_local $3) (get_local $3)
;;@ assembly/buddy.ts:514:30 ;;@ assembly/buddy.ts:514:30

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -56,7 +56,7 @@ test(u8.MAX_VALUE, -1);
test(u8.MAX_VALUE, u8.MAX_VALUE); test(u8.MAX_VALUE, u8.MAX_VALUE);
// various // various
for (var i: i32 = i8.MIN_VALUE; i <= u8.MAX_VALUE; ++i) { for (var i: i32 = i8.MIN_VALUE; i <= <i32>u8.MAX_VALUE; ++i) {
test(0, i); test(0, i);
test(1, i); test(1, i);
test(-1, i); test(-1, i);

View File

@ -4,6 +4,7 @@ const webpack = require("webpack");
// Build the C-like library // Build the C-like library
const lib = { const lib = {
mode: "production",
entry: [ "./src/glue/js", "./src/index.ts" ], entry: [ "./src/glue/js", "./src/index.ts" ],
module: { module: {
rules: [ rules: [
@ -24,20 +25,18 @@ const lib = {
library: "assemblyscript", library: "assemblyscript",
libraryTarget: "umd" libraryTarget: "umd"
}, },
plugins: [ optimization: {
new webpack.optimize.UglifyJsPlugin({ minimize: true
minimize: true, },
sourceMap: true devtool: "source-map",
}), performance: {
new webpack.SourceMapDevToolPlugin({ hints : false
filename: "assemblyscript.js.map" }
})
]
}; };
// Build asc for browser usage // Build asc for browser usage
const BabelMinifyPlugin = require("babel-minify-webpack-plugin");
const bin = { const bin = {
mode: "production",
context: path.join(__dirname, "bin"), context: path.join(__dirname, "bin"),
entry: [ "./asc.js" ], entry: [ "./asc.js" ],
externals: [{ externals: [{
@ -64,6 +63,10 @@ const bin = {
library: "asc", library: "asc",
libraryTarget: "umd" libraryTarget: "umd"
}, },
optimization: {
minimize: true
},
devtool: "source-map",
plugins: [ plugins: [
new webpack.DefinePlugin({ new webpack.DefinePlugin({
BUNDLE_VERSION: JSON.stringify(require("./package.json").version), BUNDLE_VERSION: JSON.stringify(require("./package.json").version),
@ -81,13 +84,6 @@ const bin = {
__dirname: JSON.stringify(".") __dirname: JSON.stringify(".")
}), }),
new webpack.IgnorePlugin(/\.\/src|package\.json|^(ts\-node|glob|source\-map\-support)$/), new webpack.IgnorePlugin(/\.\/src|package\.json|^(ts\-node|glob|source\-map\-support)$/),
// Error: original.line and original.column are not numbers -- you probably meant to omit the
// original mapping entirely and only map the generated position. If so, pass null for the
// original mapping instead of an object with empty or null values.
new BabelMinifyPlugin(/* {}, { sourceMap: true } */),
// new webpack.SourceMapDevToolPlugin({
// filename: "asc.js.map"
// }),
] ]
}; };