Changeset 204842 in webkit
- Timestamp:
- Aug 23, 2016 11:14:30 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r204714 r204842 1 2016-08-22 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Modules' `export default function/class` should be declaration 4 https://bugs.webkit.org/show_bug.cgi?id=160499 5 6 Reviewed by Saam Barati. 7 8 Add several module tests. And flip the failed tests flags in test262. 9 10 * modules/export-default-function-name-in-assignment-expression.js: Added. 11 (export.default): 12 * modules/export-default-function-name-in-class-declaration.js: Added. 13 * modules/export-default-function-name-in-function-declaration.js: Added. 14 (export.default): 15 * modules/export-default-function-name-in-generator-declaration.js: Added. 16 (export.default): 17 * stress/method-name.js: Added. 18 (testSyntax): 19 (testSyntaxError): 20 (testSyntaxError.Hello.prototype.hello.hello): 21 (testSyntaxError.Hello): 22 (SyntaxError.Unexpected.identifier.string_appeared_here.Expected.an.opening.string_appeared_here.before.a.method.testSyntaxError.let.obj.hello.hello): 23 (testSyntaxError.Hello.prototype.get hello): 24 (testSyntaxError.Hello.prototype.set hello): 25 * test262.yaml: 26 1 27 2016-08-22 Yusuke Suzuki <utatane.tea@gmail.com> 2 28 -
trunk/JSTests/test262.yaml
r204714 r204842 70869 70869 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 70870 70870 - path: test262/test/language/module-code/eval-export-dflt-cls-anon.js 70871 cmd: runTest262 : fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]70871 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 70872 70872 - path: test262/test/language/module-code/eval-export-dflt-cls-name-meth.js 70873 70873 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] … … 70877 70877 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 70878 70878 - path: test262/test/language/module-code/eval-export-dflt-expr-cls-anon.js 70879 cmd: runTest262 : fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]70879 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 70880 70880 - path: test262/test/language/module-code/eval-export-dflt-expr-cls-name-meth.js 70881 70881 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] … … 70887 70887 cmd: runTest262 :normal, "ReferenceError", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 70888 70888 - path: test262/test/language/module-code/eval-export-dflt-expr-fn-anon.js 70889 cmd: runTest262 : fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]70889 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 70890 70890 - path: test262/test/language/module-code/eval-export-dflt-expr-fn-named.js 70891 70891 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 70892 70892 - path: test262/test/language/module-code/eval-export-dflt-expr-gen-anon.js 70893 cmd: runTest262 : fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]70893 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 70894 70894 - path: test262/test/language/module-code/eval-export-dflt-expr-gen-named.js 70895 70895 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] … … 71073 71073 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 71074 71074 - path: test262/test/language/module-code/instn-named-bndng-dflt-fun-anon.js 71075 cmd: runTest262 : fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]71075 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 71076 71076 - path: test262/test/language/module-code/instn-named-bndng-dflt-fun-named.js 71077 71077 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 71078 71078 - path: test262/test/language/module-code/instn-named-bndng-dflt-gen-anon.js 71079 cmd: runTest262 : fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]71079 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 71080 71080 - path: test262/test/language/module-code/instn-named-bndng-dflt-gen-named.js 71081 71081 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] … … 71505 71505 cmd: runTest262 :fail, "SyntaxError", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 71506 71506 - path: test262/test/language/module-code/parse-err-invoke-anon-fun-decl.js 71507 cmd: runTest262 : fail, "SyntaxError", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]71507 cmd: runTest262 :normal, "SyntaxError", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 71508 71508 - path: test262/test/language/module-code/parse-err-invoke-anon-gen-decl.js 71509 cmd: runTest262 : fail, "SyntaxError", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]71509 cmd: runTest262 :normal, "SyntaxError", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 71510 71510 - path: test262/test/language/module-code/parse-err-reference.js 71511 71511 cmd: runTest262 :normal, "ReferenceError", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] -
trunk/Source/JavaScriptCore/ChangeLog
r204840 r204842 1 2016-08-22 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Modules' `export default function/class` should be declaration 4 https://bugs.webkit.org/show_bug.cgi?id=160499 5 6 Reviewed by Saam Barati. 7 8 Previously, we parsed the following cases as FunctionExpression and ClassExpression. 9 10 ``` 11 export default function () { } 12 export default class { } 13 ``` 14 15 But, as per ES6 spec, the above `function ...` and `class ...` parts should be parsed 16 as function declaration and class declaration. This has big difference; the instantiation 17 of the function declarations are done in the function prologue. 18 19 In this patch, we correctly parse the above cases as declaration. To handle no-named 20 declarations, we add a new flag, DeclarationDefaultContext. This indicates [Default] 21 flag in the ES6 spec's BNF. 22 23 Furthermore, this patch also fixes the following name related bugs. 24 25 1. The bug related to "export default"'s function name. If the name is not provided (like the above case), the name of the function becomes 26 "default", not "*default*". This is special handling in ES6 spec. We handle this in JSFunction's reifyName. 27 28 2. `class Hello { hello hello() { } }` is accepted. We introduced FunctionRequirements::Unnamed and fix this bug. 29 30 * parser/ModuleScopeData.h: 31 (JSC::ModuleScopeData::exportBinding): 32 Exported names are already guranteed uniqueness by m_exportedNames. Not necessary to use set here. Use vector instead. 33 34 * parser/Parser.cpp: 35 (JSC::Parser<LexerType>::parseFunctionInfo): 36 If we pass FunctionRequirements::NoRequirements, we need to initialize functionInfo.name / classInfo.className 37 with the default fallback name. For example, in the above `export default` case, we initialize it with `*default*`. 38 39 (JSC::Parser<LexerType>::parseFunctionDeclaration): 40 (JSC::Parser<LexerType>::parseClassDeclaration): 41 (JSC::Parser<LexerType>::parseClass): 42 (JSC::Parser<LexerType>::parseExportDeclaration): 43 (JSC::Parser<LexerType>::parsePropertyMethod): 44 (JSC::Parser<LexerType>::parseGetterSetter): 45 (JSC::Parser<LexerType>::parseClassExpression): 46 (JSC::Parser<LexerType>::parseFunctionExpression): 47 (JSC::Parser<LexerType>::parsePrimaryExpression): 48 (JSC::Parser<LexerType>::parseArrowFunctionExpression): 49 * parser/Parser.h: 50 * runtime/JSFunction.cpp: 51 (JSC::JSFunction::reifyName): 52 1 53 2016-08-23 Saam Barati <sbarati@apple.com> 2 54 -
trunk/Source/JavaScriptCore/inspector/JSInjectedScriptHost.cpp
r204358 r204842 229 229 result->putDirect(vm, Identifier::fromString(exec, "location"), location); 230 230 231 String name = function->name( );231 String name = function->name(vm); 232 232 if (!name.isEmpty()) 233 233 result->putDirect(vm, Identifier::fromString(exec, "name"), jsString(exec, name)); -
trunk/Source/JavaScriptCore/parser/ModuleScopeData.h
r203953 r204842 36 36 WTF_MAKE_FAST_ALLOCATED; 37 37 public: 38 typedef HashMap<RefPtr<UniquedStringImpl>, IdentifierSet, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> IdentifierAliasMap;38 typedef HashMap<RefPtr<UniquedStringImpl>, Vector<RefPtr<UniquedStringImpl>>, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> IdentifierAliasMap; 39 39 40 40 static Ref<ModuleScopeData> create() { return adoptRef(*new ModuleScopeData); } … … 49 49 void exportBinding(const Identifier& localName, const Identifier& exportedName) 50 50 { 51 m_exportedBindings.add(localName.impl(), IdentifierSet()).iterator->value.add(exportedName.impl());51 m_exportedBindings.add(localName.impl(), Vector<RefPtr<UniquedStringImpl>>()).iterator->value.append(exportedName.impl()); 52 52 } 53 53 -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r204714 r204842 1931 1931 1932 1932 template <typename LexerType> 1933 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, Function Requirements requirements, SourceParseMode mode, bool nameIsInContainingScope, ConstructorKind constructorKind, SuperBinding expectedSuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& functionInfo, FunctionDefinitionType functionDefinitionType)1933 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionNameRequirements requirements, SourceParseMode mode, bool nameIsInContainingScope, ConstructorKind constructorKind, SuperBinding expectedSuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& functionInfo, FunctionDefinitionType functionDefinitionType) 1934 1934 { 1935 1935 RELEASE_ASSERT(isFunctionParseMode(mode)); … … 2073 2073 upperScopeIsGenerator = false; 2074 2074 2075 if (matchSpecIdentifier(upperScopeIsGenerator)) { 2076 functionInfo.name = m_token.m_data.ident; 2077 m_parserState.lastFunctionName = functionInfo.name; 2078 next(); 2079 if (!nameIsInContainingScope) 2080 failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode"); 2081 } else if (requirements == FunctionNeedsName) { 2082 if (match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode) 2083 semanticFail("Function statements must have a name"); 2084 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); 2085 failDueToUnexpectedToken(); 2086 return false; 2075 if (requirements != FunctionNameRequirements::Unnamed) { 2076 ASSERT_WITH_MESSAGE(!(requirements == FunctionNameRequirements::None && !functionInfo.name), "When specifying FunctionNameRequirements::None, we need to initialize functionInfo.name with the default value in the caller side."); 2077 if (matchSpecIdentifier(upperScopeIsGenerator)) { 2078 functionInfo.name = m_token.m_data.ident; 2079 m_parserState.lastFunctionName = functionInfo.name; 2080 next(); 2081 if (!nameIsInContainingScope) 2082 failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode"); 2083 } else if (requirements == FunctionNameRequirements::Named) { 2084 if (match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode) 2085 semanticFail("Function statements must have a name"); 2086 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); 2087 failDueToUnexpectedToken(); 2088 return false; 2089 } 2090 ASSERT(functionInfo.name); 2087 2091 } 2088 2092 … … 2164 2168 failIfFalse(functionInfo.body, "Cannot parse the body of this ", stringForFunctionMode(mode)); 2165 2169 context.setEndOffset(functionInfo.body, m_lexer->currentOffset()); 2166 if (functionScope->strictMode() && functionInfo.name) { 2170 if (functionScope->strictMode() && requirements != FunctionNameRequirements::Unnamed) { 2171 ASSERT(functionInfo.name); 2167 2172 RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode); 2168 2173 semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); … … 2222 2227 2223 2228 template <typename LexerType> 2224 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context, ExportType exportType )2229 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context, ExportType exportType, DeclarationDefaultContext declarationDefaultContext) 2225 2230 { 2226 2231 ASSERT(match(FUNCTION)); … … 2228 2233 unsigned functionKeywordStart = tokenStart(); 2229 2234 next(); 2230 ParserFunctionInfo<TreeBuilder> functionInfo;2231 2235 SourceParseMode parseMode = SourceParseMode::NormalFunctionMode; 2232 2236 if (consume(TIMES)) 2233 2237 parseMode = SourceParseMode::GeneratorWrapperFunctionMode; 2234 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this function"); 2235 failIfFalse(functionInfo.name, "Function statements must have a name"); 2238 2239 ParserFunctionInfo<TreeBuilder> functionInfo; 2240 FunctionNameRequirements requirements = FunctionNameRequirements::Named; 2241 if (declarationDefaultContext == DeclarationDefaultContext::ExportDefault) { 2242 // Under the "export default" context, function declaration does not require the function name. 2243 // 2244 // ExportDeclaration: 2245 // ... 2246 // export default HoistableDeclaration[~Yield, +Default] 2247 // ... 2248 // 2249 // HoistableDeclaration[Yield, Default]: 2250 // FunctionDeclaration[?Yield, ?Default] 2251 // GeneratorDeclaration[?Yield, ?Default] 2252 // 2253 // FunctionDeclaration[Yield, Default]: 2254 // ... 2255 // [+Default] function ( FormalParameters[~Yield] ) { FunctionBody[~Yield] } 2256 // 2257 // GeneratorDeclaration[Yield, Default]: 2258 // ... 2259 // [+Default] function * ( FormalParameters[+Yield] ) { GeneratorBody } 2260 // 2261 // In this case, we use "*default*" as this function declaration's name. 2262 requirements = FunctionNameRequirements::None; 2263 functionInfo.name = &m_vm->propertyNames->builtinNames().starDefaultPrivateName(); 2264 } 2265 2266 failIfFalse((parseFunctionInfo(context, requirements, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this function"); 2267 ASSERT(functionInfo.name); 2236 2268 2237 2269 std::pair<DeclarationResultMask, ScopeRef> functionDeclaration = declareFunction(functionInfo.name); … … 2241 2273 internalFailWithMessage(false, "Cannot declare a function that shadows a let/const/class/function variable '", functionInfo.name->impl(), "' in strict mode"); 2242 2274 if (exportType == ExportType::Exported) { 2275 ASSERT_WITH_MESSAGE(declarationDefaultContext != DeclarationDefaultContext::ExportDefault, "Export default case will export the name and binding in the caller."); 2243 2276 semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'"); 2244 2277 m_moduleScopeData->exportBinding(*functionInfo.name); … … 2252 2285 2253 2286 template <typename LexerType> 2254 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType )2287 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType, DeclarationDefaultContext declarationDefaultContext) 2255 2288 { 2256 2289 ASSERT(match(CLASSTOKEN)); … … 2260 2293 2261 2294 ParserClassInfo<TreeBuilder> info; 2262 TreeClassExpression classExpr = parseClass(context, FunctionNeedsName, info); 2295 FunctionNameRequirements requirements = FunctionNameRequirements::Named; 2296 if (declarationDefaultContext == DeclarationDefaultContext::ExportDefault) { 2297 // Under the "export default" context, class declaration does not require the class name. 2298 // 2299 // ExportDeclaration: 2300 // ... 2301 // export default ClassDeclaration[~Yield, +Default] 2302 // ... 2303 // 2304 // ClassDeclaration[Yield, Default]: 2305 // ... 2306 // [+Default] class ClassTail[?Yield] 2307 // 2308 // In this case, we use "*default*" as this class declaration's name. 2309 requirements = FunctionNameRequirements::None; 2310 info.className = &m_vm->propertyNames->builtinNames().starDefaultPrivateName(); 2311 } 2312 2313 TreeClassExpression classExpr = parseClass(context, requirements, info); 2263 2314 failIfFalse(classExpr, "Failed to parse class"); 2315 ASSERT(info.className); 2264 2316 2265 2317 DeclarationResultMask declarationResult = declareVariable(info.className, DeclarationType::LetDeclaration); … … 2267 2319 internalFailWithMessage(false, "Cannot declare a class twice: '", info.className->impl(), "'"); 2268 2320 if (exportType == ExportType::Exported) { 2321 ASSERT_WITH_MESSAGE(declarationDefaultContext != DeclarationDefaultContext::ExportDefault, "Export default case will export the name and binding in the caller."); 2269 2322 semanticFailIfFalse(exportName(*info.className), "Cannot export a duplicate class name: '", info.className->impl(), "'"); 2270 2323 m_moduleScopeData->exportBinding(*info.className); … … 2278 2331 2279 2332 template <typename LexerType> 2280 template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(TreeBuilder& context, Function Requirements requirements, ParserClassInfo<TreeBuilder>& info)2333 template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(TreeBuilder& context, FunctionNameRequirements requirements, ParserClassInfo<TreeBuilder>& info) 2281 2334 { 2282 2335 ASSERT(match(CLASSTOKEN)); … … 2292 2345 classScope->setStrictMode(); 2293 2346 2294 const Identifier* className = nullptr; 2347 ASSERT_WITH_MESSAGE(requirements != FunctionNameRequirements::Unnamed, "Currently, there is no caller that uses FunctionNameRequirements::Unnamed for class syntax."); 2348 ASSERT_WITH_MESSAGE(!(requirements == FunctionNameRequirements::None && !info.className), "When specifying FunctionNameRequirements::None, we need to initialize info.className with the default value in the caller side."); 2295 2349 if (match(IDENT)) { 2296 className = m_token.m_data.ident;2297 next(); 2298 failIfTrue(classScope->declareLexicalVariable( className, true) & DeclarationResult::InvalidStrictMode, "'",className->impl(), "' is not a valid class name");2299 } else if (requirements == FunctionN eedsName) {2350 info.className = m_token.m_data.ident; 2351 next(); 2352 failIfTrue(classScope->declareLexicalVariable(info.className, true) & DeclarationResult::InvalidStrictMode, "'", info.className->impl(), "' is not a valid class name"); 2353 } else if (requirements == FunctionNameRequirements::Named) { 2300 2354 if (match(OPENBRACE)) 2301 2355 semanticFail("Class statements must have a name"); 2302 2356 semanticFailureDueToKeyword("class name"); 2303 2357 failDueToUnexpectedToken(); 2304 } else 2305 className = &m_vm->propertyNames->nullIdentifier; 2306 ASSERT(className); 2307 info.className = className; 2358 } 2359 ASSERT(info.className); 2308 2360 2309 2361 TreeExpression parentClass = 0; … … 2402 2454 semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare a generator named 'constructor'"); 2403 2455 } 2404 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method");2405 methodInfo.name = isConstructor ? className : ident;2456 methodInfo.name = isConstructor ? info.className : ident; 2457 failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, parseMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method"); 2406 2458 2407 2459 TreeExpression method = context.createMethodDefinition(methodLocation, methodInfo); … … 2857 2909 bool isFunctionOrClassDeclaration = false; 2858 2910 const Identifier* localName = nullptr; 2859 SavePoint savePoint = createSavePoint();2860 2911 2861 2912 bool startsWithFunction = match(FUNCTION); 2862 2913 if (startsWithFunction || match(CLASSTOKEN)) { 2914 SavePoint savePoint = createSavePoint(); 2863 2915 isFunctionOrClassDeclaration = true; 2864 2916 next(); … … 2872 2924 } 2873 2925 2874 if (localName) { 2875 if (match(FUNCTION)) { 2926 if (!localName) 2927 localName = &m_vm->propertyNames->builtinNames().starDefaultPrivateName(); 2928 2929 if (isFunctionOrClassDeclaration) { 2930 if (startsWithFunction) { 2931 ASSERT(match(FUNCTION)); 2876 2932 DepthManager statementDepth(&m_statementDepth); 2877 2933 m_statementDepth = 1; 2878 result = parseFunctionDeclaration(context );2934 result = parseFunctionDeclaration(context, ExportType::NotExported, DeclarationDefaultContext::ExportDefault); 2879 2935 } else { 2880 2936 ASSERT(match(CLASSTOKEN)); 2881 result = parseClassDeclaration(context );2937 result = parseClassDeclaration(context, ExportType::NotExported, DeclarationDefaultContext::ExportDefault); 2882 2938 } 2883 2939 } else { … … 2902 2958 TreeExpression assignment = context.createAssignResolve(location, m_vm->propertyNames->builtinNames().starDefaultPrivateName(), expression, start, start, tokenEndPosition(), AssignmentContext::ConstDeclarationStatement); 2903 2959 result = context.createExprStatement(location, assignment, start, tokenEndPosition()); 2904 if (!isFunctionOrClassDeclaration) 2905 failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration"); 2906 localName = &m_vm->propertyNames->builtinNames().starDefaultPrivateName(); 2960 failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration"); 2907 2961 } 2908 2962 failIfFalse(result, "Cannot parse the declaration"); … … 3430 3484 unsigned methodStart = tokenStart(); 3431 3485 ParserFunctionInfo<TreeBuilder> methodInfo; 3486 methodInfo.name = methodName; 3432 3487 SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : SourceParseMode::MethodMode; 3433 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method"); 3434 methodInfo.name = methodName; 3488 failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, parseMode, false, ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method"); 3435 3489 return context.createMethodDefinition(methodLocation, methodInfo); 3436 3490 } … … 3467 3521 if (type & PropertyNode::Getter) { 3468 3522 failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition"); 3469 failIfFalse((parseFunctionInfo(context, FunctionN oRequirements, SourceParseMode::GetterMode, false, constructorKind, SuperBinding::Needed, getterOrSetterStartOffset, info, FunctionDefinitionType::Method)), "Cannot parse getter definition");3523 failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, SourceParseMode::GetterMode, false, constructorKind, SuperBinding::Needed, getterOrSetterStartOffset, info, FunctionDefinitionType::Method)), "Cannot parse getter definition"); 3470 3524 } else { 3471 3525 failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition"); 3472 failIfFalse((parseFunctionInfo(context, FunctionN oRequirements, SourceParseMode::SetterMode, false, constructorKind, SuperBinding::Needed, getterOrSetterStartOffset, info, FunctionDefinitionType::Method)), "Cannot parse setter definition");3526 failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, SourceParseMode::SetterMode, false, constructorKind, SuperBinding::Needed, getterOrSetterStartOffset, info, FunctionDefinitionType::Method)), "Cannot parse setter definition"); 3473 3527 } 3474 3528 … … 3672 3726 3673 3727 template <typename LexerType> 3728 template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClassExpression(TreeBuilder& context) 3729 { 3730 ASSERT(match(CLASSTOKEN)); 3731 ParserClassInfo<TreeBuilder> info; 3732 info.className = &m_vm->propertyNames->nullIdentifier; 3733 return parseClass(context, FunctionNameRequirements::None, info); 3734 } 3735 3736 template <typename LexerType> 3674 3737 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseFunctionExpression(TreeBuilder& context) 3675 3738 { … … 3683 3746 if (consume(TIMES)) 3684 3747 parseMode = SourceParseMode::GeneratorWrapperFunctionMode; 3685 failIfFalse((parseFunctionInfo(context, FunctionN oRequirements, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Expression)), "Cannot parse function expression");3748 failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::None, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Expression)), "Cannot parse function expression"); 3686 3749 return context.createFunctionExpr(location, functionInfo); 3687 3750 } … … 3752 3815 case FUNCTION: 3753 3816 return parseFunctionExpression(context); 3754 case CLASSTOKEN: { 3755 ParserClassInfo<TreeBuilder> info; 3756 return parseClass(context, FunctionNoRequirements, info); 3757 } 3817 case CLASSTOKEN: 3818 return parseClassExpression(context); 3758 3819 case OPENBRACE: 3759 3820 if (strictMode()) … … 4079 4140 ParserFunctionInfo<TreeBuilder> info; 4080 4141 info.name = &m_vm->propertyNames->nullIdentifier; 4081 failIfFalse((parseFunctionInfo(context, FunctionN oRequirements, SourceParseMode::ArrowFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression");4142 failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, SourceParseMode::ArrowFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression"); 4082 4143 4083 4144 return context.createArrowFunctionExpr(location, info); -
trunk/Source/JavaScriptCore/parser/Parser.h
r204714 r204842 71 71 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode }; 72 72 enum FunctionBodyType { ArrowFunctionBodyExpression, ArrowFunctionBodyBlock, StandardFunctionBodyBlock }; 73 enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName};73 enum class FunctionNameRequirements { None, Named, Unnamed }; 74 74 75 75 enum class DestructuringKind { … … 102 102 typedef uint8_t DeclarationResultMask; 103 103 104 enum class DeclarationDefaultContext { 105 Standard, 106 ExportDefault, 107 }; 104 108 105 109 template <typename T> inline bool isEvalNode() { return false; } … … 1356 1360 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0); 1357 1361 enum class ExportType { Exported, NotExported }; 1358 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported );1359 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported );1362 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard); 1363 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard); 1360 1364 template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType, ExportType = ExportType::NotExported); 1361 1365 template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&); … … 1389 1393 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&); 1390 1394 template <class TreeBuilder> NEVER_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&); 1395 template <class TreeBuilder> ALWAYS_INLINE TreeClassExpression parseClassExpression(TreeBuilder&); 1391 1396 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseFunctionExpression(TreeBuilder&); 1392 1397 template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&); … … 1417 1422 1418 1423 enum class FunctionDefinitionType { Expression, Declaration, Method }; 1419 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, Function Requirements, SourceParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionDefinitionType);1424 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionNameRequirements, SourceParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionDefinitionType); 1420 1425 1421 1426 ALWAYS_INLINE bool isArrowFunctionParameters(); … … 1424 1429 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::FormalParameterList createGeneratorParameters(TreeBuilder&); 1425 1430 1426 template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, Function Requirements, ParserClassInfo<TreeBuilder>&);1431 template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, FunctionNameRequirements, ParserClassInfo<TreeBuilder>&); 1427 1432 1428 1433 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateString parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode, bool& elementIsTail); -
trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
r200430 r204842 83 83 EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec) 84 84 { 85 VM& vm = exec->vm(); 85 86 JSValue thisValue = exec->thisValue(); 86 87 if (thisValue.inherits(JSFunction::info())) { 87 88 JSFunction* function = jsCast<JSFunction*>(thisValue); 88 89 if (function->isHostOrBuiltinFunction()) 89 return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name( ), "() {\n [native code]\n}"));90 return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(vm), "() {\n [native code]\n}")); 90 91 91 92 FunctionExecutable* executable = function->jsExecutable(); … … 100 101 executable->parametersStartOffset(), 101 102 executable->parametersStartOffset() + executable->source().length()); 102 return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name( ), source));103 return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name(vm), source)); 103 104 } 104 105 -
trunk/Source/JavaScriptCore/runtime/JSFunction.cpp
r204321 r204842 167 167 } 168 168 169 String JSFunction::name( )169 String JSFunction::name(VM& vm) 170 170 { 171 171 if (isHostFunction()) { … … 173 173 return executable->name(); 174 174 } 175 return jsExecutable()->name().string(); 175 const Identifier identifier = jsExecutable()->name(); 176 if (identifier == vm.propertyNames->builtinNames().starDefaultPrivateName()) 177 return emptyString(); 178 return identifier.string(); 176 179 } 177 180 … … 193 196 return explicitName; 194 197 195 const String actualName = name( );198 const String actualName = name(vm); 196 199 if (!actualName.isEmpty() || isHostOrBuiltinFunction()) 197 200 return actualName; … … 617 620 void JSFunction::reifyName(ExecState* exec) 618 621 { 619 String name = jsExecutable()->ecmaName().string(); 622 const Identifier& ecmaName = jsExecutable()->ecmaName(); 623 String name; 624 // https://tc39.github.io/ecma262/#sec-exports-runtime-semantics-evaluation 625 // When the ident is "*default*", we need to set "default" for the ecma name. 626 // This "*default*" name is never shown to users. 627 if (ecmaName == exec->propertyNames().builtinNames().starDefaultPrivateName()) 628 name = exec->propertyNames().defaultKeyword.string(); 629 else 630 name = ecmaName.string(); 620 631 reifyName(exec, name); 621 632 } -
trunk/Source/JavaScriptCore/runtime/JSFunction.h
r204321 r204842 82 82 static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*, const String& name); 83 83 84 JS_EXPORT_PRIVATE String name( );84 JS_EXPORT_PRIVATE String name(VM&); 85 85 JS_EXPORT_PRIVATE String displayName(VM&); 86 86 const String calculatedDisplayName(VM&); -
trunk/Source/JavaScriptCore/runtime/LazyClassStructure.cpp
r200430 r204842 81 81 name = internalFunction->name(); 82 82 else if (JSFunction* function = jsDynamicCast<JSFunction*>(constructor)) 83 name = function->name( );83 name = function->name(vm); 84 84 else 85 85 RELEASE_ASSERT_NOT_REACHED();
Note: See TracChangeset
for help on using the changeset viewer.