Diff
Modified: trunk/JSTests/ChangeLog (220067 => 220068)
--- trunk/JSTests/ChangeLog 2017-07-31 15:13:26 UTC (rev 220067)
+++ trunk/JSTests/ChangeLog 2017-07-31 16:15:32 UTC (rev 220068)
@@ -1,3 +1,18 @@
+2017-07-31 Yusuke Suzuki <utatane....@gmail.com>
+
+ [JSC] Support optional catch binding
+ https://bugs.webkit.org/show_bug.cgi?id=174981
+
+ Reviewed by Saam Barati.
+
+ * stress/optional-catch-binding-syntax.js: Added.
+ (testSyntax):
+ (testSyntaxError):
+ (catch.catch):
+ * stress/optional-catch-binding.js: Added.
+ (shouldBe):
+ (throwException):
+
2017-07-28 Mark Lam <mark....@apple.com>
ObjectToStringAdaptiveStructureWatchpoint should not fire if it's dying imminently.
Added: trunk/JSTests/stress/optional-catch-binding-syntax.js (0 => 220068)
--- trunk/JSTests/stress/optional-catch-binding-syntax.js (rev 0)
+++ trunk/JSTests/stress/optional-catch-binding-syntax.js 2017-07-31 16:15:32 UTC (rev 220068)
@@ -0,0 +1,30 @@
+function testSyntax(script) {
+ try {
+ eval(script);
+ } catch (error) {
+ if (error instanceof SyntaxError)
+ throw new Error("Bad error: " + String(error));
+ }
+}
+
+function testSyntaxError(script, message) {
+ var error = null;
+ try {
+ eval(script);
+ } catch (e) {
+ error = e;
+ }
+ if (!error)
+ throw new Error("Expected syntax error not thrown");
+
+ if (String(error) !== message)
+ throw new Error("Bad error: " + String(error));
+}
+
+testSyntax(`try { } catch { }`);
+testSyntax(`try { } catch { } finally { }`);
+testSyntaxError(`try { } catch { { }`, `SyntaxError: Unexpected end of script`);
+testSyntaxError(`try { } catch () { }`, `SyntaxError: Unexpected token ')'. Expected a parameter pattern or a ')' in parameter list.`);
+testSyntaxError(`try { } catch }`, `SyntaxError: Unexpected token '}'. Expected '(' to start a 'catch' target.`);
+testSyntaxError(`try { } catch {`, `SyntaxError: Unexpected end of script`);
+testSyntaxError(`try { } catch {`, `SyntaxError: Unexpected end of script`);
Added: trunk/JSTests/stress/optional-catch-binding.js (0 => 220068)
--- trunk/JSTests/stress/optional-catch-binding.js (rev 0)
+++ trunk/JSTests/stress/optional-catch-binding.js 2017-07-31 16:15:32 UTC (rev 220068)
@@ -0,0 +1,50 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+function throwException() {
+ throw new Error(`Cocoa`);
+}
+
+shouldBe(function () {
+ try {
+ throwException();
+ } catch {
+ return true;
+ }
+ return false;
+}(), true);
+
+shouldBe(function () {
+ var ok = false;
+ try {
+ throwException();
+ } catch {
+ ok = true;
+ return false;
+ } finally {
+ return ok;
+ }
+ return false;
+}(), true);
+
+shouldBe(function () {
+ let value = 'Cocoa';
+ try {
+ throwException();
+ } catch {
+ let value = 'Cappuccino';
+ return value;
+ }
+}(), 'Cappuccino');
+
+shouldBe(function () {
+ var value = 'Cocoa';
+ try {
+ throwException();
+ } catch {
+ let value = 'Cappuccino';
+ }
+ return value;
+}(), 'Cocoa');
Modified: trunk/LayoutTests/ChangeLog (220067 => 220068)
--- trunk/LayoutTests/ChangeLog 2017-07-31 15:13:26 UTC (rev 220067)
+++ trunk/LayoutTests/ChangeLog 2017-07-31 16:15:32 UTC (rev 220068)
@@ -1,3 +1,17 @@
+2017-07-31 Yusuke Suzuki <utatane....@gmail.com>
+
+ [JSC] Support optional catch binding
+ https://bugs.webkit.org/show_bug.cgi?id=174981
+
+ Reviewed by Saam Barati.
+
+ Rebaseline existing tests.
+
+ * js/parser-syntax-check-expected.txt:
+ * js/script-tests/parser-syntax-check.js:
+ * sputnik/Conformance/12_Statement/12.14_The_try_Statement/S12.14_A16_T4-expected.txt:
+ * sputnik/Conformance/12_Statement/12.14_The_try_Statement/S12.14_A16_T4.html:
+
2017-07-31 Per Arne Vollan <pvol...@apple.com>
Many web-platform tests are slow on Windows.
Modified: trunk/LayoutTests/js/parser-syntax-check-expected.txt (220067 => 220068)
--- trunk/LayoutTests/js/parser-syntax-check-expected.txt 2017-07-31 15:13:26 UTC (rev 220067)
+++ trunk/LayoutTests/js/parser-syntax-check-expected.txt 2017-07-31 16:15:32 UTC (rev 220068)
@@ -631,8 +631,8 @@
PASS Invalid: "function f() { try {} finally {} catch(e) {} }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'catch'"
PASS Invalid: "try {} catch (...) {}". Produced the following syntax error: "SyntaxError: Unexpected token '...'. Expected a parameter pattern or a ')' in parameter list."
PASS Invalid: "function f() { try {} catch (...) {} }". Produced the following syntax error: "SyntaxError: Unexpected token '...'. Expected a parameter pattern or a ')' in parameter list."
-PASS Invalid: "try {} catch {}". Produced the following syntax error: "SyntaxError: Unexpected token '{'. Expected '(' to start a 'catch' target."
-PASS Invalid: "function f() { try {} catch {} }". Produced the following syntax error: "SyntaxError: Unexpected token '{'. Expected '(' to start a 'catch' target."
+PASS Valid: "try {} catch {}"
+PASS Valid: "function f() { try {} catch {} }"
PASS Valid: "if (a) try {} finally {} else b;"
PASS Valid: "function f() { if (a) try {} finally {} else b; }"
PASS Valid: "if (--a()) do with(1) try {} catch(ke) { f() ; g() } while (a in b) else {}" with ReferenceError
Modified: trunk/LayoutTests/js/script-tests/parser-syntax-check.js (220067 => 220068)
--- trunk/LayoutTests/js/script-tests/parser-syntax-check.js 2017-07-31 15:13:26 UTC (rev 220067)
+++ trunk/LayoutTests/js/script-tests/parser-syntax-check.js 2017-07-31 16:15:32 UTC (rev 220068)
@@ -411,7 +411,7 @@
invalid("try {} finally");
invalid("try {} finally {} catch(e) {}");
invalid("try {} catch (...) {}");
-invalid("try {} catch {}");
+valid ("try {} catch {}");
valid ("if (a) try {} finally {} else b;");
valid ("if (--a()) do with(1) try {} catch(ke) { f() ; g() } while (a in b) else {}");
invalid("if (a) try {} else b; catch (e) { }");
Modified: trunk/LayoutTests/sputnik/Conformance/12_Statement/12.14_The_try_Statement/S12.14_A16_T4-expected.txt (220067 => 220068)
--- trunk/LayoutTests/sputnik/Conformance/12_Statement/12.14_The_try_Statement/S12.14_A16_T4-expected.txt 2017-07-31 15:13:26 UTC (rev 220067)
+++ trunk/LayoutTests/sputnik/Conformance/12_Statement/12.14_The_try_Statement/S12.14_A16_T4-expected.txt 2017-07-31 16:15:32 UTC (rev 220068)
@@ -1,7 +1,6 @@
-CONSOLE MESSAGE: line 78: SyntaxError: Unexpected token '{'. Expected '(' to start a 'catch' target.
S12.14_A16_T4
-PASS Expected parsing failure
+PASS No error detected
TEST COMPLETE
Modified: trunk/LayoutTests/sputnik/Conformance/12_Statement/12.14_The_try_Statement/S12.14_A16_T4.html (220067 => 220068)
--- trunk/LayoutTests/sputnik/Conformance/12_Statement/12.14_The_try_Statement/S12.14_A16_T4.html 2017-07-31 15:13:26 UTC (rev 220067)
+++ trunk/LayoutTests/sputnik/Conformance/12_Statement/12.14_The_try_Statement/S12.14_A16_T4.html 2017-07-31 16:15:32 UTC (rev 220068)
@@ -86,11 +86,11 @@
<script>
if (!successfullyParsed)
- printTestPassed('Expected parsing failure');
+ printTestFailed('Expected parsing failure');
else if (sputnikException)
- printTestPassed(sputnikException);
+ printTestFailed(sputnikException);
else
- printTestFailed("No error detected");
+ printTestPassed("No error detected");
testPrint('<br /><span class="pass">TEST COMPLETE</span>');
</script>
</body>
Modified: trunk/Source/_javascript_Core/ChangeLog (220067 => 220068)
--- trunk/Source/_javascript_Core/ChangeLog 2017-07-31 15:13:26 UTC (rev 220067)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-07-31 16:15:32 UTC (rev 220068)
@@ -1,5 +1,48 @@
2017-07-31 Yusuke Suzuki <utatane....@gmail.com>
+ [JSC] Support optional catch binding
+ https://bugs.webkit.org/show_bug.cgi?id=174981
+
+ Reviewed by Saam Barati.
+
+ This patch implements optional catch binding proposal[1], which is now stage 3.
+ This proposal adds a new `catch` brace with no error value binding.
+
+ ```
+ try {
+ ...
+ } catch {
+ ...
+ }
+ ```
+
+ Sometimes we do not need to get error value actually. For example, the function returns
+ boolean which means whether the function succeeds.
+
+ ```
+ function parse(result) // -> bool
+ {
+ try {
+ parseInner(result);
+ } catch {
+ return false;
+ }
+ return true;
+ }
+ ```
+
+ In the above case, we are not interested in the actual error value. Without this syntax,
+ we always need to introduce a binding for an error value that is just ignored.
+
+ [1]: https://michaelficarra.github.io/optional-catch-binding-proposal/
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::TryNode::emitBytecode):
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::parseTryStatement):
+
+2017-07-31 Yusuke Suzuki <utatane....@gmail.com>
+
Merge WTFThreadData to Thread::current
https://bugs.webkit.org/show_bug.cgi?id=174716
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (220067 => 220068)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-07-31 15:13:26 UTC (rev 220067)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-07-31 16:15:32 UTC (rev 220068)
@@ -3413,8 +3413,11 @@
tryData = generator.pushTry(*catchLabel, *finallyViaThrowLabel, HandlerType::Finally);
}
- generator.emitPushCatchScope(m_lexicalVariables);
- m_catchPattern->bindValue(generator, thrownValueRegister.get());
+ if (m_catchPattern) {
+ generator.emitPushCatchScope(m_lexicalVariables);
+ m_catchPattern->bindValue(generator, thrownValueRegister.get());
+ }
+
generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
if (m_finallyBlock)
generator.emitNode(dst, m_catchBlock);
@@ -3421,8 +3424,10 @@
else
generator.emitNodeInTailPosition(dst, m_catchBlock);
generator.emitLoad(thrownValueRegister.get(), jsUndefined());
- generator.emitPopCatchScope(m_lexicalVariables);
+ if (m_catchPattern)
+ generator.emitPopCatchScope(m_lexicalVariables);
+
if (m_finallyBlock) {
generator.emitSetCompletionType(CompletionType::Normal);
generator.emitJump(*finallyLabel);
Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (220067 => 220068)
--- trunk/Source/_javascript_Core/parser/Parser.cpp 2017-07-31 15:13:26 UTC (rev 220067)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp 2017-07-31 16:15:32 UTC (rev 220068)
@@ -1633,27 +1633,32 @@
if (match(CATCH)) {
next();
- handleProductionOrFail(OPENPAREN, "(", "start", "'catch' target");
- AutoPopScopeRef catchScope(this, pushScope());
- catchScope->setIsLexicalScope();
- catchScope->preventVarDeclarations();
- const Identifier* ident = nullptr;
- if (matchSpecIdentifier()) {
- ident = m_token.m_data.ident;
- catchPattern = context.createBindingLocation(m_token.m_location, *ident, m_token.m_startPosition, m_token.m_endPosition, AssignmentContext::DeclarationStatement);
- next();
- failIfTrueIfStrict(catchScope->declareLexicalVariable(ident, false) & DeclarationResult::InvalidStrictMode, "Cannot declare a catch variable named '", ident->impl(), "' in strict mode");
+ if (match(OPENBRACE)) {
+ catchBlock = parseBlockStatement(context);
+ failIfFalse(catchBlock, "Unable to parse 'catch' block");
} else {
- catchPattern = parseDestructuringPattern(context, DestructuringKind::DestructureToCatchParameters, ExportType::NotExported);
- failIfFalse(catchPattern, "Cannot parse this destructuring pattern");
+ handleProductionOrFail(OPENPAREN, "(", "start", "'catch' target");
+ AutoPopScopeRef catchScope(this, pushScope());
+ catchScope->setIsLexicalScope();
+ catchScope->preventVarDeclarations();
+ const Identifier* ident = nullptr;
+ if (matchSpecIdentifier()) {
+ ident = m_token.m_data.ident;
+ catchPattern = context.createBindingLocation(m_token.m_location, *ident, m_token.m_startPosition, m_token.m_endPosition, AssignmentContext::DeclarationStatement);
+ next();
+ failIfTrueIfStrict(catchScope->declareLexicalVariable(ident, false) & DeclarationResult::InvalidStrictMode, "Cannot declare a catch variable named '", ident->impl(), "' in strict mode");
+ } else {
+ catchPattern = parseDestructuringPattern(context, DestructuringKind::DestructureToCatchParameters, ExportType::NotExported);
+ failIfFalse(catchPattern, "Cannot parse this destructuring pattern");
+ }
+ handleProductionOrFail(CLOSEPAREN, ")", "end", "'catch' target");
+ matchOrFail(OPENBRACE, "Expected exception handler to be a block statement");
+ catchBlock = parseBlockStatement(context);
+ failIfFalse(catchBlock, "Unable to parse 'catch' block");
+ catchEnvironment = catchScope->finalizeLexicalEnvironment();
+ RELEASE_ASSERT(!ident || (catchEnvironment.size() == 1 && catchEnvironment.contains(ident->impl())));
+ popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);
}
- handleProductionOrFail(CLOSEPAREN, ")", "end", "'catch' target");
- matchOrFail(OPENBRACE, "Expected exception handler to be a block statement");
- catchBlock = parseBlockStatement(context);
- failIfFalse(catchBlock, "Unable to parse 'catch' block");
- catchEnvironment = catchScope->finalizeLexicalEnvironment();
- RELEASE_ASSERT(!ident || (catchEnvironment.size() == 1 && catchEnvironment.contains(ident->impl())));
- popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);
}
if (match(FINALLY)) {