Changeset 69516 in webkit
- Timestamp:
- Oct 11, 2010 12:12:29 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 60 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/CMakeLists.txt
r69132 r69516 158 158 runtime/ScopeChain.cpp 159 159 runtime/SmallStrings.cpp 160 runtime/StrictEvalActivation.cpp 160 161 runtime/StringConstructor.cpp 161 162 runtime/StringObject.cpp -
trunk/JavaScriptCore/ChangeLog
r69475 r69516 1 2010-10-01 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Gavin Barraclough. 4 5 [ES5] Implement strict mode 6 https://bugs.webkit.org/show_bug.cgi?id=10701 7 8 Initial strict mode implementation. This is the simplest 9 implementation that could possibly work and adds (hopefully) 10 all of the restrictions required by strict mode. There are 11 a number of inefficiencies, especially in the handling of 12 arguments and eval as smart implementations would make this 13 patch more complicated. 14 15 The SyntaxChecker AST builder has become somewhat more complex 16 as strict mode does require more parse tree information to 17 validate the syntax. 18 19 Summary of major changes to the parser: 20 * We track when we enter strict mode (this may come as a surprise) 21 * Strict mode actually requires a degree of AST knowledge to validate 22 so the SyntaxChecker now produces values that can be used to distinguish 23 "node" types. 24 * We now track variables that are written to. We do this to 25 statically identify writes to global properties that don't exist 26 and abort at that point. This should actually make it possible 27 to optimise some other cases in the future but for now it's 28 purely for validity checking. Currently writes are only tracked 29 in strict mode code. 30 * Labels are now tracked as it is now a syntax error to jump to a label 31 that does not exist (or to use break, continue, or return in a context 32 where they would be invalid). 33 34 Runtime changes: 35 * In order to get correct hanlding of the Arguments object all 36 strict mode functions that reference arguments create and tearoff 37 the arguments object on entry. This is not strictly necessary 38 but was the least work necessary to get the correct behaviour. 39 * PutPropertySlot now tracks whether it is being used for a strict 40 mode write, and if so Object::put will throw when a write can't be 41 completed. 42 * StrictEvalActivation was added as an "activation" object for strict 43 mode eval (so that strict eval does not introduce new variables into 44 the containing scope). 45 46 * CMakeLists.txt: 47 * GNUmakefile.am: 48 * JavaScriptCore.exp: 49 * JavaScriptCore.pro: 50 * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: 51 * JavaScriptCore.xcodeproj/project.pbxproj: 52 * bytecode/CodeBlock.cpp: 53 (JSC::CodeBlock::dump): 54 (JSC::CodeBlock::CodeBlock): 55 (JSC::CodeBlock::reparseForExceptionInfoIfNecessary): 56 * bytecode/CodeBlock.h: 57 (JSC::CodeBlock::isStrictMode): 58 * bytecode/EvalCodeCache.h: 59 (JSC::EvalCodeCache::get): 60 * bytecode/Opcode.h: 61 * bytecompiler/BytecodeGenerator.cpp: 62 (JSC::BytecodeGenerator::BytecodeGenerator): 63 (JSC::BytecodeGenerator::createArgumentsIfNecessary): 64 (JSC::BytecodeGenerator::emitReturn): 65 * bytecompiler/BytecodeGenerator.h: 66 (JSC::BytecodeGenerator::isStrictMode): 67 (JSC::BytecodeGenerator::makeFunction): 68 * debugger/Debugger.cpp: 69 (JSC::evaluateInGlobalCallFrame): 70 * debugger/DebuggerCallFrame.cpp: 71 (JSC::DebuggerCallFrame::evaluate): 72 * interpreter/Interpreter.cpp: 73 (JSC::Interpreter::callEval): 74 (JSC::Interpreter::unwindCallFrame): 75 (JSC::Interpreter::execute): 76 (JSC::Interpreter::privateExecute): 77 * jit/JIT.cpp: 78 (JSC::JIT::privateCompileMainPass): 79 (JSC::JIT::privateCompileSlowCases): 80 * jit/JIT.h: 81 * jit/JITOpcodes.cpp: 82 (JSC::JIT::emit_op_get_pnames): 83 (JSC::JIT::emit_op_convert_this_strict): 84 (JSC::JIT::emitSlow_op_convert_this_strict): 85 * jit/JITOpcodes32_64.cpp: 86 (JSC::JIT::emit_op_get_pnames): 87 * jit/JITStubs.cpp: 88 (JSC::DEFINE_STUB_FUNCTION): 89 * jit/JITStubs.h: 90 * parser/ASTBuilder.h: 91 (JSC::ASTBuilder::createFunctionBody): 92 (JSC::ASTBuilder::isResolve): 93 * parser/JSParser.cpp: 94 (JSC::JSParser::next): 95 (JSC::JSParser::startLoop): 96 (JSC::JSParser::endLoop): 97 (JSC::JSParser::startSwitch): 98 (JSC::JSParser::endSwitch): 99 (JSC::JSParser::setStrictMode): 100 (JSC::JSParser::strictMode): 101 (JSC::JSParser::isValidStrictMode): 102 (JSC::JSParser::declareParameter): 103 (JSC::JSParser::breakIsValid): 104 (JSC::JSParser::pushLabel): 105 (JSC::JSParser::popLabel): 106 (JSC::JSParser::hasLabel): 107 (JSC::JSParser::DepthManager::DepthManager): 108 (JSC::JSParser::DepthManager::~DepthManager): 109 (JSC::JSParser::Scope::Scope): 110 (JSC::JSParser::Scope::startSwitch): 111 (JSC::JSParser::Scope::endSwitch): 112 (JSC::JSParser::Scope::startLoop): 113 (JSC::JSParser::Scope::endLoop): 114 (JSC::JSParser::Scope::inLoop): 115 (JSC::JSParser::Scope::breakIsValid): 116 (JSC::JSParser::Scope::pushLabel): 117 (JSC::JSParser::Scope::popLabel): 118 (JSC::JSParser::Scope::hasLabel): 119 (JSC::JSParser::Scope::isFunction): 120 (JSC::JSParser::Scope::declareVariable): 121 (JSC::JSParser::Scope::declareWrite): 122 (JSC::JSParser::Scope::deleteProperty): 123 (JSC::JSParser::Scope::declareParameter): 124 (JSC::JSParser::Scope::setNeedsFullActivation): 125 (JSC::JSParser::Scope::collectFreeVariables): 126 (JSC::JSParser::Scope::getUncapturedWrittenVariables): 127 (JSC::JSParser::Scope::getDeletedVariables): 128 (JSC::JSParser::Scope::setStrictMode): 129 (JSC::JSParser::Scope::strictMode): 130 (JSC::JSParser::Scope::isValidStrictMode): 131 (JSC::JSParser::pushScope): 132 (JSC::JSParser::popScope): 133 (JSC::JSParser::declareVariable): 134 (JSC::JSParser::declareWrite): 135 (JSC::JSParser::deleteProperty): 136 (JSC::jsParse): 137 (JSC::JSParser::JSParser): 138 (JSC::JSParser::parseProgram): 139 (JSC::JSParser::parseSourceElements): 140 (JSC::JSParser::parseDoWhileStatement): 141 (JSC::JSParser::parseWhileStatement): 142 (JSC::JSParser::parseVarDeclarationList): 143 (JSC::JSParser::parseConstDeclarationList): 144 (JSC::JSParser::parseForStatement): 145 (JSC::JSParser::parseBreakStatement): 146 (JSC::JSParser::parseContinueStatement): 147 (JSC::JSParser::parseReturnStatement): 148 (JSC::JSParser::parseWithStatement): 149 (JSC::JSParser::parseSwitchStatement): 150 (JSC::JSParser::parseSwitchClauses): 151 (JSC::JSParser::parseSwitchDefaultClause): 152 (JSC::JSParser::parseTryStatement): 153 (JSC::JSParser::parseBlockStatement): 154 (JSC::JSParser::parseStatement): 155 (JSC::JSParser::parseFormalParameters): 156 (JSC::JSParser::parseFunctionBody): 157 (JSC::JSParser::parseFunctionInfo): 158 (JSC::JSParser::parseFunctionDeclaration): 159 (JSC::JSParser::parseExpressionOrLabelStatement): 160 (JSC::JSParser::parseIfStatement): 161 (JSC::JSParser::parseExpression): 162 (JSC::JSParser::parseAssignmentExpression): 163 (JSC::JSParser::parseConditionalExpression): 164 (JSC::JSParser::parseBinaryExpression): 165 (JSC::JSParser::parseStrictObjectLiteral): 166 (JSC::JSParser::parsePrimaryExpression): 167 (JSC::JSParser::parseMemberExpression): 168 (JSC::JSParser::parseUnaryExpression): 169 * parser/JSParser.h: 170 * parser/Lexer.cpp: 171 (JSC::Lexer::parseString): 172 (JSC::Lexer::lex): 173 * parser/Lexer.h: 174 (JSC::Lexer::isReparsing): 175 * parser/Nodes.cpp: 176 (JSC::ScopeNode::ScopeNode): 177 (JSC::FunctionBodyNode::FunctionBodyNode): 178 (JSC::FunctionBodyNode::create): 179 * parser/Nodes.h: 180 (JSC::ScopeNode::isStrictMode): 181 * parser/Parser.cpp: 182 (JSC::Parser::parse): 183 * parser/Parser.h: 184 (JSC::Parser::parse): 185 * parser/SyntaxChecker.h: 186 (JSC::SyntaxChecker::SyntaxChecker): 187 (JSC::SyntaxChecker::makeFunctionCallNode): 188 (JSC::SyntaxChecker::appendToComma): 189 (JSC::SyntaxChecker::createCommaExpr): 190 (JSC::SyntaxChecker::makeAssignNode): 191 (JSC::SyntaxChecker::makePrefixNode): 192 (JSC::SyntaxChecker::makePostfixNode): 193 (JSC::SyntaxChecker::makeTypeOfNode): 194 (JSC::SyntaxChecker::makeDeleteNode): 195 (JSC::SyntaxChecker::makeNegateNode): 196 (JSC::SyntaxChecker::makeBitwiseNotNode): 197 (JSC::SyntaxChecker::createLogicalNot): 198 (JSC::SyntaxChecker::createUnaryPlus): 199 (JSC::SyntaxChecker::createVoid): 200 (JSC::SyntaxChecker::thisExpr): 201 (JSC::SyntaxChecker::createResolve): 202 (JSC::SyntaxChecker::createObjectLiteral): 203 (JSC::SyntaxChecker::createArray): 204 (JSC::SyntaxChecker::createNumberExpr): 205 (JSC::SyntaxChecker::createString): 206 (JSC::SyntaxChecker::createBoolean): 207 (JSC::SyntaxChecker::createNull): 208 (JSC::SyntaxChecker::createBracketAccess): 209 (JSC::SyntaxChecker::createDotAccess): 210 (JSC::SyntaxChecker::createRegex): 211 (JSC::SyntaxChecker::createNewExpr): 212 (JSC::SyntaxChecker::createConditionalExpr): 213 (JSC::SyntaxChecker::createAssignResolve): 214 (JSC::SyntaxChecker::createFunctionExpr): 215 (JSC::SyntaxChecker::createFunctionBody): 216 (JSC::SyntaxChecker::appendBinaryExpressionInfo): 217 (JSC::SyntaxChecker::operatorStackPop): 218 * runtime/Arguments.cpp: 219 (JSC::Arguments::createStrictModeCallerIfNecessary): 220 (JSC::Arguments::createStrictModeCalleeIfNecessary): 221 (JSC::Arguments::getOwnPropertySlot): 222 (JSC::Arguments::getOwnPropertyDescriptor): 223 (JSC::Arguments::put): 224 (JSC::Arguments::deleteProperty): 225 * runtime/Arguments.h: 226 (JSC::Arguments::Arguments): 227 * runtime/CommonIdentifiers.cpp: 228 (JSC::CommonIdentifiers::CommonIdentifiers): 229 * runtime/CommonIdentifiers.h: 230 * runtime/Error.cpp: 231 (JSC::StrictModeTypeErrorFunction::StrictModeTypeErrorFunction): 232 (JSC::StrictModeTypeErrorFunction::constructThrowTypeError): 233 (JSC::StrictModeTypeErrorFunction::getConstructData): 234 (JSC::StrictModeTypeErrorFunction::callThrowTypeError): 235 (JSC::StrictModeTypeErrorFunction::getCallData): 236 (JSC::createTypeErrorFunction): 237 * runtime/Error.h: 238 * runtime/Executable.cpp: 239 (JSC::EvalExecutable::EvalExecutable): 240 (JSC::ProgramExecutable::ProgramExecutable): 241 (JSC::FunctionExecutable::FunctionExecutable): 242 (JSC::EvalExecutable::compileInternal): 243 (JSC::ProgramExecutable::checkSyntax): 244 (JSC::ProgramExecutable::compileInternal): 245 (JSC::FunctionExecutable::compileForCallInternal): 246 (JSC::FunctionExecutable::compileForConstructInternal): 247 (JSC::FunctionExecutable::reparseExceptionInfo): 248 (JSC::EvalExecutable::reparseExceptionInfo): 249 (JSC::FunctionExecutable::fromGlobalCode): 250 (JSC::ProgramExecutable::reparseExceptionInfo): 251 * runtime/Executable.h: 252 (JSC::ScriptExecutable::ScriptExecutable): 253 (JSC::ScriptExecutable::isStrictMode): 254 (JSC::EvalExecutable::create): 255 (JSC::FunctionExecutable::create): 256 * runtime/JSActivation.cpp: 257 (JSC::JSActivation::toStrictThisObject): 258 * runtime/JSActivation.h: 259 * runtime/JSFunction.cpp: 260 (JSC::createDescriptorForThrowingProperty): 261 (JSC::JSFunction::getOwnPropertySlot): 262 (JSC::JSFunction::getOwnPropertyDescriptor): 263 (JSC::JSFunction::put): 264 * runtime/JSGlobalData.cpp: 265 (JSC::JSGlobalData::JSGlobalData): 266 * runtime/JSGlobalData.h: 267 * runtime/JSGlobalObject.cpp: 268 (JSC::JSGlobalObject::reset): 269 * runtime/JSGlobalObject.h: 270 (JSC::JSGlobalObject::internalFunctionStructure): 271 * runtime/JSGlobalObjectFunctions.cpp: 272 (JSC::globalFuncEval): 273 * runtime/JSObject.cpp: 274 (JSC::JSObject::put): 275 (JSC::JSObject::toStrictThisObject): 276 (JSC::throwTypeError): 277 * runtime/JSObject.h: 278 (JSC::JSObject::isStrictModeFunction): 279 (JSC::JSObject::putDirectInternal): 280 (JSC::JSObject::putDirect): 281 (JSC::JSValue::putDirect): 282 (JSC::JSValue::toStrictThisObject): 283 * runtime/JSStaticScopeObject.cpp: 284 (JSC::JSStaticScopeObject::toStrictThisObject): 285 * runtime/JSStaticScopeObject.h: 286 * runtime/JSValue.h: 287 * runtime/JSZombie.h: 288 (JSC::JSZombie::toStrictThisObject): 289 * runtime/PutPropertySlot.h: 290 (JSC::PutPropertySlot::PutPropertySlot): 291 (JSC::PutPropertySlot::isStrictMode): 292 * runtime/StrictEvalActivation.cpp: Added. 293 (JSC::StrictEvalActivation::StrictEvalActivation): 294 (JSC::StrictEvalActivation::deleteProperty): 295 (JSC::StrictEvalActivation::toThisObject): 296 (JSC::StrictEvalActivation::toStrictThisObject): 297 * runtime/StrictEvalActivation.h: Added. 298 1 299 2010-10-10 Patrick Gansterer <paroga@webkit.org> 2 300 -
trunk/JavaScriptCore/GNUmakefile.am
r67963 r69516 389 389 JavaScriptCore/runtime/SmallStrings.cpp \ 390 390 JavaScriptCore/runtime/SmallStrings.h \ 391 JavaScriptCore/runtime/StrictEvalActivation.cpp\ 392 JavaScriptCore/runtime/StrictEvalActivation.h\ 391 393 JavaScriptCore/runtime/StringBuilder.h \ 392 394 JavaScriptCore/runtime/StringConcatenate.h \ -
trunk/JavaScriptCore/JavaScriptCore.exp
r69277 r69516 532 532 __ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE 533 533 __ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE 534 __ZNK3JSC8JSObject18toStrictThisObjectEPNS_9ExecStateE 534 535 __ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE 535 536 __ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE -
trunk/JavaScriptCore/JavaScriptCore.pro
r67306 r69516 198 198 runtime/ScopeChain.cpp \ 199 199 runtime/SmallStrings.cpp \ 200 runtime/StrictEvalActivation.cpp \ 200 201 runtime/StringConstructor.cpp \ 201 202 runtime/StringObject.cpp \ -
trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
r64943 r69516 1174 1174 </File> 1175 1175 <File 1176 RelativePath="..\..\runtime\StrictEvalActivation.cpp" 1177 > 1178 </File> 1179 <File 1180 RelativePath="..\..\runtime\StrictEvalActivation.h" 1181 > 1182 </File> 1183 <File 1176 1184 RelativePath="..\..\runtime\StringConstructor.cpp" 1177 1185 > -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r69045 r69516 319 319 A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */; }; 320 320 A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 321 A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = A730B6101250068F009D25B1 /* StrictEvalActivation.h */; }; 322 A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */; }; 321 323 A7386554118697B400540279 /* SpecializedThunkJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = A7386551118697B400540279 /* SpecializedThunkJIT.h */; }; 322 324 A7386555118697B400540279 /* ThunkGenerators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7386552118697B400540279 /* ThunkGenerators.cpp */; }; … … 952 954 A727FF650DA3053B00E548D7 /* JSPropertyNameIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPropertyNameIterator.h; sourceTree = "<group>"; }; 953 955 A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPropertyNameIterator.cpp; sourceTree = "<group>"; }; 956 A730B6101250068F009D25B1 /* StrictEvalActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StrictEvalActivation.h; sourceTree = "<group>"; }; 957 A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StrictEvalActivation.cpp; sourceTree = "<group>"; }; 954 958 A7386551118697B400540279 /* SpecializedThunkJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecializedThunkJIT.h; sourceTree = "<group>"; }; 955 959 A7386552118697B400540279 /* ThunkGenerators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThunkGenerators.cpp; sourceTree = "<group>"; }; … … 1815 1819 14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */, 1816 1820 1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */, 1821 A730B6101250068F009D25B1 /* StrictEvalActivation.h */, 1822 A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */, 1817 1823 ); 1818 1824 path = runtime; … … 2315 2321 9714AF60122F32070092D9F5 /* URLString.h in Headers */, 2316 2322 90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */, 2323 A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */, 2317 2324 ); 2318 2325 runOnlyForDeploymentPostprocessing = 0; … … 2408 2415 buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */; 2409 2416 compatibilityVersion = "Xcode 2.4"; 2410 developmentRegion = English;2411 2417 hasScannedForEncodings = 1; 2412 2418 knownRegions = ( … … 2770 2776 9714AF5E122F32070092D9F5 /* ParsedURL.cpp in Sources */, 2771 2777 90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */, 2778 A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */, 2772 2779 ); 2773 2780 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/bytecode/CodeBlock.cpp
r69045 r69516 518 518 break; 519 519 } 520 case op_convert_this_strict: { 521 int r0 = (++it)->u.operand; 522 printf("[%4d] convert_this_strict %s\n", location, registerName(exec, r0).data()); 523 break; 524 } 520 525 case op_new_object: { 521 526 int r0 = (++it)->u.operand; … … 1372 1377 , m_usesEval(ownerExecutable->usesEval()) 1373 1378 , m_isNumericCompareFunction(false) 1379 , m_isStrictMode(ownerExecutable->isStrictMode()) 1374 1380 , m_codeType(codeType) 1375 1381 , m_source(sourceProvider) … … 1558 1564 } 1559 1565 1560 m_exceptionInfo = m_ownerExecutable->reparseExceptionInfo( m_globalData,scopeChain, this);1566 m_exceptionInfo = m_ownerExecutable->reparseExceptionInfo(scopeChain, this); 1561 1567 return m_exceptionInfo; 1562 1568 } -
trunk/JavaScriptCore/bytecode/CodeBlock.h
r69045 r69516 298 298 #endif 299 299 300 bool isStrictMode() const { return m_isStrictMode; } 301 300 302 inline bool isKnownNotImmediate(int index) 301 303 { … … 565 567 bool m_usesEval; 566 568 bool m_isNumericCompareFunction; 569 bool m_isStrictMode; 567 570 568 571 CodeType m_codeType; -
trunk/JavaScriptCore/bytecode/EvalCodeCache.h
r65177 r69516 44 44 class EvalCodeCache { 45 45 public: 46 PassRefPtr<EvalExecutable> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)46 PassRefPtr<EvalExecutable> get(ExecState* exec, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) 47 47 { 48 48 RefPtr<EvalExecutable> evalExecutable; 49 49 50 if ( evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())50 if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject()) 51 51 evalExecutable = m_cacheMap.get(evalSource.impl()); 52 52 53 53 if (!evalExecutable) { 54 evalExecutable = EvalExecutable::create(exec, makeSource(evalSource) );54 evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext); 55 55 exceptionValue = evalExecutable->compile(exec, scopeChain); 56 56 if (exceptionValue) 57 57 return 0; 58 58 59 if ( evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)59 if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) 60 60 m_cacheMap.set(evalSource.impl(), evalExecutable); 61 61 } -
trunk/JavaScriptCore/bytecode/Opcode.h
r69045 r69516 46 46 macro(op_get_callee, 2) \ 47 47 macro(op_convert_this, 2) \ 48 macro(op_convert_this_strict, 2) \ 48 49 \ 49 50 macro(op_new_object, 2) \ -
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r69045 r69516 344 344 emitInitLazyRegister(argumentsRegister); 345 345 emitInitLazyRegister(unmodifiedArgumentsRegister); 346 347 if (m_codeBlock->isStrictMode()) { 348 emitOpcode(op_create_arguments); 349 instructions().append(argumentsRegister->index()); 350 } 346 351 347 352 // The debugger currently retrieves the arguments object from an activation rather than pulling … … 443 448 instructions().append(funcProto->index()); 444 449 } else if (functionBody->usesThis() || m_shouldEmitDebugHooks) { 445 emitOpcode(op_convert_this); 450 if (codeBlock->isStrictMode()) 451 emitOpcode(op_convert_this_strict); 452 else 453 emitOpcode(op_convert_this); 446 454 instructions().append(m_thisRegister.index()); 447 455 } … … 1558 1566 ASSERT(m_codeBlock->usesArguments()); 1559 1567 1568 // If we're in strict mode we tear off the arguments on function 1569 // entry, so there's no need to check if we need to create them 1570 // now 1571 if (m_codeBlock->isStrictMode()) 1572 return; 1573 1560 1574 emitOpcode(op_create_arguments); 1561 1575 instructions().append(m_codeBlock->argumentsRegister()); … … 1675 1689 instructions().append(m_activationRegister->index()); 1676 1690 instructions().append(m_codeBlock->argumentsRegister()); 1677 } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1) { // If there are no named parameters, there's nothing to tear off, since extra / unnamed parameters get copied to the arguments object at construct time. 1691 } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1 1692 && !m_codeBlock->isStrictMode()) { // If there are no named parameters, there's nothing to tear off, since extra / unnamed parameters get copied to the arguments object at construct time. 1678 1693 emitOpcode(op_tear_off_arguments); 1679 1694 instructions().append(m_codeBlock->argumentsRegister()); -
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r69045 r69516 420 420 421 421 bool shouldEmitProfileHooks() { return m_shouldEmitProfileHooks; } 422 423 bool isStrictMode() const { return m_codeBlock->isStrictMode(); } 422 424 423 425 private: … … 500 502 PassRefPtr<FunctionExecutable> makeFunction(ExecState* exec, FunctionBodyNode* body) 501 503 { 502 return FunctionExecutable::create(exec, body->ident(), body->source(), body->usesArguments(), body->parameters(), body-> lineNo(), body->lastLine());504 return FunctionExecutable::create(exec, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine()); 503 505 } 504 506 505 507 PassRefPtr<FunctionExecutable> makeFunction(JSGlobalData* globalData, FunctionBodyNode* body) 506 508 { 507 return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body-> lineNo(), body->lastLine());509 return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine()); 508 510 } 509 511 -
trunk/JavaScriptCore/debugger/Debugger.cpp
r54464 r69516 102 102 CallFrame* globalCallFrame = globalObject->globalExec(); 103 103 104 RefPtr<EvalExecutable> eval = EvalExecutable::create(globalCallFrame, makeSource(script) );104 RefPtr<EvalExecutable> eval = EvalExecutable::create(globalCallFrame, makeSource(script), false); 105 105 JSObject* error = eval->compile(globalCallFrame, globalCallFrame->scopeChain()); 106 106 if (error) -
trunk/JavaScriptCore/debugger/DebuggerCallFrame.cpp
r65286 r69516 89 89 return JSValue(); 90 90 91 RefPtr<EvalExecutable> eval = EvalExecutable::create(m_callFrame, makeSource(script) );91 RefPtr<EvalExecutable> eval = EvalExecutable::create(m_callFrame, makeSource(script), m_callFrame->codeBlock()->isStrictMode()); 92 92 JSObject* error = eval->compile(m_callFrame, m_callFrame->scopeChain()); 93 93 if (error) -
trunk/JavaScriptCore/interpreter/Interpreter.cpp
r69096 r69516 60 60 #include "Register.h" 61 61 #include "SamplingTool.h" 62 #include "StrictEvalActivation.h" 62 63 #include <limits.h> 63 64 #include <stdio.h> … … 390 391 if (callFrame->hadException()) 391 392 return JSValue(); 392 393 LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON); 394 if (JSValue parsedObject = preparser.tryLiteralParse()) 395 return parsedObject; 393 394 CodeBlock* codeBlock = callFrame->codeBlock(); 395 if (!codeBlock->isStrictMode()) { 396 // FIXME: We can use the preparser in strict mode, we just need additional logic 397 // to prevent duplicates. 398 LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON); 399 if (JSValue parsedObject = preparser.tryLiteralParse()) 400 return parsedObject; 401 } 396 402 397 403 ScopeChainNode* scopeChain = callFrame->scopeChain(); 398 CodeBlock* codeBlock = callFrame->codeBlock(); 399 RefPtr<EvalExecutable> eval = codeBlock->evalCodeCache().get(callFrame, programSource, scopeChain, exceptionValue); 404 RefPtr<EvalExecutable> eval = codeBlock->evalCodeCache().get(callFrame, codeBlock->isStrictMode(), programSource, scopeChain, exceptionValue); 400 405 401 406 JSValue result = jsUndefined(); … … 562 567 JSActivation* activation = asActivation(scopeChain->object); 563 568 activation->copyRegisters(); 564 if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) 565 asArguments(arguments)->setActivation(activation); 566 } else if (oldCodeBlock->usesArguments()) { 569 if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) { 570 if (!oldCodeBlock->isStrictMode()) 571 asArguments(arguments)->setActivation(activation); 572 } 573 } else if (oldCodeBlock->usesArguments() && !oldCodeBlock->isStrictMode()) { 567 574 if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) 568 575 asArguments(arguments)->copyRegisters(); … … 1062 1069 EvalCodeBlock* codeBlock = &eval->generatedBytecode(); 1063 1070 1064 JS VariableObject* variableObject;1071 JSObject* variableObject; 1065 1072 for (ScopeChainNode* node = scopeChain; ; node = node->next) { 1066 1073 ASSERT(node); … … 1073 1080 unsigned numVariables = codeBlock->numVariables(); 1074 1081 int numFunctions = codeBlock->numberOfFunctionDecls(); 1082 bool pushedScope = false; 1075 1083 if (numVariables || numFunctions) { 1084 if (codeBlock->isStrictMode()) { 1085 variableObject = new (callFrame) StrictEvalActivation(callFrame); 1086 scopeChain = scopeChain->push(variableObject); 1087 pushedScope = true; 1088 } 1076 1089 // Scope for BatchedTransitionOptimizer 1077 1090 BatchedTransitionOptimizer optimizer(variableObject); … … 1096 1109 if (!m_registerFile.grow(newEnd)) { 1097 1110 *exception = createStackOverflowError(callFrame); 1111 if (pushedScope) 1112 scopeChain->pop(); 1098 1113 return jsNull(); 1099 1114 } … … 1138 1153 1139 1154 m_registerFile.shrink(oldEnd); 1155 if (pushedScope) 1156 scopeChain->pop(); 1140 1157 return result; 1141 1158 } … … 2965 2982 JSValue baseValue = callFrame->r(base).jsValue(); 2966 2983 Identifier& ident = codeBlock->identifier(property); 2967 PutPropertySlot slot ;2984 PutPropertySlot slot(codeBlock->isStrictMode()); 2968 2985 if (direct) { 2969 2986 baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot); … … 3081 3098 JSValue baseValue = callFrame->r(base).jsValue(); 3082 3099 Identifier& ident = codeBlock->identifier(property); 3083 PutPropertySlot slot ;3100 PutPropertySlot slot(codeBlock->isStrictMode()); 3084 3101 if (direct) { 3085 3102 baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot); … … 3106 3123 JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); 3107 3124 Identifier& ident = codeBlock->identifier(property); 3108 JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, ident)); 3125 bool result = baseObj->deleteProperty(callFrame, ident); 3126 if (!result && codeBlock->isStrictMode()) { 3127 exceptionValue = createTypeError(callFrame, "Unable to delete property."); 3128 goto vm_throw; 3129 } 3109 3130 CHECK_FOR_EXCEPTION(); 3110 callFrame->r(dst) = result;3131 callFrame->r(dst) = jsBoolean(result); 3111 3132 vPC += OPCODE_LENGTH(op_del_by_id); 3112 3133 NEXT_INSTRUCTION(); … … 3261 3282 Identifier property(callFrame, subscript.toString(callFrame)); 3262 3283 if (!globalData->exception) { // Don't put to an object if toString threw an exception. 3263 PutPropertySlot slot ;3284 PutPropertySlot slot(codeBlock->isStrictMode()); 3264 3285 baseValue.put(callFrame, property, callFrame->r(value).jsValue(), slot); 3265 3286 } … … 3285 3306 3286 3307 JSValue subscript = callFrame->r(property).jsValue(); 3287 JSValueresult;3308 bool result; 3288 3309 uint32_t i; 3289 3310 if (subscript.getUInt32(i)) 3290 result = jsBoolean(baseObj->deleteProperty(callFrame, i));3311 result = baseObj->deleteProperty(callFrame, i); 3291 3312 else { 3292 3313 CHECK_FOR_EXCEPTION(); 3293 3314 Identifier property(callFrame, subscript.toString(callFrame)); 3294 3315 CHECK_FOR_EXCEPTION(); 3295 result = jsBoolean(baseObj->deleteProperty(callFrame, property)); 3296 } 3297 3316 result = baseObj->deleteProperty(callFrame, property); 3317 } 3318 if (!result && codeBlock->isStrictMode()) { 3319 exceptionValue = createTypeError(callFrame, "Unable to delete property."); 3320 goto vm_throw; 3321 } 3298 3322 CHECK_FOR_EXCEPTION(); 3299 callFrame->r(dst) = result;3323 callFrame->r(dst) = jsBoolean(result); 3300 3324 vPC += OPCODE_LENGTH(op_del_by_val); 3301 3325 NEXT_INSTRUCTION(); … … 4037 4061 asArguments(argumentsValue)->copyRegisters(); 4038 4062 4063 if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(src2)).jsValue()) { 4064 if (!codeBlock->isStrictMode()) 4065 asArguments(arguments)->setActivation(activation); 4066 } 4067 4039 4068 vPC += OPCODE_LENGTH(op_tear_off_activation); 4040 4069 NEXT_INSTRUCTION(); … … 4224 4253 4225 4254 vPC += OPCODE_LENGTH(op_convert_this); 4255 NEXT_INSTRUCTION(); 4256 } 4257 DEFINE_OPCODE(op_convert_this_strict) { 4258 /* convert_this_strict this(r) 4259 4260 Takes the value in the 'this' register, and converts it to 4261 its "this" form if (and only if) "this" is an object with a 4262 custom this conversion 4263 4264 This opcode should only be used at the beginning of a code 4265 block. 4266 */ 4267 4268 int thisRegister = vPC[1].u.operand; 4269 JSValue thisVal = callFrame->r(thisRegister).jsValue(); 4270 if (thisVal.isObject() && thisVal.needsThisConversion()) 4271 callFrame->r(thisRegister) = JSValue(thisVal.toStrictThisObject(callFrame)); 4272 4273 vPC += OPCODE_LENGTH(op_convert_this_strict); 4226 4274 NEXT_INSTRUCTION(); 4227 4275 } -
trunk/JavaScriptCore/jit/JIT.cpp
r69045 r69516 226 226 DEFINE_OP(op_create_this) 227 227 DEFINE_OP(op_convert_this) 228 DEFINE_OP(op_convert_this_strict) 228 229 DEFINE_OP(op_init_lazy_reg) 229 230 DEFINE_OP(op_create_arguments) … … 397 398 DEFINE_SLOWCASE_OP(op_construct) 398 399 DEFINE_SLOWCASE_OP(op_convert_this) 400 DEFINE_SLOWCASE_OP(op_convert_this_strict) 399 401 #if !USE(JSVALUE32) 400 402 DEFINE_SLOWCASE_OP(op_div) -
trunk/JavaScriptCore/jit/JIT.h
r69045 r69516 739 739 void emit_op_create_this(Instruction*); 740 740 void emit_op_convert_this(Instruction*); 741 void emit_op_convert_this_strict(Instruction*); 741 742 void emit_op_create_arguments(Instruction*); 742 743 void emit_op_debug(Instruction*); … … 846 847 void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&); 847 848 void emitSlow_op_convert_this(Instruction*, Vector<SlowCaseEntry>::iterator&); 849 void emitSlow_op_convert_this_strict(Instruction*, Vector<SlowCaseEntry>::iterator&); 848 850 void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&); 849 851 void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); -
trunk/JavaScriptCore/jit/JITOpcodes.cpp
r69045 r69516 896 896 if (!m_codeBlock->isKnownNotImmediate(base)) 897 897 isNotObject.append(emitJumpIfNotJSCell(regT0)); 898 if (base != m_codeBlock->thisRegister() ) {898 if (base != m_codeBlock->thisRegister() || m_codeBlock->isStrictMode()) { 899 899 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); 900 900 isNotObject.append(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); … … 1256 1256 } 1257 1257 1258 void JIT::emit_op_convert_this_strict(Instruction* currentInstruction) 1259 { 1260 emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); 1261 Jump notNull = branchTestPtr(NonZero, regT0); 1262 move(ImmPtr(JSValue::encode(jsNull())), regT0); 1263 emitPutVirtualRegister(currentInstruction[1].u.operand, regT0); 1264 Jump setThis = jump(); 1265 notNull.link(this); 1266 Jump isImmediate = emitJumpIfNotJSCell(regT0); 1267 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1); 1268 Jump notAnObject = branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); 1269 addSlowCase(branchTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion))); 1270 isImmediate.link(this); 1271 notAnObject.link(this); 1272 setThis.link(this); 1273 } 1274 1258 1275 void JIT::emit_op_get_callee(Instruction* currentInstruction) 1259 1276 { … … 1301 1318 linkSlowCase(iter); 1302 1319 JITStubCall stubCall(this, cti_op_convert_this); 1320 stubCall.addArgument(regT0); 1321 stubCall.call(currentInstruction[1].u.operand); 1322 } 1323 1324 void JIT::emitSlow_op_convert_this_strict(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1325 { 1326 linkSlowCase(iter); 1327 JITStubCall stubCall(this, cti_op_convert_this_strict); 1303 1328 stubCall.addArgument(regT0); 1304 1329 stubCall.call(currentInstruction[1].u.operand); -
trunk/JavaScriptCore/jit/JITOpcodes32_64.cpp
r69045 r69516 1240 1240 if (!m_codeBlock->isKnownNotImmediate(base)) 1241 1241 isNotObject.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); 1242 if (base != m_codeBlock->thisRegister() ) {1242 if (base != m_codeBlock->thisRegister() || m_codeBlock->isStrictMode()) { 1243 1243 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); 1244 1244 isNotObject.append(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); … … 1555 1555 } 1556 1556 1557 void JIT::emit_op_convert_this_strict(Instruction* currentInstruction) 1558 { 1559 unsigned thisRegister = currentInstruction[1].u.operand; 1560 1561 emitLoad(thisRegister, regT1, regT0); 1562 1563 Jump notNull = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag)); 1564 emitStore(thisRegister, jsNull()); 1565 Jump setThis = jump(); 1566 notNull.link(this); 1567 Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag)); 1568 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1); 1569 Jump notAnObject = branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); 1570 addSlowCase(branchTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion))); 1571 isImmediate.link(this); 1572 notAnObject.link(this); 1573 setThis.link(this); 1574 map(m_bytecodeOffset + OPCODE_LENGTH(op_convert_this), thisRegister, regT1, regT0); 1575 } 1576 1557 1577 void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1558 1578 { … … 1563 1583 1564 1584 JITStubCall stubCall(this, cti_op_convert_this); 1585 stubCall.addArgument(regT1, regT0); 1586 stubCall.call(thisRegister); 1587 } 1588 1589 void JIT::emitSlow_op_convert_this_strict(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1590 { 1591 unsigned thisRegister = currentInstruction[1].u.operand; 1592 1593 linkSlowCase(iter); 1594 1595 JITStubCall stubCall(this, cti_op_convert_this_strict); 1565 1596 stubCall.addArgument(regT1, regT0); 1566 1597 stubCall.call(thisRegister); -
trunk/JavaScriptCore/jit/JITStubs.cpp
r69045 r69516 1066 1066 } while (0) 1067 1067 #define VM_THROW_EXCEPTION_AT_END() \ 1068 returnToThrowTrampoline(stackFrame.globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS) 1068 do {\ 1069 returnToThrowTrampoline(stackFrame.globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS);\ 1070 } while (0) 1069 1071 1070 1072 #define CHECK_FOR_EXCEPTION() \ … … 1302 1304 } 1303 1305 1306 DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this_strict) 1307 { 1308 STUB_INIT_STACK_FRAME(stackFrame); 1309 1310 JSValue v1 = stackFrame.args[0].jsValue(); 1311 CallFrame* callFrame = stackFrame.callFrame; 1312 1313 JSValue result = v1.toStrictThisObject(callFrame); 1314 CHECK_FOR_EXCEPTION_AT_END(); 1315 return JSValue::encode(result); 1316 } 1317 1304 1318 DEFINE_STUB_FUNCTION(void, op_end) 1305 1319 { … … 1405 1419 STUB_INIT_STACK_FRAME(stackFrame); 1406 1420 1407 PutPropertySlot slot ;1421 PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode()); 1408 1422 stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot); 1409 1423 CHECK_FOR_EXCEPTION_AT_END(); … … 1414 1428 STUB_INIT_STACK_FRAME(stackFrame); 1415 1429 1416 PutPropertySlot slot ;1430 PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode()); 1417 1431 stackFrame.args[0].jsValue().putDirect(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot); 1418 1432 CHECK_FOR_EXCEPTION_AT_END(); … … 1442 1456 Identifier& ident = stackFrame.args[1].identifier(); 1443 1457 1444 PutPropertySlot slot ;1458 PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); 1445 1459 stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot); 1446 1460 … … 1461 1475 Identifier& ident = stackFrame.args[1].identifier(); 1462 1476 1463 PutPropertySlot slot ;1477 PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); 1464 1478 stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot); 1465 1479 … … 1480 1494 CallFrame* callFrame = stackFrame.callFrame; 1481 1495 Identifier& ident = stackFrame.args[1].identifier(); 1482 1483 PutPropertySlot slot ;1496 1497 PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); 1484 1498 stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot); 1485 1499 … … 1494 1508 Identifier& ident = stackFrame.args[1].identifier(); 1495 1509 1496 PutPropertySlot slot ;1510 PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); 1497 1511 stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot); 1498 1512 … … 1881 1895 JSObject* baseObj = stackFrame.args[0].jsValue().toObject(callFrame); 1882 1896 1883 JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, stackFrame.args[1].identifier())); 1897 bool couldDelete = baseObj->deleteProperty(callFrame, stackFrame.args[1].identifier()); 1898 JSValue result = jsBoolean(couldDelete); 1899 if (!couldDelete && callFrame->codeBlock()->isStrictMode()) 1900 stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property."); 1901 1884 1902 CHECK_FOR_EXCEPTION_AT_END(); 1885 1903 return JSValue::encode(result); … … 2223 2241 JSActivation* activation = asActivation(stackFrame.args[0].jsValue()); 2224 2242 activation->copyRegisters(); 2225 if (JSValue v = stackFrame.args[1].jsValue()) 2226 asArguments(v)->setActivation(activation); 2243 if (JSValue v = stackFrame.args[1].jsValue()) { 2244 if (!stackFrame.callFrame->codeBlock()->isStrictMode()) 2245 asArguments(v)->setActivation(activation); 2246 } 2227 2247 } 2228 2248 … … 2504 2524 Identifier property(callFrame, subscript.toString(callFrame)); 2505 2525 if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception. 2506 PutPropertySlot slot ;2526 PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); 2507 2527 baseValue.put(callFrame, property, value, slot); 2508 2528 } … … 2547 2567 Identifier property(callFrame, subscript.toString(callFrame)); 2548 2568 if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception. 2549 PutPropertySlot slot ;2569 PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); 2550 2570 baseValue.put(callFrame, property, value, slot); 2551 2571 } … … 3502 3522 3503 3523 JSValue subscript = stackFrame.args[1].jsValue(); 3504 JSValueresult;3524 bool result; 3505 3525 uint32_t i; 3506 3526 if (subscript.getUInt32(i)) 3507 result = jsBoolean(baseObj->deleteProperty(callFrame, i));3527 result = baseObj->deleteProperty(callFrame, i); 3508 3528 else { 3509 3529 CHECK_FOR_EXCEPTION(); 3510 3530 Identifier property(callFrame, subscript.toString(callFrame)); 3511 3531 CHECK_FOR_EXCEPTION(); 3512 result = jsBoolean(baseObj->deleteProperty(callFrame, property)); 3513 } 3514 3515 CHECK_FOR_EXCEPTION_AT_END(); 3516 return JSValue::encode(result); 3532 result = baseObj->deleteProperty(callFrame, property); 3533 } 3534 3535 if (!result && callFrame->codeBlock()->isStrictMode()) 3536 stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property."); 3537 3538 CHECK_FOR_EXCEPTION_AT_END(); 3539 return JSValue::encode(jsBoolean(result)); 3517 3540 } 3518 3541 -
trunk/JavaScriptCore/jit/JITStubs.h
r67943 r69516 297 297 EncodedJSValue JIT_STUB cti_op_create_this(STUB_ARGS_DECLARATION); 298 298 EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION); 299 EncodedJSValue JIT_STUB cti_op_convert_this_strict(STUB_ARGS_DECLARATION); 299 300 EncodedJSValue JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION); 300 301 EncodedJSValue JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS_DECLARATION); -
trunk/JavaScriptCore/parser/ASTBuilder.h
r67583 r69516 250 250 } 251 251 252 FunctionBodyNode* createFunctionBody( )252 FunctionBodyNode* createFunctionBody(bool inStrictContext) 253 253 { 254 254 usesClosures(); 255 return FunctionBodyNode::create(m_globalData );255 return FunctionBodyNode::create(m_globalData, inStrictContext); 256 256 } 257 257 … … 579 579 const Identifier& getName(Property property) { return property->name(); } 580 580 PropertyNode::Type getType(Property property) { return property->type(); } 581 582 bool isResolve(ExpressionNode* expr) { return expr->isResolveNode(); } 583 581 584 private: 582 585 struct Scope { -
trunk/JavaScriptCore/parser/JSParser.cpp
r68288 r69516 30 30 using namespace JSC; 31 31 32 #include "CodeBlock.h" 32 33 #include "JSGlobalData.h" 33 34 #include "NodeInfo.h" … … 43 44 #define failIfFalse(cond) do { if (!(cond)) fail(); } while (0) 44 45 #define failIfTrue(cond) do { if ((cond)) fail(); } while (0) 46 #define failIfTrueIfStrict(cond) do { if ((cond) && strictMode()) fail(); } while (0) 47 #define failIfFalseIfStrict(cond) do { if ((!(cond)) && strictMode()) fail(); } while (0) 45 48 #define consumeOrFail(tokenType) do { if (!consume(tokenType)) fail(); } while (0) 46 49 #define matchOrFail(tokenType) do { if (!match(tokenType)) fail(); } while (0) … … 68 71 class JSParser { 69 72 public: 70 JSParser(Lexer*, JSGlobalData*, FunctionParameters*, SourceProvider*);71 bool parseProgram( );73 JSParser(Lexer*, JSGlobalData*, FunctionParameters*, bool isStrictContext, bool isFunction, SourceProvider*); 74 bool parseProgram(JSGlobalObject*); 72 75 private: 73 76 struct AllowInOverride { … … 91 94 m_lastTokenEnd = m_token.m_info.endOffset; 92 95 m_lexer->setLastLineNumber(m_lastLine); 93 m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_info, lexType );96 m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_info, lexType, strictMode()); 94 97 m_tokenCount++; 95 98 } … … 122 125 return m_token.m_info.endOffset; 123 126 } 124 125 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&); 126 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&); 127 128 void startLoop() { currentScope()->startLoop(); } 129 void endLoop() { currentScope()->endLoop(); } 130 void startSwitch() { currentScope()->startSwitch(); } 131 void endSwitch() { currentScope()->endSwitch(); } 132 void setStrictMode() { currentScope()->setStrictMode(); } 133 bool strictMode() { return currentScope()->strictMode(); } 134 bool isValidStrictMode() { return currentScope()->isValidStrictMode(); } 135 bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); } 136 bool breakIsValid() { return currentScope()->breakIsValid(); } 137 void pushLabel(const Identifier* label) { currentScope()->pushLabel(label); } 138 void popLabel() { currentScope()->popLabel(); } 139 bool hasLabel(const Identifier* label) { return currentScope()->hasLabel(label); } 140 141 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode }; 142 template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&); 143 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive); 127 144 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&); 128 145 template <class TreeBuilder> TreeStatement parseVarDeclaration(TreeBuilder&); … … 200 217 int m_nonLHSCount; 201 218 bool m_syntaxAlreadyValidated; 219 int m_statementDepth; 220 int m_nonTrivialExpressionCount; 221 const Identifier* m_lastIdentifier; 222 223 struct DepthManager { 224 DepthManager(int* depth) 225 : m_originalDepth(*depth) 226 , m_depth(depth) 227 { 228 } 229 230 ~DepthManager() 231 { 232 *m_depth = m_originalDepth; 233 } 234 235 private: 236 int m_originalDepth; 237 int* m_depth; 238 }; 202 239 203 240 struct Scope { 204 Scope() 205 : m_usesEval(false) 241 Scope(JSGlobalData* globalData, bool isFunction, bool strictMode) 242 : m_globalData(globalData) 243 , m_usesEval(false) 206 244 , m_needsFullActivation(false) 207 245 , m_allowsNewDecls(true) 246 , m_strictMode(strictMode) 247 , m_isFunction(isFunction) 248 , m_isValidStrictMode(true) 249 , m_loopDepth(0) 250 , m_switchDepth(0) 251 , m_labels(0) 208 252 { 209 253 } 210 254 211 void declareVariable(const Identifier* ident) 255 void startSwitch() { m_switchDepth++; } 256 void endSwitch() { m_switchDepth--; } 257 void startLoop() { m_loopDepth++; } 258 void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; } 259 bool inLoop() { return !!m_loopDepth; } 260 bool breakIsValid() { return m_loopDepth || m_switchDepth; } 261 262 void pushLabel(const Identifier* label) 212 263 { 264 if (!m_labels) 265 m_labels = new LabelStack; 266 m_labels->append(label->impl()); 267 } 268 269 void popLabel() 270 { 271 ASSERT(m_labels); 272 ASSERT(m_labels->size()); 273 m_labels->removeLast(); 274 } 275 276 bool hasLabel(const Identifier* label) 277 { 278 if (!m_labels) 279 return false; 280 for (int i = m_labels->size(); i > 0; i--) { 281 if (m_labels->at(i - 1) == label->impl()) 282 return true; 283 } 284 return false; 285 } 286 287 void setIsFunction() { m_isFunction = true; } 288 bool isFunction() { return m_isFunction; } 289 290 bool declareVariable(const Identifier* ident) 291 { 292 bool isValidStrictMode = m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident; 293 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode; 213 294 m_declaredVariables.add(ident->ustring().impl()); 295 return isValidStrictMode; 296 } 297 298 void declareWrite(const Identifier* ident) 299 { 300 ASSERT(m_strictMode); 301 m_writtenVariables.add(ident->impl()); 302 } 303 304 bool deleteProperty(const Identifier* ident) 305 { 306 if (m_declaredVariables.contains(ident->impl())) 307 return false; 308 m_deletedVariables.add(ident->impl()); 309 return true; 214 310 } 215 311 … … 217 313 bool allowsNewDecls() const { return m_allowsNewDecls; } 218 314 315 bool declareParameter(const Identifier* ident) 316 { 317 bool isValidStrictMode = m_declaredVariables.add(ident->ustring().impl()).second && m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident; 318 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode; 319 return isValidStrictMode; 320 } 321 219 322 void useVariable(const Identifier* ident, bool isEval) 220 323 { … … 223 326 } 224 327 225 void needsFullActivation() { m_needsFullActivation = true; }328 void setNeedsFullActivation() { m_needsFullActivation = true; } 226 329 227 voidcollectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)330 bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables) 228 331 { 229 332 if (nestedScope->m_usesEval) … … 237 340 m_closedVariables.add(*ptr); 238 341 } 342 if (nestedScope->m_writtenVariables.size()) { 343 IdentifierSet::iterator end = nestedScope->m_writtenVariables.end(); 344 for (IdentifierSet::iterator ptr = nestedScope->m_writtenVariables.begin(); ptr != end; ++ptr) { 345 if (nestedScope->m_declaredVariables.contains(*ptr)) 346 continue; 347 m_writtenVariables.add(*ptr); 348 } 349 } 350 if (nestedScope->m_deletedVariables.size()) { 351 IdentifierSet::iterator end = nestedScope->m_deletedVariables.end(); 352 for (IdentifierSet::iterator ptr = nestedScope->m_deletedVariables.begin(); ptr != end; ++ptr) { 353 if (nestedScope->m_declaredVariables.contains(*ptr)) 354 return false; 355 if (m_declaredVariables.contains(*ptr)) 356 return false; 357 m_deletedVariables.add(*ptr); 358 } 359 } 360 return true; 361 } 362 363 void getUncapturedWrittenVariables(IdentifierSet& writtenVariables) 364 { 365 IdentifierSet::iterator end = m_writtenVariables.end(); 366 for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) { 367 if (!m_declaredVariables.contains(*ptr)) 368 writtenVariables.add(*ptr); 369 } 370 } 371 372 bool getDeletedVariables(IdentifierSet& deletedVariables) 373 { 374 IdentifierSet::iterator end = m_deletedVariables.end(); 375 for (IdentifierSet::iterator ptr = m_deletedVariables.begin(); ptr != end; ++ptr) { 376 if (m_declaredVariables.contains(*ptr)) 377 return false; 378 } 379 deletedVariables.swap(m_deletedVariables); 380 return true; 239 381 } 240 382 … … 251 393 } 252 394 } 395 void setStrictMode() { m_strictMode = true; } 396 bool strictMode() const { return m_strictMode; } 397 bool isValidStrictMode() const { return m_isValidStrictMode; } 398 253 399 private: 254 bool m_usesEval; 255 bool m_needsFullActivation; 256 bool m_allowsNewDecls; 400 JSGlobalData* m_globalData; 401 bool m_usesEval : 1; 402 bool m_needsFullActivation : 1; 403 bool m_allowsNewDecls : 1; 404 bool m_strictMode : 1; 405 bool m_isFunction : 1; 406 bool m_isValidStrictMode : 1; 407 int m_loopDepth; 408 int m_switchDepth; 409 typedef Vector<StringImpl*, 2> LabelStack; 410 LabelStack* m_labels; 257 411 IdentifierSet m_declaredVariables; 258 412 IdentifierSet m_usedVariables; 259 413 IdentifierSet m_closedVariables; 414 IdentifierSet m_writtenVariables; 415 IdentifierSet m_deletedVariables; 260 416 }; 261 417 … … 282 438 ScopeRef pushScope() 283 439 { 284 m_scopeStack.append(Scope()); 440 bool isFunction = false; 441 bool isStrict = false; 442 if (!m_scopeStack.isEmpty()) { 443 isStrict = m_scopeStack.last().strictMode(); 444 isFunction = m_scopeStack.last().isFunction(); 445 } 446 m_scopeStack.append(Scope(m_globalData, isFunction, isStrict)); 285 447 return currentScope(); 286 448 } 287 449 288 voidpopScope(ScopeRef scope, bool shouldTrackClosedVariables)450 bool popScope(ScopeRef scope, bool shouldTrackClosedVariables) 289 451 { 290 452 ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1); 291 453 ASSERT(m_scopeStack.size() > 1); 292 m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);454 bool result = m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables); 293 455 m_scopeStack.removeLast(); 456 return result; 294 457 } 295 458 296 voiddeclareVariable(const Identifier* ident)459 bool declareVariable(const Identifier* ident) 297 460 { 298 461 unsigned i = m_scopeStack.size() - 1; … … 302 465 ASSERT(i < m_scopeStack.size()); 303 466 } 304 m_scopeStack[i].declareVariable(ident); 305 } 306 467 return m_scopeStack[i].declareVariable(ident); 468 } 469 470 void declareWrite(const Identifier* ident) 471 { 472 if (!m_syntaxAlreadyValidated) 473 m_scopeStack.last().declareWrite(ident); 474 } 475 476 bool deleteProperty(const Identifier* ident) 477 { 478 if (!m_syntaxAlreadyValidated) 479 return m_scopeStack.last().deleteProperty(ident); 480 return true; 481 } 482 307 483 ScopeStack m_scopeStack; 308 484 }; 309 485 310 int jsParse(JSGlobal Data* globalData, FunctionParameters* parameters, const SourceCode* source)311 { 312 JSParser parser( globalData->lexer, globalData, parameters, source->provider());313 return parser.parseProgram( );314 } 315 316 JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, FunctionParameters* parameters, SourceProvider* provider)486 int jsParse(JSGlobalObject* lexicalGlobalObject, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode, const SourceCode* source) 487 { 488 JSParser parser(lexicalGlobalObject->globalData()->lexer, lexicalGlobalObject->globalData(), parameters, strictness == JSParseStrict, parserMode == JSParseFunctionCode, source->provider()); 489 return parser.parseProgram(lexicalGlobalObject); 490 } 491 492 JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, FunctionParameters* parameters, bool inStrictContext, bool isFunction, SourceProvider* provider) 317 493 : m_lexer(lexer) 318 494 , m_endAddress(0) … … 326 502 , m_nonLHSCount(0) 327 503 , m_syntaxAlreadyValidated(provider->isValid()) 504 , m_statementDepth(0) 505 , m_nonTrivialExpressionCount(0) 506 , m_lastIdentifier(0) 328 507 { 329 508 m_endAddress = wtfThreadData().approximatedStackStart() - kMaxParserStackUsage; 330 next();331 m_lexer->setLastLineNumber(tokenLine());332 509 ScopeRef scope = pushScope(); 510 if (isFunction) 511 scope->setIsFunction(); 512 if (inStrictContext) 513 scope->setStrictMode(); 333 514 if (parameters) { 334 515 for (unsigned i = 0; i < parameters->size(); i++) 335 scope->declareVariable(¶meters->at(i)); 336 } 337 } 338 339 bool JSParser::parseProgram() 516 scope->declareParameter(¶meters->at(i)); 517 } 518 next(); 519 m_lexer->setLastLineNumber(tokenLine()); 520 } 521 522 bool JSParser::parseProgram(JSGlobalObject* lexicalGlobalObject) 340 523 { 341 524 ASTBuilder context(m_globalData, m_lexer); 525 if (m_lexer->isReparsing()) 526 m_statementDepth--; 342 527 ScopeRef scope = currentScope(); 343 SourceElements* sourceElements = parseSourceElements< ASTBuilder>(context);528 SourceElements* sourceElements = parseSourceElements<CheckForStrictMode>(context); 344 529 if (!sourceElements || !consume(EOFTOK)) 345 530 return true; 531 if (!m_syntaxAlreadyValidated) { 532 IdentifierSet writtenVariables; 533 scope->getUncapturedWrittenVariables(writtenVariables); 534 IdentifierSet::const_iterator end = writtenVariables.end(); 535 for (IdentifierSet::const_iterator ptr = writtenVariables.begin(); ptr != end; ++ptr) { 536 PropertySlot slot(lexicalGlobalObject); 537 if (!lexicalGlobalObject->getPropertySlot(lexicalGlobalObject->globalExec(), Identifier(m_globalData, *ptr), slot)) 538 return true; 539 } 540 IdentifierSet deletedVariables; 541 if (!scope->getDeletedVariables(deletedVariables)) 542 return true; 543 end = deletedVariables.end(); 544 SymbolTable& globalEnvRecord = lexicalGlobalObject->symbolTable(); 545 for (IdentifierSet::const_iterator ptr = deletedVariables.begin(); ptr != end; ++ptr) { 546 if (!globalEnvRecord.get(*ptr).isNull()) 547 return true; 548 } 549 } 346 550 IdentifierSet capturedVariables; 347 551 scope->getCapturedVariables(capturedVariables); 348 m_globalData->parser->didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), context.features() ,349 m_lastLine, context.numConstants(), capturedVariables);552 m_globalData->parser->didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), context.features() | (scope->strictMode() ? StrictModeFeature : 0), 553 m_lastLine, context.numConstants(), capturedVariables); 350 554 return false; 351 555 } … … 356 560 } 357 561 358 template < class TreeBuilder> TreeSourceElements JSParser::parseSourceElements(TreeBuilder& context)562 template <JSParser::SourceElementsMode mode, class TreeBuilder> TreeSourceElements JSParser::parseSourceElements(TreeBuilder& context) 359 563 { 360 564 TreeSourceElements sourceElements = context.createSourceElements(); 361 while (TreeStatement statement = parseStatement(context)) 565 bool seenNonDirective = false; 566 const Identifier* directive = 0; 567 unsigned startOffset = m_token.m_info.startOffset; 568 bool hasSetStrict = false; 569 while (TreeStatement statement = parseStatement(context, directive)) { 570 if (mode == CheckForStrictMode && !seenNonDirective) { 571 if (directive) { 572 if (!hasSetStrict && m_globalData->propertyNames->useStrictIdentifier == *directive) { 573 setStrictMode(); 574 hasSetStrict = true; 575 failIfFalse(isValidStrictMode()); 576 m_lexer->setOffset(startOffset); 577 next(); 578 failIfTrue(m_error); 579 continue; 580 } 581 } else 582 seenNonDirective = true; 583 } 362 584 context.appendStatement(sourceElements, statement); 585 } 363 586 364 587 if (m_error) … … 400 623 int startLine = tokenLine(); 401 624 next(); 402 TreeStatement statement = parseStatement(context); 625 const Identifier* unused = 0; 626 startLoop(); 627 TreeStatement statement = parseStatement(context, unused); 628 endLoop(); 403 629 failIfFalse(statement); 404 630 int endLine = tokenLine(); … … 423 649 int endLine = tokenLine(); 424 650 consumeOrFail(CLOSEPAREN); 425 TreeStatement statement = parseStatement(context); 651 const Identifier* unused = 0; 652 startLoop(); 653 TreeStatement statement = parseStatement(context, unused); 654 endLoop(); 426 655 failIfFalse(statement); 427 656 return context.createWhileStatement(expr, statement, startLine, endLine); … … 442 671 next(); 443 672 bool hasInitializer = match(EQUAL); 444 declareVariable(name);673 failIfFalseIfStrict(declareVariable(name)); 445 674 context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0); 446 675 if (hasInitializer) { … … 466 695 template <class TreeBuilder> TreeConstDeclList JSParser::parseConstDeclarationList(TreeBuilder& context) 467 696 { 697 failIfTrue(strictMode()); 468 698 TreeConstDeclList constDecls = 0; 469 699 TreeConstDeclList tail = 0; … … 533 763 consumeOrFail(CLOSEPAREN); 534 764 535 TreeStatement statement = parseStatement(context); 765 const Identifier* unused = 0; 766 startLoop(); 767 TreeStatement statement = parseStatement(context, unused); 768 endLoop(); 536 769 failIfFalse(statement); 537 770 … … 567 800 int endLine = tokenLine(); 568 801 consumeOrFail(CLOSEPAREN); 569 TreeStatement statement = parseStatement(context); 802 const Identifier* unused = 0; 803 startLoop(); 804 TreeStatement statement = parseStatement(context, unused); 805 endLoop(); 570 806 failIfFalse(statement); 571 807 return context.createForLoop(decls, condition, increment, statement, hasDeclaration, startLine, endLine); … … 580 816 int endLine = tokenLine(); 581 817 consumeOrFail(CLOSEPAREN); 582 TreeStatement statement = parseStatement(context); 818 const Identifier* unused = 0; 819 startLoop(); 820 TreeStatement statement = parseStatement(context, unused); 821 endLoop(); 583 822 failIfFalse(statement); 584 823 … … 595 834 next(); 596 835 597 if (autoSemiColon()) 836 if (autoSemiColon()) { 837 failIfFalseIfStrict(breakIsValid()); 598 838 return context.createBreakStatement(startCol, endCol, startLine, endLine); 839 } 599 840 matchOrFail(IDENT); 600 841 const Identifier* ident = m_token.m_data.ident; 842 failIfFalseIfStrict(hasLabel(ident)); 601 843 endCol = tokenEnd(); 602 844 endLine = tokenLine(); … … 615 857 next(); 616 858 617 if (autoSemiColon()) 859 if (autoSemiColon()) { 860 failIfFalseIfStrict(breakIsValid()); 618 861 return context.createContinueStatement(startCol, endCol, startLine, endLine); 862 } 619 863 matchOrFail(IDENT); 620 864 const Identifier* ident = m_token.m_data.ident; 865 failIfFalseIfStrict(hasLabel(ident)); 621 866 endCol = tokenEnd(); 622 867 endLine = tokenLine(); … … 629 874 { 630 875 ASSERT(match(RETURN)); 876 failIfFalseIfStrict(currentScope()->isFunction()); 631 877 int startLine = tokenLine(); 632 878 int endLine = startLine; … … 669 915 { 670 916 ASSERT(match(WITH)); 671 currentScope()->needsFullActivation(); 917 failIfTrue(strictMode()); 918 currentScope()->setNeedsFullActivation(); 672 919 int startLine = tokenLine(); 673 920 next(); … … 680 927 int endLine = tokenLine(); 681 928 consumeOrFail(CLOSEPAREN); 682 683 TreeStatement statement = parseStatement(context );929 const Identifier* unused = 0; 930 TreeStatement statement = parseStatement(context, unused); 684 931 failIfFalse(statement); 685 932 … … 698 945 consumeOrFail(CLOSEPAREN); 699 946 consumeOrFail(OPENBRACE); 700 947 startSwitch(); 701 948 TreeClauseList firstClauses = parseSwitchClauses(context); 702 949 failIfTrue(m_error); … … 707 954 TreeClauseList secondClauses = parseSwitchClauses(context); 708 955 failIfTrue(m_error); 956 endSwitch(); 709 957 consumeOrFail(CLOSEBRACE); 710 958 … … 721 969 failIfFalse(condition); 722 970 consumeOrFail(COLON); 723 TreeSourceElements statements = parseSourceElements (context);971 TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context); 724 972 failIfFalse(statements); 725 973 TreeClause clause = context.createClause(condition, statements); … … 732 980 failIfFalse(condition); 733 981 consumeOrFail(COLON); 734 TreeSourceElements statements = parseSourceElements (context);982 TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context); 735 983 failIfFalse(statements); 736 984 clause = context.createClause(condition, statements); … … 746 994 next(); 747 995 consumeOrFail(COLON); 748 TreeSourceElements statements = parseSourceElements (context);996 TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context); 749 997 failIfFalse(statements); 750 998 return context.createClause(0, statements); … … 768 1016 769 1017 if (match(CATCH)) { 770 currentScope()-> needsFullActivation();1018 currentScope()->setNeedsFullActivation(); 771 1019 next(); 772 1020 consumeOrFail(OPENPAREN); … … 775 1023 next(); 776 1024 ScopeRef catchScope = pushScope(); 777 catchScope->declareVariable(ident);1025 failIfFalseIfStrict(catchScope->declareVariable(ident)); 778 1026 catchScope->preventNewDecls(); 779 1027 consumeOrFail(CLOSEPAREN); … … 783 1031 failIfFalse(catchBlock); 784 1032 catchHasEval = initialEvalCount != context.evalCount(); 785 popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);1033 failIfFalse(popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo)); 786 1034 } 787 1035 … … 817 1065 return context.createBlockStatement(0, start, m_lastLine); 818 1066 } 819 TreeSourceElements subtree = parseSourceElements (context);1067 TreeSourceElements subtree = parseSourceElements<DontCheckForStrictMode>(context); 820 1068 failIfFalse(subtree); 821 1069 matchOrFail(CLOSEBRACE); … … 824 1072 } 825 1073 826 template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder& context) 827 { 1074 template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder& context, const Identifier*& directive) 1075 { 1076 DepthManager statementDepth(&m_statementDepth); 1077 m_statementDepth++; 1078 directive = 0; 1079 int nonTrivialExpressionCount = 0; 828 1080 failIfStackOverflow(); 829 1081 switch (m_token.m_type) { … … 835 1087 return parseConstDeclaration(context); 836 1088 case FUNCTION: 1089 failIfFalseIfStrict(m_statementDepth == 1); 837 1090 return parseFunctionDeclaration(context); 838 1091 case SEMICOLON: … … 871 1124 case IDENT: 872 1125 return parseExpressionOrLabelStatement(context); 1126 case STRING: 1127 directive = m_token.m_data.ident; 1128 nonTrivialExpressionCount = m_nonTrivialExpressionCount; 873 1129 default: 874 return parseExpressionStatement(context); 1130 TreeStatement exprStatement = parseExpressionStatement(context); 1131 if (directive && nonTrivialExpressionCount != m_nonTrivialExpressionCount) 1132 directive = 0; 1133 return exprStatement; 875 1134 } 876 1135 } … … 880 1139 matchOrFail(IDENT); 881 1140 usesArguments = m_globalData->propertyNames->arguments == *m_token.m_data.ident; 882 declareVariable(m_token.m_data.ident);1141 failIfFalseIfStrict(declareParameter(m_token.m_data.ident)); 883 1142 TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident); 884 1143 TreeFormalParameterList tail = list; … … 888 1147 matchOrFail(IDENT); 889 1148 const Identifier* ident = m_token.m_data.ident; 890 declareVariable(ident); 1149 usesArguments |= m_globalData->propertyNames->arguments == *m_token.m_data.ident; 1150 failIfFalseIfStrict(declareParameter(ident)); 891 1151 next(); 892 1152 usesArguments = usesArguments || m_globalData->propertyNames->arguments == *ident; … … 899 1159 { 900 1160 if (match(CLOSEBRACE)) 901 return context.createFunctionBody(); 1161 return context.createFunctionBody(strictMode()); 1162 DepthManager statementDepth(&m_statementDepth); 1163 m_statementDepth = 0; 902 1164 typename TreeBuilder::FunctionBodyBuilder bodyBuilder(m_globalData, m_lexer); 903 failIfFalse(parseSourceElements (bodyBuilder));904 return context.createFunctionBody( );1165 failIfFalse(parseSourceElements<CheckForStrictMode>(bodyBuilder)); 1166 return context.createFunctionBody(strictMode()); 905 1167 } 906 1168 … … 908 1170 { 909 1171 ScopeRef functionScope = pushScope(); 1172 functionScope->setIsFunction(); 910 1173 if (match(IDENT)) { 911 1174 name = m_token.m_data.ident; 912 1175 next(); 913 1176 if (!nameIsInContainingScope) 914 f unctionScope->declareVariable(name);1177 failIfFalseIfStrict(functionScope->declareVariable(name)); 915 1178 } else if (requirements == FunctionNeedsName) 916 1179 return false; … … 932 1195 if (usesArguments) 933 1196 context.setUsesArguments(body); 934 popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo); 1197 if (functionScope->strictMode() && name) { 1198 failIfTrue(m_globalData->propertyNames->arguments == *name); 1199 failIfTrue(m_globalData->propertyNames->eval == *name); 1200 } 1201 failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo)); 935 1202 matchOrFail(CLOSEBRACE); 936 1203 closeBracePos = m_token.m_data.intValue; … … 951 1218 failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine))); 952 1219 failIfFalse(name); 953 declareVariable(name);1220 failIfFalseIfStrict(declareVariable(name)); 954 1221 return context.createFuncDeclStatement(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine); 955 1222 } … … 974 1241 int end = tokenEnd(); 975 1242 consumeOrFail(COLON); 976 TreeStatement statement = parseStatement(context); 1243 const Identifier* unused = 0; 1244 if (strictMode() && !m_syntaxAlreadyValidated) 1245 pushLabel(ident); 1246 TreeStatement statement = parseStatement(context, unused); 1247 if (strictMode() && !m_syntaxAlreadyValidated) 1248 popLabel(); 977 1249 failIfFalse(statement); 978 1250 return context.createLabelStatement(ident, statement, start, end); … … 1002 1274 consumeOrFail(CLOSEPAREN); 1003 1275 1004 TreeStatement trueBlock = parseStatement(context); 1276 const Identifier* unused = 0; 1277 TreeStatement trueBlock = parseStatement(context, unused); 1005 1278 failIfFalse(trueBlock); 1006 1279 … … 1015 1288 next(); 1016 1289 if (!match(IF)) { 1017 TreeStatement block = parseStatement(context); 1290 const Identifier* unused = 0; 1291 TreeStatement block = parseStatement(context, unused); 1018 1292 failIfFalse(block); 1019 1293 statementStack.append(block); … … 1030 1304 int innerEnd = tokenLine(); 1031 1305 consumeOrFail(CLOSEPAREN); 1032 1033 TreeStatement innerTrueBlock = parseStatement(context );1306 const Identifier* unused = 0; 1307 TreeStatement innerTrueBlock = parseStatement(context, unused); 1034 1308 failIfFalse(innerTrueBlock); 1035 1309 exprStack.append(innerCondition); … … 1071 1345 return node; 1072 1346 next(); 1347 m_nonTrivialExpressionCount++; 1073 1348 m_nonLHSCount++; 1074 1349 TreeExpression right = parseAssignmentExpression(context); … … 1116 1391 goto end; 1117 1392 } 1393 m_nonTrivialExpressionCount++; 1118 1394 hadAssignment = true; 1119 1395 context.assignmentStackAppend(assignmentStack, lhs, start, tokenStart(), m_assignmentCount, op); … … 1121 1397 m_assignmentCount++; 1122 1398 next(); 1399 if (strictMode() && m_lastIdentifier && context.isResolve(lhs)) { 1400 failIfTrueIfStrict(m_globalData->propertyNames->eval == *m_lastIdentifier); 1401 declareWrite(m_lastIdentifier); 1402 m_lastIdentifier = 0; 1403 } 1123 1404 lhs = parseConditionalExpression(context); 1124 1405 failIfFalse(lhs); … … 1145 1426 if (!match(QUESTION)) 1146 1427 return cond; 1428 m_nonTrivialExpressionCount++; 1147 1429 m_nonLHSCount++; 1148 1430 next(); … … 1182 1464 if (!precedence) 1183 1465 break; 1466 m_nonTrivialExpressionCount++; 1184 1467 m_nonLHSCount++; 1185 1468 int operatorToken = m_token.m_type; … … 1197 1480 context.operatorStackAppend(operatorStackDepth, operatorToken, precedence); 1198 1481 } 1199 1200 1482 while (operatorStackDepth) { 1201 1483 ASSERT(operandStackDepth > 1); … … 1328 1610 std::pair<ObjectValidationMap::iterator, bool> propertyEntryIter = objectValidator.add(context.getName(property).impl(), context.getType(property)); 1329 1611 if (!propertyEntryIter.second) { 1612 failIfTrue(strictMode()); 1330 1613 if ((context.getType(property) & propertyEntryIter.first->second) != PropertyNode::Constant) { 1331 1614 // Can't have multiple getters or setters with the same name, nor can we define … … 1390 1673 switch (m_token.m_type) { 1391 1674 case OPENBRACE: 1675 if (strictMode()) 1676 return parseStrictObjectLiteral(context); 1392 1677 return parseObjectLiteral(context); 1393 1678 case OPENBRACKET: … … 1411 1696 next(); 1412 1697 currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident); 1698 m_lastIdentifier = ident; 1413 1699 return context.createResolve(ident, start); 1414 1700 } … … 1486 1772 newCount++; 1487 1773 } 1774 1488 1775 if (match(FUNCTION)) { 1489 1776 const Identifier* name = &m_globalData->propertyNames->nullIdentifier; … … 1503 1790 switch (m_token.m_type) { 1504 1791 case OPENBRACKET: { 1792 m_nonTrivialExpressionCount++; 1505 1793 int expressionEnd = lastTokenEnd(); 1506 1794 next(); … … 1516 1804 } 1517 1805 case OPENPAREN: { 1806 m_nonTrivialExpressionCount++; 1518 1807 if (newCount) { 1519 1808 newCount--; … … 1536 1825 } 1537 1826 case DOT: { 1827 m_nonTrivialExpressionCount++; 1538 1828 int expressionEnd = lastTokenEnd(); 1539 1829 next(Lexer::IgnoreReservedWords); … … 1557 1847 AllowInOverride allowInOverride(this); 1558 1848 int tokenStackDepth = 0; 1849 bool modifiesExpr = false; 1850 bool requiresLExpr = false; 1559 1851 while (isUnaryOp(m_token.m_type)) { 1852 if (strictMode()) { 1853 switch (m_token.m_type) { 1854 case PLUSPLUS: 1855 case MINUSMINUS: 1856 case AUTOPLUSPLUS: 1857 case AUTOMINUSMINUS: 1858 failIfTrue(requiresLExpr); 1859 modifiesExpr = true; 1860 requiresLExpr = true; 1861 break; 1862 case DELETETOKEN: 1863 failIfTrue(requiresLExpr); 1864 requiresLExpr = true; 1865 break; 1866 default: 1867 failIfTrue(requiresLExpr); 1868 break; 1869 } 1870 } 1560 1871 m_nonLHSCount++; 1561 1872 context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStart()); 1562 1873 next(); 1874 m_nonTrivialExpressionCount++; 1563 1875 } 1564 1876 int subExprStart = tokenStart(); 1565 1877 TreeExpression expr = parseMemberExpression(context); 1566 1878 failIfFalse(expr); 1879 bool isEval = false; 1880 if (strictMode() && !m_syntaxAlreadyValidated) { 1881 if (context.isResolve(expr)) 1882 isEval = m_globalData->propertyNames->eval == *m_lastIdentifier; 1883 } 1884 failIfTrueIfStrict(isEval && modifiesExpr); 1567 1885 switch (m_token.m_type) { 1568 1886 case PLUSPLUS: 1887 m_nonTrivialExpressionCount++; 1569 1888 m_nonLHSCount++; 1570 1889 expr = context.makePostfixNode(expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd()); 1571 1890 m_assignmentCount++; 1891 failIfTrueIfStrict(isEval); 1892 failIfTrueIfStrict(requiresLExpr); 1572 1893 next(); 1573 1894 break; 1574 1895 case MINUSMINUS: 1896 m_nonTrivialExpressionCount++; 1575 1897 m_nonLHSCount++; 1576 1898 expr = context.makePostfixNode(expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd()); 1577 1899 m_assignmentCount++; 1900 failIfTrueIfStrict(isEval); 1901 failIfTrueIfStrict(requiresLExpr); 1578 1902 next(); 1579 1903 break; … … 1584 1908 int end = lastTokenEnd(); 1585 1909 1586 if (!TreeBuilder::CreatesAST )1910 if (!TreeBuilder::CreatesAST && (m_syntaxAlreadyValidated || !strictMode())) 1587 1911 return expr; 1588 1912 … … 1618 1942 break; 1619 1943 case DELETETOKEN: 1944 if (strictMode() && context.isResolve(expr)) 1945 failIfFalse(deleteProperty(m_lastIdentifier)); 1620 1946 expr = context.makeDeleteNode(expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end); 1621 1947 break; -
trunk/JavaScriptCore/parser/JSParser.h
r67769 r69516 29 29 namespace JSC { 30 30 31 class ExecState; 31 32 class FunctionParameters; 32 33 class Identifier; 33 class JSGlobal Data;34 class JSGlobalObject; 34 35 class SourceCode; 35 36 … … 156 157 }; 157 158 158 int jsParse(JSGlobalData*, FunctionParameters*, const SourceCode*); 159 enum JSParserStrictness { JSParseNormal, JSParseStrict }; 160 enum JSParserMode { JSParseProgramCode, JSParseFunctionCode }; 161 162 int jsParse(JSGlobalObject*, FunctionParameters*, JSParserStrictness, JSParserMode, const SourceCode*); 159 163 } 160 164 #endif // JSParser_h -
trunk/JavaScriptCore/parser/Lexer.cpp
r67066 r69516 454 454 } 455 455 456 ALWAYS_INLINE bool Lexer::parseString(JSTokenData* lvalp )456 ALWAYS_INLINE bool Lexer::parseString(JSTokenData* lvalp, bool strictMode) 457 457 { 458 458 int stringQuoteCharacter = m_current; … … 495 495 } else if (isASCIIOctalDigit(m_current)) { 496 496 // Octal character sequences 497 if (strictMode) 498 return false; 497 499 int character1 = m_current; 498 500 shift(); … … 697 699 } 698 700 699 JSTokenType Lexer::lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType lexType )701 JSTokenType Lexer::lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType lexType, bool strictMode) 700 702 { 701 703 ASSERT(!m_error); … … 977 979 record8('0'); 978 980 if (isASCIIOctalDigit(m_current)) { 979 if (parseOctal(lvalp->doubleValue)) 981 if (parseOctal(lvalp->doubleValue)) { 982 if (strictMode) 983 goto returnError; 980 984 token = NUMBER; 985 } 981 986 } 982 987 } … … 1007 1012 break; 1008 1013 case CharacterQuote: 1009 if (UNLIKELY(!parseString(lvalp )))1014 if (UNLIKELY(!parseString(lvalp, strictMode))) 1010 1015 goto returnError; 1011 1016 shift(); -
trunk/JavaScriptCore/parser/Lexer.h
r66962 r69516 49 49 void setCode(const SourceCode&, ParserArena&); 50 50 void setIsReparsing() { m_isReparsing = true; } 51 bool isReparsing() const { return m_isReparsing; } 51 52 52 53 // Functions for the parser itself. 53 54 enum LexType { IdentifyReservedWords, IgnoreReservedWords }; 54 JSTokenType lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType );55 JSTokenType lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType, bool strictMode); 55 56 int lineNumber() const { return m_lineNumber; } 56 57 void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; } … … 96 97 97 98 ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, LexType); 98 ALWAYS_INLINE bool parseString(JSTokenData* lvalp );99 ALWAYS_INLINE bool parseString(JSTokenData* lvalp, bool strictMode); 99 100 ALWAYS_INLINE void parseHex(double& returnValue); 100 101 ALWAYS_INLINE bool parseOctal(double& returnValue); -
trunk/JavaScriptCore/parser/Nodes.cpp
r67583 r69516 90 90 // ------------------------------ ScopeNode ----------------------------- 91 91 92 ScopeNode::ScopeNode(JSGlobalData* globalData )92 ScopeNode::ScopeNode(JSGlobalData* globalData, bool inStrictContext) 93 93 : StatementNode(globalData) 94 94 , ParserArenaRefCounted(globalData) 95 , m_features( NoFeatures)95 , m_features(inStrictContext ? StrictModeFeature : NoFeatures) 96 96 { 97 97 } … … 155 155 } 156 156 157 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData )158 : ScopeNode(globalData )157 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, bool inStrictContext) 158 : ScopeNode(globalData, inStrictContext) 159 159 { 160 160 } … … 178 178 } 179 179 180 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData )180 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, bool inStrictContext) 181 181 { 182 return new FunctionBodyNode(globalData );182 return new FunctionBodyNode(globalData, inStrictContext); 183 183 } 184 184 -
trunk/JavaScriptCore/parser/Nodes.h
r68281 r69516 58 58 const CodeFeatures CatchFeature = 1 << 5; 59 59 const CodeFeatures ThisFeature = 1 << 6; 60 const CodeFeatures StrictModeFeature = 1 << 7; 60 61 const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature; 61 62 … … 1394 1395 typedef DeclarationStacks::FunctionStack FunctionStack; 1395 1396 1396 ScopeNode(JSGlobalData* );1397 ScopeNode(JSGlobalData*, bool inStrictContext); 1397 1398 ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants); 1398 1399 … … 1411 1412 bool usesEval() const { return m_features & EvalFeature; } 1412 1413 bool usesArguments() const { return m_features & ArgumentsFeature; } 1414 bool isStrictMode() const { return m_features & StrictModeFeature; } 1413 1415 void setUsesArguments() { m_features |= ArgumentsFeature; } 1414 1416 bool usesThis() const { return m_features & ThisFeature; } … … 1445 1447 class ProgramNode : public ScopeNode { 1446 1448 public: 1449 static const bool isFunctionNode = false; 1447 1450 static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1448 1451 … … 1457 1460 class EvalNode : public ScopeNode { 1458 1461 public: 1462 static const bool isFunctionNode = false; 1459 1463 static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1460 1464 … … 1477 1481 class FunctionBodyNode : public ScopeNode { 1478 1482 public: 1479 static FunctionBodyNode* create(JSGlobalData*); 1483 static const bool isFunctionNode = true; 1484 static FunctionBodyNode* create(JSGlobalData*, bool isStrictMode); 1480 1485 static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1481 1486 … … 1493 1498 1494 1499 private: 1495 FunctionBodyNode(JSGlobalData* );1500 FunctionBodyNode(JSGlobalData*, bool inStrictContext); 1496 1501 FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1497 1502 -
trunk/JavaScriptCore/parser/Parser.cpp
r67769 r69516 36 36 namespace JSC { 37 37 38 void Parser::parse(JSGlobal Data* globalData, FunctionParameters* parameters, int* errLine, UString* errMsg)38 void Parser::parse(JSGlobalObject* lexicalGlobalObject, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode mode, int* errLine, UString* errMsg) 39 39 { 40 ASSERT(lexicalGlobalObject); 40 41 m_sourceElements = 0; 41 42 … … 51 52 *errMsg = UString(); 52 53 53 Lexer& lexer = * globalData->lexer;54 Lexer& lexer = *lexicalGlobalObject->globalData()->lexer; 54 55 lexer.setCode(*m_source, m_arena); 55 56 56 int parseError = jsParse( globalData, parameters, m_source);57 int parseError = jsParse(lexicalGlobalObject, parameters, strictness, mode, m_source); 57 58 int lineNumber = lexer.lineNumber(); 58 59 bool lexError = lexer.sawError(); -
trunk/JavaScriptCore/parser/Parser.h
r67769 r69516 49 49 public: 50 50 template <class ParsedNode> 51 PassRefPtr<ParsedNode> parse(JSGlobal Data* globalData, JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, const SourceCode& source, FunctionParameters*, JSObject** exception);51 PassRefPtr<ParsedNode> parse(JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, const SourceCode& source, FunctionParameters*, JSParserStrictness strictness, JSObject** exception); 52 52 53 53 void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, … … 58 58 59 59 private: 60 void parse(JSGlobal Data*, FunctionParameters*, int* errLine, UString* errMsg);60 void parse(JSGlobalObject* lexicalGlobalObject, FunctionParameters*, JSParserStrictness strictness, JSParserMode mode, int* errLine, UString* errMsg); 61 61 62 62 // Used to determine type of error to report. … … 76 76 77 77 template <class ParsedNode> 78 PassRefPtr<ParsedNode> Parser::parse(JSGlobal Data* globalData, JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, FunctionParameters* parameters, JSObject** exception)78 PassRefPtr<ParsedNode> Parser::parse(JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, FunctionParameters* parameters, JSParserStrictness strictness, JSObject** exception) 79 79 { 80 ASSERT(lexicalGlobalObject); 80 81 ASSERT(exception && !*exception); 81 82 int errLine; … … 84 85 m_source = &source; 85 86 if (ParsedNode::scopeIsFunction) 86 globalData->lexer->setIsReparsing();87 parse( globalData, parameters, &errLine, &errMsg);87 lexicalGlobalObject->globalData()->lexer->setIsReparsing(); 88 parse(lexicalGlobalObject, parameters, strictness, ParsedNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, &errLine, &errMsg); 88 89 89 90 RefPtr<ParsedNode> result; 90 91 if (m_sourceElements) { 91 result = ParsedNode::create( globalData,92 result = ParsedNode::create(lexicalGlobalObject->globalData(), 92 93 m_sourceElements, 93 94 m_varDeclarations ? &m_varDeclarations->data : 0, … … 108 109 *exception = createStackOverflowError(lexicalGlobalObject); 109 110 else 110 *exception = addErrorInfo( globalData, createSyntaxError(lexicalGlobalObject, errMsg), errLine, source);111 *exception = addErrorInfo(lexicalGlobalObject->globalData(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, source); 111 112 } 112 113 -
trunk/JavaScriptCore/parser/SyntaxChecker.h
r67583 r69516 31 31 public: 32 32 SyntaxChecker(JSGlobalData* , Lexer*) 33 : m_topBinaryExpr(0) 33 34 { 34 35 } 35 36 36 37 typedef SyntaxChecker FunctionBodyBuilder; 37 38 typedef int Expression; 38 enum { NoneExpr = 0, 39 ResolveEvalExpr, ResolveExpr, NumberExpr, StringExpr, 40 ThisExpr, NullExpr, BoolExpr, RegExpExpr, ObjectLiteralExpr, 41 FunctionExpr, BracketExpr, DotExpr, CallExpr, 42 NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr, 43 ConditionalExpr, AssignmentExpr, TypeofExpr, 44 DeleteExpr, ArrayLiteralExpr }; 45 typedef int ExpressionType; 46 47 typedef ExpressionType Expression; 39 48 typedef int SourceElements; 40 49 typedef int Arguments; 41 typedef intComma;50 typedef ExpressionType Comma; 42 51 struct Property { 43 52 ALWAYS_INLINE Property(void* = 0) … … 74 83 75 84 int createSourceElements() { return 1; } 76 int makeFunctionCallNode(int, int, int, int, int) { return 1; }77 void appendToComma( int, int) {}78 int createCommaExpr(int, int) { return 1; }79 int makeAssignNode(int, Operator, int, bool, bool, int, int, int) { return 1; }80 int makePrefixNode(int, Operator, int, int, int) { return 1; }81 int makePostfixNode(int, Operator, int, int, int) { return 1; }82 int makeTypeOfNode(int) { return 1; }83 int makeDeleteNode(int, int, int, int) { return 1; }84 int makeNegateNode(int) { return 1; }85 int makeBitwiseNotNode(int) { return 1; }86 int createLogicalNot(int) { return 1; }87 int createUnaryPlus(int) { return 1; }88 int createVoid(int) { return 1; }89 int thisExpr() { return 1; }90 int createResolve(const Identifier*, int) { return 1; }91 int createObjectLiteral() { return 1; }92 int createObjectLiteral(int) { return 1; }93 int createArray(int) { return 1; }94 int createArray(int, int) { return 1; }95 int createNumberExpr(double) { return 1; }96 int createString(const Identifier*) { return 1; }97 int createBoolean(bool) { return 1; }98 int createNull() { return 1; }99 int createBracketAccess(int, int, bool, int, int, int) { return 1; }100 int createDotAccess(int, const Identifier&, int, int, int) { return 1; }101 int createRegex(const Identifier&, const Identifier&, int) { return 1; }102 int createNewExpr(int, int, int, int, int) { return 1; }103 int createNewExpr(int, int, int) { return 1; }104 int createConditionalExpr(int, int, int) { return 1; }105 int createAssignResolve(const Identifier&, int, bool, int, int, int) { return 1; }106 int createFunctionExpr(const Identifier*, int, int, int, int, int, int) { return 1; }107 int createFunctionBody( ) { return 1; }85 ExpressionType makeFunctionCallNode(int, int, int, int, int) { return CallExpr; } 86 void appendToComma(ExpressionType& base, ExpressionType right) { base = right; } 87 ExpressionType createCommaExpr(ExpressionType, ExpressionType right) { return right; } 88 ExpressionType makeAssignNode(ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; } 89 ExpressionType makePrefixNode(ExpressionType, Operator, int, int, int) { return PreExpr; } 90 ExpressionType makePostfixNode(ExpressionType, Operator, int, int, int) { return PostExpr; } 91 ExpressionType makeTypeOfNode(ExpressionType) { return TypeofExpr; } 92 ExpressionType makeDeleteNode(ExpressionType, int, int, int) { return DeleteExpr; } 93 ExpressionType makeNegateNode(ExpressionType) { return UnaryExpr; } 94 ExpressionType makeBitwiseNotNode(ExpressionType) { return UnaryExpr; } 95 ExpressionType createLogicalNot(ExpressionType) { return UnaryExpr; } 96 ExpressionType createUnaryPlus(ExpressionType) { return UnaryExpr; } 97 ExpressionType createVoid(ExpressionType) { return UnaryExpr; } 98 ExpressionType thisExpr() { return ThisExpr; } 99 ExpressionType createResolve(const Identifier*, int) { return ResolveExpr; } 100 ExpressionType createObjectLiteral() { return ObjectLiteralExpr; } 101 ExpressionType createObjectLiteral(int) { return ObjectLiteralExpr; } 102 ExpressionType createArray(int) { return ArrayLiteralExpr; } 103 ExpressionType createArray(int, int) { return ArrayLiteralExpr; } 104 ExpressionType createNumberExpr(double) { return NumberExpr; } 105 ExpressionType createString(const Identifier*) { return StringExpr; } 106 ExpressionType createBoolean(bool) { return BoolExpr; } 107 ExpressionType createNull() { return NullExpr; } 108 ExpressionType createBracketAccess(ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; } 109 ExpressionType createDotAccess(ExpressionType, const Identifier&, int, int, int) { return DotExpr; } 110 ExpressionType createRegex(const Identifier&, const Identifier&, int) { return RegExpExpr; } 111 ExpressionType createNewExpr(ExpressionType, int, int, int, int) { return NewExpr; } 112 ExpressionType createNewExpr(ExpressionType, int, int) { return NewExpr; } 113 ExpressionType createConditionalExpr(ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; } 114 ExpressionType createAssignResolve(const Identifier&, ExpressionType, bool, int, int, int) { return AssignmentExpr; } 115 ExpressionType createFunctionExpr(const Identifier*, int, int, int, int, int, int) { return FunctionExpr; } 116 int createFunctionBody(bool) { return 1; } 108 117 int createArguments() { return 1; } 109 118 int createArguments(int) { return 1; } … … 170 179 int combineCommaNodes(int, int) { return 1; } 171 180 int evalCount() const { return 0; } 172 void appendBinaryExpressionInfo(int& operandStackDepth, int, int, int, int, bool) { operandStackDepth++; } 181 void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool) 182 { 183 if (!m_topBinaryExpr) 184 m_topBinaryExpr = expr; 185 else 186 m_topBinaryExpr = BinaryExpr; 187 operandStackDepth++; 188 } 173 189 174 190 // Logic to handle datastructures used during parsing of binary expressions 175 191 void operatorStackPop(int& operatorStackDepth) { operatorStackDepth--; } 176 192 bool operatorStackHasHigherPrecedence(int&, int) { return true; } 177 BinaryOperand getFromOperandStack(int) { return 1; }193 BinaryOperand getFromOperandStack(int) { return m_topBinaryExpr; } 178 194 void shrinkOperandStackBy(int& operandStackDepth, int amount) { operandStackDepth -= amount; } 179 195 void appendBinaryOperation(int& operandStackDepth, int&, BinaryOperand, BinaryOperand) { operandStackDepth++; } 180 196 void operatorStackAppend(int& operatorStackDepth, int, int) { operatorStackDepth++; } 181 int popOperandStack(int&) { return 1; }182 183 void appendUnaryToken(int& , int, int) {}184 int unaryTokenStackLastType(int&) { ASSERT_NOT_REACHED(); return 1; }185 int unaryTokenStackLastStart(int&) { ASSERT_NOT_REACHED(); return 1; }186 void unaryTokenStackRemoveLast(int& ) {}197 int popOperandStack(int&) { int res = m_topBinaryExpr; m_topBinaryExpr = 0; return res; } 198 199 void appendUnaryToken(int& stackDepth, int tok, int) { stackDepth = 1; m_topUnaryToken = tok; } 200 int unaryTokenStackLastType(int&) { return m_topUnaryToken; } 201 int unaryTokenStackLastStart(int&) { return 0; } 202 void unaryTokenStackRemoveLast(int& stackDepth) { stackDepth = 0; } 187 203 188 204 void assignmentStackAppend(int, int, int, int, int, Operator) { } … … 190 206 const Identifier& getName(const Property& property) { ASSERT(property.name); return *property.name; } 191 207 PropertyNode::Type getType(const Property& property) { return property.type; } 208 bool isResolve(ExpressionType expr) { return expr == ResolveExpr || expr == ResolveEvalExpr; } 209 210 private: 211 int m_topBinaryExpr; 212 int m_topUnaryToken; 192 213 }; 193 214 -
trunk/JavaScriptCore/runtime/Arguments.cpp
r65588 r69516 154 154 return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::number(i)), slot); 155 155 } 156 157 void Arguments::createStrictModeCallerIfNecessary(ExecState* exec) 158 { 159 if (d->overrodeCaller) 160 return; 161 162 d->overrodeCaller = true; 163 PropertyDescriptor descriptor; 164 JSValue thrower = createTypeErrorFunction(exec, "Unable to access caller of strict mode function"); 165 descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter); 166 defineOwnProperty(exec, exec->propertyNames().caller, descriptor, false); 167 } 168 169 void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec) 170 { 171 if (d->overrodeCallee) 172 return; 173 174 d->overrodeCallee = true; 175 PropertyDescriptor descriptor; 176 JSValue thrower = createTypeErrorFunction(exec, "Unable to access callee of strict mode function"); 177 descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter); 178 defineOwnProperty(exec, exec->propertyNames().callee, descriptor, false); 179 } 156 180 157 181 bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) … … 173 197 174 198 if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) { 175 slot.setValue(d->callee); 176 return true; 177 } 199 if (!d->isStrictMode) { 200 slot.setValue(d->callee); 201 return true; 202 } 203 createStrictModeCalleeIfNecessary(exec); 204 } 205 206 if (propertyName == exec->propertyNames().caller && d->isStrictMode) 207 createStrictModeCallerIfNecessary(exec); 178 208 179 209 return JSObject::getOwnPropertySlot(exec, propertyName, slot); … … 198 228 199 229 if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) { 200 descriptor.setDescriptor(d->callee, DontEnum); 201 return true; 202 } 230 if (!d->isStrictMode) { 231 descriptor.setDescriptor(d->callee, DontEnum); 232 return true; 233 } 234 createStrictModeCalleeIfNecessary(exec); 235 } 236 237 if (propertyName == exec->propertyNames().caller && d->isStrictMode) 238 createStrictModeCallerIfNecessary(exec); 203 239 204 240 return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); … … 250 286 251 287 if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) { 252 d->overrodeCallee = true; 253 putDirect(propertyName, value, DontEnum); 254 return; 255 } 288 if (!d->isStrictMode) { 289 d->overrodeCallee = true; 290 putDirect(propertyName, value, DontEnum); 291 return; 292 } 293 createStrictModeCalleeIfNecessary(exec); 294 } 295 296 if (propertyName == exec->propertyNames().caller && d->isStrictMode) 297 createStrictModeCallerIfNecessary(exec); 256 298 257 299 JSObject::put(exec, propertyName, value, slot); … … 295 337 296 338 if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) { 297 d->overrodeCallee = true; 298 return true; 299 } 339 if (!d->isStrictMode) { 340 d->overrodeCallee = true; 341 return true; 342 } 343 createStrictModeCalleeIfNecessary(exec); 344 } 345 346 if (propertyName == exec->propertyNames().caller && !d->isStrictMode) 347 createStrictModeCallerIfNecessary(exec); 300 348 301 349 return JSObject::deleteProperty(exec, propertyName); -
trunk/JavaScriptCore/runtime/Arguments.h
r68171 r69516 51 51 bool overrodeLength : 1; 52 52 bool overrodeCallee : 1; 53 bool overrodeCaller : 1; 54 bool isStrictMode : 1; 53 55 }; 54 56 … … 106 108 virtual bool deleteProperty(ExecState*, const Identifier& propertyName); 107 109 virtual bool deleteProperty(ExecState*, unsigned propertyName); 110 void createStrictModeCallerIfNecessary(ExecState*); 111 void createStrictModeCalleeIfNecessary(ExecState*); 108 112 109 113 virtual const ClassInfo* classInfo() const { return &info; } … … 173 177 d->overrodeLength = false; 174 178 d->overrodeCallee = false; 179 d->overrodeCaller = false; 180 d->isStrictMode = callFrame->codeBlock()->isStrictMode(); 181 if (d->isStrictMode) 182 copyRegisters(); 175 183 } 176 184 … … 202 210 d->overrodeLength = false; 203 211 d->overrodeCallee = false; 212 d->overrodeCaller = false; 213 d->isStrictMode = callFrame->codeBlock()->isStrictMode(); 214 if (d->isStrictMode) 215 copyRegisters(); 204 216 } 205 217 -
trunk/JavaScriptCore/runtime/CommonIdentifiers.cpp
r55751 r69516 33 33 , underscoreProto(globalData, "__proto__") 34 34 , thisIdentifier(globalData, "this") 35 , useStrictIdentifier(globalData, "use strict") 35 36 JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME) 36 37 { -
trunk/JavaScriptCore/runtime/CommonIdentifiers.h
r55751 r69516 95 95 const Identifier underscoreProto; 96 96 const Identifier thisIdentifier; 97 const Identifier useStrictIdentifier; 97 98 98 99 #define JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL(name) const Identifier name; -
trunk/JavaScriptCore/runtime/Error.cpp
r60762 r69516 196 196 } 197 197 198 class StrictModeTypeErrorFunction : public InternalFunction { 199 public: 200 StrictModeTypeErrorFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const UString& message) 201 : InternalFunction(&exec->globalData(), globalObject, structure, exec->globalData().propertyNames->emptyIdentifier) 202 , m_message(message) 203 { 204 } 205 206 static EncodedJSValue JSC_HOST_CALL constructThrowTypeError(ExecState* exec) 207 { 208 throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message); 209 return JSValue::encode(jsNull()); 210 } 211 212 ConstructType getConstructData(ConstructData& constructData) 213 { 214 constructData.native.function = constructThrowTypeError; 215 return ConstructTypeHost; 216 } 217 218 static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec) 219 { 220 throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message); 221 return JSValue::encode(jsNull()); 222 } 223 224 CallType getCallData(CallData& callData) 225 { 226 callData.native.function = callThrowTypeError; 227 return CallTypeHost; 228 } 229 230 private: 231 UString m_message; 232 }; 233 234 COMPILE_ASSERT(sizeof(StrictModeTypeErrorFunction) <= sizeof(CollectorCell), sizeof_StrictModeTypeErrorFunction_must_be_less_than_CollectorCell); 235 236 JSValue createTypeErrorFunction(ExecState* exec, const UString& message) 237 { 238 return new (exec) StrictModeTypeErrorFunction(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->internalFunctionStructure(), message); 239 } 240 198 241 } // namespace JSC -
trunk/JavaScriptCore/runtime/Error.h
r60762 r69516 74 74 inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); } 75 75 76 JSValue createTypeErrorFunction(ExecState* exec, const UString& message); 77 76 78 } // namespace JSC 77 79 -
trunk/JavaScriptCore/runtime/Executable.cpp
r68171 r69516 46 46 } 47 47 48 EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source )49 : ScriptExecutable(exec, source )48 EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext) 49 : ScriptExecutable(exec, source, inStrictContext) 50 50 { 51 51 } … … 56 56 57 57 ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source) 58 : ScriptExecutable(exec, source )58 : ScriptExecutable(exec, source, false) 59 59 { 60 60 } … … 64 64 } 65 65 66 FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)67 : ScriptExecutable(globalData, source )66 FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine) 67 : ScriptExecutable(globalData, source, inStrictContext) 68 68 , m_numCapturedVariables(0) 69 69 , m_forceUsesArguments(forceUsesArguments) … … 76 76 } 77 77 78 FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)79 : ScriptExecutable(exec, source )78 FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine) 79 : ScriptExecutable(exec, source, inStrictContext) 80 80 , m_numCapturedVariables(0) 81 81 , m_forceUsesArguments(forceUsesArguments) … … 97 97 JSGlobalData* globalData = &exec->globalData(); 98 98 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 99 RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>( globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);99 RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception); 100 100 if (!evalNode) { 101 101 ASSERT(exception); … … 132 132 JSGlobalData* globalData = &exec->globalData(); 133 133 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 134 RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>( globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);134 RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, JSParseNormal, &exception); 135 135 if (programNode) 136 136 return 0; … … 146 146 JSGlobalData* globalData = &exec->globalData(); 147 147 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 148 RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>( globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);148 RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception); 149 149 if (!programNode) { 150 150 ASSERT(exception); … … 179 179 JSObject* exception = 0; 180 180 JSGlobalData* globalData = scopeChainNode->globalData; 181 RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>( globalData, exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), &exception);181 RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception); 182 182 if (!body) { 183 183 ASSERT(exception); … … 220 220 JSObject* exception = 0; 221 221 JSGlobalData* globalData = scopeChainNode->globalData; 222 RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>( globalData, exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), &exception);222 RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception); 223 223 if (!body) { 224 224 ASSERT(exception); … … 265 265 } 266 266 267 PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock) 268 { 269 JSObject* exception = 0; 270 RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, 0, m_source, m_parameters.get(), &exception); 267 PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(ScopeChainNode* scopeChainNode, CodeBlock* codeBlock) 268 { 269 JSObject* exception = 0; 270 JSGlobalData* globalData = scopeChainNode->globalData; 271 RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(scopeChainNode->globalObject, 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception); 271 272 if (!newFunctionBody) 272 273 return PassOwnPtr<ExceptionInfo>(); 274 ASSERT(newFunctionBody->isStrictMode() == isStrictMode()); 273 275 if (m_forceUsesArguments) 274 276 newFunctionBody->setUsesArguments(); … … 299 301 } 300 302 301 PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock) 302 { 303 JSObject* exception = 0; 304 RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(globalData, 0, 0, 0, m_source, 0, &exception); 303 PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(ScopeChainNode* scopeChainNode, CodeBlock* codeBlock) 304 { 305 JSObject* exception = 0; 306 JSGlobalData* globalData = scopeChainNode->globalData; 307 RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(scopeChainNode->globalObject, 0, 0, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception); 308 ASSERT(newEvalBody->isStrictMode() == isStrictMode()); 305 309 if (!newEvalBody) 306 310 return PassOwnPtr<ExceptionInfo>(); … … 342 346 { 343 347 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 344 RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>( &exec->globalData(), lexicalGlobalObject, debugger, exec, source, 0, exception);348 RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(lexicalGlobalObject, debugger, exec, source, 0, JSParseNormal, exception); 345 349 if (!program) { 346 350 ASSERT(*exception); … … 358 362 ASSERT(body); 359 363 360 return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine());364 return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), false, body->lineNo(), body->lastLine()); 361 365 } 362 366 … … 373 377 } 374 378 375 PassOwnPtr<ExceptionInfo> ProgramExecutable::reparseExceptionInfo( JSGlobalData*,ScopeChainNode*, CodeBlock*)379 PassOwnPtr<ExceptionInfo> ProgramExecutable::reparseExceptionInfo(ScopeChainNode*, CodeBlock*) 376 380 { 377 381 // CodeBlocks for program code are transient and therefore do not gain from from throwing out their exception information. -
trunk/JavaScriptCore/runtime/Executable.h
r68171 r69516 139 139 class ScriptExecutable : public ExecutableBase { 140 140 public: 141 ScriptExecutable(JSGlobalData* globalData, const SourceCode& source )141 ScriptExecutable(JSGlobalData* globalData, const SourceCode& source, bool isInStrictContext) 142 142 : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED) 143 143 , m_source(source) 144 , m_features( 0)144 , m_features(isInStrictContext ? StrictModeFeature : 0) 145 145 { 146 146 #if ENABLE(CODEBLOCK_SAMPLING) … … 153 153 } 154 154 155 ScriptExecutable(ExecState* exec, const SourceCode& source )155 ScriptExecutable(ExecState* exec, const SourceCode& source, bool isInStrictContext) 156 156 : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED) 157 157 , m_source(source) 158 , m_features( 0)158 , m_features(isInStrictContext ? StrictModeFeature : 0) 159 159 { 160 160 #if ENABLE(CODEBLOCK_SAMPLING) … … 176 176 bool usesArguments() const { return m_features & ArgumentsFeature; } 177 177 bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); } 178 179 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0; 178 bool isStrictMode() const { return m_features & StrictModeFeature; } 179 180 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*) = 0; 180 181 181 182 protected: … … 215 216 } 216 217 217 static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source ) { return adoptRef(new EvalExecutable(exec, source)); }218 static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source, bool isInStrictContext) { return adoptRef(new EvalExecutable(exec, source, isInStrictContext)); } 218 219 219 220 #if ENABLE(JIT) … … 225 226 226 227 private: 227 EvalExecutable(ExecState*, const SourceCode& );228 EvalExecutable(ExecState*, const SourceCode&, bool); 228 229 229 230 JSObject* compileInternal(ExecState*, ScopeChainNode*); 230 231 231 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo( JSGlobalData*,ScopeChainNode*, CodeBlock*);232 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*); 232 233 233 234 OwnPtr<EvalCodeBlock> m_evalCodeBlock; … … 272 273 JSObject* compileInternal(ExecState*, ScopeChainNode*); 273 274 274 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo( JSGlobalData*,ScopeChainNode*, CodeBlock*);275 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*); 275 276 276 277 OwnPtr<ProgramCodeBlock> m_programCodeBlock; … … 280 281 friend class JIT; 281 282 public: 282 static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)283 { 284 return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, firstLine, lastLine));285 } 286 287 static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)288 { 289 return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, firstLine, lastLine));283 static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine) 284 { 285 return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine)); 286 } 287 288 static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine) 289 { 290 return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine)); 290 291 } 291 292 … … 359 360 360 361 private: 361 FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, int firstLine, int lastLine);362 FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, int firstLine, int lastLine);362 FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine); 363 FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine); 363 364 364 365 JSObject* compileForCallInternal(ExecState*, ScopeChainNode*); 365 366 JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*); 366 367 367 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo( JSGlobalData*,ScopeChainNode*, CodeBlock*);368 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*); 368 369 369 370 unsigned m_numCapturedVariables : 31; -
trunk/JavaScriptCore/runtime/JSActivation.cpp
r68171 r69516 187 187 } 188 188 189 JSValue JSActivation::toStrictThisObject(ExecState*) const 190 { 191 return jsNull(); 192 } 193 189 194 bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const 190 195 { -
trunk/JavaScriptCore/runtime/JSActivation.h
r68171 r69516 61 61 62 62 virtual JSObject* toThisObject(ExecState*) const; 63 virtual JSValue toStrictThisObject(ExecState*) const; 63 64 64 65 void copyRegisters(); -
trunk/JavaScriptCore/runtime/JSFunction.cpp
r65104 r69516 123 123 } 124 124 125 static const char* StrictModeCallerAccessError = "Cannot access caller property of a strict mode function"; 126 static const char* StrictModeArgumentsAccessError = "Cannot access arguments property of a strict mode function"; 127 128 static void createDescriptorForThrowingProperty(ExecState* exec, PropertyDescriptor& descriptor, const char* message) 129 { 130 JSValue thrower = createTypeErrorFunction(exec, message); 131 descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter); 132 } 133 125 134 const UString& JSFunction::name(ExecState* exec) 126 135 { … … 210 219 211 220 if (propertyName == exec->propertyNames().arguments) { 221 if (jsExecutable()->isStrictMode()) { 222 throwTypeError(exec, "Can't access arguments object of a strict mode function"); 223 slot.setValue(jsNull()); 224 return true; 225 } 226 212 227 slot.setCacheableCustom(this, argumentsGetter); 213 228 return true; … … 220 235 221 236 if (propertyName == exec->propertyNames().caller) { 237 if (jsExecutable()->isStrictMode()) { 238 throwTypeError(exec, StrictModeCallerAccessError); 239 slot.setValue(jsNull()); 240 return true; 241 } 222 242 slot.setCacheableCustom(this, callerGetter); 223 243 return true; … … 227 247 } 228 248 229 bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 230 { 231 if (isHostFunction()) 232 return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); 233 234 if (propertyName == exec->propertyNames().prototype) { 235 PropertySlot slot; 236 getOwnPropertySlot(exec, propertyName, slot); 237 return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); 238 } 239 240 if (propertyName == exec->propertyNames().arguments) { 249 bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 250 { 251 if (isHostFunction()) 252 return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); 253 254 if (propertyName == exec->propertyNames().prototype) { 255 PropertySlot slot; 256 getOwnPropertySlot(exec, propertyName, slot); 257 return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); 258 } 259 260 if (propertyName == exec->propertyNames().arguments) { 261 if (jsExecutable()->isStrictMode()) 262 createDescriptorForThrowingProperty(exec, descriptor, StrictModeArgumentsAccessError); 263 else 241 264 descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete); 242 return true; 243 } 244 245 if (propertyName == exec->propertyNames().length) { 246 descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete); 247 return true; 248 } 249 250 if (propertyName == exec->propertyNames().caller) { 265 return true; 266 } 267 268 if (propertyName == exec->propertyNames().length) { 269 descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete); 270 return true; 271 } 272 273 if (propertyName == exec->propertyNames().caller) { 274 if (jsExecutable()->isStrictMode()) 275 createDescriptorForThrowingProperty(exec, descriptor, StrictModeCallerAccessError); 276 else 251 277 descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete); 252 253 254 255 256 257 278 return true; 279 } 280 281 return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); 282 } 283 258 284 void JSFunction::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 259 285 { … … 273 299 return; 274 300 } 301 if (jsExecutable()->isStrictMode()) { 302 if (propertyName == exec->propertyNames().arguments) { 303 throwTypeError(exec, StrictModeArgumentsAccessError); 304 return; 305 } 306 if (propertyName == exec->propertyNames().caller) { 307 throwTypeError(exec, StrictModeCallerAccessError); 308 return; 309 } 310 } 275 311 if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length) 276 312 return; -
trunk/JavaScriptCore/runtime/JSGlobalData.cpp
r67146 r69516 51 51 #include "Parser.h" 52 52 #include "RegExpCache.h" 53 #include "StrictEvalActivation.h" 53 54 #include <wtf/WTFThreadData.h> 54 55 #if ENABLE(REGEXP_TRACING) … … 125 126 , terminatedExecutionErrorStructure(JSObject::createStructure(jsNull())) 126 127 , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull())) 128 , strictEvalActivationStructure(StrictEvalActivation::createStructure(jsNull())) 127 129 , stringStructure(JSString::createStructure(jsNull())) 128 130 , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull())) -
trunk/JavaScriptCore/runtime/JSGlobalData.h
r67146 r69516 146 146 RefPtr<Structure> terminatedExecutionErrorStructure; 147 147 RefPtr<Structure> staticScopeStructure; 148 RefPtr<Structure> strictEvalActivationStructure; 148 149 RefPtr<Structure> stringStructure; 149 150 RefPtr<Structure> notAnObjectErrorStubStructure; -
trunk/JavaScriptCore/runtime/JSGlobalObject.cpp
r66019 r69516 205 205 d()->functionPrototype = new (exec) FunctionPrototype(exec, this, FunctionPrototype::createStructure(jsNull())); // The real prototype will be set once ObjectPrototype is created. 206 206 d()->prototypeFunctionStructure = PrototypeFunction::createStructure(d()->functionPrototype); 207 d()->internalFunctionStructure = InternalFunction::createStructure(d()->functionPrototype); 207 208 NativeFunctionWrapper* callFunction = 0; 208 209 NativeFunctionWrapper* applyFunction = 0; -
trunk/JavaScriptCore/runtime/JSGlobalObject.h
r66019 r69516 149 149 RefPtr<Structure> regExpStructure; 150 150 RefPtr<Structure> stringObjectStructure; 151 RefPtr<Structure> internalFunctionStructure; 151 152 152 153 SymbolTable symbolTable; … … 244 245 Structure* numberObjectStructure() const { return d()->numberObjectStructure.get(); } 245 246 Structure* prototypeFunctionStructure() const { return d()->prototypeFunctionStructure.get(); } 247 Structure* internalFunctionStructure() const { return d()->internalFunctionStructure.get(); } 246 248 Structure* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); } 247 249 Structure* regExpStructure() const { return d()->regExpStructure.get(); } -
trunk/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
r65593 r69516 451 451 return JSValue::encode(parsedObject); 452 452 453 RefPtr<EvalExecutable> eval = EvalExecutable::create(exec, makeSource(s) );453 RefPtr<EvalExecutable> eval = EvalExecutable::create(exec, makeSource(s), false); 454 454 JSObject* error = eval->compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node()); 455 455 if (error) -
trunk/JavaScriptCore/runtime/JSObject.cpp
r60762 r69516 44 44 ASSERT_CLASS_FITS_IN_CELL(JSObject); 45 45 46 const char* StrictModeReadonlyPropertyWriteError = "Attempted to assign to readonly property."; 47 46 48 static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode) 47 49 { … … 115 117 prototype = obj->prototype(); 116 118 if (prototype.isNull()) { 117 putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot); 119 if (!putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot) && slot.isStrictMode()) 120 throwTypeError(exec, StrictModeReadonlyPropertyWriteError); 118 121 return; 119 122 } … … 122 125 unsigned attributes; 123 126 JSCell* specificValue; 124 if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) 127 if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) { 128 if (slot.isStrictMode()) 129 throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError)); 125 130 return; 131 } 126 132 127 133 for (JSObject* obj = this; ; obj = asObject(prototype)) { … … 152 158 } 153 159 154 putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot); 160 if (!putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot) && slot.isStrictMode()) 161 throwTypeError(exec, StrictModeReadonlyPropertyWriteError); 155 162 return; 156 163 } … … 486 493 487 494 JSObject* JSObject::toThisObject(ExecState*) const 495 { 496 return const_cast<JSObject*>(this); 497 } 498 499 JSValue JSObject::toStrictThisObject(ExecState*) const 488 500 { 489 501 return const_cast<JSObject*>(this); … … 703 715 } 704 716 717 JSObject* throwTypeError(ExecState* exec, const UString& message) 718 { 719 return throwError(exec, createTypeError(exec, message)); 720 } 721 705 722 } // namespace JSC -
trunk/JavaScriptCore/runtime/JSObject.h
r64684 r69516 56 56 struct HashTable; 57 57 58 JSObject* throwTypeError(ExecState*, const UString&); 59 extern const char* StrictModeReadonlyPropertyWriteError; 60 58 61 // ECMA 262-3 8.6.1 59 62 // Property attributes … … 141 144 142 145 virtual JSObject* toThisObject(ExecState*) const; 146 virtual JSValue toStrictThisObject(ExecState*) const; 143 147 virtual JSObject* unwrappedObject(); 144 148 … … 176 180 bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); } 177 181 178 voidputDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);182 bool putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot); 179 183 void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0); 180 voidputDirect(const Identifier& propertyName, JSValue value, PutPropertySlot&);184 bool putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot&); 181 185 182 186 void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr = 0); … … 206 210 virtual bool isActivationObject() const { return false; } 207 211 virtual bool isNotAnObjectErrorStub() const { return false; } 212 virtual bool isStrictModeFunction() const { return false; } 208 213 209 214 virtual ComplType exceptionType() const { return Throw; } … … 266 271 } 267 272 268 voidputDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*);269 voidputDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);273 bool putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*); 274 bool putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot); 270 275 void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr = 0); 271 276 … … 451 456 } 452 457 453 inline voidJSObject::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction)458 inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction) 454 459 { 455 460 ASSERT(value); … … 466 471 m_structure->despecifyDictionaryFunction(propertyName); 467 472 if (checkReadOnly && currentAttributes & ReadOnly) 468 return; 473 return false; 474 469 475 putDirectOffset(offset, value); 470 476 // At this point, the objects structure only has a specific value set if previously there … … 476 482 if (!currentSpecificFunction || (specificFunction != currentSpecificFunction)) 477 483 slot.setExistingProperty(this, offset); 478 return ;484 return true; 479 485 } 480 486 … … 489 495 if (!specificFunction) 490 496 slot.setNewProperty(this, offset); 491 return ;497 return true; 492 498 } 493 499 … … 505 511 if (!specificFunction) 506 512 slot.setNewProperty(this, offset); 507 return ;513 return true; 508 514 } 509 515 … … 513 519 if (offset != WTF::notFound) { 514 520 if (checkReadOnly && currentAttributes & ReadOnly) 515 return ;521 return false; 516 522 517 523 // There are three possibilities here: … … 528 534 if (specificFunction == currentSpecificFunction) { 529 535 putDirectOffset(offset, value); 530 return ;536 return true; 531 537 } 532 538 // case (2) Despecify, fall through to (3). … … 537 543 slot.setExistingProperty(this, offset); 538 544 putDirectOffset(offset, value); 539 return ;545 return true; 540 546 } 541 547 … … 562 568 if (!specificFunction) 563 569 slot.setNewProperty(this, offset); 564 } 565 566 inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 570 return true; 571 } 572 573 inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 567 574 { 568 575 ASSERT(value); 569 576 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 570 577 571 putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));578 return putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value)); 572 579 } 573 580 … … 578 585 } 579 586 580 inline voidJSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)587 inline bool JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 581 588 { 582 589 ASSERT(value); 583 590 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 584 591 585 putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, 0);592 return putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, 0); 586 593 } 587 594 … … 592 599 } 593 600 594 inline voidJSObject::putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot& slot)595 { 596 putDirectInternal(propertyName, value, 0, false, slot, 0);601 inline bool JSObject::putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 602 { 603 return putDirectInternal(propertyName, value, 0, false, slot, 0); 597 604 } 598 605 … … 699 706 } 700 707 701 inline void JSValue::putDirect(ExecState* , const Identifier& propertyName, JSValue value, PutPropertySlot& slot)708 inline void JSValue::putDirect(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 702 709 { 703 710 ASSERT(isCell() && isObject()); 704 asObject(asCell())->putDirect(propertyName, value, slot); 711 if (!asObject(asCell())->putDirect(propertyName, value, slot) && slot.isStrictMode()) 712 throwTypeError(exec, StrictModeReadonlyPropertyWriteError); 705 713 } 706 714 … … 757 765 } 758 766 767 inline JSValue JSValue::toStrictThisObject(ExecState* exec) const 768 { 769 if (!isObject()) 770 return *this; 771 return asObject(asCell())->toStrictThisObject(exec); 772 } 773 759 774 } // namespace JSC 760 775 -
trunk/JavaScriptCore/runtime/JSStaticScopeObject.cpp
r64684 r69516 43 43 } 44 44 45 JSValue JSStaticScopeObject::toStrictThisObject(ExecState*) const 46 { 47 return jsNull(); 48 } 49 45 50 void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot&) 46 51 { -
trunk/JavaScriptCore/runtime/JSStaticScopeObject.h
r65104 r69516 54 54 bool isDynamicScope(bool& requiresDynamicChecks) const; 55 55 virtual JSObject* toThisObject(ExecState*) const; 56 virtual JSValue toStrictThisObject(ExecState*) const; 56 57 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 57 58 virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); -
trunk/JavaScriptCore/runtime/JSValue.h
r67825 r69516 194 194 bool needsThisConversion() const; 195 195 JSObject* toThisObject(ExecState*) const; 196 JSValue toStrictThisObject(ExecState*) const; 196 197 UString toThisString(ExecState*) const; 197 198 JSString* toThisJSString(ExecState*) const; -
trunk/JavaScriptCore/runtime/JSZombie.h
r57019 r69516 61 61 virtual bool deleteProperty(ExecState*, unsigned) { ASSERT_NOT_REACHED(); return false; } 62 62 virtual JSObject* toThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return 0; } 63 virtual JSValue toStrictThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return JSValue(); } 63 64 virtual JSValue getJSNumber() { ASSERT_NOT_REACHED(); return jsNull(); } 64 65 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&) { ASSERT_NOT_REACHED(); return false; } -
trunk/JavaScriptCore/runtime/PutPropertySlot.h
r44076 r69516 39 39 enum Type { Uncachable, ExistingProperty, NewProperty }; 40 40 41 PutPropertySlot( )41 PutPropertySlot(bool isStrictMode = false) 42 42 : m_type(Uncachable) 43 43 , m_base(0) 44 , m_isStrictMode(isStrictMode) 44 45 { 45 46 } … … 62 63 JSObject* base() const { return m_base; } 63 64 65 bool isStrictMode() const { return m_isStrictMode; } 64 66 bool isCacheable() const { return m_type != Uncachable; } 65 67 size_t cachedOffset() const { … … 71 73 JSObject* m_base; 72 74 size_t m_offset; 75 bool m_isStrictMode; 73 76 }; 74 77 -
trunk/LayoutTests/ChangeLog
r69515 r69516 1 2010-10-01 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Gavin Barraclough. 4 5 [ES5] Implement strict mode 6 https://bugs.webkit.org/show_bug.cgi?id=10701 7 8 Tests for the many different behaviours we get in strict mode. 9 10 * fast/js/basic-strict-mode-expected.txt: Added. 11 * fast/js/basic-strict-mode.html: Added. 12 * fast/js/script-tests/basic-strict-mode.js: Added. 13 (testThis): 14 (testGlobalAccess): 15 1 16 2010-10-10 Antonio Gomes <agomes@rim.com> 2 17 -
trunk/WebCore/ChangeLog
r69514 r69516 1 2010-10-01 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Gavin Barraclough. 4 5 [ES5] Implement strict mode 6 https://bugs.webkit.org/show_bug.cgi?id=10701 7 8 Test: fast/js/basic-strict-mode.html 9 10 Override toStrictThisObject on the domwindow so that 11 it correctly provides the shell object when used as this 12 in a strict mode function. 13 14 * bindings/js/JSDOMWindowBase.cpp: 15 (WebCore::JSDOMWindowBase::toStrictThisObject): 16 * bindings/js/JSDOMWindowBase.h: 17 1 18 2010-10-11 Joseph Pecoraro <joepeck@webkit.org> 2 19 -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r69284 r69516 21151 21151 buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */; 21152 21152 compatibilityVersion = "Xcode 2.4"; 21153 developmentRegion = English;21154 21153 hasScannedForEncodings = 1; 21155 21154 knownRegions = ( -
trunk/WebCore/bindings/js/JSDOMWindowBase.cpp
r58012 r69516 147 147 } 148 148 149 JSValue JSDOMWindowBase::toStrictThisObject(ExecState*) const 150 { 151 return shell(); 152 } 153 149 154 JSDOMWindowShell* JSDOMWindowBase::shell() const 150 155 { -
trunk/WebCore/bindings/js/JSDOMWindowBase.h
r65021 r69516 70 70 // Don't call this version of allowsAccessFrom -- it's a slightly incorrect implementation used only by WebScriptObject 71 71 virtual bool allowsAccessFrom(const JSC::JSGlobalObject*) const; 72 72 73 73 virtual JSC::JSObject* toThisObject(JSC::ExecState*) const; 74 virtual JSC::JSValue toStrictThisObject(JSC::ExecState*) const; 74 75 JSDOMWindowShell* shell() const; 75 76
Note: See TracChangeset
for help on using the changeset viewer.