1336783 - Remove TokenStream::KeywordIsName.
This commit is contained in:
parent
165084547d
commit
2bb2a37638
|
@ -63,7 +63,7 @@ included_inclnames_to_ignore = set([
|
||||||
'devtools/Instruments.h', # we ignore devtools/ in general
|
'devtools/Instruments.h', # we ignore devtools/ in general
|
||||||
'double-conversion.h', # strange MFBT case
|
'double-conversion.h', # strange MFBT case
|
||||||
'javascript-trace.h', # generated in $OBJDIR if HAVE_DTRACE is defined
|
'javascript-trace.h', # generated in $OBJDIR if HAVE_DTRACE is defined
|
||||||
'jsautokw.h', # generated in $OBJDIR
|
'frontend/ReservedWordsGenerated.h', # generated in $OBJDIR
|
||||||
'jscustomallocator.h', # provided by embedders; allowed to be missing
|
'jscustomallocator.h', # provided by embedders; allowed to be missing
|
||||||
'js-config.h', # generated in $OBJDIR
|
'js-config.h', # generated in $OBJDIR
|
||||||
'fdlibm.h', # fdlibm
|
'fdlibm.h', # fdlibm
|
||||||
|
@ -99,7 +99,7 @@ included_inclnames_to_ignore = set([
|
||||||
# ignore #includes of them when checking #include ordering.
|
# ignore #includes of them when checking #include ordering.
|
||||||
oddly_ordered_inclnames = set([
|
oddly_ordered_inclnames = set([
|
||||||
'ctypes/typedefs.h', # Included multiple times in the body of ctypes/CTypes.h
|
'ctypes/typedefs.h', # Included multiple times in the body of ctypes/CTypes.h
|
||||||
'jsautokw.h', # Included in the body of frontend/TokenStream.h
|
'frontend/ReservedWordsGenerated.h', # Included in the body of frontend/TokenStream.h
|
||||||
'jswin.h', # Must be #included before <psapi.h>
|
'jswin.h', # Must be #included before <psapi.h>
|
||||||
'machine/endian.h', # Must be included after <sys/types.h> on BSD
|
'machine/endian.h', # Must be included after <sys/types.h> on BSD
|
||||||
'winbase.h', # Must precede other system headers(?)
|
'winbase.h', # Must precede other system headers(?)
|
||||||
|
|
213
js/src/frontend/GenerateReservedWords.py
Normal file
213
js/src/frontend/GenerateReservedWords.py
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def read_reserved_word_list(filename):
|
||||||
|
macro_pat = re.compile(r"^\s*macro\(([^,]+), *[^,]+, *[^\)]+\)\s*\\?$")
|
||||||
|
|
||||||
|
reserved_word_list = []
|
||||||
|
index = 0
|
||||||
|
with open(filename, 'r') as f:
|
||||||
|
for line in f:
|
||||||
|
m = macro_pat.search(line)
|
||||||
|
if m:
|
||||||
|
reserved_word_list.append((index, m.group(1)))
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
assert(len(reserved_word_list) != 0)
|
||||||
|
|
||||||
|
return reserved_word_list
|
||||||
|
|
||||||
|
def line(opt, s):
|
||||||
|
opt['output'].write('{}{}\n'.format(' ' * opt['indent_level'], s))
|
||||||
|
|
||||||
|
def indent(opt):
|
||||||
|
opt['indent_level'] += 1
|
||||||
|
|
||||||
|
def dedent(opt):
|
||||||
|
opt['indent_level'] -= 1
|
||||||
|
|
||||||
|
def span_and_count_at(reserved_word_list, column):
|
||||||
|
assert(len(reserved_word_list) != 0);
|
||||||
|
|
||||||
|
chars_dict = {}
|
||||||
|
for index, word in reserved_word_list:
|
||||||
|
chars_dict[ord(word[column])] = True
|
||||||
|
|
||||||
|
chars = sorted(chars_dict.keys())
|
||||||
|
return chars[-1] - chars[0] + 1, len(chars)
|
||||||
|
|
||||||
|
def optimal_switch_column(opt, reserved_word_list, columns, unprocessed_columns):
|
||||||
|
assert(len(reserved_word_list) != 0);
|
||||||
|
assert(unprocessed_columns != 0);
|
||||||
|
|
||||||
|
min_count = 0
|
||||||
|
min_span = 0
|
||||||
|
min_count_index = 0
|
||||||
|
min_span_index = 0
|
||||||
|
|
||||||
|
for index in range(0, unprocessed_columns):
|
||||||
|
span, count = span_and_count_at(reserved_word_list, columns[index])
|
||||||
|
assert(span != 0)
|
||||||
|
|
||||||
|
if span == 1:
|
||||||
|
assert(count == 1)
|
||||||
|
return 1, True
|
||||||
|
|
||||||
|
assert(count != 1)
|
||||||
|
if index == 0 or min_span > span:
|
||||||
|
min_span = span
|
||||||
|
min_span_index = index
|
||||||
|
|
||||||
|
if index == 0 or min_count > count:
|
||||||
|
min_count = count
|
||||||
|
min_count_index = index
|
||||||
|
|
||||||
|
if min_count <= opt['use_if_threshold']:
|
||||||
|
return min_count_index, True
|
||||||
|
|
||||||
|
return min_span_index, False
|
||||||
|
|
||||||
|
def split_list_per_column(reserved_word_list, column):
|
||||||
|
assert(len(reserved_word_list) != 0);
|
||||||
|
|
||||||
|
column_dict = {}
|
||||||
|
for item in reserved_word_list:
|
||||||
|
index, word = item
|
||||||
|
per_column = column_dict.setdefault(word[column], [])
|
||||||
|
per_column.append(item)
|
||||||
|
|
||||||
|
return sorted(column_dict.items(), key=lambda (char, word): ord(char))
|
||||||
|
|
||||||
|
def generate_letter_switch(opt, unprocessed_columns, reserved_word_list,
|
||||||
|
columns=None):
|
||||||
|
assert(len(reserved_word_list) != 0);
|
||||||
|
|
||||||
|
if not columns:
|
||||||
|
columns = range(0, unprocessed_columns)
|
||||||
|
|
||||||
|
if len(reserved_word_list) == 1:
|
||||||
|
index, word = reserved_word_list[0]
|
||||||
|
|
||||||
|
if unprocessed_columns == 0:
|
||||||
|
line(opt, 'JSRW_GOT_MATCH({}) /* {} */'.format(index, word))
|
||||||
|
return
|
||||||
|
|
||||||
|
if unprocessed_columns > opt['char_tail_test_threshold']:
|
||||||
|
line(opt, 'JSRW_TEST_GUESS({}) /* {} */'.format(index, word))
|
||||||
|
return
|
||||||
|
|
||||||
|
conds = []
|
||||||
|
for column in columns[0:unprocessed_columns]:
|
||||||
|
quoted = repr(word[column])
|
||||||
|
conds.append('JSRW_AT({})=={}'.format(column, quoted))
|
||||||
|
|
||||||
|
line(opt, 'if ({}) {{'.format(' && '.join(conds)))
|
||||||
|
|
||||||
|
indent(opt)
|
||||||
|
line(opt, 'JSRW_GOT_MATCH({}) /* {} */'.format(index, word))
|
||||||
|
dedent(opt)
|
||||||
|
|
||||||
|
line(opt, '}')
|
||||||
|
line(opt, 'JSRW_NO_MATCH()')
|
||||||
|
return
|
||||||
|
|
||||||
|
assert(unprocessed_columns != 0);
|
||||||
|
|
||||||
|
optimal_column_index, use_if = optimal_switch_column(opt, reserved_word_list,
|
||||||
|
columns,
|
||||||
|
unprocessed_columns)
|
||||||
|
optimal_column = columns[optimal_column_index]
|
||||||
|
|
||||||
|
# Make a copy to avoid breaking passed list.
|
||||||
|
columns = columns[:]
|
||||||
|
columns[optimal_column_index] = columns[unprocessed_columns - 1]
|
||||||
|
|
||||||
|
list_per_column = split_list_per_column(reserved_word_list, optimal_column)
|
||||||
|
|
||||||
|
if not use_if:
|
||||||
|
line(opt, 'switch (JSRW_AT({})) {{'.format(optimal_column))
|
||||||
|
|
||||||
|
for char, reserved_word_list_per_column in list_per_column:
|
||||||
|
quoted = repr(char)
|
||||||
|
if use_if:
|
||||||
|
line(opt, 'if (JSRW_AT({}) == {}) {{'.format(optimal_column,
|
||||||
|
quoted))
|
||||||
|
else:
|
||||||
|
line(opt, ' case {}:'.format(quoted))
|
||||||
|
|
||||||
|
indent(opt)
|
||||||
|
generate_letter_switch(opt, unprocessed_columns - 1,
|
||||||
|
reserved_word_list_per_column, columns)
|
||||||
|
dedent(opt)
|
||||||
|
|
||||||
|
if use_if:
|
||||||
|
line(opt, '}')
|
||||||
|
|
||||||
|
if not use_if:
|
||||||
|
line(opt, '}')
|
||||||
|
|
||||||
|
line(opt, 'JSRW_NO_MATCH()')
|
||||||
|
|
||||||
|
def split_list_per_length(reserved_word_list):
|
||||||
|
assert(len(reserved_word_list) != 0);
|
||||||
|
|
||||||
|
length_dict = {}
|
||||||
|
for item in reserved_word_list:
|
||||||
|
index, word = item
|
||||||
|
per_length = length_dict.setdefault(len(word), [])
|
||||||
|
per_length.append(item)
|
||||||
|
|
||||||
|
return sorted(length_dict.items(), key=lambda (length, word): length)
|
||||||
|
|
||||||
|
def generate_switch(opt, reserved_word_list):
|
||||||
|
assert(len(reserved_word_list) != 0);
|
||||||
|
|
||||||
|
line(opt, '/*')
|
||||||
|
line(opt, ' * Generating switch for the list of {} entries:'.format(len(reserved_word_list)))
|
||||||
|
for index, word in reserved_word_list:
|
||||||
|
line(opt, ' * {}'.format(word))
|
||||||
|
line(opt, ' */')
|
||||||
|
|
||||||
|
list_per_length = split_list_per_length(reserved_word_list)
|
||||||
|
|
||||||
|
use_if = False
|
||||||
|
if len(list_per_length) < opt['use_if_threshold']:
|
||||||
|
use_if = True
|
||||||
|
|
||||||
|
if not use_if:
|
||||||
|
line(opt, 'switch (JSRW_LENGTH()) {')
|
||||||
|
|
||||||
|
for length, reserved_word_list_per_length in list_per_length:
|
||||||
|
if use_if:
|
||||||
|
line(opt, 'if (JSRW_LENGTH() == {}) {{'.format(length))
|
||||||
|
else:
|
||||||
|
line(opt, ' case {}:'.format(length))
|
||||||
|
|
||||||
|
indent(opt)
|
||||||
|
generate_letter_switch(opt, length, reserved_word_list_per_length)
|
||||||
|
dedent(opt)
|
||||||
|
|
||||||
|
if use_if:
|
||||||
|
line(opt, '}')
|
||||||
|
|
||||||
|
if not use_if:
|
||||||
|
line(opt, '}')
|
||||||
|
line(opt, 'JSRW_NO_MATCH()')
|
||||||
|
|
||||||
|
def main(output, reserved_words_h):
|
||||||
|
reserved_word_list = read_reserved_word_list(reserved_words_h)
|
||||||
|
|
||||||
|
opt = {
|
||||||
|
'indent_level': 1,
|
||||||
|
'use_if_threshold': 3,
|
||||||
|
'char_tail_test_threshold': 4,
|
||||||
|
'output': output
|
||||||
|
}
|
||||||
|
generate_switch(opt, reserved_word_list)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main(sys.stdout, *sys.argv[1:])
|
File diff suppressed because it is too large
Load Diff
|
@ -734,6 +734,9 @@ class UsedNameTracker
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename ParseHandler>
|
||||||
|
class AutoAwaitIsKeyword;
|
||||||
|
|
||||||
class ParserBase : public StrictModeGetter
|
class ParserBase : public StrictModeGetter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -783,7 +786,13 @@ class ParserBase : public StrictModeGetter
|
||||||
/* Unexpected end of input, i.e. TOK_EOF not at top-level. */
|
/* Unexpected end of input, i.e. TOK_EOF not at top-level. */
|
||||||
bool isUnexpectedEOF_:1;
|
bool isUnexpectedEOF_:1;
|
||||||
|
|
||||||
|
bool awaitIsKeyword_:1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool awaitIsKeyword() const {
|
||||||
|
return awaitIsKeyword_;
|
||||||
|
}
|
||||||
|
|
||||||
ParserBase(ExclusiveContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,
|
ParserBase(ExclusiveContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,
|
||||||
const char16_t* chars, size_t length, bool foldConstants,
|
const char16_t* chars, size_t length, bool foldConstants,
|
||||||
UsedNameTracker& usedNames, Parser<SyntaxParseHandler>* syntaxParser,
|
UsedNameTracker& usedNames, Parser<SyntaxParseHandler>* syntaxParser,
|
||||||
|
@ -998,6 +1007,9 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
|
||||||
Parser<SyntaxParseHandler>* syntaxParser, LazyScript* lazyOuterFunction);
|
Parser<SyntaxParseHandler>* syntaxParser, LazyScript* lazyOuterFunction);
|
||||||
~Parser();
|
~Parser();
|
||||||
|
|
||||||
|
friend class AutoAwaitIsKeyword<ParseHandler>;
|
||||||
|
void setAwaitIsKeyword(bool isKeyword);
|
||||||
|
|
||||||
bool checkOptions();
|
bool checkOptions();
|
||||||
|
|
||||||
// A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
|
// A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
|
||||||
|
@ -1047,8 +1059,6 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
|
||||||
|
|
||||||
void trace(JSTracer* trc);
|
void trace(JSTracer* trc);
|
||||||
|
|
||||||
bool checkUnescapedName();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Parser* thisForCtor() { return this; }
|
Parser* thisForCtor() { return this; }
|
||||||
|
|
||||||
|
@ -1321,17 +1331,22 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
|
||||||
Node classDefinition(YieldHandling yieldHandling, ClassContext classContext,
|
Node classDefinition(YieldHandling yieldHandling, ClassContext classContext,
|
||||||
DefaultHandling defaultHandling);
|
DefaultHandling defaultHandling);
|
||||||
|
|
||||||
PropertyName* labelOrIdentifierReference(YieldHandling yieldHandling,
|
bool checkLabelOrIdentifierReference(HandlePropertyName ident,
|
||||||
bool yieldTokenizedAsName);
|
uint32_t offset,
|
||||||
|
YieldHandling yieldHandling);
|
||||||
|
|
||||||
|
bool checkBindingIdentifier(HandlePropertyName ident,
|
||||||
|
uint32_t offset,
|
||||||
|
YieldHandling yieldHandling);
|
||||||
|
|
||||||
|
PropertyName* labelOrIdentifierReference(YieldHandling yieldHandling);
|
||||||
|
|
||||||
PropertyName* labelIdentifier(YieldHandling yieldHandling) {
|
PropertyName* labelIdentifier(YieldHandling yieldHandling) {
|
||||||
return labelOrIdentifierReference(yieldHandling, false);
|
return labelOrIdentifierReference(yieldHandling);
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyName* identifierReference(YieldHandling yieldHandling,
|
PropertyName* identifierReference(YieldHandling yieldHandling) {
|
||||||
bool yieldTokenizedAsName = false)
|
return labelOrIdentifierReference(yieldHandling);
|
||||||
{
|
|
||||||
return labelOrIdentifierReference(yieldHandling, yieldTokenizedAsName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyName* importedBinding() {
|
PropertyName* importedBinding() {
|
||||||
|
@ -1393,7 +1408,6 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
|
||||||
private:
|
private:
|
||||||
bool checkIncDecOperand(Node operand, uint32_t operandOffset);
|
bool checkIncDecOperand(Node operand, uint32_t operandOffset);
|
||||||
bool checkStrictAssignment(Node lhs);
|
bool checkStrictAssignment(Node lhs);
|
||||||
bool checkStrictBinding(PropertyName* name, TokenPos pos);
|
|
||||||
|
|
||||||
bool hasValidSimpleStrictParameterNames();
|
bool hasValidSimpleStrictParameterNames();
|
||||||
|
|
||||||
|
@ -1455,6 +1469,25 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
|
||||||
bool asmJS(Node list);
|
bool asmJS(Node list);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename ParseHandler>
|
||||||
|
class MOZ_STACK_CLASS AutoAwaitIsKeyword
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Parser<ParseHandler>* parser_;
|
||||||
|
bool oldAwaitIsKeyword_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AutoAwaitIsKeyword(Parser<ParseHandler>* parser, bool awaitIsKeyword) {
|
||||||
|
parser_ = parser;
|
||||||
|
oldAwaitIsKeyword_ = parser_->awaitIsKeyword_;
|
||||||
|
parser_->setAwaitIsKeyword(awaitIsKeyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
~AutoAwaitIsKeyword() {
|
||||||
|
parser_->setAwaitIsKeyword(oldAwaitIsKeyword_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} /* namespace frontend */
|
} /* namespace frontend */
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,16 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/* A higher-order macro for enumerating keyword tokens. */
|
/* A higher-order macro for enumerating reserved word tokens. */
|
||||||
|
|
||||||
#ifndef vm_Keywords_h
|
#ifndef vm_ReservedWords_h
|
||||||
#define vm_Keywords_h
|
#define vm_ReservedWords_h
|
||||||
|
|
||||||
#define FOR_EACH_JAVASCRIPT_KEYWORD(macro) \
|
#define FOR_EACH_JAVASCRIPT_RESERVED_WORD(macro) \
|
||||||
macro(false, false_, TOK_FALSE) \
|
macro(false, false_, TOK_FALSE) \
|
||||||
macro(true, true_, TOK_TRUE) \
|
macro(true, true_, TOK_TRUE) \
|
||||||
macro(null, null, TOK_NULL) \
|
macro(null, null, TOK_NULL) \
|
||||||
|
\
|
||||||
/* Keywords. */ \
|
/* Keywords. */ \
|
||||||
macro(break, break_, TOK_BREAK) \
|
macro(break, break_, TOK_BREAK) \
|
||||||
macro(case, case_, TOK_CASE) \
|
macro(case, case_, TOK_CASE) \
|
||||||
|
@ -36,31 +37,45 @@
|
||||||
macro(this, this_, TOK_THIS) \
|
macro(this, this_, TOK_THIS) \
|
||||||
macro(throw, throw_, TOK_THROW) \
|
macro(throw, throw_, TOK_THROW) \
|
||||||
macro(try, try_, TOK_TRY) \
|
macro(try, try_, TOK_TRY) \
|
||||||
macro(typeof, typeof, TOK_TYPEOF) \
|
macro(typeof, typeof_, TOK_TYPEOF) \
|
||||||
macro(var, var, TOK_VAR) \
|
macro(var, var, TOK_VAR) \
|
||||||
macro(void, void_, TOK_VOID) \
|
macro(void, void_, TOK_VOID) \
|
||||||
macro(while, while_, TOK_WHILE) \
|
macro(while, while_, TOK_WHILE) \
|
||||||
macro(with, with, TOK_WITH) \
|
macro(with, with, TOK_WITH) \
|
||||||
macro(import, import, TOK_IMPORT) \
|
macro(import, import, TOK_IMPORT) \
|
||||||
macro(export, export, TOK_EXPORT) \
|
macro(export, export_, TOK_EXPORT) \
|
||||||
macro(class, class_, TOK_CLASS) \
|
macro(class, class_, TOK_CLASS) \
|
||||||
macro(extends, extends, TOK_EXTENDS) \
|
macro(extends, extends, TOK_EXTENDS) \
|
||||||
macro(super, super, TOK_SUPER) \
|
macro(super, super, TOK_SUPER) \
|
||||||
/* Reserved keywords. */ \
|
\
|
||||||
macro(enum, enum_, TOK_RESERVED) \
|
/* Future reserved words. */ \
|
||||||
/* Future reserved keywords, but only in strict mode. */ \
|
macro(enum, enum_, TOK_ENUM) \
|
||||||
macro(implements, implements, TOK_STRICT_RESERVED) \
|
\
|
||||||
macro(interface, interface, TOK_STRICT_RESERVED) \
|
/* Future reserved words, but only in strict mode. */ \
|
||||||
macro(package, package, TOK_STRICT_RESERVED) \
|
macro(implements, implements, TOK_IMPLEMENTS) \
|
||||||
macro(private, private_, TOK_STRICT_RESERVED) \
|
macro(interface, interface, TOK_INTERFACE) \
|
||||||
macro(protected, protected_, TOK_STRICT_RESERVED) \
|
macro(package, package, TOK_PACKAGE) \
|
||||||
macro(public, public_, TOK_STRICT_RESERVED) \
|
macro(private, private_, TOK_PRIVATE) \
|
||||||
|
macro(protected, protected_, TOK_PROTECTED) \
|
||||||
|
macro(public, public_, TOK_PUBLIC) \
|
||||||
|
\
|
||||||
|
/* Contextual keywords. */ \
|
||||||
|
macro(as, as, TOK_AS) \
|
||||||
|
macro(async, async, TOK_ASYNC) \
|
||||||
macro(await, await, TOK_AWAIT) \
|
macro(await, await, TOK_AWAIT) \
|
||||||
|
macro(each, each, TOK_EACH) \
|
||||||
|
macro(from, from, TOK_FROM) \
|
||||||
|
macro(get, get, TOK_GET) \
|
||||||
|
macro(let, let, TOK_LET) \
|
||||||
|
macro(of, of, TOK_OF) \
|
||||||
|
macro(set, set, TOK_SET) \
|
||||||
|
macro(static, static_, TOK_STATIC) \
|
||||||
|
macro(target, target, TOK_TARGET) \
|
||||||
/* \
|
/* \
|
||||||
* Yield is a token inside function*. Outside of a function*, it is a \
|
* Yield is a token inside function*. Outside of a function*, it is a \
|
||||||
* future reserved keyword in strict mode, but a keyword in JS1.7 even \
|
* future reserved word in strict mode, but a keyword in JS1.7 even \
|
||||||
* when strict. Punt logic to parser. \
|
* when strict. Punt logic to parser. \
|
||||||
*/ \
|
*/ \
|
||||||
macro(yield, yield, TOK_YIELD)
|
macro(yield, yield, TOK_YIELD)
|
||||||
|
|
||||||
#endif /* vm_Keywords_h */
|
#endif /* vm_ReservedWords_h */
|
|
@ -81,9 +81,12 @@
|
||||||
\
|
\
|
||||||
macro(REGEXP, "regular expression literal") \
|
macro(REGEXP, "regular expression literal") \
|
||||||
macro(TRUE, "boolean literal 'true'") \
|
macro(TRUE, "boolean literal 'true'") \
|
||||||
|
range(RESERVED_WORD_LITERAL_FIRST, TRUE) \
|
||||||
macro(FALSE, "boolean literal 'false'") \
|
macro(FALSE, "boolean literal 'false'") \
|
||||||
macro(NULL, "null literal") \
|
macro(NULL, "null literal") \
|
||||||
|
range(RESERVED_WORD_LITERAL_LAST, NULL) \
|
||||||
macro(THIS, "keyword 'this'") \
|
macro(THIS, "keyword 'this'") \
|
||||||
|
range(KEYWORD_FIRST, THIS) \
|
||||||
macro(FUNCTION, "keyword 'function'") \
|
macro(FUNCTION, "keyword 'function'") \
|
||||||
macro(IF, "keyword 'if'") \
|
macro(IF, "keyword 'if'") \
|
||||||
macro(ELSE, "keyword 'else'") \
|
macro(ELSE, "keyword 'else'") \
|
||||||
|
@ -106,16 +109,43 @@
|
||||||
macro(FINALLY, "keyword 'finally'") \
|
macro(FINALLY, "keyword 'finally'") \
|
||||||
macro(THROW, "keyword 'throw'") \
|
macro(THROW, "keyword 'throw'") \
|
||||||
macro(DEBUGGER, "keyword 'debugger'") \
|
macro(DEBUGGER, "keyword 'debugger'") \
|
||||||
macro(YIELD, "keyword 'yield'") \
|
|
||||||
macro(AWAIT, "keyword 'await'") \
|
|
||||||
macro(EXPORT, "keyword 'export'") \
|
macro(EXPORT, "keyword 'export'") \
|
||||||
macro(IMPORT, "keyword 'import'") \
|
macro(IMPORT, "keyword 'import'") \
|
||||||
macro(CLASS, "keyword 'class'") \
|
macro(CLASS, "keyword 'class'") \
|
||||||
macro(EXTENDS, "keyword 'extends'") \
|
macro(EXTENDS, "keyword 'extends'") \
|
||||||
macro(SUPER, "keyword 'super'") \
|
macro(SUPER, "keyword 'super'") \
|
||||||
macro(RESERVED, "reserved keyword") \
|
range(KEYWORD_LAST, SUPER) \
|
||||||
/* reserved keywords in strict mode */ \
|
\
|
||||||
macro(STRICT_RESERVED, "reserved keyword") \
|
/* contextual keywords */ \
|
||||||
|
macro(AS, "'as'") \
|
||||||
|
range(CONTEXTUAL_KEYWORD_FIRST, AS) \
|
||||||
|
macro(ASYNC, "'async'") \
|
||||||
|
macro(AWAIT, "'await'") \
|
||||||
|
macro(EACH, "'each'") \
|
||||||
|
macro(FROM, "'from'") \
|
||||||
|
macro(GET, "'get'") \
|
||||||
|
macro(LET, "'let'") \
|
||||||
|
macro(OF, "'of'") \
|
||||||
|
macro(SET, "'set'") \
|
||||||
|
macro(STATIC, "'static'") \
|
||||||
|
macro(TARGET, "'target'") \
|
||||||
|
macro(YIELD, "'yield'") \
|
||||||
|
range(CONTEXTUAL_KEYWORD_LAST, YIELD) \
|
||||||
|
\
|
||||||
|
/* future reserved words */ \
|
||||||
|
macro(ENUM, "reserved word 'enum'") \
|
||||||
|
range(FUTURE_RESERVED_KEYWORD_FIRST, ENUM) \
|
||||||
|
range(FUTURE_RESERVED_KEYWORD_LAST, ENUM) \
|
||||||
|
\
|
||||||
|
/* reserved words in strict mode */ \
|
||||||
|
macro(IMPLEMENTS, "reserved word 'implements'") \
|
||||||
|
range(STRICT_RESERVED_KEYWORD_FIRST, IMPLEMENTS) \
|
||||||
|
macro(INTERFACE, "reserved word 'interface'") \
|
||||||
|
macro(PACKAGE, "reserved word 'package'") \
|
||||||
|
macro(PRIVATE, "reserved word 'private'") \
|
||||||
|
macro(PROTECTED, "reserved word 'protected'") \
|
||||||
|
macro(PUBLIC, "reserved word 'public'") \
|
||||||
|
range(STRICT_RESERVED_KEYWORD_LAST, PUBLIC) \
|
||||||
\
|
\
|
||||||
/* \
|
/* \
|
||||||
* The following token types occupy contiguous ranges to enable easy \
|
* The following token types occupy contiguous ranges to enable easy \
|
||||||
|
@ -149,7 +179,9 @@
|
||||||
range(RELOP_LAST, GE) \
|
range(RELOP_LAST, GE) \
|
||||||
\
|
\
|
||||||
macro(INSTANCEOF, "keyword 'instanceof'") \
|
macro(INSTANCEOF, "keyword 'instanceof'") \
|
||||||
|
range(KEYWORD_BINOP_FIRST, INSTANCEOF) \
|
||||||
macro(IN, "keyword 'in'") \
|
macro(IN, "keyword 'in'") \
|
||||||
|
range(KEYWORD_BINOP_LAST, IN) \
|
||||||
\
|
\
|
||||||
/* Shift ops, per TokenKindIsShift. */ \
|
/* Shift ops, per TokenKindIsShift. */ \
|
||||||
macro(LSH, "'<<'") \
|
macro(LSH, "'<<'") \
|
||||||
|
@ -168,7 +200,9 @@
|
||||||
\
|
\
|
||||||
/* Unary operation tokens. */ \
|
/* Unary operation tokens. */ \
|
||||||
macro(TYPEOF, "keyword 'typeof'") \
|
macro(TYPEOF, "keyword 'typeof'") \
|
||||||
|
range(KEYWORD_UNOP_FIRST, TYPEOF) \
|
||||||
macro(VOID, "keyword 'void'") \
|
macro(VOID, "keyword 'void'") \
|
||||||
|
range(KEYWORD_UNOP_LAST, VOID) \
|
||||||
macro(NOT, "'!'") \
|
macro(NOT, "'!'") \
|
||||||
macro(BITNOT, "'~'") \
|
macro(BITNOT, "'~'") \
|
||||||
\
|
\
|
||||||
|
@ -239,6 +273,61 @@ TokenKindIsAssignment(TokenKind tt)
|
||||||
return TOK_ASSIGNMENT_START <= tt && tt <= TOK_ASSIGNMENT_LAST;
|
return TOK_ASSIGNMENT_START <= tt && tt <= TOK_ASSIGNMENT_LAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline MOZ_MUST_USE bool
|
||||||
|
TokenKindIsKeyword(TokenKind tt)
|
||||||
|
{
|
||||||
|
return (TOK_KEYWORD_FIRST <= tt && tt <= TOK_KEYWORD_LAST) ||
|
||||||
|
(TOK_KEYWORD_BINOP_FIRST <= tt && tt <= TOK_KEYWORD_BINOP_LAST) ||
|
||||||
|
(TOK_KEYWORD_UNOP_FIRST <= tt && tt <= TOK_KEYWORD_UNOP_LAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MOZ_MUST_USE bool
|
||||||
|
TokenKindIsContextualKeyword(TokenKind tt)
|
||||||
|
{
|
||||||
|
return TOK_CONTEXTUAL_KEYWORD_FIRST <= tt && tt <= TOK_CONTEXTUAL_KEYWORD_LAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MOZ_MUST_USE bool
|
||||||
|
TokenKindIsFutureReservedWord(TokenKind tt)
|
||||||
|
{
|
||||||
|
return TOK_FUTURE_RESERVED_KEYWORD_FIRST <= tt && tt <= TOK_FUTURE_RESERVED_KEYWORD_LAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MOZ_MUST_USE bool
|
||||||
|
TokenKindIsStrictReservedWord(TokenKind tt)
|
||||||
|
{
|
||||||
|
return TOK_STRICT_RESERVED_KEYWORD_FIRST <= tt && tt <= TOK_STRICT_RESERVED_KEYWORD_LAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MOZ_MUST_USE bool
|
||||||
|
TokenKindIsReservedWordLiteral(TokenKind tt)
|
||||||
|
{
|
||||||
|
return TOK_RESERVED_WORD_LITERAL_FIRST <= tt && tt <= TOK_RESERVED_WORD_LITERAL_LAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MOZ_MUST_USE bool
|
||||||
|
TokenKindIsReservedWord(TokenKind tt)
|
||||||
|
{
|
||||||
|
return TokenKindIsKeyword(tt) ||
|
||||||
|
TokenKindIsFutureReservedWord(tt) ||
|
||||||
|
TokenKindIsReservedWordLiteral(tt);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MOZ_MUST_USE bool
|
||||||
|
TokenKindIsPossibleIdentifier(TokenKind tt)
|
||||||
|
{
|
||||||
|
return tt == TOK_NAME ||
|
||||||
|
TokenKindIsContextualKeyword(tt) ||
|
||||||
|
TokenKindIsStrictReservedWord(tt);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MOZ_MUST_USE bool
|
||||||
|
TokenKindIsPossibleIdentifierName(TokenKind tt)
|
||||||
|
{
|
||||||
|
return TokenKindIsPossibleIdentifier(tt) ||
|
||||||
|
TokenKindIsReservedWord(tt);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace frontend
|
} // namespace frontend
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
#include "jsnum.h"
|
#include "jsnum.h"
|
||||||
|
|
||||||
#include "frontend/BytecodeCompiler.h"
|
#include "frontend/BytecodeCompiler.h"
|
||||||
|
#include "frontend/ReservedWords.h"
|
||||||
#include "js/CharacterEncoding.h"
|
#include "js/CharacterEncoding.h"
|
||||||
#include "js/UniquePtr.h"
|
#include "js/UniquePtr.h"
|
||||||
#include "vm/HelperThreads.h"
|
#include "vm/HelperThreads.h"
|
||||||
#include "vm/Keywords.h"
|
|
||||||
#include "vm/StringBuffer.h"
|
#include "vm/StringBuffer.h"
|
||||||
#include "vm/Unicode.h"
|
#include "vm/Unicode.h"
|
||||||
|
|
||||||
|
@ -40,65 +40,65 @@ using mozilla::PodAssign;
|
||||||
using mozilla::PodCopy;
|
using mozilla::PodCopy;
|
||||||
using mozilla::PodZero;
|
using mozilla::PodZero;
|
||||||
|
|
||||||
struct KeywordInfo {
|
struct ReservedWordInfo {
|
||||||
const char* chars; // C string with keyword text
|
const char* chars; // C string with reserved word text
|
||||||
TokenKind tokentype;
|
TokenKind tokentype;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const KeywordInfo keywords[] = {
|
static const ReservedWordInfo reservedWords[] = {
|
||||||
#define KEYWORD_INFO(keyword, name, type) \
|
#define RESERVED_WORD_INFO(word, name, type) \
|
||||||
{js_##keyword##_str, type},
|
{js_##word##_str, type},
|
||||||
FOR_EACH_JAVASCRIPT_KEYWORD(KEYWORD_INFO)
|
FOR_EACH_JAVASCRIPT_RESERVED_WORD(RESERVED_WORD_INFO)
|
||||||
#undef KEYWORD_INFO
|
#undef RESERVED_WORD_INFO
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a KeywordInfo for the specified characters, or nullptr if the string
|
// Returns a ReservedWordInfo for the specified characters, or nullptr if the
|
||||||
// is not a keyword.
|
// string is not a reserved word.
|
||||||
template <typename CharT>
|
template <typename CharT>
|
||||||
static const KeywordInfo*
|
static const ReservedWordInfo*
|
||||||
FindKeyword(const CharT* s, size_t length)
|
FindReservedWord(const CharT* s, size_t length)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(length != 0);
|
MOZ_ASSERT(length != 0);
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
const KeywordInfo* kw;
|
const ReservedWordInfo* rw;
|
||||||
const char* chars;
|
const char* chars;
|
||||||
|
|
||||||
#define JSKW_LENGTH() length
|
#define JSRW_LENGTH() length
|
||||||
#define JSKW_AT(column) s[column]
|
#define JSRW_AT(column) s[column]
|
||||||
#define JSKW_GOT_MATCH(index) i = (index); goto got_match;
|
#define JSRW_GOT_MATCH(index) i = (index); goto got_match;
|
||||||
#define JSKW_TEST_GUESS(index) i = (index); goto test_guess;
|
#define JSRW_TEST_GUESS(index) i = (index); goto test_guess;
|
||||||
#define JSKW_NO_MATCH() goto no_match;
|
#define JSRW_NO_MATCH() goto no_match;
|
||||||
#include "jsautokw.h"
|
#include "frontend/ReservedWordsGenerated.h"
|
||||||
#undef JSKW_NO_MATCH
|
#undef JSRW_NO_MATCH
|
||||||
#undef JSKW_TEST_GUESS
|
#undef JSRW_TEST_GUESS
|
||||||
#undef JSKW_GOT_MATCH
|
#undef JSRW_GOT_MATCH
|
||||||
#undef JSKW_AT
|
#undef JSRW_AT
|
||||||
#undef JSKW_LENGTH
|
#undef JSRW_LENGTH
|
||||||
|
|
||||||
got_match:
|
got_match:
|
||||||
return &keywords[i];
|
return &reservedWords[i];
|
||||||
|
|
||||||
test_guess:
|
test_guess:
|
||||||
kw = &keywords[i];
|
rw = &reservedWords[i];
|
||||||
chars = kw->chars;
|
chars = rw->chars;
|
||||||
do {
|
do {
|
||||||
if (*s++ != (unsigned char)(*chars++))
|
if (*s++ != (unsigned char)(*chars++))
|
||||||
goto no_match;
|
goto no_match;
|
||||||
} while (--length != 0);
|
} while (--length != 0);
|
||||||
return kw;
|
return rw;
|
||||||
|
|
||||||
no_match:
|
no_match:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const KeywordInfo*
|
static const ReservedWordInfo*
|
||||||
FindKeyword(JSLinearString* str)
|
FindReservedWord(JSLinearString* str)
|
||||||
{
|
{
|
||||||
JS::AutoCheckCannotGC nogc;
|
JS::AutoCheckCannotGC nogc;
|
||||||
return str->hasLatin1Chars()
|
return str->hasLatin1Chars()
|
||||||
? FindKeyword(str->latin1Chars(nogc), str->length())
|
? FindReservedWord(str->latin1Chars(nogc), str->length())
|
||||||
: FindKeyword(str->twoByteChars(nogc), str->length());
|
: FindReservedWord(str->twoByteChars(nogc), str->length());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT>
|
template <typename CharT>
|
||||||
|
@ -188,7 +188,68 @@ frontend::IsIdentifier(const char16_t* chars, size_t length)
|
||||||
bool
|
bool
|
||||||
frontend::IsKeyword(JSLinearString* str)
|
frontend::IsKeyword(JSLinearString* str)
|
||||||
{
|
{
|
||||||
return FindKeyword(str) != nullptr;
|
if (const ReservedWordInfo* rw = FindReservedWord(str))
|
||||||
|
return TokenKindIsKeyword(rw->tokentype);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
frontend::IsFutureReservedWord(JSLinearString* str)
|
||||||
|
{
|
||||||
|
if (const ReservedWordInfo* rw = FindReservedWord(str))
|
||||||
|
return TokenKindIsFutureReservedWord(rw->tokentype);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
frontend::IsStrictReservedWord(JSLinearString* str)
|
||||||
|
{
|
||||||
|
if (const ReservedWordInfo* rw = FindReservedWord(str))
|
||||||
|
return TokenKindIsStrictReservedWord(rw->tokentype);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
frontend::IsReservedWordLiteral(JSLinearString* str)
|
||||||
|
{
|
||||||
|
if (const ReservedWordInfo* rw = FindReservedWord(str))
|
||||||
|
return TokenKindIsReservedWordLiteral(rw->tokentype);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
frontend::ReservedWordToCharZ(PropertyName* str)
|
||||||
|
{
|
||||||
|
const ReservedWordInfo* rw = FindReservedWord(str);
|
||||||
|
if (rw == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
switch (rw->tokentype) {
|
||||||
|
#define EMIT_CASE(word, name, type) case type: return js_##word##_str;
|
||||||
|
FOR_EACH_JAVASCRIPT_RESERVED_WORD(EMIT_CASE)
|
||||||
|
#undef EMIT_CASE
|
||||||
|
default:
|
||||||
|
MOZ_ASSERT_UNREACHABLE("Not a reserved word PropertyName.");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyName*
|
||||||
|
TokenStream::reservedWordToPropertyName(TokenKind tt) const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(tt != TOK_NAME);
|
||||||
|
switch (tt) {
|
||||||
|
#define EMIT_CASE(word, name, type) case type: return cx->names().name;
|
||||||
|
FOR_EACH_JAVASCRIPT_RESERVED_WORD(EMIT_CASE)
|
||||||
|
#undef EMIT_CASE
|
||||||
|
default:
|
||||||
|
MOZ_ASSERT_UNREACHABLE("Not a reserved word TokenKind.");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenStream::SourceCoords::SourceCoords(ExclusiveContext* cx, uint32_t ln)
|
TokenStream::SourceCoords::SourceCoords(ExclusiveContext* cx, uint32_t ln)
|
||||||
|
@ -1169,38 +1230,6 @@ TokenStream::putIdentInTokenbuf(const char16_t* identStart)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
TokenStream::checkForKeyword(const KeywordInfo* kw, TokenKind* ttp)
|
|
||||||
{
|
|
||||||
if (!awaitIsKeyword && kw->tokentype == TOK_AWAIT) {
|
|
||||||
if (ttp)
|
|
||||||
*ttp = TOK_NAME;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kw->tokentype == TOK_RESERVED) {
|
|
||||||
error(JSMSG_RESERVED_ID, kw->chars);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kw->tokentype == TOK_STRICT_RESERVED)
|
|
||||||
return reportStrictModeError(JSMSG_RESERVED_ID, kw->chars);
|
|
||||||
|
|
||||||
// Working keyword.
|
|
||||||
*ttp = kw->tokentype;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
TokenStream::checkForKeyword(JSAtom* atom, TokenKind* ttp)
|
|
||||||
{
|
|
||||||
const KeywordInfo* kw = FindKeyword(atom);
|
|
||||||
if (!kw)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return checkForKeyword(kw, ttp);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum FirstCharKind {
|
enum FirstCharKind {
|
||||||
// A char16_t has the 'OneChar' kind if it, by itself, constitutes a valid
|
// A char16_t has the 'OneChar' kind if it, by itself, constitutes a valid
|
||||||
// token that cannot also be a prefix of a longer token. E.g. ';' has the
|
// token that cannot also be a prefix of a longer token. E.g. ';' has the
|
||||||
|
@ -1424,36 +1453,18 @@ TokenStream::getTokenInternal(TokenKind* ttp, Modifier modifier)
|
||||||
length = userbuf.addressOfNextRawChar() - identStart;
|
length = userbuf.addressOfNextRawChar() - identStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Represent keywords as keyword tokens unless told otherwise.
|
// Represent reserved words as reserved word tokens.
|
||||||
if (modifier != KeywordIsName) {
|
if (!hadUnicodeEscape) {
|
||||||
if (const KeywordInfo* kw = FindKeyword(chars, length)) {
|
if (const ReservedWordInfo* rw = FindReservedWord(chars, length)) {
|
||||||
// That said, keywords can't contain escapes. (Contexts where
|
tp->type = rw->tokentype;
|
||||||
// keywords are treated as names, that also sometimes treat
|
goto out;
|
||||||
// keywords as keywords, must manually check this requirement.)
|
|
||||||
// There are two exceptions
|
|
||||||
// 1) StrictReservedWords: These keywords need to be treated as
|
|
||||||
// names in non-strict mode.
|
|
||||||
// 2) yield is also treated as a name if it contains an escape
|
|
||||||
// sequence. The parser must handle this case separately.
|
|
||||||
if (hadUnicodeEscape && !(
|
|
||||||
(kw->tokentype == TOK_STRICT_RESERVED && !strictMode()) ||
|
|
||||||
kw->tokentype == TOK_YIELD))
|
|
||||||
{
|
|
||||||
reportError(JSMSG_ESCAPED_KEYWORD);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
tp->type = TOK_NAME;
|
|
||||||
if (!checkForKeyword(kw, &tp->type))
|
|
||||||
goto error;
|
|
||||||
if (tp->type != TOK_NAME && !hadUnicodeEscape)
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JSAtom* atom = AtomizeChars(cx, chars, length);
|
JSAtom* atom = AtomizeChars(cx, chars, length);
|
||||||
if (!atom)
|
if (!atom) {
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
tp->type = TOK_NAME;
|
tp->type = TOK_NAME;
|
||||||
tp->setName(atom->asPropertyName());
|
tp->setName(atom->asPropertyName());
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -26,14 +26,13 @@
|
||||||
#include "js/UniquePtr.h"
|
#include "js/UniquePtr.h"
|
||||||
#include "js/Vector.h"
|
#include "js/Vector.h"
|
||||||
#include "vm/RegExpObject.h"
|
#include "vm/RegExpObject.h"
|
||||||
|
#include "vm/String.h"
|
||||||
|
|
||||||
struct KeywordInfo;
|
struct KeywordInfo;
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
|
||||||
class AutoAwaitIsKeyword;
|
|
||||||
|
|
||||||
struct TokenPos {
|
struct TokenPos {
|
||||||
uint32_t begin; // Offset of the token's first char.
|
uint32_t begin; // Offset of the token's first char.
|
||||||
uint32_t end; // Offset of 1 past the token's last char.
|
uint32_t end; // Offset of 1 past the token's last char.
|
||||||
|
@ -120,9 +119,6 @@ struct Token
|
||||||
// TOK_DIV.
|
// TOK_DIV.
|
||||||
Operand,
|
Operand,
|
||||||
|
|
||||||
// Treat keywords as names by returning TOK_NAME.
|
|
||||||
KeywordIsName,
|
|
||||||
|
|
||||||
// Treat subsequent characters as the tail of a template literal, after
|
// Treat subsequent characters as the tail of a template literal, after
|
||||||
// a template substitution, beginning with a "}", continuing with zero
|
// a template substitution, beginning with a "}", continuing with zero
|
||||||
// or more template literal characters, and ending with either "${" or
|
// or more template literal characters, and ending with either "${" or
|
||||||
|
@ -164,10 +160,6 @@ struct Token
|
||||||
// If a semicolon is inserted automatically, the next token is already
|
// If a semicolon is inserted automatically, the next token is already
|
||||||
// gotten with None, but we expect Operand.
|
// gotten with None, but we expect Operand.
|
||||||
OperandIsNone,
|
OperandIsNone,
|
||||||
|
|
||||||
// If name of method definition is `get` or `set`, the next token is
|
|
||||||
// already gotten with KeywordIsName, but we expect None.
|
|
||||||
NoneIsKeywordIsName,
|
|
||||||
};
|
};
|
||||||
friend class TokenStream;
|
friend class TokenStream;
|
||||||
|
|
||||||
|
@ -224,11 +216,6 @@ struct Token
|
||||||
return u.name->JSAtom::asPropertyName(); // poor-man's type verification
|
return u.name->JSAtom::asPropertyName(); // poor-man's type verification
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nameContainsEscape() const {
|
|
||||||
PropertyName* n = name();
|
|
||||||
return pos.begin + n->length() != pos.end;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSAtom* atom() const {
|
JSAtom* atom() const {
|
||||||
MOZ_ASSERT(type == TOK_STRING ||
|
MOZ_ASSERT(type == TOK_STRING ||
|
||||||
type == TOK_TEMPLATE_HEAD ||
|
type == TOK_TEMPLATE_HEAD ||
|
||||||
|
@ -254,10 +241,22 @@ struct Token
|
||||||
};
|
};
|
||||||
|
|
||||||
class CompileError : public JSErrorReport {
|
class CompileError : public JSErrorReport {
|
||||||
public:
|
public:
|
||||||
void throwError(JSContext* cx);
|
void throwError(JSContext* cx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const char*
|
||||||
|
ReservedWordToCharZ(PropertyName* str);
|
||||||
|
|
||||||
|
extern MOZ_MUST_USE bool
|
||||||
|
IsFutureReservedWord(JSLinearString* str);
|
||||||
|
|
||||||
|
extern MOZ_MUST_USE bool
|
||||||
|
IsReservedWordLiteral(JSLinearString* str);
|
||||||
|
|
||||||
|
extern MOZ_MUST_USE bool
|
||||||
|
IsStrictReservedWord(JSLinearString* str);
|
||||||
|
|
||||||
// Ideally, tokenizing would be entirely independent of context. But the
|
// Ideally, tokenizing would be entirely independent of context. But the
|
||||||
// strict mode flag, which is in SharedContext, affects tokenizing, and
|
// strict mode flag, which is in SharedContext, affects tokenizing, and
|
||||||
// TokenStream needs to see it.
|
// TokenStream needs to see it.
|
||||||
|
@ -344,25 +343,26 @@ class MOZ_STACK_CLASS TokenStream
|
||||||
JSVersion versionNumber() const { return VersionNumber(options().version); }
|
JSVersion versionNumber() const { return VersionNumber(options().version); }
|
||||||
JSVersion versionWithFlags() const { return options().version; }
|
JSVersion versionWithFlags() const { return options().version; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PropertyName* reservedWordToPropertyName(TokenKind tt) const;
|
||||||
|
|
||||||
|
public:
|
||||||
PropertyName* currentName() const {
|
PropertyName* currentName() const {
|
||||||
if (isCurrentTokenType(TOK_YIELD))
|
if (isCurrentTokenType(TOK_NAME)) {
|
||||||
return cx->names().yield;
|
return currentToken().name();
|
||||||
MOZ_ASSERT(isCurrentTokenType(TOK_NAME));
|
}
|
||||||
return currentToken().name();
|
|
||||||
|
MOZ_ASSERT(TokenKindIsPossibleIdentifierName(currentToken().type));
|
||||||
|
return reservedWordToPropertyName(currentToken().type);
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyName* nextName() const {
|
PropertyName* nextName() const {
|
||||||
if (nextToken().type == TOK_YIELD)
|
if (nextToken().type != TOK_NAME) {
|
||||||
return cx->names().yield;
|
return nextToken().name();
|
||||||
MOZ_ASSERT(nextToken().type == TOK_NAME);
|
}
|
||||||
return nextToken().name();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nextNameContainsEscape() const {
|
MOZ_ASSERT(TokenKindIsPossibleIdentifierName(nextToken().type));
|
||||||
if (nextToken().type == TOK_YIELD)
|
return reservedWordToPropertyName(nextToken().type);
|
||||||
return false;
|
|
||||||
MOZ_ASSERT(nextToken().type == TOK_NAME);
|
|
||||||
return nextToken().nameContainsEscape();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isCurrentTokenAssignment() const {
|
bool isCurrentTokenAssignment() const {
|
||||||
|
@ -498,9 +498,6 @@ class MOZ_STACK_CLASS TokenStream
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool awaitIsKeyword = false;
|
|
||||||
friend class AutoAwaitIsKeyword;
|
|
||||||
|
|
||||||
uint32_t invalidTemplateEscapeOffset = 0;
|
uint32_t invalidTemplateEscapeOffset = 0;
|
||||||
InvalidEscapeType invalidTemplateEscapeType = InvalidEscapeType::None;
|
InvalidEscapeType invalidTemplateEscapeType = InvalidEscapeType::None;
|
||||||
|
|
||||||
|
@ -508,14 +505,12 @@ class MOZ_STACK_CLASS TokenStream
|
||||||
typedef Token::Modifier Modifier;
|
typedef Token::Modifier Modifier;
|
||||||
static constexpr Modifier None = Token::None;
|
static constexpr Modifier None = Token::None;
|
||||||
static constexpr Modifier Operand = Token::Operand;
|
static constexpr Modifier Operand = Token::Operand;
|
||||||
static constexpr Modifier KeywordIsName = Token::KeywordIsName;
|
|
||||||
static constexpr Modifier TemplateTail = Token::TemplateTail;
|
static constexpr Modifier TemplateTail = Token::TemplateTail;
|
||||||
|
|
||||||
typedef Token::ModifierException ModifierException;
|
typedef Token::ModifierException ModifierException;
|
||||||
static constexpr ModifierException NoException = Token::NoException;
|
static constexpr ModifierException NoException = Token::NoException;
|
||||||
static constexpr ModifierException NoneIsOperand = Token::NoneIsOperand;
|
static constexpr ModifierException NoneIsOperand = Token::NoneIsOperand;
|
||||||
static constexpr ModifierException OperandIsNone = Token::OperandIsNone;
|
static constexpr ModifierException OperandIsNone = Token::OperandIsNone;
|
||||||
static constexpr ModifierException NoneIsKeywordIsName = Token::NoneIsKeywordIsName;
|
|
||||||
|
|
||||||
void addModifierException(ModifierException modifierException) {
|
void addModifierException(ModifierException modifierException) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -544,10 +539,6 @@ class MOZ_STACK_CLASS TokenStream
|
||||||
MOZ_ASSERT(next.type != TOK_DIV && next.type != TOK_REGEXP,
|
MOZ_ASSERT(next.type != TOK_DIV && next.type != TOK_REGEXP,
|
||||||
"next token requires contextual specifier to be parsed unambiguously");
|
"next token requires contextual specifier to be parsed unambiguously");
|
||||||
break;
|
break;
|
||||||
case NoneIsKeywordIsName:
|
|
||||||
MOZ_ASSERT(next.modifier == KeywordIsName);
|
|
||||||
MOZ_ASSERT(next.type != TOK_NAME);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
MOZ_CRASH("unexpected modifier exception");
|
MOZ_CRASH("unexpected modifier exception");
|
||||||
}
|
}
|
||||||
|
@ -574,12 +565,6 @@ class MOZ_STACK_CLASS TokenStream
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lookaheadToken.modifierException == NoneIsKeywordIsName) {
|
|
||||||
// getToken() permissibly following getToken(KeywordIsName).
|
|
||||||
if (modifier == None && lookaheadToken.modifier == KeywordIsName)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT_UNREACHABLE("this token was previously looked up with a "
|
MOZ_ASSERT_UNREACHABLE("this token was previously looked up with a "
|
||||||
"different modifier, potentially making "
|
"different modifier, potentially making "
|
||||||
"tokenization non-deterministic");
|
"tokenization non-deterministic");
|
||||||
|
@ -713,36 +698,6 @@ class MOZ_STACK_CLASS TokenStream
|
||||||
MOZ_ALWAYS_TRUE(matched);
|
MOZ_ALWAYS_TRUE(matched);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like matchToken(..., TOK_NAME) but further matching the name token only
|
|
||||||
// if it has the given characters, without containing escape sequences.
|
|
||||||
// If the name token has the given characters yet *does* contain an escape,
|
|
||||||
// a syntax error will be reported.
|
|
||||||
//
|
|
||||||
// This latter behavior makes this method unsuitable for use in any context
|
|
||||||
// where ASI might occur. In such places, an escaped "contextual keyword"
|
|
||||||
// on a new line is the start of an ExpressionStatement, not a continuation
|
|
||||||
// of a StatementListItem (or ImportDeclaration or ExportDeclaration, in
|
|
||||||
// modules).
|
|
||||||
MOZ_MUST_USE bool matchContextualKeyword(bool* matchedp, Handle<PropertyName*> keyword,
|
|
||||||
Modifier modifier = None)
|
|
||||||
{
|
|
||||||
TokenKind token;
|
|
||||||
if (!getToken(&token, modifier))
|
|
||||||
return false;
|
|
||||||
if (token == TOK_NAME && currentToken().name() == keyword) {
|
|
||||||
if (currentToken().nameContainsEscape()) {
|
|
||||||
reportError(JSMSG_ESCAPED_KEYWORD);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*matchedp = true;
|
|
||||||
} else {
|
|
||||||
*matchedp = false;
|
|
||||||
ungetToken();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_MUST_USE bool nextTokenEndsExpr(bool* endsExpr) {
|
MOZ_MUST_USE bool nextTokenEndsExpr(bool* endsExpr) {
|
||||||
TokenKind tt;
|
TokenKind tt;
|
||||||
if (!peekToken(&tt))
|
if (!peekToken(&tt))
|
||||||
|
@ -808,19 +763,6 @@ class MOZ_STACK_CLASS TokenStream
|
||||||
return sourceMapURL_.get();
|
return sourceMapURL_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If |atom| is not a keyword in this version, return true with *ttp
|
|
||||||
// unchanged.
|
|
||||||
//
|
|
||||||
// If it is a reserved word in this version and strictness mode, and thus
|
|
||||||
// can't be present in correct code, report a SyntaxError and return false.
|
|
||||||
//
|
|
||||||
// If it is a keyword, like "if", return true with the keyword's TokenKind
|
|
||||||
// in *ttp.
|
|
||||||
MOZ_MUST_USE bool checkForKeyword(JSAtom* atom, TokenKind* ttp);
|
|
||||||
|
|
||||||
// Same semantics as above, but for the provided keyword.
|
|
||||||
MOZ_MUST_USE bool checkForKeyword(const KeywordInfo* kw, TokenKind* ttp);
|
|
||||||
|
|
||||||
// This class maps a userbuf offset (which is 0-indexed) to a line number
|
// This class maps a userbuf offset (which is 0-indexed) to a line number
|
||||||
// (which is 1-indexed) and a column index (which is 0-indexed).
|
// (which is 1-indexed) and a column index (which is 0-indexed).
|
||||||
class SourceCoords
|
class SourceCoords
|
||||||
|
@ -1102,25 +1044,6 @@ class MOZ_STACK_CLASS TokenStream
|
||||||
StrictModeGetter* strictModeGetter; // used to test for strict mode
|
StrictModeGetter* strictModeGetter; // used to test for strict mode
|
||||||
};
|
};
|
||||||
|
|
||||||
class MOZ_STACK_CLASS AutoAwaitIsKeyword
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
TokenStream* ts_;
|
|
||||||
bool oldAwaitIsKeyword_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AutoAwaitIsKeyword(TokenStream* ts, bool awaitIsKeyword) {
|
|
||||||
ts_ = ts;
|
|
||||||
oldAwaitIsKeyword_ = ts_->awaitIsKeyword;
|
|
||||||
ts_->awaitIsKeyword = awaitIsKeyword;
|
|
||||||
}
|
|
||||||
|
|
||||||
~AutoAwaitIsKeyword() {
|
|
||||||
ts_->awaitIsKeyword = oldAwaitIsKeyword_;
|
|
||||||
ts_ = nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const char*
|
extern const char*
|
||||||
TokenKindToDesc(TokenKind tt);
|
TokenKindToDesc(TokenKind tt);
|
||||||
|
|
||||||
|
|
|
@ -403,9 +403,7 @@ assertThrowsInstanceOf(function() {
|
||||||
parseAsModule("export {,} from 'a'");
|
parseAsModule("export {,} from 'a'");
|
||||||
}, SyntaxError);
|
}, SyntaxError);
|
||||||
|
|
||||||
assertThrowsInstanceOf(function() {
|
parseAsModule("export { true as a } from 'b'");
|
||||||
parseAsModule("export { true as a } from 'b'");
|
|
||||||
}, SyntaxError);
|
|
||||||
|
|
||||||
assertThrowsInstanceOf(function () {
|
assertThrowsInstanceOf(function () {
|
||||||
parseAsModule("export { a } from 'b' f();");
|
parseAsModule("export { a } from 'b' f();");
|
||||||
|
|
|
@ -265,6 +265,7 @@ MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations
|
||||||
MSG_DEF(JSMSG_OF_AFTER_FOR_LOOP_DECL, 0, JSEXN_SYNTAXERR, "a declaration in the head of a for-of loop can't have an initializer")
|
MSG_DEF(JSMSG_OF_AFTER_FOR_LOOP_DECL, 0, JSEXN_SYNTAXERR, "a declaration in the head of a for-of loop can't have an initializer")
|
||||||
MSG_DEF(JSMSG_IN_AFTER_LEXICAL_FOR_DECL,0,JSEXN_SYNTAXERR, "a lexical declaration in the head of a for-in loop can't have an initializer")
|
MSG_DEF(JSMSG_IN_AFTER_LEXICAL_FOR_DECL,0,JSEXN_SYNTAXERR, "a lexical declaration in the head of a for-in loop can't have an initializer")
|
||||||
MSG_DEF(JSMSG_INVALID_FOR_IN_DECL_WITH_INIT,0,JSEXN_SYNTAXERR,"for-in loop head declarations may not have initializers")
|
MSG_DEF(JSMSG_INVALID_FOR_IN_DECL_WITH_INIT,0,JSEXN_SYNTAXERR,"for-in loop head declarations may not have initializers")
|
||||||
|
MSG_DEF(JSMSG_INVALID_ID, 1, JSEXN_SYNTAXERR, "{0} is an invalid identifier")
|
||||||
MSG_DEF(JSMSG_LABEL_NOT_FOUND, 0, JSEXN_SYNTAXERR, "label not found")
|
MSG_DEF(JSMSG_LABEL_NOT_FOUND, 0, JSEXN_SYNTAXERR, "label not found")
|
||||||
MSG_DEF(JSMSG_LET_COMP_BINDING, 0, JSEXN_SYNTAXERR, "'let' is not a valid name for a comprehension variable")
|
MSG_DEF(JSMSG_LET_COMP_BINDING, 0, JSEXN_SYNTAXERR, "'let' is not a valid name for a comprehension variable")
|
||||||
MSG_DEF(JSMSG_LEXICAL_DECL_NOT_IN_BLOCK, 1, JSEXN_SYNTAXERR, "{0} declaration not directly within block")
|
MSG_DEF(JSMSG_LEXICAL_DECL_NOT_IN_BLOCK, 1, JSEXN_SYNTAXERR, "{0} declaration not directly within block")
|
||||||
|
|
|
@ -54,41 +54,9 @@ FOR_EACH_COMMON_PROPERTYNAME(CONST_CHAR_STR)
|
||||||
#undef CONST_CHAR_STR
|
#undef CONST_CHAR_STR
|
||||||
|
|
||||||
/* Constant strings that are not atomized. */
|
/* Constant strings that are not atomized. */
|
||||||
const char js_break_str[] = "break";
|
|
||||||
const char js_case_str[] = "case";
|
|
||||||
const char js_catch_str[] = "catch";
|
|
||||||
const char js_class_str[] = "class";
|
|
||||||
const char js_const_str[] = "const";
|
|
||||||
const char js_continue_str[] = "continue";
|
|
||||||
const char js_debugger_str[] = "debugger";
|
|
||||||
const char js_default_str[] = "default";
|
|
||||||
const char js_do_str[] = "do";
|
|
||||||
const char js_else_str[] = "else";
|
|
||||||
const char js_enum_str[] = "enum";
|
|
||||||
const char js_export_str[] = "export";
|
|
||||||
const char js_extends_str[] = "extends";
|
|
||||||
const char js_finally_str[] = "finally";
|
|
||||||
const char js_for_str[] = "for";
|
|
||||||
const char js_getter_str[] = "getter";
|
const char js_getter_str[] = "getter";
|
||||||
const char js_if_str[] = "if";
|
|
||||||
const char js_implements_str[] = "implements";
|
|
||||||
const char js_import_str[] = "import";
|
|
||||||
const char js_in_str[] = "in";
|
|
||||||
const char js_instanceof_str[] = "instanceof";
|
|
||||||
const char js_interface_str[] = "interface";
|
|
||||||
const char js_package_str[] = "package";
|
|
||||||
const char js_private_str[] = "private";
|
|
||||||
const char js_protected_str[] = "protected";
|
|
||||||
const char js_public_str[] = "public";
|
|
||||||
const char js_send_str[] = "send";
|
const char js_send_str[] = "send";
|
||||||
const char js_setter_str[] = "setter";
|
const char js_setter_str[] = "setter";
|
||||||
const char js_switch_str[] = "switch";
|
|
||||||
const char js_this_str[] = "this";
|
|
||||||
const char js_try_str[] = "try";
|
|
||||||
const char js_typeof_str[] = "typeof";
|
|
||||||
const char js_void_str[] = "void";
|
|
||||||
const char js_while_str[] = "while";
|
|
||||||
const char js_with_str[] = "with";
|
|
||||||
|
|
||||||
// Use a low initial capacity for atom hash tables to avoid penalizing runtimes
|
// Use a low initial capacity for atom hash tables to avoid penalizing runtimes
|
||||||
// which create a small number of atoms.
|
// which create a small number of atoms.
|
||||||
|
|
|
@ -142,44 +142,9 @@ FOR_EACH_COMMON_PROPERTYNAME(DECLARE_CONST_CHAR_STR)
|
||||||
#undef DECLARE_CONST_CHAR_STR
|
#undef DECLARE_CONST_CHAR_STR
|
||||||
|
|
||||||
/* Constant strings that are not atomized. */
|
/* Constant strings that are not atomized. */
|
||||||
extern const char js_break_str[];
|
|
||||||
extern const char js_case_str[];
|
|
||||||
extern const char js_catch_str[];
|
|
||||||
extern const char js_class_str[];
|
|
||||||
extern const char js_close_str[];
|
|
||||||
extern const char js_const_str[];
|
|
||||||
extern const char js_continue_str[];
|
|
||||||
extern const char js_debugger_str[];
|
|
||||||
extern const char js_default_str[];
|
|
||||||
extern const char js_do_str[];
|
|
||||||
extern const char js_else_str[];
|
|
||||||
extern const char js_enum_str[];
|
|
||||||
extern const char js_export_str[];
|
|
||||||
extern const char js_extends_str[];
|
|
||||||
extern const char js_finally_str[];
|
|
||||||
extern const char js_for_str[];
|
|
||||||
extern const char js_getter_str[];
|
extern const char js_getter_str[];
|
||||||
extern const char js_if_str[];
|
|
||||||
extern const char js_implements_str[];
|
|
||||||
extern const char js_import_str[];
|
|
||||||
extern const char js_in_str[];
|
|
||||||
extern const char js_instanceof_str[];
|
|
||||||
extern const char js_interface_str[];
|
|
||||||
extern const char js_package_str[];
|
|
||||||
extern const char js_private_str[];
|
|
||||||
extern const char js_protected_str[];
|
|
||||||
extern const char js_public_str[];
|
|
||||||
extern const char js_send_str[];
|
extern const char js_send_str[];
|
||||||
extern const char js_setter_str[];
|
extern const char js_setter_str[];
|
||||||
extern const char js_static_str[];
|
|
||||||
extern const char js_super_str[];
|
|
||||||
extern const char js_switch_str[];
|
|
||||||
extern const char js_this_str[];
|
|
||||||
extern const char js_try_str[];
|
|
||||||
extern const char js_typeof_str[];
|
|
||||||
extern const char js_void_str[];
|
|
||||||
extern const char js_while_str[];
|
|
||||||
extern const char js_with_str[];
|
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
|
|
|
@ -619,11 +619,11 @@ else:
|
||||||
'perf/pm_stub.cpp'
|
'perf/pm_stub.cpp'
|
||||||
]
|
]
|
||||||
|
|
||||||
GENERATED_FILES += ['jsautokw.h']
|
GENERATED_FILES += ['frontend/ReservedWordsGenerated.h']
|
||||||
jsautokw = GENERATED_FILES['jsautokw.h']
|
ReservedWordsGenerated = GENERATED_FILES['frontend/ReservedWordsGenerated.h']
|
||||||
jsautokw.script = 'jsautokw.py'
|
ReservedWordsGenerated.script = 'frontend/GenerateReservedWords.py'
|
||||||
jsautokw.inputs += [
|
ReservedWordsGenerated.inputs += [
|
||||||
'vm/Keywords.h'
|
'frontend/ReservedWords.h'
|
||||||
]
|
]
|
||||||
|
|
||||||
# JavaScript must be built shared, even for static builds, as it is used by
|
# JavaScript must be built shared, even for static builds, as it is used by
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
macro(Bool32x4, Bool32x4, "Bool32x4") \
|
macro(Bool32x4, Bool32x4, "Bool32x4") \
|
||||||
macro(Bool64x2, Bool64x2, "Bool64x2") \
|
macro(Bool64x2, Bool64x2, "Bool64x2") \
|
||||||
macro(boundWithSpace, boundWithSpace, "bound ") \
|
macro(boundWithSpace, boundWithSpace, "bound ") \
|
||||||
|
macro(break, break_, "break") \
|
||||||
macro(breakdown, breakdown, "breakdown") \
|
macro(breakdown, breakdown, "breakdown") \
|
||||||
macro(buffer, buffer, "buffer") \
|
macro(buffer, buffer, "buffer") \
|
||||||
macro(builder, builder, "builder") \
|
macro(builder, builder, "builder") \
|
||||||
|
@ -52,8 +53,10 @@
|
||||||
macro(callee, callee, "callee") \
|
macro(callee, callee, "callee") \
|
||||||
macro(caller, caller, "caller") \
|
macro(caller, caller, "caller") \
|
||||||
macro(callFunction, callFunction, "callFunction") \
|
macro(callFunction, callFunction, "callFunction") \
|
||||||
|
macro(case, case_, "case") \
|
||||||
macro(caseFirst, caseFirst, "caseFirst") \
|
macro(caseFirst, caseFirst, "caseFirst") \
|
||||||
macro(class_, class_, "class") \
|
macro(catch, catch_, "catch") \
|
||||||
|
macro(class, class_, "class") \
|
||||||
macro(close, close, "close") \
|
macro(close, close, "close") \
|
||||||
macro(Collator, Collator, "Collator") \
|
macro(Collator, Collator, "Collator") \
|
||||||
macro(CollatorCompareGet, CollatorCompareGet, "Intl_Collator_compare_get") \
|
macro(CollatorCompareGet, CollatorCompareGet, "Intl_Collator_compare_get") \
|
||||||
|
@ -62,9 +65,11 @@
|
||||||
macro(comma, comma, ",") \
|
macro(comma, comma, ",") \
|
||||||
macro(compare, compare, "compare") \
|
macro(compare, compare, "compare") \
|
||||||
macro(configurable, configurable, "configurable") \
|
macro(configurable, configurable, "configurable") \
|
||||||
|
macro(const, const_, "const") \
|
||||||
macro(construct, construct, "construct") \
|
macro(construct, construct, "construct") \
|
||||||
macro(constructContentFunction, constructContentFunction, "constructContentFunction") \
|
macro(constructContentFunction, constructContentFunction, "constructContentFunction") \
|
||||||
macro(constructor, constructor, "constructor") \
|
macro(constructor, constructor, "constructor") \
|
||||||
|
macro(continue, continue_, "continue") \
|
||||||
macro(ConvertAndCopyTo, ConvertAndCopyTo, "ConvertAndCopyTo") \
|
macro(ConvertAndCopyTo, ConvertAndCopyTo, "ConvertAndCopyTo") \
|
||||||
macro(copyWithin, copyWithin, "copyWithin") \
|
macro(copyWithin, copyWithin, "copyWithin") \
|
||||||
macro(count, count, "count") \
|
macro(count, count, "count") \
|
||||||
|
@ -76,28 +81,32 @@
|
||||||
macro(DateTimeFormatFormatToParts, DateTimeFormatFormatToParts, "Intl_DateTimeFormat_formatToParts") \
|
macro(DateTimeFormatFormatToParts, DateTimeFormatFormatToParts, "Intl_DateTimeFormat_formatToParts") \
|
||||||
macro(day, day, "day") \
|
macro(day, day, "day") \
|
||||||
macro(dayPeriod, dayPeriod, "dayPeriod") \
|
macro(dayPeriod, dayPeriod, "dayPeriod") \
|
||||||
|
macro(debugger, debugger, "debugger") \
|
||||||
macro(decodeURI, decodeURI, "decodeURI") \
|
macro(decodeURI, decodeURI, "decodeURI") \
|
||||||
macro(decodeURIComponent, decodeURIComponent, "decodeURIComponent") \
|
macro(decodeURIComponent, decodeURIComponent, "decodeURIComponent") \
|
||||||
macro(DefaultBaseClassConstructor, DefaultBaseClassConstructor, "DefaultBaseClassConstructor") \
|
macro(DefaultBaseClassConstructor, DefaultBaseClassConstructor, "DefaultBaseClassConstructor") \
|
||||||
macro(DefaultDerivedClassConstructor, DefaultDerivedClassConstructor, "DefaultDerivedClassConstructor") \
|
macro(DefaultDerivedClassConstructor, DefaultDerivedClassConstructor, "DefaultDerivedClassConstructor") \
|
||||||
macro(default_, default_, "default") \
|
macro(default, default_, "default") \
|
||||||
macro(defineGetter, defineGetter, "__defineGetter__") \
|
macro(defineGetter, defineGetter, "__defineGetter__") \
|
||||||
macro(defineProperty, defineProperty, "defineProperty") \
|
macro(defineProperty, defineProperty, "defineProperty") \
|
||||||
macro(defineSetter, defineSetter, "__defineSetter__") \
|
macro(defineSetter, defineSetter, "__defineSetter__") \
|
||||||
macro(delete, delete_, "delete") \
|
macro(delete, delete_, "delete") \
|
||||||
macro(deleteProperty, deleteProperty, "deleteProperty") \
|
macro(deleteProperty, deleteProperty, "deleteProperty") \
|
||||||
macro(displayURL, displayURL, "displayURL") \
|
macro(displayURL, displayURL, "displayURL") \
|
||||||
|
macro(do, do_, "do") \
|
||||||
macro(done, done, "done") \
|
macro(done, done, "done") \
|
||||||
macro(dotGenerator, dotGenerator, ".generator") \
|
macro(dotGenerator, dotGenerator, ".generator") \
|
||||||
macro(dotThis, dotThis, ".this") \
|
macro(dotThis, dotThis, ".this") \
|
||||||
macro(each, each, "each") \
|
macro(each, each, "each") \
|
||||||
macro(elementType, elementType, "elementType") \
|
macro(elementType, elementType, "elementType") \
|
||||||
|
macro(else, else_, "else") \
|
||||||
macro(empty, empty, "") \
|
macro(empty, empty, "") \
|
||||||
macro(emptyRegExp, emptyRegExp, "(?:)") \
|
macro(emptyRegExp, emptyRegExp, "(?:)") \
|
||||||
macro(encodeURI, encodeURI, "encodeURI") \
|
macro(encodeURI, encodeURI, "encodeURI") \
|
||||||
macro(encodeURIComponent, encodeURIComponent, "encodeURIComponent") \
|
macro(encodeURIComponent, encodeURIComponent, "encodeURIComponent") \
|
||||||
macro(endTimestamp, endTimestamp, "endTimestamp") \
|
macro(endTimestamp, endTimestamp, "endTimestamp") \
|
||||||
macro(entries, entries, "entries") \
|
macro(entries, entries, "entries") \
|
||||||
|
macro(enum, enum_, "enum") \
|
||||||
macro(enumerable, enumerable, "enumerable") \
|
macro(enumerable, enumerable, "enumerable") \
|
||||||
macro(enumerate, enumerate, "enumerate") \
|
macro(enumerate, enumerate, "enumerate") \
|
||||||
macro(era, era, "era") \
|
macro(era, era, "era") \
|
||||||
|
@ -105,11 +114,14 @@
|
||||||
macro(escape, escape, "escape") \
|
macro(escape, escape, "escape") \
|
||||||
macro(eval, eval, "eval") \
|
macro(eval, eval, "eval") \
|
||||||
macro(exec, exec, "exec") \
|
macro(exec, exec, "exec") \
|
||||||
|
macro(export, export_, "export") \
|
||||||
|
macro(extends, extends, "extends") \
|
||||||
macro(false, false_, "false") \
|
macro(false, false_, "false") \
|
||||||
macro(fieldOffsets, fieldOffsets, "fieldOffsets") \
|
macro(fieldOffsets, fieldOffsets, "fieldOffsets") \
|
||||||
macro(fieldTypes, fieldTypes, "fieldTypes") \
|
macro(fieldTypes, fieldTypes, "fieldTypes") \
|
||||||
macro(fileName, fileName, "fileName") \
|
macro(fileName, fileName, "fileName") \
|
||||||
macro(fill, fill, "fill") \
|
macro(fill, fill, "fill") \
|
||||||
|
macro(finally, finally_, "finally") \
|
||||||
macro(find, find, "find") \
|
macro(find, find, "find") \
|
||||||
macro(findIndex, findIndex, "findIndex") \
|
macro(findIndex, findIndex, "findIndex") \
|
||||||
macro(firstDayOfWeek, firstDayOfWeek, "firstDayOfWeek") \
|
macro(firstDayOfWeek, firstDayOfWeek, "firstDayOfWeek") \
|
||||||
|
@ -121,6 +133,7 @@
|
||||||
macro(Float32x4, Float32x4, "Float32x4") \
|
macro(Float32x4, Float32x4, "Float32x4") \
|
||||||
macro(float64, float64, "float64") \
|
macro(float64, float64, "float64") \
|
||||||
macro(Float64x2, Float64x2, "Float64x2") \
|
macro(Float64x2, Float64x2, "Float64x2") \
|
||||||
|
macro(for, for_, "for") \
|
||||||
macro(forceInterpreter, forceInterpreter, "forceInterpreter") \
|
macro(forceInterpreter, forceInterpreter, "forceInterpreter") \
|
||||||
macro(forEach, forEach, "forEach") \
|
macro(forEach, forEach, "forEach") \
|
||||||
macro(format, format, "format") \
|
macro(format, format, "format") \
|
||||||
|
@ -146,8 +159,12 @@
|
||||||
macro(hasOwn, hasOwn, "hasOwn") \
|
macro(hasOwn, hasOwn, "hasOwn") \
|
||||||
macro(hasOwnProperty, hasOwnProperty, "hasOwnProperty") \
|
macro(hasOwnProperty, hasOwnProperty, "hasOwnProperty") \
|
||||||
macro(hour, hour, "hour") \
|
macro(hour, hour, "hour") \
|
||||||
|
macro(if, if_, "if") \
|
||||||
macro(ignoreCase, ignoreCase, "ignoreCase") \
|
macro(ignoreCase, ignoreCase, "ignoreCase") \
|
||||||
macro(ignorePunctuation, ignorePunctuation, "ignorePunctuation") \
|
macro(ignorePunctuation, ignorePunctuation, "ignorePunctuation") \
|
||||||
|
macro(implements, implements, "implements") \
|
||||||
|
macro(import, import, "import") \
|
||||||
|
macro(in, in, "in") \
|
||||||
macro(includes, includes, "includes") \
|
macro(includes, includes, "includes") \
|
||||||
macro(incumbentGlobal, incumbentGlobal, "incumbentGlobal") \
|
macro(incumbentGlobal, incumbentGlobal, "incumbentGlobal") \
|
||||||
macro(index, index, "index") \
|
macro(index, index, "index") \
|
||||||
|
@ -158,12 +175,14 @@
|
||||||
macro(innermost, innermost, "innermost") \
|
macro(innermost, innermost, "innermost") \
|
||||||
macro(inNursery, inNursery, "inNursery") \
|
macro(inNursery, inNursery, "inNursery") \
|
||||||
macro(input, input, "input") \
|
macro(input, input, "input") \
|
||||||
|
macro(instanceof, instanceof, "instanceof") \
|
||||||
macro(int8, int8, "int8") \
|
macro(int8, int8, "int8") \
|
||||||
macro(int16, int16, "int16") \
|
macro(int16, int16, "int16") \
|
||||||
macro(int32, int32, "int32") \
|
macro(int32, int32, "int32") \
|
||||||
macro(Int8x16, Int8x16, "Int8x16") \
|
macro(Int8x16, Int8x16, "Int8x16") \
|
||||||
macro(Int16x8, Int16x8, "Int16x8") \
|
macro(Int16x8, Int16x8, "Int16x8") \
|
||||||
macro(Int32x4, Int32x4, "Int32x4") \
|
macro(Int32x4, Int32x4, "Int32x4") \
|
||||||
|
macro(interface, interface, "interface") \
|
||||||
macro(InterpretGeneratorResume, InterpretGeneratorResume, "InterpretGeneratorResume") \
|
macro(InterpretGeneratorResume, InterpretGeneratorResume, "InterpretGeneratorResume") \
|
||||||
macro(isEntryPoint, isEntryPoint, "isEntryPoint") \
|
macro(isEntryPoint, isEntryPoint, "isEntryPoint") \
|
||||||
macro(isExtensible, isExtensible, "isExtensible") \
|
macro(isExtensible, isExtensible, "isExtensible") \
|
||||||
|
@ -240,13 +259,17 @@
|
||||||
macro(outOfMemory, outOfMemory, "out of memory") \
|
macro(outOfMemory, outOfMemory, "out of memory") \
|
||||||
macro(ownKeys, ownKeys, "ownKeys") \
|
macro(ownKeys, ownKeys, "ownKeys") \
|
||||||
macro(Object_valueOf, Object_valueOf, "Object_valueOf") \
|
macro(Object_valueOf, Object_valueOf, "Object_valueOf") \
|
||||||
|
macro(package, package, "package") \
|
||||||
macro(parseFloat, parseFloat, "parseFloat") \
|
macro(parseFloat, parseFloat, "parseFloat") \
|
||||||
macro(parseInt, parseInt, "parseInt") \
|
macro(parseInt, parseInt, "parseInt") \
|
||||||
macro(pattern, pattern, "pattern") \
|
macro(pattern, pattern, "pattern") \
|
||||||
macro(pending, pending, "pending") \
|
macro(pending, pending, "pending") \
|
||||||
|
macro(public, public_, "public") \
|
||||||
macro(preventExtensions, preventExtensions, "preventExtensions") \
|
macro(preventExtensions, preventExtensions, "preventExtensions") \
|
||||||
|
macro(private, private_, "private") \
|
||||||
macro(promise, promise, "promise") \
|
macro(promise, promise, "promise") \
|
||||||
macro(propertyIsEnumerable, propertyIsEnumerable, "propertyIsEnumerable") \
|
macro(propertyIsEnumerable, propertyIsEnumerable, "propertyIsEnumerable") \
|
||||||
|
macro(protected, protected_, "protected") \
|
||||||
macro(proto, proto, "__proto__") \
|
macro(proto, proto, "__proto__") \
|
||||||
macro(prototype, prototype, "prototype") \
|
macro(prototype, prototype, "prototype") \
|
||||||
macro(proxy, proxy, "proxy") \
|
macro(proxy, proxy, "proxy") \
|
||||||
|
@ -295,10 +318,12 @@
|
||||||
macro(StructType, StructType, "StructType") \
|
macro(StructType, StructType, "StructType") \
|
||||||
macro(style, style, "style") \
|
macro(style, style, "style") \
|
||||||
macro(super, super, "super") \
|
macro(super, super, "super") \
|
||||||
|
macro(switch, switch_, "switch") \
|
||||||
macro(Symbol_iterator_fun, Symbol_iterator_fun, "[Symbol.iterator]") \
|
macro(Symbol_iterator_fun, Symbol_iterator_fun, "[Symbol.iterator]") \
|
||||||
macro(target, target, "target") \
|
macro(target, target, "target") \
|
||||||
macro(test, test, "test") \
|
macro(test, test, "test") \
|
||||||
macro(then, then, "then") \
|
macro(then, then, "then") \
|
||||||
|
macro(this, this_, "this") \
|
||||||
macro(throw, throw_, "throw") \
|
macro(throw, throw_, "throw") \
|
||||||
macro(timestamp, timestamp, "timestamp") \
|
macro(timestamp, timestamp, "timestamp") \
|
||||||
macro(timeZone, timeZone, "timeZone") \
|
macro(timeZone, timeZone, "timeZone") \
|
||||||
|
@ -311,7 +336,9 @@
|
||||||
macro(toString, toString, "toString") \
|
macro(toString, toString, "toString") \
|
||||||
macro(toUTCString, toUTCString, "toUTCString") \
|
macro(toUTCString, toUTCString, "toUTCString") \
|
||||||
macro(true, true_, "true") \
|
macro(true, true_, "true") \
|
||||||
|
macro(try, try_, "try") \
|
||||||
macro(type, type, "type") \
|
macro(type, type, "type") \
|
||||||
|
macro(typeof, typeof_, "typeof") \
|
||||||
macro(uint8, uint8, "uint8") \
|
macro(uint8, uint8, "uint8") \
|
||||||
macro(uint8Clamped, uint8Clamped, "uint8Clamped") \
|
macro(uint8Clamped, uint8Clamped, "uint8Clamped") \
|
||||||
macro(uint16, uint16, "uint16") \
|
macro(uint16, uint16, "uint16") \
|
||||||
|
@ -331,6 +358,7 @@
|
||||||
macro(useAsm, useAsm, "use asm") \
|
macro(useAsm, useAsm, "use asm") \
|
||||||
macro(useGrouping, useGrouping, "useGrouping") \
|
macro(useGrouping, useGrouping, "useGrouping") \
|
||||||
macro(useStrict, useStrict, "use strict") \
|
macro(useStrict, useStrict, "use strict") \
|
||||||
|
macro(void, void_, "void") \
|
||||||
macro(value, value, "value") \
|
macro(value, value, "value") \
|
||||||
macro(valueOf, valueOf, "valueOf") \
|
macro(valueOf, valueOf, "valueOf") \
|
||||||
macro(values, values, "values") \
|
macro(values, values, "values") \
|
||||||
|
@ -345,6 +373,8 @@
|
||||||
macro(weekday, weekday, "weekday") \
|
macro(weekday, weekday, "weekday") \
|
||||||
macro(weekendEnd, weekendEnd, "weekendEnd") \
|
macro(weekendEnd, weekendEnd, "weekendEnd") \
|
||||||
macro(weekendStart, weekendStart, "weekendStart") \
|
macro(weekendStart, weekendStart, "weekendStart") \
|
||||||
|
macro(while, while_, "while") \
|
||||||
|
macro(with, with, "with") \
|
||||||
macro(writable, writable, "writable") \
|
macro(writable, writable, "writable") \
|
||||||
macro(year, year, "year") \
|
macro(year, year, "year") \
|
||||||
macro(yield, yield, "yield") \
|
macro(yield, yield, "yield") \
|
||||||
|
|
|
@ -7057,7 +7057,7 @@ ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line)
|
||||||
TokenKind tk;
|
TokenKind tk;
|
||||||
if (!tokenStream.getToken(&tk, TokenStream::Operand))
|
if (!tokenStream.getToken(&tk, TokenStream::Operand))
|
||||||
return false;
|
return false;
|
||||||
if (tk != TOK_NAME && tk != TOK_YIELD)
|
if (!TokenKindIsPossibleIdentifier(tk))
|
||||||
return false; // The regular parser will throw a SyntaxError, no need to m.fail.
|
return false; // The regular parser will throw a SyntaxError, no need to m.fail.
|
||||||
|
|
||||||
RootedPropertyName name(m.cx(), m.parser().bindingIdentifier(YieldIsName));
|
RootedPropertyName name(m.cx(), m.parser().bindingIdentifier(YieldIsName));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user