source: webkit/trunk/JavaScriptCore/parser/Parser.cpp@ 69516

Last change on this file since 69516 was 69516, checked in by [email protected], 15 years ago

2010-10-01 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

[ES5] Implement strict mode
https://bugs.webkit.org/show_bug.cgi?id=10701

Initial strict mode implementation. This is the simplest
implementation that could possibly work and adds (hopefully)
all of the restrictions required by strict mode. There are
a number of inefficiencies, especially in the handling of
arguments and eval as smart implementations would make this
patch more complicated.

The SyntaxChecker AST builder has become somewhat more complex
as strict mode does require more parse tree information to
validate the syntax.

Summary of major changes to the parser:

  • We track when we enter strict mode (this may come as a surprise)
  • Strict mode actually requires a degree of AST knowledge to validate so the SyntaxChecker now produces values that can be used to distinguish "node" types.
  • We now track variables that are written to. We do this to statically identify writes to global properties that don't exist and abort at that point. This should actually make it possible to optimise some other cases in the future but for now it's purely for validity checking. Currently writes are only tracked in strict mode code.
  • Labels are now tracked as it is now a syntax error to jump to a label that does not exist (or to use break, continue, or return in a context where they would be invalid).

Runtime changes:

  • In order to get correct hanlding of the Arguments object all strict mode functions that reference arguments create and tearoff the arguments object on entry. This is not strictly necessary but was the least work necessary to get the correct behaviour.
  • PutPropertySlot now tracks whether it is being used for a strict mode write, and if so Object::put will throw when a write can't be completed.
  • StrictEvalActivation was added as an "activation" object for strict mode eval (so that strict eval does not introduce new variables into the containing scope).
  • CMakeLists.txt:
  • GNUmakefile.am:
  • JavaScriptCore.exp:
  • JavaScriptCore.pro:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dump): (JSC::CodeBlock::CodeBlock): (JSC::CodeBlock::reparseForExceptionInfoIfNecessary):
  • bytecode/CodeBlock.h: (JSC::CodeBlock::isStrictMode):
  • bytecode/EvalCodeCache.h: (JSC::EvalCodeCache::get):
  • bytecode/Opcode.h:
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::BytecodeGenerator): (JSC::BytecodeGenerator::createArgumentsIfNecessary): (JSC::BytecodeGenerator::emitReturn):
  • bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::isStrictMode): (JSC::BytecodeGenerator::makeFunction):
  • debugger/Debugger.cpp: (JSC::evaluateInGlobalCallFrame):
  • debugger/DebuggerCallFrame.cpp: (JSC::DebuggerCallFrame::evaluate):
  • interpreter/Interpreter.cpp: (JSC::Interpreter::callEval): (JSC::Interpreter::unwindCallFrame): (JSC::Interpreter::execute): (JSC::Interpreter::privateExecute):
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases):
  • jit/JIT.h:
  • jit/JITOpcodes.cpp: (JSC::JIT::emit_op_get_pnames): (JSC::JIT::emit_op_convert_this_strict): (JSC::JIT::emitSlow_op_convert_this_strict):
  • jit/JITOpcodes32_64.cpp: (JSC::JIT::emit_op_get_pnames):
  • jit/JITStubs.cpp: (JSC::DEFINE_STUB_FUNCTION):
  • jit/JITStubs.h:
  • parser/ASTBuilder.h: (JSC::ASTBuilder::createFunctionBody): (JSC::ASTBuilder::isResolve):
  • parser/JSParser.cpp: (JSC::JSParser::next): (JSC::JSParser::startLoop): (JSC::JSParser::endLoop): (JSC::JSParser::startSwitch): (JSC::JSParser::endSwitch): (JSC::JSParser::setStrictMode): (JSC::JSParser::strictMode): (JSC::JSParser::isValidStrictMode): (JSC::JSParser::declareParameter): (JSC::JSParser::breakIsValid): (JSC::JSParser::pushLabel): (JSC::JSParser::popLabel): (JSC::JSParser::hasLabel): (JSC::JSParser::DepthManager::DepthManager): (JSC::JSParser::DepthManager::~DepthManager): (JSC::JSParser::Scope::Scope): (JSC::JSParser::Scope::startSwitch): (JSC::JSParser::Scope::endSwitch): (JSC::JSParser::Scope::startLoop): (JSC::JSParser::Scope::endLoop): (JSC::JSParser::Scope::inLoop): (JSC::JSParser::Scope::breakIsValid): (JSC::JSParser::Scope::pushLabel): (JSC::JSParser::Scope::popLabel): (JSC::JSParser::Scope::hasLabel): (JSC::JSParser::Scope::isFunction): (JSC::JSParser::Scope::declareVariable): (JSC::JSParser::Scope::declareWrite): (JSC::JSParser::Scope::deleteProperty): (JSC::JSParser::Scope::declareParameter): (JSC::JSParser::Scope::setNeedsFullActivation): (JSC::JSParser::Scope::collectFreeVariables): (JSC::JSParser::Scope::getUncapturedWrittenVariables): (JSC::JSParser::Scope::getDeletedVariables): (JSC::JSParser::Scope::setStrictMode): (JSC::JSParser::Scope::strictMode): (JSC::JSParser::Scope::isValidStrictMode): (JSC::JSParser::pushScope): (JSC::JSParser::popScope): (JSC::JSParser::declareVariable): (JSC::JSParser::declareWrite): (JSC::JSParser::deleteProperty): (JSC::jsParse): (JSC::JSParser::JSParser): (JSC::JSParser::parseProgram): (JSC::JSParser::parseSourceElements): (JSC::JSParser::parseDoWhileStatement): (JSC::JSParser::parseWhileStatement): (JSC::JSParser::parseVarDeclarationList): (JSC::JSParser::parseConstDeclarationList): (JSC::JSParser::parseForStatement): (JSC::JSParser::parseBreakStatement): (JSC::JSParser::parseContinueStatement): (JSC::JSParser::parseReturnStatement): (JSC::JSParser::parseWithStatement): (JSC::JSParser::parseSwitchStatement): (JSC::JSParser::parseSwitchClauses): (JSC::JSParser::parseSwitchDefaultClause): (JSC::JSParser::parseTryStatement): (JSC::JSParser::parseBlockStatement): (JSC::JSParser::parseStatement): (JSC::JSParser::parseFormalParameters): (JSC::JSParser::parseFunctionBody): (JSC::JSParser::parseFunctionInfo): (JSC::JSParser::parseFunctionDeclaration): (JSC::JSParser::parseExpressionOrLabelStatement): (JSC::JSParser::parseIfStatement): (JSC::JSParser::parseExpression): (JSC::JSParser::parseAssignmentExpression): (JSC::JSParser::parseConditionalExpression): (JSC::JSParser::parseBinaryExpression): (JSC::JSParser::parseStrictObjectLiteral): (JSC::JSParser::parsePrimaryExpression): (JSC::JSParser::parseMemberExpression): (JSC::JSParser::parseUnaryExpression):
  • parser/JSParser.h:
  • parser/Lexer.cpp: (JSC::Lexer::parseString): (JSC::Lexer::lex):
  • parser/Lexer.h: (JSC::Lexer::isReparsing):
  • parser/Nodes.cpp: (JSC::ScopeNode::ScopeNode): (JSC::FunctionBodyNode::FunctionBodyNode): (JSC::FunctionBodyNode::create):
  • parser/Nodes.h: (JSC::ScopeNode::isStrictMode):
  • parser/Parser.cpp: (JSC::Parser::parse):
  • parser/Parser.h: (JSC::Parser::parse):
  • parser/SyntaxChecker.h: (JSC::SyntaxChecker::SyntaxChecker): (JSC::SyntaxChecker::makeFunctionCallNode): (JSC::SyntaxChecker::appendToComma): (JSC::SyntaxChecker::createCommaExpr): (JSC::SyntaxChecker::makeAssignNode): (JSC::SyntaxChecker::makePrefixNode): (JSC::SyntaxChecker::makePostfixNode): (JSC::SyntaxChecker::makeTypeOfNode): (JSC::SyntaxChecker::makeDeleteNode): (JSC::SyntaxChecker::makeNegateNode): (JSC::SyntaxChecker::makeBitwiseNotNode): (JSC::SyntaxChecker::createLogicalNot): (JSC::SyntaxChecker::createUnaryPlus): (JSC::SyntaxChecker::createVoid): (JSC::SyntaxChecker::thisExpr): (JSC::SyntaxChecker::createResolve): (JSC::SyntaxChecker::createObjectLiteral): (JSC::SyntaxChecker::createArray): (JSC::SyntaxChecker::createNumberExpr): (JSC::SyntaxChecker::createString): (JSC::SyntaxChecker::createBoolean): (JSC::SyntaxChecker::createNull): (JSC::SyntaxChecker::createBracketAccess): (JSC::SyntaxChecker::createDotAccess): (JSC::SyntaxChecker::createRegex): (JSC::SyntaxChecker::createNewExpr): (JSC::SyntaxChecker::createConditionalExpr): (JSC::SyntaxChecker::createAssignResolve): (JSC::SyntaxChecker::createFunctionExpr): (JSC::SyntaxChecker::createFunctionBody): (JSC::SyntaxChecker::appendBinaryExpressionInfo): (JSC::SyntaxChecker::operatorStackPop):
  • runtime/Arguments.cpp: (JSC::Arguments::createStrictModeCallerIfNecessary): (JSC::Arguments::createStrictModeCalleeIfNecessary): (JSC::Arguments::getOwnPropertySlot): (JSC::Arguments::getOwnPropertyDescriptor): (JSC::Arguments::put): (JSC::Arguments::deleteProperty):
  • runtime/Arguments.h: (JSC::Arguments::Arguments):
  • runtime/CommonIdentifiers.cpp: (JSC::CommonIdentifiers::CommonIdentifiers):
  • runtime/CommonIdentifiers.h:
  • runtime/Error.cpp: (JSC::StrictModeTypeErrorFunction::StrictModeTypeErrorFunction): (JSC::StrictModeTypeErrorFunction::constructThrowTypeError): (JSC::StrictModeTypeErrorFunction::getConstructData): (JSC::StrictModeTypeErrorFunction::callThrowTypeError): (JSC::StrictModeTypeErrorFunction::getCallData): (JSC::createTypeErrorFunction):
  • runtime/Error.h:
  • runtime/Executable.cpp: (JSC::EvalExecutable::EvalExecutable): (JSC::ProgramExecutable::ProgramExecutable): (JSC::FunctionExecutable::FunctionExecutable): (JSC::EvalExecutable::compileInternal): (JSC::ProgramExecutable::checkSyntax): (JSC::ProgramExecutable::compileInternal): (JSC::FunctionExecutable::compileForCallInternal): (JSC::FunctionExecutable::compileForConstructInternal): (JSC::FunctionExecutable::reparseExceptionInfo): (JSC::EvalExecutable::reparseExceptionInfo): (JSC::FunctionExecutable::fromGlobalCode): (JSC::ProgramExecutable::reparseExceptionInfo):
  • runtime/Executable.h: (JSC::ScriptExecutable::ScriptExecutable): (JSC::ScriptExecutable::isStrictMode): (JSC::EvalExecutable::create): (JSC::FunctionExecutable::create):
  • runtime/JSActivation.cpp: (JSC::JSActivation::toStrictThisObject):
  • runtime/JSActivation.h:
  • runtime/JSFunction.cpp: (JSC::createDescriptorForThrowingProperty): (JSC::JSFunction::getOwnPropertySlot): (JSC::JSFunction::getOwnPropertyDescriptor): (JSC::JSFunction::put):
  • runtime/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData):
  • runtime/JSGlobalData.h:
  • runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::reset):
  • runtime/JSGlobalObject.h: (JSC::JSGlobalObject::internalFunctionStructure):
  • runtime/JSGlobalObjectFunctions.cpp: (JSC::globalFuncEval):
  • runtime/JSObject.cpp: (JSC::JSObject::put): (JSC::JSObject::toStrictThisObject): (JSC::throwTypeError):
  • runtime/JSObject.h: (JSC::JSObject::isStrictModeFunction): (JSC::JSObject::putDirectInternal): (JSC::JSObject::putDirect): (JSC::JSValue::putDirect): (JSC::JSValue::toStrictThisObject):
  • runtime/JSStaticScopeObject.cpp: (JSC::JSStaticScopeObject::toStrictThisObject):
  • runtime/JSStaticScopeObject.h:
  • runtime/JSValue.h:
  • runtime/JSZombie.h: (JSC::JSZombie::toStrictThisObject):
  • runtime/PutPropertySlot.h: (JSC::PutPropertySlot::PutPropertySlot): (JSC::PutPropertySlot::isStrictMode):
  • runtime/StrictEvalActivation.cpp: Added. (JSC::StrictEvalActivation::StrictEvalActivation): (JSC::StrictEvalActivation::deleteProperty): (JSC::StrictEvalActivation::toThisObject): (JSC::StrictEvalActivation::toStrictThisObject):
  • runtime/StrictEvalActivation.h: Added.

