diff --git a/lexer.js b/lexer.js index 773acf2..0aac189 100755 --- a/lexer.js +++ b/lexer.js @@ -254,6 +254,48 @@ function tryBacktrackAddStarExportBinding (bPos) { } } +// `Object.` `prototype.`? hasOwnProperty.call(` IDENTIFIER `, ` IDENTIFIER$2 `)` +function tryParseObjectHasOwnProperty (it_id) { + ch = commentWhitespace(); + if (ch !== 79/*O*/ || !source.startsWith('bject', pos + 1)) return false; + pos += 6; + ch = commentWhitespace(); + if (ch !== 46/*.*/) return false; + pos++; + ch = commentWhitespace(); + if (ch === 112/*p*/) { + if (!source.startsWith('rototype', pos + 1)) return false; + pos += 9; + ch = commentWhitespace(); + if (ch !== 46/*.*/) return false; + pos++; + ch = commentWhitespace(); + } + if (ch !== 104/*h*/ || !source.startsWith('asOwnProperty', pos + 1)) return false; + pos += 14; + ch = commentWhitespace(); + if (ch !== 46/*.*/) return false; + pos++; + ch = commentWhitespace(); + if (ch !== 99/*c*/ || !source.startsWith('all', pos + 1)) return false; + pos += 4; + ch = commentWhitespace(); + if (ch !== 40/*(*/) return false; + pos++; + ch = commentWhitespace(); + if (!identifier()) return false; + ch = commentWhitespace(); + if (ch !== 44/*,*/) return false; + pos++; + ch = commentWhitespace(); + if (!source.startsWith(it_id, pos)) return false; + pos += it_id.length; + ch = commentWhitespace(); + if (ch !== 41/*)*/) return false; + pos++; + return true; +} + function tryParseObjectDefineOrKeys (keys) { pos += 6; let revertPos = pos - 1; @@ -474,7 +516,7 @@ function tryParseObjectDefineOrKeys (keys) { pos++; ch = commentWhitespace(); } - // `if (` IDENTIFIER$2 `!==` ( `'default'` | `"default"` ) `)` + // `if (` IDENTIFIER$2 `!==` ( `'default'` | `"default"` ) (`&& !` IDENTIFIER `.hasOwnProperty(` IDENTIFIER$2 `)` )? `)` else if (ch === 33/*!*/) { if (!source.startsWith('==', pos + 1)) break; pos += 3; @@ -487,6 +529,34 @@ function tryParseObjectDefineOrKeys (keys) { if (ch !== quot) break; pos += 1; ch = commentWhitespace(); + if (ch === 38/*&*/) { + if (source.charCodeAt(pos + 1) !== 38/*&*/) break; + pos += 2; + ch = commentWhitespace(); + if (ch !== 33/*!*/) break; + pos += 1; + ch = commentWhitespace(); + if (source.startsWith(id, pos)) { + pos += id.length; + ch = commentWhitespace(); + if (ch !== 46/*.*/) break; + pos++; + ch = commentWhitespace(); + if (ch !== 104/*h*/ || !source.startsWith('asOwnProperty', pos + 1)) break; + pos += 14; + ch = commentWhitespace(); + if (ch !== 40/*(*/) break; + pos += 1; + ch = commentWhitespace(); + if (!source.startsWith(it_id, pos)) break; + pos += it_id.length; + ch = commentWhitespace(); + if (ch !== 41/*)*/) break; + pos += 1; + } + else if (!tryParseObjectHasOwnProperty(it_id)) break; + ch = commentWhitespace(); + } if (ch !== 41/*)*/) break; pos += 1; ch = commentWhitespace(); @@ -495,59 +565,18 @@ function tryParseObjectDefineOrKeys (keys) { // `if (Object.prototype.hasOwnProperty.call(` IDENTIFIER `, ` IDENTIFIER$2 `)) return` `;`? currentIfStatement: if (ch === 105/*i*/ && source.charCodeAt(pos + 1) === 102/*f*/) { - let ifStartPos = pos; - + const ifStartPos = pos; pos += 2; ch = commentWhitespace(); if (ch !== 40/*(*/) break; pos++; - ch = commentWhitespace(); - if (ch !== 79/*O*/ || !source.startsWith('bject', pos + 1)) { - // Revert parsing the current optional if statement, but don't bail - // out since we can try parse the next possible if statement. - pos = ifStartPos; - ch = 105/*i*/; - break currentIfStatement; - } - pos += 6; - ch = commentWhitespace(); - if (ch !== 46/*.*/) { + if (!tryParseObjectHasOwnProperty(it_id)) { // Revert parsing the current optional if statement, but don't bail // out since we can try parse the next possible if statement. pos = ifStartPos; ch = 105/*i*/; break currentIfStatement; } - pos++; - ch = commentWhitespace(); - if (ch !== 112/*p*/ || !source.startsWith('rototype', pos + 1)) break; - pos += 9; - ch = commentWhitespace(); - if (ch !== 46/*.*/) break; - pos++; - ch = commentWhitespace(); - if (ch !== 104/*h*/ || !source.startsWith('asOwnProperty', pos + 1)) break; - pos += 14; - ch = commentWhitespace(); - if (ch !== 46/*.*/) break; - pos++; - ch = commentWhitespace(); - if (ch !== 99/*c*/ || !source.startsWith('all', pos + 1)) break; - pos += 4; - ch = commentWhitespace(); - if (ch !== 40/*(*/) break; - pos++; - ch = commentWhitespace(); - if (!identifier()) break; - ch = commentWhitespace(); - if (ch !== 44/*,*/) break; - pos++; - ch = commentWhitespace(); - if (!source.startsWith(it_id, pos)) break; - pos += it_id.length; - ch = commentWhitespace(); - if (ch !== 41/*)*/) break; - pos++; ch = commentWhitespace(); if (ch !== 41/*)*/) break; pos++; diff --git a/lib/lexer.wasm b/lib/lexer.wasm index 3cb9878..03c8169 100755 Binary files a/lib/lexer.wasm and b/lib/lexer.wasm differ diff --git a/lib/lexer.wat b/lib/lexer.wat index 2a626b3..9c1aa8a 100644 --- a/lib/lexer.wat +++ b/lib/lexer.wat @@ -12,9 +12,9 @@ (type (;10;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) (type (;11;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) (type (;12;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) - (type (;13;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) + (type (;13;) (func (param i32 i32) (result i32))) (type (;14;) (func (param i32 i32 i32 i32) (result i32))) - (type (;15;) (func (param i32 i32) (result i32))) + (type (;15;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) (func (;0;) (type 2) (param i32) (result i32) (local i32) i32.const 0 @@ -2237,14 +2237,21 @@ local.get 4 i32.sub local.tee 3 - call 64 + call 65 br_if 1 (;@1;) + local.get 0 + local.get 2 + i32.sub + local.tee 6 + i32.const 1 + i32.shr_s + local.set 7 i32.const 0 local.get 5 local.get 3 i32.const 1 i32.shr_s - local.tee 6 + local.tee 8 i32.const 1 i32.shl i32.add @@ -2253,45 +2260,45 @@ block ;; label = @4 block ;; label = @5 call 39 - local.tee 5 + local.tee 0 i32.const 33 i32.eq br_if 0 (;@5;) - local.get 5 + local.get 0 i32.const 61 i32.ne br_if 4 (;@1;) i32.const 0 i32.load offset=20540 - local.tee 5 + local.tee 0 i32.load16_u offset=2 i32.const 61 i32.ne br_if 4 (;@1;) - local.get 5 + local.get 0 i32.load16_u offset=4 i32.const 61 i32.ne br_if 4 (;@1;) i32.const 0 - local.get 5 + local.get 0 i32.const 6 i32.add i32.store offset=20540 block ;; label = @6 call 39 - local.tee 5 + local.tee 0 i32.const 39 i32.eq br_if 0 (;@6;) - local.get 5 + local.get 0 i32.const 34 i32.ne br_if 5 (;@1;) end i32.const 0 i32.load offset=20540 - local.tee 7 + local.tee 5 i32.const 2 i32.add i32.const 100 @@ -2305,12 +2312,12 @@ i32.eqz br_if 4 (;@1;) i32.const 0 - local.get 7 + local.get 5 i32.const 16 i32.add i32.store offset=20540 call 39 - local.get 5 + local.get 0 i32.ne br_if 4 (;@1;) i32.const 0 @@ -2325,13 +2332,13 @@ br_if 4 (;@1;) i32.const 0 i32.load offset=20540 - local.tee 5 + local.tee 0 i32.load16_u offset=2 i32.const 124 i32.ne br_if 4 (;@1;) i32.const 0 - local.get 5 + local.get 0 i32.const 4 i32.add i32.store offset=20540 @@ -2339,14 +2346,14 @@ drop i32.const 0 i32.load offset=20540 - local.tee 5 + local.tee 0 local.get 4 local.get 3 - call 64 + call 65 br_if 4 (;@1;) i32.const 0 - local.get 5 - local.get 6 + local.get 0 + local.get 8 i32.const 1 i32.shl i32.add @@ -2357,35 +2364,35 @@ br_if 4 (;@1;) i32.const 0 i32.load offset=20540 - local.tee 5 + local.tee 0 i32.load16_u offset=2 i32.const 61 i32.ne br_if 4 (;@1;) - local.get 5 + local.get 0 i32.load16_u offset=4 i32.const 61 i32.ne br_if 4 (;@1;) i32.const 0 - local.get 5 + local.get 0 i32.const 6 i32.add i32.store offset=20540 block ;; label = @6 call 39 - local.tee 5 + local.tee 0 i32.const 39 i32.eq br_if 0 (;@6;) - local.get 5 + local.get 0 i32.const 34 i32.ne br_if 5 (;@1;) end i32.const 0 i32.load offset=20540 - local.tee 7 + local.tee 5 i32.const 2 i32.add i32.const 95 @@ -2402,12 +2409,12 @@ i32.eqz br_if 4 (;@1;) i32.const 0 - local.get 7 + local.get 5 i32.const 22 i32.add i32.store offset=20540 call 39 - local.get 5 + local.get 0 i32.ne br_if 4 (;@1;) i32.const 0 @@ -2432,7 +2439,7 @@ br_if 4 (;@1;) i32.const 0 i32.load offset=20540 - local.tee 5 + local.tee 0 i32.const 2 i32.add i32.const 101 @@ -2444,7 +2451,7 @@ i32.eqz br_if 4 (;@1;) i32.const 0 - local.get 5 + local.get 0 i32.const 12 i32.add i32.store offset=20540 @@ -2456,35 +2463,35 @@ end i32.const 0 i32.load offset=20540 - local.tee 5 + local.tee 0 i32.load16_u offset=2 i32.const 61 i32.ne br_if 3 (;@1;) - local.get 5 + local.get 0 i32.load16_u offset=4 i32.const 61 i32.ne br_if 3 (;@1;) i32.const 0 - local.get 5 + local.get 0 i32.const 6 i32.add i32.store offset=20540 block ;; label = @5 call 39 - local.tee 5 + local.tee 0 i32.const 39 i32.eq br_if 0 (;@5;) - local.get 5 + local.get 0 i32.const 34 i32.ne br_if 4 (;@1;) end i32.const 0 i32.load offset=20540 - local.tee 7 + local.tee 5 i32.const 2 i32.add i32.const 100 @@ -2498,60 +2505,12 @@ i32.eqz br_if 3 (;@1;) i32.const 0 - local.get 7 - i32.const 16 - i32.add - i32.store offset=20540 - call 39 - local.get 5 - i32.ne - br_if 3 (;@1;) - i32.const 0 - i32.const 0 - i32.load offset=20540 - i32.const 2 - i32.add - i32.store offset=20540 - call 39 - i32.const 41 - i32.ne - br_if 3 (;@1;) - end - i32.const 0 - i32.const 0 - i32.load offset=20540 - i32.const 2 - i32.add - i32.store offset=20540 - end - local.get 0 - local.get 2 - i32.sub - local.tee 7 - i32.const 1 - i32.shr_s - local.set 8 - block ;; label = @3 - call 39 - local.tee 0 - i32.const 105 - i32.ne - br_if 0 (;@3;) - block ;; label = @4 - i32.const 0 - i32.load offset=20540 - local.tee 5 - i32.load16_u offset=2 - i32.const 102 - i32.ne - br_if 0 (;@4;) - i32.const 0 local.get 5 - i32.const 4 + i32.const 16 i32.add i32.store offset=20540 call 39 - i32.const 40 + local.get 0 i32.ne br_if 3 (;@1;) i32.const 0 @@ -2561,193 +2520,171 @@ i32.add i32.store offset=20540 block ;; label = @5 - block ;; label = @6 - call 39 - i32.const 79 - i32.ne - br_if 0 (;@6;) - i32.const 0 - i32.load offset=20540 - local.tee 0 - i32.const 2 - i32.add - i32.const 98 - i32.const 106 - i32.const 101 - i32.const 99 - i32.const 116 - call 19 - br_if 1 (;@5;) - end + call 39 + local.tee 0 + i32.const 38 + i32.ne + br_if 0 (;@5;) i32.const 0 - local.get 5 + i32.load offset=20540 + local.tee 0 + i32.load16_u offset=2 + i32.const 38 + i32.ne + br_if 4 (;@1;) + i32.const 0 + local.get 0 + i32.const 4 + i32.add i32.store offset=20540 - br 1 (;@4;) - end - i32.const 0 - local.get 0 - i32.const 12 - i32.add - i32.store offset=20540 - block ;; label = @5 call 39 - i32.const 46 - i32.eq - br_if 0 (;@5;) + i32.const 33 + i32.ne + br_if 4 (;@1;) i32.const 0 - local.get 5 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add i32.store offset=20540 - br 1 (;@4;) - end - i32.const 0 - i32.const 0 - i32.load offset=20540 - i32.const 2 - i32.add - i32.store offset=20540 - call 39 - i32.const 112 - i32.ne - br_if 3 (;@1;) - i32.const 0 - i32.load offset=20540 - local.tee 0 - i32.const 2 - i32.add - i32.const 114 - i32.const 111 - i32.const 116 - i32.const 111 - i32.const 116 - i32.const 121 - i32.const 112 - i32.const 101 - call 51 - i32.eqz - br_if 3 (;@1;) - i32.const 0 - local.get 0 - i32.const 18 - i32.add - i32.store offset=20540 - call 39 - i32.const 46 - i32.ne - br_if 3 (;@1;) - i32.const 0 - i32.const 0 - i32.load offset=20540 - i32.const 2 - i32.add - i32.store offset=20540 - call 39 - i32.const 104 - i32.ne - br_if 3 (;@1;) - i32.const 0 - i32.load offset=20540 - local.tee 0 - i32.const 2 - i32.add - i32.const 97 - i32.const 115 - i32.const 79 - i32.const 119 - i32.const 110 - i32.const 80 - i32.const 114 - i32.const 111 - i32.const 112 - i32.const 101 - i32.const 114 - i32.const 116 - i32.const 121 - call 47 - i32.eqz - br_if 3 (;@1;) - i32.const 0 - local.get 0 - i32.const 28 - i32.add - i32.store offset=20540 - call 39 - i32.const 46 - i32.ne - br_if 3 (;@1;) - i32.const 0 - i32.const 0 - i32.load offset=20540 - i32.const 2 - i32.add - i32.store offset=20540 - call 39 - i32.const 99 - i32.ne - br_if 3 (;@1;) - i32.const 0 - i32.load offset=20540 - local.tee 0 - i32.load16_u offset=2 - i32.const 97 - i32.ne - br_if 3 (;@1;) - local.get 0 - i32.load16_u offset=4 - i32.const 108 - i32.ne - br_if 3 (;@1;) - local.get 0 - i32.load16_u offset=6 - i32.const 108 - i32.ne - br_if 3 (;@1;) - i32.const 0 - local.get 0 - i32.const 8 - i32.add - i32.store offset=20540 - call 39 - i32.const 40 - i32.ne - br_if 3 (;@1;) - i32.const 0 - i32.const 0 - i32.load offset=20540 - i32.const 2 - i32.add - i32.store offset=20540 - call 39 - call 45 - i32.eqz - br_if 3 (;@1;) - call 39 - i32.const 44 + call 39 + drop + block ;; label = @6 + block ;; label = @7 + i32.const 0 + i32.load offset=20540 + local.tee 0 + local.get 2 + local.get 6 + call 65 + br_if 0 (;@7;) + i32.const 0 + local.get 0 + local.get 7 + i32.const 1 + i32.shl + i32.add + i32.store offset=20540 + call 39 + i32.const 46 + i32.ne + br_if 6 (;@1;) + i32.const 0 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add + i32.store offset=20540 + call 39 + i32.const 104 + i32.ne + br_if 6 (;@1;) + i32.const 0 + i32.load offset=20540 + local.tee 0 + i32.const 2 + i32.add + i32.const 97 + i32.const 115 + i32.const 79 + i32.const 119 + i32.const 110 + i32.const 80 + i32.const 114 + i32.const 111 + i32.const 112 + i32.const 101 + i32.const 114 + i32.const 116 + i32.const 121 + call 47 + i32.eqz + br_if 6 (;@1;) + i32.const 0 + local.get 0 + i32.const 28 + i32.add + i32.store offset=20540 + call 39 + i32.const 40 + i32.ne + br_if 6 (;@1;) + i32.const 0 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add + i32.store offset=20540 + call 39 + drop + i32.const 0 + i32.load offset=20540 + local.tee 0 + local.get 4 + local.get 3 + call 65 + br_if 6 (;@1;) + i32.const 0 + local.get 0 + local.get 8 + i32.const 1 + i32.shl + i32.add + i32.store offset=20540 + call 39 + i32.const 41 + i32.ne + br_if 6 (;@1;) + i32.const 0 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add + i32.store offset=20540 + br 1 (;@6;) + end + local.get 4 + local.get 8 + call 51 + i32.eqz + br_if 5 (;@1;) + end + call 39 + local.set 0 + end + local.get 0 + i32.const 41 i32.ne br_if 3 (;@1;) - i32.const 0 - i32.const 0 - i32.load offset=20540 - i32.const 2 - i32.add - i32.store offset=20540 - call 39 - drop + end + i32.const 0 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add + i32.store offset=20540 + end + block ;; label = @3 + call 39 + local.tee 0 + i32.const 105 + i32.ne + br_if 0 (;@3;) + block ;; label = @4 i32.const 0 i32.load offset=20540 - local.tee 0 - local.get 4 - local.get 3 - call 64 - br_if 3 (;@1;) + local.tee 5 + i32.load16_u offset=2 + i32.const 102 + i32.ne + br_if 0 (;@4;) i32.const 0 - local.get 0 - local.get 6 - i32.const 1 - i32.shl + local.get 5 + i32.const 4 i32.add i32.store offset=20540 call 39 - i32.const 41 + i32.const 40 i32.ne br_if 3 (;@1;) i32.const 0 @@ -2756,6 +2693,16 @@ i32.const 2 i32.add i32.store offset=20540 + block ;; label = @5 + local.get 4 + local.get 8 + call 51 + br_if 0 (;@5;) + i32.const 0 + local.get 5 + i32.store offset=20540 + br 1 (;@4;) + end call 39 i32.const 41 i32.ne @@ -2838,11 +2785,11 @@ local.tee 0 local.get 4 local.get 3 - call 64 + call 65 br_if 2 (;@1;) i32.const 0 local.get 0 - local.get 6 + local.get 8 i32.const 1 i32.shl i32.add @@ -2909,11 +2856,11 @@ local.tee 0 local.get 4 local.get 3 - call 64 + call 65 br_if 2 (;@1;) i32.const 0 local.get 0 - local.get 6 + local.get 8 i32.const 1 i32.shl i32.add @@ -2955,12 +2902,12 @@ i32.load offset=20540 local.tee 0 local.get 2 - local.get 7 - call 64 + local.get 6 + call 65 br_if 2 (;@1;) i32.const 0 local.get 0 - local.get 8 + local.get 7 i32.const 1 i32.shl i32.add @@ -2982,11 +2929,11 @@ local.tee 0 local.get 4 local.get 3 - call 64 + call 65 br_if 2 (;@1;) i32.const 0 local.get 0 - local.get 6 + local.get 8 i32.const 1 i32.shl i32.add @@ -3072,11 +3019,11 @@ local.tee 0 local.get 4 local.get 3 - call 64 + call 65 br_if 4 (;@1;) i32.const 0 local.get 0 - local.get 6 + local.get 8 i32.const 1 i32.shl i32.add @@ -3107,12 +3054,12 @@ i32.load offset=20540 local.tee 0 local.get 2 - local.get 7 - call 64 + local.get 6 + call 65 br_if 4 (;@1;) i32.const 0 local.get 0 - local.get 8 + local.get 7 i32.const 1 i32.shl i32.add @@ -3134,11 +3081,11 @@ local.tee 0 local.get 4 local.get 3 - call 64 + call 65 br_if 4 (;@1;) i32.const 0 local.get 0 - local.get 6 + local.get 8 i32.const 1 i32.shl i32.add @@ -3259,11 +3206,11 @@ local.tee 0 local.get 4 local.get 3 - call 64 + call 65 br_if 3 (;@1;) i32.const 0 local.get 0 - local.get 6 + local.get 8 i32.const 1 i32.shl i32.add @@ -3478,12 +3425,12 @@ i32.load offset=20540 local.tee 0 local.get 2 - local.get 7 - call 64 + local.get 6 + call 65 br_if 3 (;@1;) i32.const 0 local.get 0 - local.get 8 + local.get 7 i32.const 1 i32.shl i32.add @@ -3505,11 +3452,11 @@ local.tee 0 local.get 4 local.get 3 - call 64 + call 65 br_if 3 (;@1;) i32.const 0 local.get 0 - local.get 6 + local.get 8 i32.const 1 i32.shl i32.add @@ -3625,7 +3572,7 @@ local.get 0 i32.eq br_if 0 (;@5;) - local.get 8 + local.get 7 local.get 0 i32.const 12 i32.add @@ -3642,8 +3589,8 @@ br_if 1 (;@4;) local.get 2 local.get 3 - local.get 7 - call 64 + local.get 6 + call 65 br_if 1 (;@4;) local.get 0 i32.load @@ -4314,7 +4261,7 @@ i32.store offset=20540 br 1 (;@1;) end - call 63 + call 64 drop br 0 (;@1;) end) @@ -4675,7 +4622,7 @@ i32.ne br_if 0 (;@2;) local.get 1 - call 62 + call 63 i32.eqz br_if 1 (;@1;) end @@ -4866,7 +4813,7 @@ i32.const 46 i32.ne local.get 0 - call 62 + call 63 i32.and local.set 1 end @@ -5214,7 +5161,7 @@ (func (;45;) (type 2) (param i32) (result i32) (local i32 i32) local.get 0 - call 61 + call 62 local.tee 0 call 42 local.set 1 @@ -5247,7 +5194,7 @@ i32.store offset=20540 local.get 0 i32.load16_u - call 61 + call 62 local.tee 1 i32.eqz br_if 1 (;@2;) @@ -5672,142 +5619,319 @@ local.get 3 i32.ne br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=6 - local.get 4 - i32.ne - br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=8 - local.get 5 - i32.ne - br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=10 - local.get 6 - i32.ne - br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=12 - local.get 7 - i32.ne + local.get 0 + i32.load16_u offset=6 + local.get 4 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=8 + local.get 5 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=10 + local.get 6 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=12 + local.get 7 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=14 + local.get 8 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=16 + local.get 9 + i32.eq + local.set 10 + end + local.get 10) + (func (;50;) (type 12) (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 11 + block ;; label = @1 + local.get 0 + i32.load16_u + local.get 1 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=2 + local.get 2 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=4 + local.get 3 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=6 + local.get 4 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=8 + local.get 5 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=10 + local.get 6 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=12 + local.get 7 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=14 + local.get 8 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=16 + local.get 9 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=18 + local.get 10 + i32.eq + local.set 11 + end + local.get 11) + (func (;51;) (type 13) (param i32 i32) (result i32) + (local i32 i32) + i32.const 0 + local.set 2 + block ;; label = @1 + call 39 + i32.const 79 + i32.ne + br_if 0 (;@1;) + i32.const 0 + local.set 2 + i32.const 0 + i32.load offset=20540 + local.tee 3 + i32.const 2 + i32.add + i32.const 98 + i32.const 106 + i32.const 101 + i32.const 99 + i32.const 116 + call 19 + i32.eqz + br_if 0 (;@1;) + i32.const 0 + local.set 2 + i32.const 0 + local.get 3 + i32.const 12 + i32.add + i32.store offset=20540 + call 39 + i32.const 46 + i32.ne + br_if 0 (;@1;) + i32.const 0 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add + i32.store offset=20540 + block ;; label = @2 + call 39 + local.tee 3 + i32.const 112 + i32.ne + br_if 0 (;@2;) + i32.const 0 + local.set 2 + i32.const 0 + i32.load offset=20540 + local.tee 3 + i32.const 2 + i32.add + i32.const 114 + i32.const 111 + i32.const 116 + i32.const 111 + i32.const 116 + i32.const 121 + i32.const 112 + i32.const 101 + call 61 + i32.eqz + br_if 1 (;@1;) + i32.const 0 + local.set 2 + i32.const 0 + local.get 3 + i32.const 18 + i32.add + i32.store offset=20540 + call 39 + i32.const 46 + i32.ne + br_if 1 (;@1;) + i32.const 0 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add + i32.store offset=20540 + call 39 + local.set 3 + end + i32.const 0 + local.set 2 + local.get 3 + i32.const 104 + i32.ne + br_if 0 (;@1;) + i32.const 0 + local.set 2 + i32.const 0 + i32.load offset=20540 + local.tee 3 + i32.const 2 + i32.add + i32.const 97 + i32.const 115 + i32.const 79 + i32.const 119 + i32.const 110 + i32.const 80 + i32.const 114 + i32.const 111 + i32.const 112 + i32.const 101 + i32.const 114 + i32.const 116 + i32.const 121 + call 47 + i32.eqz br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=14 - local.get 8 + i32.const 0 + local.set 2 + i32.const 0 + local.get 3 + i32.const 28 + i32.add + i32.store offset=20540 + call 39 + i32.const 46 i32.ne br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=16 - local.get 9 - i32.eq - local.set 10 - end - local.get 10) - (func (;50;) (type 12) (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) - (local i32) - i32.const 0 - local.set 11 - block ;; label = @1 - local.get 0 - i32.load16_u - local.get 1 + i32.const 0 + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add + i32.store offset=20540 + call 39 + i32.const 99 i32.ne br_if 0 (;@1;) - local.get 0 + i32.const 0 + local.set 2 + i32.const 0 + i32.load offset=20540 + local.tee 3 i32.load16_u offset=2 - local.get 2 + i32.const 97 i32.ne br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=4 local.get 3 + i32.load16_u offset=4 + i32.const 108 i32.ne br_if 0 (;@1;) - local.get 0 + local.get 3 i32.load16_u offset=6 - local.get 4 - i32.ne - br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=8 - local.get 5 - i32.ne - br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=10 - local.get 6 + i32.const 108 i32.ne br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=12 - local.get 7 + i32.const 0 + local.set 2 + i32.const 0 + local.get 3 + i32.const 8 + i32.add + i32.store offset=20540 + call 39 + i32.const 40 i32.ne br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=14 - local.get 8 - i32.ne + i32.const 0 + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add + i32.store offset=20540 + call 39 + call 45 + i32.eqz br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=16 - local.get 9 + call 39 + i32.const 44 i32.ne br_if 0 (;@1;) + i32.const 0 + local.set 2 + i32.const 0 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add + i32.store offset=20540 + call 39 + drop + i32.const 0 + i32.load offset=20540 + local.tee 3 local.get 0 - i32.load16_u offset=18 - local.get 10 - i32.eq - local.set 11 - end - local.get 11) - (func (;51;) (type 13) (param i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) - (local i32) - i32.const 0 - local.set 9 - block ;; label = @1 - local.get 0 - i32.load16_u local.get 1 - i32.ne - br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=2 - local.get 2 - i32.ne + i32.const 1 + i32.shl + local.tee 1 + call 65 br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=4 + i32.const 0 + local.set 2 + i32.const 0 local.get 3 + local.get 1 + i32.add + i32.store offset=20540 + call 39 + i32.const 41 i32.ne br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=6 - local.get 4 - i32.ne - br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=8 - local.get 5 - i32.ne - br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=10 - local.get 6 - i32.ne - br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=12 - local.get 7 - i32.ne - br_if 0 (;@1;) - local.get 0 - i32.load16_u offset=14 - local.get 8 - i32.eq - local.set 9 + i32.const 0 + i32.const 0 + i32.load offset=20540 + i32.const 2 + i32.add + i32.store offset=20540 + i32.const 1 + local.set 2 end - local.get 9) + local.get 2) (func (;52;) (type 4) (param i32 i32 i32 i32 i32 i32) (result i32) (local i32 i32 i32) i32.const 0 @@ -5934,7 +6058,7 @@ local.set 7 end local.get 7) - (func (;55;) (type 15) (param i32 i32) (result i32) + (func (;55;) (type 13) (param i32 i32) (result i32) (local i32 i32) i32.const 0 local.set 2 @@ -9319,7 +9443,54 @@ return end i32.const 1) - (func (;61;) (type 2) (param i32) (result i32) + (func (;61;) (type 15) (param i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) + (local i32) + i32.const 0 + local.set 9 + block ;; label = @1 + local.get 0 + i32.load16_u + local.get 1 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=2 + local.get 2 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=4 + local.get 3 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=6 + local.get 4 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=8 + local.get 5 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=10 + local.get 6 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=12 + local.get 7 + i32.ne + br_if 0 (;@1;) + local.get 0 + i32.load16_u offset=14 + local.get 8 + i32.eq + local.set 9 + end + local.get 9) + (func (;62;) (type 2) (param i32) (result i32) block ;; label = @1 local.get 0 i32.const 64512 @@ -9343,7 +9514,7 @@ local.set 0 end local.get 0) - (func (;62;) (type 2) (param i32) (result i32) + (func (;63;) (type 2) (param i32) (result i32) (local i32 i32) i32.const 1 local.set 1 @@ -9400,7 +9571,7 @@ local.set 1 end local.get 1) - (func (;63;) (type 3) (result i32) + (func (;64;) (type 3) (result i32) (local i32 i32 i32 i32 i32) i32.const 0 i32.load offset=20540 @@ -9466,7 +9637,7 @@ local.set 0 br 0 (;@1;) end) - (func (;64;) (type 8) (param i32 i32 i32) (result i32) + (func (;65;) (type 8) (param i32 i32 i32) (result i32) (local i32 i32 i32) i32.const 0 local.set 3 diff --git a/src/lexer.c b/src/lexer.c index 32c1d63..ef972fb 100755 --- a/src/lexer.c +++ b/src/lexer.c @@ -267,6 +267,47 @@ void tryBacktrackAddStarExportBinding (uint16_t* bPos) { } } +bool tryParseObjectHasOwnProperty (uint16_t* it_id_start, ptrdiff_t it_id_len) { + uint16_t ch = commentWhitespace(); + if (ch != 'O' || !str_eq5(pos + 1, 'b', 'j', 'e', 'c', 't')) return false; + pos += 6; + ch = commentWhitespace(); + if (ch != '.') return false; + pos++; + ch = commentWhitespace(); + if (ch == 'p') { + if (!str_eq8(pos + 1, 'r', 'o', 't', 'o', 't', 'y', 'p', 'e')) return false; + pos += 9; + ch = commentWhitespace(); + if (ch != '.') return false; + pos++; + ch = commentWhitespace(); + } + if (ch != 'h' || !str_eq13(pos + 1, 'a', 's', 'O', 'w', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y')) return false; + pos += 14; + ch = commentWhitespace(); + if (ch != '.') return false; + pos++; + ch = commentWhitespace(); + if (ch != 'c' || !str_eq3(pos + 1, 'a', 'l', 'l')) return false; + pos += 4; + ch = commentWhitespace(); + if (ch != '(') return false; + pos++; + ch = commentWhitespace(); + if (!identifier(ch)) return false; + ch = commentWhitespace(); + if (ch != ',') return false; + pos++; + ch = commentWhitespace(); + if (memcmp(pos, it_id_start, it_id_len * sizeof(uint16_t)) != 0) return false; + pos += it_id_len; + ch = commentWhitespace(); + if (ch != ')') return false; + pos++; + return true; +} + void tryParseObjectDefineOrKeys (bool keys) { pos += 6; uint16_t* revertPos = pos - 1; @@ -488,7 +529,7 @@ void tryParseObjectDefineOrKeys (bool keys) { pos++; ch = commentWhitespace(); } - // `if (` IDENTIFIER$2 `!==` ( `'default'` | `"default"` ) `)` + // `if (` IDENTIFIER$2 `!==` ( `'default'` | `"default"` ) (`&& !` IDENTIFIER `.hasOwnProperty(` IDENTIFIER$2 `)` )? `)` else if (ch == '!') { if (!str_eq2(pos + 1, '=', '=')) break; pos += 3; @@ -501,6 +542,34 @@ void tryParseObjectDefineOrKeys (bool keys) { if (ch != quot) break; pos += 1; ch = commentWhitespace(); + if (ch == '&') { + if (*(pos + 1) != '&') break; + pos += 2; + ch = commentWhitespace(); + if (ch != '!') break; + pos += 1; + ch = commentWhitespace(); + if (memcmp(pos, id_start, id_len * sizeof(uint16_t)) == 0) { + pos += id_len; + ch = commentWhitespace(); + if (ch != '.') break; + pos++; + ch = commentWhitespace(); + if (ch != 'h' || !str_eq13(pos + 1, 'a', 's', 'O', 'w', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y')) break; + pos += 14; + ch = commentWhitespace(); + if (ch != '(') break; + pos += 1; + ch = commentWhitespace(); + if (memcmp(pos, it_id_start, it_id_len * sizeof(uint16_t)) != 0) break; + pos += it_id_len; + ch = commentWhitespace(); + if (ch != ')') break; + pos += 1; + } + else if (!tryParseObjectHasOwnProperty(it_id_start, it_id_len)) break; + ch = commentWhitespace(); + } if (ch != ')') break; pos += 1; ch = commentWhitespace(); @@ -511,58 +580,17 @@ void tryParseObjectDefineOrKeys (bool keys) { // `if (Object.prototype.hasOwnProperty.call(` IDENTIFIER `, ` IDENTIFIER$2 `)) return` `;`? if (ch == 'i' && *(pos + 1) == 'f') { uint16_t *ifStartPos = pos; - pos += 2; ch = commentWhitespace(); if (ch != '(') break; pos++; - ch = commentWhitespace(); - if (ch != 'O' || !str_eq5(pos + 1, 'b', 'j', 'e', 'c', 't')) { + if (!tryParseObjectHasOwnProperty(it_id_start, it_id_len)) { // Revert parsing the current optional if statement, but don't bail // out since we can try parse the next possible if statement. pos = ifStartPos; ch = 'i'; goto currentIfStatementEnd; } - pos += 6; - ch = commentWhitespace(); - if (ch != '.') { - // Revert parsing the current optional if statement, but don't bail - // out since we can try parse the next possible if statement. - pos = ifStartPos; - ch = 'i'; - goto currentIfStatementEnd; - } - pos++; - ch = commentWhitespace(); - if (ch != 'p' || !str_eq8(pos + 1, 'r', 'o', 't', 'o', 't', 'y', 'p', 'e')) break; - pos += 9; - ch = commentWhitespace(); - if (ch != '.') break; - pos++; - ch = commentWhitespace(); - if (ch != 'h' || !str_eq13(pos + 1, 'a', 's', 'O', 'w', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y')) break; - pos += 14; - ch = commentWhitespace(); - if (ch != '.') break; - pos++; - ch = commentWhitespace(); - if (ch != 'c' || !str_eq3(pos + 1, 'a', 'l', 'l')) break; - pos += 4; - ch = commentWhitespace(); - if (ch != '(') break; - pos++; - ch = commentWhitespace(); - if (!identifier(ch)) break; - ch = commentWhitespace(); - if (ch != ',') break; - pos++; - ch = commentWhitespace(); - if (memcmp(pos, it_id_start, it_id_len * sizeof(uint16_t)) != 0) break; - pos += it_id_len; - ch = commentWhitespace(); - if (ch != ')') break; - pos++; ch = commentWhitespace(); if (ch != ')') break; pos++; diff --git a/test/_unit.js b/test/_unit.js index c0dc8a2..9a6d505 100755 --- a/test/_unit.js +++ b/test/_unit.js @@ -209,6 +209,16 @@ suite('Lexer', () => { if (k !== 'default') exports[k] = externalǽ[k]; }); + let external5 = require('e5'); + let external6 = require('e6'); + Object.keys(external5).forEach(function (k) { + if (k !== 'default' && !Object.hasOwnProperty.call(exports, k)) exports[k] = external5[k]; + }); + + Object.keys(external6).forEach(function (k) { + if (k !== 'default' && !external6.hasOwnProperty(k)) exports[k] = external6[k]; + }); + const external𤭢 = require('external𤭢'); Object.keys(external𤭢).forEach(function (k) { if (k !== 'default') exports[k] = external𤭢[k]; @@ -316,7 +326,7 @@ suite('Lexer', () => { `); assert.equal(exports.length, 1); assert.equal(exports[0], '__esModule'); - assert.equal(reexports.length, 10); + assert.equal(reexports.length, 12); assert.equal(reexports[0], 'external'); assert.equal(reexports[1], 'external2'); assert.equal(reexports[2], 'external001'); @@ -326,7 +336,9 @@ suite('Lexer', () => { assert.equal(reexports[6], 'external3'); assert.equal(reexports[7], 'external4'); assert.equal(reexports[8], 'external😃'); - assert.equal(reexports[9], 'external𤭢'); + assert.equal(reexports[9], 'e5'); + assert.equal(reexports[10], 'e6'); + assert.equal(reexports[11], 'external𤭢'); }); test('invalid exports cases', () => {