WebKit Bugzilla
Attachment 348887 Details for
Bug 189014
: [WHLSL] The parser is too slow
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
bug-189014-20180904194151.patch (text/plain), 32.18 KB, created by
Myles C. Maxfield
on 2018-09-04 19:41:52 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2018-09-04 19:41:52 PDT
Size:
32.18 KB
patch
obsolete
>Subversion Revision: 235652 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 9a359a6e7c24a58a51683d3413de4da14bcd4d59..5558242f88d5ce54f423393a187f14093be0cd49 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,51 @@ >+2018-09-04 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] The parser is too slow >+ https://bugs.webkit.org/show_bug.cgi?id=189014 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WebGPUShadingLanguageRI/Lexer.js: >+ (Lexer.prototype.next): >+ (Lexer): >+ * WebGPUShadingLanguageRI/Parse.js: >+ (genericConsume): >+ (genericTest): >+ (consumeEndOfTypeArgs): >+ (parseTerm): >+ (parseTypeArguments): >+ (parseType): >+ (parseTypeDef): >+ (parseCallExpression.let.parseArguments): >+ (isCallExpression): >+ (parseSuffixOperator): >+ (parsePreIncrement): >+ (parsePossibleTernaryConditional): >+ (parsePossibleAssignment): >+ (parsePostIncrement): >+ (genericParseCommaExpression): >+ (parseEffectfulStatement): >+ (parseReturn): >+ (parseBreak): >+ (parseContinue): >+ (parseIfStatement): >+ (parseWhile): >+ (parseFor): >+ (parseDo): >+ (parseVariableDecls): >+ (parseSwitchCase): >+ (parseSwitchStatement): >+ (parseStatement): >+ (parseBlock): >+ (parseFuncName): >+ (parseField): >+ (parseStructType): >+ (parseNativeFunc): >+ (parseNative): >+ (parseRestrictedFuncDef): >+ (parseEnumType): >+ (parse): >+ > 2018-09-04 Wenson Hsieh <wenson_hsieh@apple.com> > > Populate "text/uri-list" with multiple URLs when the pasteboard contains multiple URLs >diff --git a/Tools/WebGPUShadingLanguageRI/Lexer.js b/Tools/WebGPUShadingLanguageRI/Lexer.js >index 956dca336a2a9a3121a277285ae3db76dde72370..f800c118eacd8b30390aa515ab5d43be4e5e649c 100644 >--- a/Tools/WebGPUShadingLanguageRI/Lexer.js >+++ b/Tools/WebGPUShadingLanguageRI/Lexer.js >@@ -73,7 +73,7 @@ class Lexer { > { > return Lexer._textIsIdentifierImpl(text) && !RegExp.rightContext.length; > } >- >+ > next() > { > if (this._stack.length) >@@ -102,7 +102,7 @@ class Lexer { > if (/^\/\*/.test(relevantText)) { > let endIndex = relevantText.search(/\*\//); > if (endIndex < 0) >- this.fail("Unterminated comment"); >+ return this.fail("Unterminated comment"); > this._index += endIndex + 2; > continue; > } >@@ -149,52 +149,44 @@ class Lexer { > let remaining = relevantText.substring(0, 20).split(/\s/)[0]; > if (!remaining.length) > remaining = relevantText.substring(0, 20); >- this.fail("Unrecognized token beginning with: " + remaining); >+ return this.fail("Unrecognized token beginning with: " + remaining); > } > > push(token) > { > this._stack.push(token); > } >- >+ > peek() > { > let result = this.next(); >+ if (result instanceof WSyntaxError) >+ return result; > this.push(result); > return result; > } > > fail(error) > { >- throw new WSyntaxError(this.originString, error); >+ return new WSyntaxError(this.originString, error); > } > > backtrackingScope(callback) > { > let state = this.state; >- try { >- return callback(); >- } catch (e) { >- if (e instanceof WSyntaxError) { >- this.state = state; >- return null; >- } >- throw e; >+ let result = callback(); >+ if (result instanceof WSyntaxError) { >+ this.state = state; >+ return null; > } >+ return result; > } > > testScope(callback) > { > let state = this.state; >- try { >- callback(); >- return true; >- } catch (e) { >- if (e instanceof WSyntaxError) >- return false; >- throw e; >- } finally { >- this.state = state; >- } >+ let result = callback(); >+ this.state = state; >+ return !(result instanceof WSyntaxError); > } > } >diff --git a/Tools/WebGPUShadingLanguageRI/Parse.js b/Tools/WebGPUShadingLanguageRI/Parse.js >index ee4c980f3a1672b68a77ebb48525edd249443a53..b0f349243d0b661644c28229c27c2fa76816b12b 100644 >--- a/Tools/WebGPUShadingLanguageRI/Parse.js >+++ b/Tools/WebGPUShadingLanguageRI/Parse.js >@@ -61,36 +61,48 @@ function parse(program, origin, originKind, lineNumberOffset, text) > // pointers means that we can still allow function call statements - unlike in C, those cannot > // have arbitrary expressions as the callee. The remaining two problems are solved by > // backtracking. In all other respects, this is a simple recursive descent parser. >- >+ > function genericConsume(callback, explanation) > { > let token = lexer.next(); > if (!token) >- lexer.fail("Unexpected end of file"); >+ return lexer.fail("Unexpected end of file"); >+ if (token instanceof WSyntaxError) >+ return token; > if (!callback(token)) >- lexer.fail("Unexpected token: " + token.text + "; expected: " + explanation); >+ return lexer.fail("Unexpected token: " + token.text + "; expected: " + explanation); > return token; > } >- >+ > function consume(...texts) > { > return genericConsume(token => texts.includes(token.text), texts); > } > >+ // NeedsUpdateCallers > function consumeKind(kind) > { > return genericConsume(token => token.kind == kind, kind); > } > >+ // NeedsUpdateCallers > function assertNext(...texts) > { >- lexer.push(consume(...texts)); >+ let result = consume(...texts); >+ if (result instanceof WSyntaxError) >+ return result; >+ lexer.push(result); > } > >+ // NeedsUpdateCallers > function genericTest(callback) > { > let token = lexer.peek(); >- if (token && callback(token)) >+ if (!token) >+ return null; >+ if (token instanceof WSyntaxError) >+ return token; >+ if (callback(token)) > return token; > return null; > } >@@ -104,12 +116,16 @@ function parse(program, origin, originKind, lineNumberOffset, text) > { > return genericTest(token => token.kind == kind); > } >- >+ >+ // NeedsUpdateCallers > function tryConsume(...texts) > { > let result = test(...texts); >- if (result) >- lexer.next(); >+ if (!result) >+ return result; >+ if (result instanceof WSyntaxError) >+ return result; >+ lexer.next(); > return result; > } > >@@ -121,15 +137,20 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return result; > } > >+ // NeedsUpdateCallers > function consumeEndOfTypeArgs() > { > let rightShift = tryConsume(">>"); > if (rightShift) > lexer.push(new LexerToken(lexer, rightShift, rightShift.index, rightShift.kind, ">")); >- else >- consume(">"); >+ else { >+ let result = consume(">"); >+ if (result instanceof WSyntaxError) >+ return result; >+ } > } >- >+ >+ // NeedsUpdateCallers > function parseTerm() > { > let token; >@@ -140,13 +161,13 @@ function parse(program, origin, originKind, lineNumberOffset, text) > if (token = tryConsumeKind("intLiteral")) { > let intVersion = (+token.text) | 0; > if ("" + intVersion !== token.text) >- lexer.fail("Integer literal is not an integer: " + token.text); >+ return lexer.fail("Integer literal is not an integer: " + token.text); > return new IntLiteral(token, intVersion); > } > if (token = tryConsumeKind("uintLiteral")) { > let uintVersion = token.text.substr(0, token.text.length - 1) >>> 0; > if (uintVersion + "u" !== token.text) >- lexer.fail("Integer literal is not 32-bit unsigned integer: " + token.text); >+ return lexer.fail("Integer literal is not 32-bit unsigned integer: " + token.text); > return new UintLiteral(token, uintVersion); > } > if ((token = tryConsumeKind("intHexLiteral")) >@@ -162,7 +183,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > else > intVersion = intVersion >>> 0; > if (intVersion.toString(16) !== hexString) >- lexer.fail("Hex integer literal is not an integer: " + token.text); >+ return lexer.fail("Hex integer literal is not an integer: " + token.text); > if (token.kind == "intHexLiteral") > return new IntLiteral(token, intVersion); > return new UintLiteral(token, intVersion >>> 0); >@@ -178,9 +199,13 @@ function parse(program, origin, originKind, lineNumberOffset, text) > if (token = tryConsume("true", "false")) > return new BoolLiteral(token, token.text == "true"); > // FIXME: Need support for other literals too. >- consume("("); >+ let parenthesisResult = consume("("); >+ if (parenthesisResult instanceof WSyntaxError) >+ return parenthesisResult; > let result = parseExpression(); >- consume(")"); >+ parenthesisResult = consume(")"); >+ if (parenthesisResult instanceof WSyntaxError) >+ return parenthesisResult; > return result; > } > >@@ -195,13 +220,16 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return left; > } > >+ // NeedsUpdateCallers > function parseTypeArguments() > { > if (!test("<")) > return []; > > let result = []; >- consume("<"); >+ let bracketResult = consume("<"); >+ if (bracketResult instanceof WSyntaxError) >+ return bracketResult; > while (!test(">")) { > // It's possible for a constexpr or type can syntactically overlap in the single > // identifier case. Let's consider the possibilities: >@@ -238,7 +266,8 @@ function parse(program, origin, originKind, lineNumberOffset, text) > consumeEndOfTypeArgs(); > return result; > } >- >+ >+ // NeedsUpdateCallers > function parseType() > { > let token; >@@ -251,6 +280,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > let typeArguments = parseTypeArguments(); > let type = new TypeRef(name, name.text, typeArguments); > >+ // NeedsUpdateCallers > function getAddressSpace() > { > addressSpaceConsumed = true; >@@ -277,25 +307,34 @@ function parse(program, origin, originKind, lineNumberOffset, text) > > const lengthExpr = parseConstexpr(); > typeConstructorStack.unshift(type => new ArrayType(token, type, lengthExpr)); >- consume("]"); >+ let bracketResult = consume("]"); >+ if (bracketResult instanceof WSyntaxError) >+ return bracketResult; > } > > for (let constructor of typeConstructorStack) > type = constructor(type); > > if (addressSpace && !addressSpaceConsumed) >- lexer.fail("Address space specified for type that does not need address space"); >+ return lexer.fail("Address space specified for type that does not need address space"); > > return type; > } > >+ // NeedsUpdateCallers > function parseTypeDef() > { > let origin = consume("typedef"); >+ if (origin instanceof WSyntaxError) >+ return origin > let name = consumeKind("identifier").text; >- consume("="); >+ let maybeError = consume("="); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let type = parseType(); >- consume(";"); >+ maybeError = consume(";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError > return new TypeDef(origin, name, type); > } > >@@ -316,6 +355,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > new CallExpression(token, "operator" + token.text, [left, right])); > } > >+ // NeedsUpdateCallers > function parseCallExpression() > { > let parseArguments = function(origin, callName) { >@@ -326,13 +366,17 @@ function parse(program, origin, originKind, lineNumberOffset, text) > if (!tryConsume(",")) > break; > } >- consume(")"); >+ let maybeError = consume(")"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return new CallExpression(origin, callName, argumentList); > } > > let name = lexer.backtrackingScope(() => { > let name = consumeKind("identifier"); >- consume("("); >+ let maybeError = consume("("); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return name; > }); > >@@ -341,21 +385,28 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return result; > } else { > let returnType = parseType(); >- consume("("); >+ let maybeError = consume("("); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let result = parseArguments(returnType.origin, "operator cast"); > result.setCastData(returnType); > return result; > } > } > >+ // NeedsUpdateCallers > function isCallExpression() > { > return lexer.testScope(() => { > consumeKind("identifier"); >- consume("("); >+ let maybeError = consume("("); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > }) || lexer.testScope(() => { > parseType(); >- consume("("); >+ let maybeError = consume("("); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > }); > } > >@@ -383,6 +434,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return readModifyWrite; > } > >+ // NeedsUpdateCallers > function parseSuffixOperator(left, acceptableOperators) > { > let token; >@@ -399,7 +451,9 @@ function parse(program, origin, originKind, lineNumberOffset, text) > break; > case "[": { > let index = parseExpression(); >- consume("]"); >+ let maybeError = consume("]"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > left = new IndexExpression(token, left, index); > break; > } >@@ -432,9 +486,12 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return readModifyWrite; > } > >+ // NeedsUpdateCallers > function parsePreIncrement() > { > let token = consume("++", "--"); >+ if (token instanceof WSyntaxError) >+ return token; > let left = parsePossiblePrefix(); > return finishParsingPreIncrement(token, left); > } >@@ -523,6 +580,7 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return parseLeftLogicalExpression(["||"], parsePossibleLogicalAnd); > } > >+ // NeedsUpdateCallers > function parsePossibleTernaryConditional() > { > let predicate = parsePossibleLogicalOr(); >@@ -530,18 +588,21 @@ function parse(program, origin, originKind, lineNumberOffset, text) > if (!operator) > return predicate; > let bodyExpression = parsePossibleAssignment(); >- consume(":"); >+ let maybeError = consume(":"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let elseExpression = parsePossibleAssignment(); > return new TernaryExpression(operator, predicate, bodyExpression, elseExpression); > } >- >+ >+ // NeedsUpdateCallers > function parsePossibleAssignment(mode) > { > let lhs = parsePossibleTernaryConditional(); > let operator = tryConsume("=", "+=", "-=", "*=", "/=", "%=", "^=", "|=", "&="); > if (!operator) { > if (mode == "required") >- lexer.fail("Expected assignment: " + lexer._text.substring(lexer._index)); >+ return lexer.fail("Expected assignment: " + lexer._text.substring(lexer._index)); > return lhs; > } > if (operator.text == "=") >@@ -554,10 +615,13 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return parsePossibleAssignment("required"); > } > >+ // NeedsUpdateCallers > function parsePostIncrement() > { > let left = parseSuffixOperator(parseTerm(), ".", "->", "["); > let token = consume("++", "--"); >+ if (token instanceof WSyntaxError) >+ return token; > return finishParsingPostIncrement(token, left); > } > >@@ -573,17 +637,22 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return postIncrement; > return parseAssignment(); > } >- >+ >+ // NeedsUpdateCallers > function genericParseCommaExpression(finalExpressionParser) > { > let list = []; > let origin = lexer.peek(); > if (!origin) >- lexer.fail("Unexpected end of file"); >+ return lexer.fail("Unexpected end of file"); >+ if (origin instanceof WSyntaxError) >+ return origin; > for (;;) { > let effectfulExpression = lexer.backtrackingScope(() => { > parseEffectfulExpression(); >- consume(","); >+ let maybeError = consume(","); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > }); > if (!effectfulExpression) { > let final = finalExpressionParser(); >@@ -609,43 +678,68 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return parseCommaExpression(); > } > >+ // NeedsUpdateCallers > function parseEffectfulStatement() > { > let result = genericParseCommaExpression(parseEffectfulExpression); >- consume(";"); >+ let maybeError = consume(";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return result; > } > >+ // NeedsUpdateCallers > function parseReturn() > { > let origin = consume("return"); >+ if (origin instanceof WSyntaxError) >+ return origin; > if (tryConsume(";")) > return new Return(origin, null); > let expression = parseExpression(); >- consume(";"); >+ let maybeError = consume(";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return new Return(origin, expression); > } > >+ // NeedsUpdateCallers > function parseBreak() > { > let origin = consume("break"); >- consume(";"); >+ if (origin instanceof WSyntaxError) >+ return origin; >+ let maybeError = consume(";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return new Break(origin); > } > >+ // NeedsUpdateCallers > function parseContinue() > { > let origin = consume("continue"); >- consume(";"); >+ if (origin instanceof WSyntaxError) >+ return origin; >+ let maybeError = consume(";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return new Continue(origin); > } > >+ // NeedsUpdateCallers > function parseIfStatement() > { > let origin = consume("if"); >- consume("("); >+ if (origin instanceof WSyntaxError) >+ return origin; >+ let maybeError = consume("("); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let conditional = parseExpression(); >- consume(")"); >+ maybeError = consume(")"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let body = parseStatement(); > let elseBody; > if (tryConsume("else")) >@@ -653,20 +747,32 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return new IfStatement(origin, new CallExpression(conditional.origin, "bool", [conditional]), body, elseBody); > } > >+ // NeedsUpdateCallers > function parseWhile() > { > let origin = consume("while"); >- consume("("); >+ if (origin instanceof WSyntaxError) >+ return origin; >+ let maybeError = consume("("); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let conditional = parseExpression(); >- consume(")"); >+ maybeError = consume(")"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let body = parseStatement(); > return new WhileLoop(origin, new CallExpression(conditional.origin, "bool", [conditional]), body); > } > >+ // NeedsUpdateCallers > function parseFor() > { > let origin = consume("for"); >- consume("("); >+ if (origin instanceof WSyntaxError) >+ return origin; >+ let maybeError = consume("("); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let initialization; > if (tryConsume(";")) > initialization = undefined; >@@ -680,7 +786,9 @@ function parse(program, origin, originKind, lineNumberOffset, text) > condition = undefined; > else { > condition = parseExpression(); >- consume(";"); >+ maybeError = consume(";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > condition = new CallExpression(condition.origin, "bool", [condition]); > } > let increment; >@@ -688,62 +796,96 @@ function parse(program, origin, originKind, lineNumberOffset, text) > increment = undefined; > else { > increment = parseExpression(); >- consume(")"); >+ maybeError = consume(")"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > } > let body = parseStatement(); > return new ForLoop(origin, initialization, condition, increment, body); > } > >+ // NeedsUpdateCallers > function parseDo() > { > let origin = consume("do"); >+ if (origin instanceof WSyntaxError) >+ return origin; > let body = parseStatement(); >- consume("while"); >- consume("("); >+ let maybeError = consume("while"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; >+ maybeError = consume("("); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let conditional = parseExpression(); >- consume(")"); >+ maybeError = consume(")"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return new DoWhileLoop(origin, body, new CallExpression(conditional.origin, "bool", [conditional])); > } > >+ // NeedsUpdateCallers > function parseVariableDecls() > { > let type = parseType(); > let list = []; >+ let repeat; > do { > let name = consumeKind("identifier"); > let initializer = tryConsume("=") ? parseExpression() : null; > list.push(new VariableDecl(name, name.text, type, initializer)); >- } while (consume(",", ";").text == ","); >+ let maybeError = consume(",", ";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; >+ repeat = maybeError.text == ","; >+ } while (repeat); > return new CommaExpression(type.origin, list); > } > >+ // NeedsUpdateCallers > function parseSwitchCase() > { > let token = consume("default", "case"); >+ if (token instanceof WSyntaxError) >+ return token; > let value; > if (token.text == "case") > value = parseConstexpr(); >- consume(":"); >+ let maybeError = consume(":"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let body = parseBlockBody("}", "default", "case"); > return new SwitchCase(token, value, body); > } > >+ // NeedsUpdateCallers > function parseSwitchStatement() > { > let origin = consume("switch"); >- consume("("); >+ if (origin instanceof WSyntaxError) >+ return origin; >+ let maybeError = consume("("); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let value = parseExpression(); >- consume(")"); >- consume("{"); >+ maybeError = consume(")"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; >+ maybeError = consume("{"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let result = new SwitchStatement(origin, value); > while (!tryConsume("}")) > result.add(parseSwitchCase()); > return result; > } > >+ // NeedsUpdateCallers > function parseStatement() > { > let token = lexer.peek(); >+ if (token instanceof WSyntaxError) >+ return token; > if (token.text == ";") { > lexer.next(); > return null; >@@ -766,7 +908,11 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return parseSwitchStatement(); > if (token.text == "trap") { > let origin = consume("trap"); >- consume(";"); >+ if (origin instanceof WSyntaxError) >+ return origin; >+ let maybeError = consume(";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return new TrapStatement(origin); > } > if (token.text == "{") >@@ -788,11 +934,16 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return block; > } > >+ // NeedsUpdateCallers > function parseBlock() > { > let origin = consume("{"); >+ if (origin instanceof WSyntaxError) >+ return origin; > let block = parseBlockBody("}"); >- consume("}"); >+ let maybeError = consume("}"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return block; > } > >@@ -803,26 +954,36 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return new FuncParameter(type.origin, name ? name.text : null, type); > } > >+ // NeedsUpdateCallers > function parseParameters() > { >- consume("("); >+ let maybeError = consume("("); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let parameters = []; > while (!test(")")) { > parameters.push(parseParameter()); > if (!tryConsume(",")) > break; > } >- consume(")"); >+ maybeError = consume(")"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return parameters; > } > >+ // NeedsUpdateCallers > function parseFuncName() > { > if (tryConsume("operator")) { > let token = consume("+", "-", "*", "/", "%", "^", "&", "|", "<", ">", "<=", ">=", "==", "++", "--", ".", "~", "<<", ">>", "["); >+ if (token instanceof WSyntaxError) >+ return token; > if (token.text == "&") { > if (tryConsume("[")) { >- consume("]"); >+ let maybeError = consume("]"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return "operator&[]"; > } > if (tryConsume(".")) >@@ -836,7 +997,9 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return result; > } > if (token.text == "[") { >- consume("]"); >+ let maybeError = consume("]"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError > let result = "operator[]"; > if (tryConsume("=")) > result += "="; >@@ -882,47 +1045,66 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return new FuncDef(func.origin, func.name, func.returnType, func.parameters, body, func.isCast, func.shaderType); > } > >+ // NeedsUpdateCallers > function parseField() > { > let type = parseType(); > let name = consumeKind("identifier"); >- consume(";"); >+ let maybeError = consume(";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return new Field(name, name.text, type); > } > >+ // NeedsUpdateCallers > function parseStructType() > { > let origin = consume("struct"); >+ if (origin instanceof WSyntaxError) >+ return origin; > let name = consumeKind("identifier").text; > let result = new StructType(origin, name); >- consume("{"); >+ let maybeError = consume("{"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > while (!tryConsume("}")) > result.add(parseField()); > return result; > } > >+ // NeedsUpdateCallers > function parseNativeFunc() > { > let func = parseFuncDecl(); >- consume(";"); >+ let maybeError = consume(";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return new NativeFunc(func.origin, func.name, func.returnType, func.parameters, func.isCast, func.shaderType); > } > >+ // NeedsUpdateCallers > function parseNative() > { > let origin = consume("native"); >+ if (origin instanceof WSyntaxError) >+ return origin; > if (tryConsume("typedef")) { > let name = consumeKind("identifier"); > let args = parseTypeArguments(); >- consume(";"); >+ let maybeError = consume(";"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return NativeType.create(origin, name.text, args); > } > return parseNativeFunc(); > } > >+ // NeedsUpdateCallers > function parseRestrictedFuncDef() > { >- consume("restricted"); >+ let maybeError = consume("restricted"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let result; > if (tryConsume("native")) > result = parseNativeFunc(); >@@ -941,23 +1123,30 @@ function parse(program, origin, originKind, lineNumberOffset, text) > return new EnumMember(name, name.text, value); > } > >+ // NeedsUpdateCallers > function parseEnumType() > { >- consume("enum"); >+ let maybeError = consume("enum"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError > let name = consumeKind("identifier"); > let baseType; > if (tryConsume(":")) > baseType = parseType(); > else > baseType = new TypeRef(name, "int"); >- consume("{"); >+ maybeError = consume("{"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > let result = new EnumType(name, name.text, baseType); > while (!test("}")) { > result.add(parseEnumMember()); > if (!tryConsume(",")) > break; > } >- consume("}"); >+ maybeError = consume("}"); >+ if (maybeError instanceof WSyntaxError) >+ return maybeError; > return result; > } > >@@ -965,6 +1154,8 @@ function parse(program, origin, originKind, lineNumberOffset, text) > let token = lexer.peek(); > if (!token) > return; >+ if (token instanceof WSyntaxError) >+ return token; > if (token.text == ";") > lexer.next(); > else if (token.text == "typedef")
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 189014
:
348887
|
348951
|
348955
|
348970
|
348985
|
348993
|
348994