Diff
Modified: trunk/JSTests/ChangeLog (223231 => 223232)
--- trunk/JSTests/ChangeLog 2017-10-12 06:15:11 UTC (rev 223231)
+++ trunk/JSTests/ChangeLog 2017-10-12 06:45:23 UTC (rev 223232)
@@ -1,3 +1,14 @@
+2017-10-11 Yusuke Suzuki <[email protected]>
+
+ import.meta should not be assignable
+ https://bugs.webkit.org/show_bug.cgi?id=178202
+
+ Reviewed by Saam Barati.
+
+ * modules/import-meta-assignment.js: Added.
+ (shouldThrow):
+ (SyntaxError.import.meta.can.shouldThrow):
+
2017-10-11 Saam Barati <[email protected]>
Unreviewed. Actually skip certain type profiler tests in debug.
Added: trunk/JSTests/modules/import-meta-assignment.js (0 => 223232)
--- trunk/JSTests/modules/import-meta-assignment.js (rev 0)
+++ trunk/JSTests/modules/import-meta-assignment.js 2017-10-12 06:45:23 UTC (rev 223232)
@@ -0,0 +1,25 @@
+import { shouldThrow } from "./resources/assert.js";
+
+shouldThrow(() => {
+ checkModuleSyntax(`import.meta = 42`);
+}, `SyntaxError: import.meta can't be the left hand side of an assignment _expression_.:1`);
+
+shouldThrow(() => {
+ checkModuleSyntax(`import.meta += 42`);
+}, `SyntaxError: import.meta can't be the left hand side of an assignment _expression_.:1`);
+
+shouldThrow(() => {
+ checkModuleSyntax(`++import.meta`);
+}, `SyntaxError: import.meta can't come after a prefix operator.:1`);
+
+shouldThrow(() => {
+ checkModuleSyntax(`--import.meta`);
+}, `SyntaxError: import.meta can't come after a prefix operator.:1`);
+
+shouldThrow(() => {
+ checkModuleSyntax(`import.meta++`);
+}, `SyntaxError: import.meta can't come before a postfix operator.:1`);
+
+shouldThrow(() => {
+ checkModuleSyntax(`import.meta--`);
+}, `SyntaxError: import.meta can't come before a postfix operator.:1`);
Modified: trunk/Source/_javascript_Core/ChangeLog (223231 => 223232)
--- trunk/Source/_javascript_Core/ChangeLog 2017-10-12 06:15:11 UTC (rev 223231)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-10-12 06:45:23 UTC (rev 223232)
@@ -1,3 +1,38 @@
+2017-10-11 Yusuke Suzuki <[email protected]>
+
+ import.meta should not be assignable
+ https://bugs.webkit.org/show_bug.cgi?id=178202
+
+ Reviewed by Saam Barati.
+
+ `import.meta` cannot be used for LHS. This patch adds MetaPropertyNode
+ and make NewTargetNode and ImportMetaNode as derived classes of MetaPropertyNode.
+ We change the parser not to allow assignments for MetaPropertyNode.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ImportMetaNode::emitBytecode):
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::createImportMetaExpr):
+ (JSC::ASTBuilder::isMetaProperty):
+ (JSC::ASTBuilder::isImportMeta):
+ * parser/NodeConstructors.h:
+ (JSC::MetaPropertyNode::MetaPropertyNode):
+ (JSC::NewTargetNode::NewTargetNode):
+ (JSC::ImportMetaNode::ImportMetaNode):
+ * parser/Nodes.h:
+ (JSC::ExpressionNode::isMetaProperty const):
+ (JSC::ExpressionNode::isImportMeta const):
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::metaPropertyName):
+ (JSC::Parser<LexerType>::parseAssignmentExpression):
+ (JSC::Parser<LexerType>::parseMemberExpression):
+ (JSC::Parser<LexerType>::parseUnaryExpression):
+ * parser/Parser.h:
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::createImportMetaExpr):
+ (JSC::SyntaxChecker::isMetaProperty):
+ (JSC::SyntaxChecker::isImportMeta):
+
2017-10-11 Saam Barati <[email protected]>
Runtime disable poly proto because it may be a 3-4% Speedometer regression
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (223231 => 223232)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-10-12 06:15:11 UTC (rev 223231)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-10-12 06:45:23 UTC (rev 223232)
@@ -211,6 +211,13 @@
return generator.moveToDestinationIfNeeded(dst, generator.newTarget());
}
+// ------------------------------ ImportMetaNode ---------------------------------
+
+RegisterID* ImportMetaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ return generator.emitNode(dst, m_expr);
+}
+
// ------------------------------ ResolveNode ----------------------------------
bool ResolveNode::isPure(BytecodeGenerator& generator) const
Modified: trunk/Source/_javascript_Core/parser/ASTBuilder.h (223231 => 223232)
--- trunk/Source/_javascript_Core/parser/ASTBuilder.h 2017-10-12 06:15:11 UTC (rev 223231)
+++ trunk/Source/_javascript_Core/parser/ASTBuilder.h 2017-10-12 06:45:23 UTC (rev 223232)
@@ -189,7 +189,10 @@
usesNewTarget();
return new (m_parserArena) NewTargetNode(location);
}
+ ExpressionNode* createImportMetaExpr(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_parserArena) ImportMetaNode(location, expr); }
+ bool isMetaProperty(ExpressionNode* node) { return node->isMetaProperty(); }
bool isNewTarget(ExpressionNode* node) { return node->isNewTarget(); }
+ bool isImportMeta(ExpressionNode* node) { return node->isImportMeta(); }
ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier& ident, const JSTextPosition& start, const JSTextPosition& end)
{
if (m_vm->propertyNames->arguments == ident)
Modified: trunk/Source/_javascript_Core/parser/NodeConstructors.h (223231 => 223232)
--- trunk/Source/_javascript_Core/parser/NodeConstructors.h 2017-10-12 06:15:11 UTC (rev 223231)
+++ trunk/Source/_javascript_Core/parser/NodeConstructors.h 2017-10-12 06:45:23 UTC (rev 223232)
@@ -171,11 +171,22 @@
{
}
- inline NewTargetNode::NewTargetNode(const JSTokenLocation& location)
+ inline MetaPropertyNode::MetaPropertyNode(const JSTokenLocation& location)
: ExpressionNode(location)
{
}
+ inline NewTargetNode::NewTargetNode(const JSTokenLocation& location)
+ : MetaPropertyNode(location)
+ {
+ }
+
+ inline ImportMetaNode::ImportMetaNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : MetaPropertyNode(location)
+ , m_expr(expr)
+ {
+ }
+
inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifier& ident, const JSTextPosition& start)
: ExpressionNode(location)
, m_ident(ident)
Modified: trunk/Source/_javascript_Core/parser/Nodes.h (223231 => 223232)
--- trunk/Source/_javascript_Core/parser/Nodes.h 2017-10-12 06:15:11 UTC (rev 223231)
+++ trunk/Source/_javascript_Core/parser/Nodes.h 2017-10-12 06:45:23 UTC (rev 223232)
@@ -186,7 +186,9 @@
virtual bool isSpreadExpression() const { return false; }
virtual bool isSuperNode() const { return false; }
virtual bool isImportNode() const { return false; }
+ virtual bool isMetaProperty() const { return false; }
virtual bool isNewTarget() const { return false; }
+ virtual bool isImportMeta() const { return false; }
virtual bool isBytecodeIntrinsicNode() const { return false; }
virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label&, Label&, FallThroughMode);
@@ -584,8 +586,16 @@
ExpressionNode* m_expr;
};
- class NewTargetNode final : public ExpressionNode {
+ class MetaPropertyNode : public ExpressionNode {
public:
+ MetaPropertyNode(const JSTokenLocation&);
+
+ private:
+ bool isMetaProperty() const final { return true; }
+ };
+
+ class NewTargetNode final : public MetaPropertyNode {
+ public:
NewTargetNode(const JSTokenLocation&);
private:
@@ -593,6 +603,17 @@
RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
+ class ImportMetaNode final : public MetaPropertyNode {
+ public:
+ ImportMetaNode(const JSTokenLocation&, ExpressionNode*);
+
+ private:
+ bool isImportMeta() const final { return true; }
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
+ };
+
class ResolveNode : public ExpressionNode {
public:
ResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& start);
Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (223231 => 223232)
--- trunk/Source/_javascript_Core/parser/Parser.cpp 2017-10-12 06:15:11 UTC (rev 223231)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp 2017-10-12 06:45:23 UTC (rev 223232)
@@ -3585,6 +3585,18 @@
ExpressionErrorClassifier classifier(this);
return parseAssignmentExpression(context, classifier);
}
+
+
+template <typename LexerType>
+template <typename TreeBuilder> NEVER_INLINE const char* Parser<LexerType>::metaPropertyName(TreeBuilder& context, TreeExpression expr)
+{
+ if (context.isNewTarget(expr))
+ return "new.target";
+ if (context.isImportMeta(expr))
+ return "import.meta";
+ RELEASE_ASSERT_NOT_REACHED();
+ return "error";
+}
template <typename LexerType>
template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpression(TreeBuilder& context, ExpressionErrorClassifier& classifier)
@@ -3690,8 +3702,8 @@
}
m_parserState.nonTrivialExpressionCount++;
hadAssignment = true;
- if (UNLIKELY(context.isNewTarget(lhs)))
- internalFailWithMessage(false, "new.target can't be the left hand side of an assignment _expression_");
+ if (UNLIKELY(context.isMetaProperty(lhs)))
+ internalFailWithMessage(false, metaPropertyName(context, lhs), " can't be the left hand side of an assignment _expression_");
context.assignmentStackAppend(assignmentStack, lhs, start, tokenStartPosition(), m_parserState.assignmentCount, op);
start = tokenStartPosition();
m_parserState.assignmentCount++;
@@ -4698,7 +4710,7 @@
semanticFailIfFalse(m_scriptMode == JSParserScriptMode::Module, "import.meta is only valid inside modules");
JSTokenLocation location(tokenLocation());
- base = createResolveAndUseVariable(context, &m_vm->propertyNames->builtinNames().metaPrivateName(), false, expressionStart, location);
+ base = context.createImportMetaExpr(location, createResolveAndUseVariable(context, &m_vm->propertyNames->builtinNames().metaPrivateName(), false, expressionStart, location));
next();
} else {
failIfTrue(match(IDENT), "\"import.\" can only followed with meta");
@@ -4924,8 +4936,8 @@
failWithMessage("Cannot parse subexpression of ", operatorString(true, lastOperator), "operator");
failWithMessage("Cannot parse member _expression_");
}
- if (UNLIKELY(isUpdateOp(static_cast<JSTokenType>(lastOperator)) && context.isNewTarget(expr)))
- internalFailWithMessage(false, "new.target can't come after a prefix operator");
+ if (UNLIKELY(isUpdateOp(static_cast<JSTokenType>(lastOperator)) && context.isMetaProperty(expr)))
+ internalFailWithMessage(false, metaPropertyName(context, expr), " can't come after a prefix operator");
bool isEvalOrArguments = false;
if (strictMode() && !m_syntaxAlreadyValidated) {
if (context.isResolve(expr))
@@ -4934,8 +4946,8 @@
failIfTrueIfStrict(isEvalOrArguments && modifiesExpr, "Cannot modify '", m_parserState.lastIdentifier->impl(), "' in strict mode");
switch (m_token.m_type) {
case PLUSPLUS:
- if (UNLIKELY(context.isNewTarget(expr)))
- internalFailWithMessage(false, "new.target can't come before a postfix operator");
+ if (UNLIKELY(context.isMetaProperty(expr)))
+ internalFailWithMessage(false, metaPropertyName(context, expr), " can't come before a postfix operator");
m_parserState.nonTrivialExpressionCount++;
m_parserState.nonLHSCount++;
expr = context.makePostfixNode(location, expr, OpPlusPlus, subExprStart, lastTokenEndPosition(), tokenEndPosition());
@@ -4946,8 +4958,8 @@
next();
break;
case MINUSMINUS:
- if (UNLIKELY(context.isNewTarget(expr)))
- internalFailWithMessage(false, "new.target can't come before a postfix operator");
+ if (UNLIKELY(context.isMetaProperty(expr)))
+ internalFailWithMessage(false, metaPropertyName(context, expr), " can't come before a postfix operator");
m_parserState.nonTrivialExpressionCount++;
m_parserState.nonLHSCount++;
expr = context.makePostfixNode(location, expr, OpMinusMinus, subExprStart, lastTokenEndPosition(), tokenEndPosition());
Modified: trunk/Source/_javascript_Core/parser/Parser.h (223231 => 223232)
--- trunk/Source/_javascript_Core/parser/Parser.h 2017-10-12 06:15:11 UTC (rev 223231)
+++ trunk/Source/_javascript_Core/parser/Parser.h 2017-10-12 06:45:23 UTC (rev 223232)
@@ -1612,6 +1612,8 @@
template <class TreeBuilder> ALWAYS_INLINE bool shouldCheckPropertyForUnderscoreProtoDuplicate(TreeBuilder&, const TreeProperty&);
+ template <class TreeBuilder> NEVER_INLINE const char* metaPropertyName(TreeBuilder&, TreeExpression);
+
ALWAYS_INLINE int isBinaryOperator(JSTokenType);
bool allowAutomaticSemicolon();
Modified: trunk/Source/_javascript_Core/parser/SyntaxChecker.h (223231 => 223232)
--- trunk/Source/_javascript_Core/parser/SyntaxChecker.h 2017-10-12 06:15:11 UTC (rev 223231)
+++ trunk/Source/_javascript_Core/parser/SyntaxChecker.h 2017-10-12 06:45:23 UTC (rev 223232)
@@ -68,12 +68,13 @@
{
}
- enum { NoneExpr = 0,
+ static const constexpr int MetaPropertyBit = 0x80000000;
+ enum : int { NoneExpr = 0,
ResolveEvalExpr, ResolveExpr, IntegerExpr, DoubleExpr, StringExpr,
ThisExpr, NullExpr, BoolExpr, RegExpExpr, ObjectLiteralExpr,
FunctionExpr, ClassExpr, SuperExpr, ImportExpr, BracketExpr, DotExpr, CallExpr,
NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr,
- ConditionalExpr, AssignmentExpr, TypeofExpr, NewTargetExpr,
+ ConditionalExpr, AssignmentExpr, TypeofExpr,
DeleteExpr, ArrayLiteralExpr, BindingDestructuring, RestParameter,
ArrayDestructuring, ObjectDestructuring, SourceElementsResult,
FunctionBodyResult, SpreadExpr, ObjectSpreadExpr, ArgumentsResult,
@@ -85,7 +86,10 @@
TaggedTemplateExpr, YieldExpr, AwaitExpr,
ModuleNameResult,
ImportSpecifierResult, ImportSpecifierListResult,
- ExportSpecifierResult, ExportSpecifierListResult
+ ExportSpecifierResult, ExportSpecifierListResult,
+
+ NewTargetExpr = MetaPropertyBit | 0,
+ ImportMetaExpr = MetaPropertyBit | 1,
};
typedef int ExpressionType;
@@ -160,7 +164,10 @@
ExpressionType createThisExpr(const JSTokenLocation&) { return ThisExpr; }
ExpressionType createSuperExpr(const JSTokenLocation&) { return SuperExpr; }
ExpressionType createNewTargetExpr(const JSTokenLocation&) { return NewTargetExpr; }
+ ExpressionType createImportMetaExpr(const JSTokenLocation&, ExpressionType) { return ImportMetaExpr; }
+ ALWAYS_INLINE bool isMetaProperty(ExpressionType type) { return type & MetaPropertyBit; }
ALWAYS_INLINE bool isNewTarget(ExpressionType type) { return type == NewTargetExpr; }
+ ALWAYS_INLINE bool isImportMeta(ExpressionType type) { return type == ImportMetaExpr; }
ExpressionType createResolve(const JSTokenLocation&, const Identifier&, int, int) { return ResolveExpr; }
ExpressionType createObjectLiteral(const JSTokenLocation&) { return ObjectLiteralExpr; }
ExpressionType createObjectLiteral(const JSTokenLocation&, int) { return ObjectLiteralExpr; }