2010-10-01 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

[ES5] Implement strict mode
https://bugs.webkit.org/show_bug.cgi?id=10701

Tests for the many different behaviours we get in strict mode.

  • fast/js/basic-strict-mode-expected.txt: Added.
  • fast/js/basic-strict-mode.html: Added.
  • fast/js/script-tests/basic-strict-mode.js: Added. (testThis): (testGlobalAccess):

2010-10-01 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

[ES5] Implement strict mode
https://bugs.webkit.org/show_bug.cgi?id=10701

Test: fast/js/basic-strict-mode.html

Override toStrictThisObject on the domwindow so that
it correctly provides the shell object when used as this
in a strict mode function.

  • bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::toStrictThisObject):
  • bindings/js/JSDOMWindowBase.h:
  • Property svn:eol-style set to native
File size: 2.6 KB
Line 
1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include "config.h"
24#include "Parser.h"
25
26#include "Debugger.h"
27#include "JSParser.h"
28#include "Lexer.h"
29#include <wtf/HashSet.h>
30#include <wtf/Vector.h>
31
32#ifndef yyparse
33extern int jscyyparse(void*);
34#endif
35
36namespace JSC {
37
38void Parser::parse(JSGlobalObject* lexicalGlobalObject, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode mode, int* errLine, UString* errMsg)
39{
40 ASSERT(lexicalGlobalObject);
41 m_sourceElements = 0;
42
43 int defaultErrLine;
44 UString defaultErrMsg;
45
46 if (!errLine)
47 errLine = &defaultErrLine;
48 if (!errMsg)
49 errMsg = &defaultErrMsg;
50
51 *errLine = -1;
52 *errMsg = UString();
53
54 Lexer& lexer = *lexicalGlobalObject->globalData()->lexer;
55 lexer.setCode(*m_source, m_arena);
56
57 int parseError = jsParse(lexicalGlobalObject, parameters, strictness, mode, m_source);
58 int lineNumber = lexer.lineNumber();
59 bool lexError = lexer.sawError();
60 lexer.clear();
61
62 if (parseError || lexError) {
63 *errLine = lineNumber;
64 *errMsg = "Parse error";
65 m_sourceElements = 0;
66 }
67}
68
69void Parser::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack,
70 ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants, IdentifierSet& capturedVars)
71{
72 m_sourceElements = sourceElements;
73 m_varDeclarations = varStack;
74 m_funcDeclarations = funcStack;
75 m_capturedVariables.swap(capturedVars);
76 m_features = features;
77 m_lastLine = lastLine;
78 m_numConstants = numConstants;
79}
80
81} // namespace JSC
Note: See TracBrowser for help on using the repository browser.