Changeset 272883 in webkit for trunk/Source/JavaScriptCore/bytecompiler
- Timestamp:
- Feb 15, 2021, 2:40:26 PM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore/bytecompiler
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r272580 r272883 57 57 #include "UnlinkedProgramCodeBlock.h" 58 58 #include <wtf/BitVector.h> 59 #include <wtf/HashSet.h> 59 60 #include <wtf/Optional.h> 60 #include <wtf/SmallPtrSet.h>61 61 #include <wtf/StdLibExtras.h> 62 62 #include <wtf/text/WTFString.h> … … 1901 1901 // FIXME: only do this if there is an eval() within a nested scope --- otherwise it isn't needed. 1902 1902 // https://bugs.webkit.org/show_bug.cgi?id=206663 1903 if (entry.value.isPrivateField()) 1904 symbolTable->addPrivateName(entry.key.get(), PrivateNameEntry(PrivateNameEntry::Traits::IsDeclared)); 1905 else if (entry.value.isPrivateMethod()) 1906 symbolTable->addPrivateName(entry.key.get(), PrivateNameEntry(PrivateNameEntry::Traits::IsDeclared | PrivateNameEntry::Traits::IsMethod)); 1903 1904 const PrivateNameEnvironment* privateEnvironment = lexicalVariables.privateNameEnvironment(); 1905 if (!privateEnvironment) 1906 continue; 1907 1908 auto findResult = privateEnvironment->find(entry.key.get()); 1909 1910 if (findResult == privateEnvironment->end()) 1911 continue; 1912 1913 symbolTable->addPrivateName(findResult->key.get(), findResult->value); 1907 1914 } 1908 1915 } … … 2932 2939 } 2933 2940 2934 bool BytecodeGenerator::isPrivateMethod(const Identifier& ident) 2941 // This should be called only with PrivateNames available. 2942 PrivateNameEntry BytecodeGenerator::getPrivateTraits(const Identifier& ident) 2935 2943 { 2936 2944 for (unsigned i = m_privateNamesStack.size(); i--; ) { … … 2938 2946 auto it = map.find(ident.impl()); 2939 2947 if (it != map.end()) 2940 return it->value.isMethod(); 2941 } 2942 2943 return false; 2948 return it->value; 2949 } 2950 2951 RELEASE_ASSERT_NOT_REACHED(); 2952 return PrivateNameEntry(); 2944 2953 } 2945 2954 … … 2982 2991 { 2983 2992 PrivateNameEnvironment result; 2984 SmallPtrSet<UniquedStringImpl*, 16> excludedNames;2993 HashSet<UniquedStringImpl*> excludedNames; 2985 2994 for (unsigned i = m_privateNamesStack.size(); i--; ) { 2986 2995 auto& map = m_privateNamesStack[i]; 2987 2996 for (auto& entry : map) { 2988 if (entry.value.isPrivateMethodOrAcessor()) { 2989 if (!excludedNames.contains(entry.key.get())) { 2990 result.add(entry.key, entry.value); 2991 excludedNames.add(entry.key.get()); 2992 } 2993 } else 2994 excludedNames.add(entry.key.get()); 2997 auto addResult = excludedNames.add(entry.key.get()); 2998 if (addResult.isNewEntry) 2999 result.add(entry.key, entry.value); 2995 3000 } 2996 3001 } -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r272580 r272883 1264 1264 } 1265 1265 1266 bool isPrivateMethod(const Identifier&);1266 PrivateNameEntry getPrivateTraits(const Identifier&); 1267 1267 1268 1268 void pushPrivateAccessNames(const PrivateNameEnvironment*); -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r272580 r272883 580 580 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dstOrConstructor, RegisterID* prototype, Vector<JSTextPosition>* instanceFieldLocations, Vector<JSTextPosition>* staticFieldLocations) 581 581 { 582 using GetterSetterPair = std::pair<PropertyNode*, PropertyNode*>; 583 using GetterSetterMap = HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash>; 584 585 if (hasPrivateAccessors()) { 586 GetterSetterMap privateAccessorMap; 587 588 for (PropertyListNode* propertyList = this; propertyList; propertyList = propertyList->m_next) { 589 if (!(propertyList->m_node->type() & (PropertyNode::PrivateGetter | PropertyNode::PrivateSetter))) 590 continue; 591 592 // We group private getters and setters to store them in a object 593 GetterSetterPair pair(propertyList->m_node, static_cast<PropertyNode*>(nullptr)); 594 GetterSetterMap::AddResult result = privateAccessorMap.add(propertyList->m_node->name()->impl(), pair); 595 auto& resultPair = result.iterator->value; 596 // If the map already contains an element with node->name(), 597 // we need to store this node in the second part. 598 if (!result.isNewEntry) 599 resultPair.second = propertyList->m_node; 600 continue; 601 } 602 603 // Then we declare private accessors 604 for (auto& it : privateAccessorMap) { 605 // FIXME: Use GetterSetter to store private accessors 606 // https://bugs.webkit.org/show_bug.cgi?id=221915 607 RefPtr<RegisterID> getterSetterObj = generator.emitNewObject(generator.newTemporary()); 608 GetterSetterPair pair = it.value; 609 610 auto emitPutAccessor = [&] (PropertyNode* propertyNode) { 611 RegisterID* base = propertyNode->isInstanceClassProperty() ? prototype : dstOrConstructor; 612 613 RefPtr<RegisterID> value = generator.emitNode(propertyNode->m_assign); 614 if (propertyNode->needsSuperBinding()) 615 emitPutHomeObject(generator, value.get(), base); 616 auto setterOrGetterIdent = propertyNode->m_type & PropertyNode::PrivateGetter 617 ? generator.propertyNames().builtinNames().getPrivateName() 618 : generator.propertyNames().builtinNames().setPrivateName(); 619 generator.emitDirectPutById(getterSetterObj.get(), setterOrGetterIdent, value.get()); 620 }; 621 622 if (pair.first) 623 emitPutAccessor(pair.first); 624 625 if (pair.second) 626 emitPutAccessor(pair.second); 627 628 Variable var = generator.variable(*pair.first->name()); 629 generator.emitPutToScope(generator.scopeRegister(), var, getterSetterObj.get(), DoNotThrowIfNotFound, InitializationMode::ConstInitialization); 630 } 631 } 632 582 633 PropertyListNode* p = this; 583 634 RegisterID* dst = nullptr; … … 586 637 for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next) { 587 638 dst = p->m_node->isInstanceClassProperty() ? prototype : dstOrConstructor; 639 640 if (p->m_node->type() & (PropertyNode::PrivateGetter | PropertyNode::PrivateSetter)) 641 continue; 588 642 589 643 if (p->isComputedClassField()) … … 611 665 bool canOverrideProperties = false; 612 666 613 typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;614 typedef HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash> GetterSetterMap;615 667 GetterSetterMap instanceMap; 616 668 GetterSetterMap staticMap; … … 651 703 if (p->isComputedClassField()) 652 704 emitSaveComputedFieldName(generator, *p->m_node); 705 706 if (p->m_node->type() & (PropertyNode::PrivateGetter | PropertyNode::PrivateSetter)) 707 continue; 653 708 654 709 if (p->isInstanceClassField()) { … … 783 838 if (node.isClassProperty()) { 784 839 ASSERT(node.needsSuperBinding()); 840 ASSERT(!(node.type() & PropertyNode::PrivateSetter)); 841 ASSERT(!(node.type() & PropertyNode::PrivateGetter)); 785 842 786 843 if (node.type() & PropertyNode::PrivateMethod) { … … 920 977 { 921 978 if (isPrivateMember()) { 922 if (generator.isPrivateMethod(identifier())) { 923 Variable var = generator.variable(identifier()); 979 auto identifierName = identifier(); 980 auto privateTraits = generator.getPrivateTraits(identifierName); 981 if (privateTraits.isMethod()) { 982 Variable var = generator.variable(identifierName); 924 983 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 925 984 926 Re gisterID*privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get());927 generator.emitCheckPrivateBrand(base, privateBrandSymbol );985 RefPtr<RegisterID> privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get()); 986 generator.emitCheckPrivateBrand(base, privateBrandSymbol.get()); 928 987 929 988 return generator.emitGetFromScope(dst, scope.get(), var, ThrowIfNotFound); 930 989 } 931 990 991 if (privateTraits.isGetter()) { 992 Variable var = generator.variable(identifierName); 993 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 994 995 RefPtr<RegisterID> privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get()); 996 generator.emitCheckPrivateBrand(base, privateBrandSymbol.get()); 997 998 RefPtr<RegisterID> getterSetterObj = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound); 999 RefPtr<RegisterID> getterFunction = generator.emitDirectGetById(generator.newTemporary(), getterSetterObj.get(), generator.propertyNames().builtinNames().getPrivateName()); 1000 CallArguments args(generator, nullptr); 1001 generator.move(args.thisRegister(), base); 1002 return generator.emitCall(dst, getterFunction.get(), NoExpectedFunction, args, m_position, m_position, m_position, DebuggableCall::Yes); 1003 } 1004 1005 if (privateTraits.isSetter()) { 1006 // We need to perform brand check to follow the spec 1007 Variable var = generator.variable(identifierName); 1008 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 1009 1010 RefPtr<RegisterID> privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get()); 1011 generator.emitCheckPrivateBrand(base, privateBrandSymbol.get()); 1012 generator.emitThrowTypeError("Trying to access an undefined private getter"); 1013 return dst; 1014 } 1015 1016 ASSERT(privateTraits.isField()); 932 1017 Variable var = generator.variable(m_ident); 933 1018 ASSERT_WITH_MESSAGE(!var.local(), "Private Field names must be stored in captured variables"); … … 958 1043 if (isPrivateMember()) { 959 1044 auto identifierName = identifier(); 960 if (generator.isPrivateMethod(identifierName)) { 1045 auto privateTraits = generator.getPrivateTraits(identifierName); 1046 if (privateTraits.isSetter()) { 961 1047 Variable var = generator.variable(identifierName); 962 1048 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 963 1049 964 RegisterID* privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get()); 965 generator.emitCheckPrivateBrand(base, privateBrandSymbol); 966 967 generator.emitThrowTypeError("Trying to access a not defined private setter"); 968 } 969 1050 RefPtr<RegisterID> privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get()); 1051 generator.emitCheckPrivateBrand(base, privateBrandSymbol.get()); 1052 1053 RefPtr<RegisterID> getterSetterObj = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound); 1054 RefPtr<RegisterID> setterFunction = generator.emitDirectGetById(generator.newTemporary(), getterSetterObj.get(), generator.propertyNames().builtinNames().setPrivateName()); 1055 CallArguments args(generator, nullptr, 1); 1056 generator.move(args.thisRegister(), base); 1057 generator.move(args.argumentRegister(0), value); 1058 generator.emitCall(generator.newTemporary(), setterFunction.get(), NoExpectedFunction, args, m_position, m_position, m_position, DebuggableCall::Yes); 1059 1060 return value; 1061 } 1062 1063 if (privateTraits.isGetter() || privateTraits.isMethod()) { 1064 Variable var = generator.variable(identifierName); 1065 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 1066 1067 RefPtr<RegisterID> privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get()); 1068 generator.emitCheckPrivateBrand(base, privateBrandSymbol.get()); 1069 1070 generator.emitThrowTypeError("Trying to access an undefined private setter"); 1071 return value; 1072 } 1073 1074 ASSERT(privateTraits.isField()); 970 1075 Variable var = generator.variable(m_ident); 971 1076 ASSERT_WITH_MESSAGE(!var.local(), "Private Field names must be stored in captured variables"); … … 2288 2393 if (dotAccessor->isPrivateMember()) { 2289 2394 ASSERT(!baseIsSuper); 2395 auto privateTraits = generator.getPrivateTraits(ident); 2396 2397 if (privateTraits.isField()) { 2398 Variable var = generator.variable(ident); 2399 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 2400 RefPtr<RegisterID> privateName = generator.newTemporary(); 2401 generator.emitGetFromScope(privateName.get(), scope.get(), var, DoNotThrowIfNotFound); 2402 2403 RefPtr<RegisterID> value = generator.emitGetPrivateName(generator.newTemporary(), base.get(), privateName.get()); 2404 RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator); 2405 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 2406 generator.emitPrivateFieldPut(base.get(), privateName.get(), value.get()); 2407 generator.emitProfileType(value.get(), divotStart(), divotEnd()); 2408 return generator.move(dst, oldValue.get()); 2409 } 2410 2411 if (privateTraits.isMethod()) { 2412 Variable var = generator.variable(ident); 2413 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 2414 2415 RefPtr<RegisterID> privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get()); 2416 generator.emitCheckPrivateBrand(base.get(), privateBrandSymbol.get()); 2417 2418 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 2419 generator.emitThrowTypeError("Trying to access an undefined private setter"); 2420 return generator.tempDestination(dst); 2421 } 2422 2290 2423 Variable var = generator.variable(ident); 2291 2424 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 2292 RefPtr<RegisterID> privateName = generator.newTemporary(); 2293 generator.emitGetFromScope(privateName.get(), scope.get(), var, DoNotThrowIfNotFound); 2294 2295 RefPtr<RegisterID> value = generator.emitGetPrivateName(generator.newTemporary(), base.get(), privateName.get()); 2425 2426 RefPtr<RegisterID> privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get()); 2427 generator.emitCheckPrivateBrand(base.get(), privateBrandSymbol.get()); 2428 2429 RefPtr<RegisterID> value; 2430 if (privateTraits.isGetter()) { 2431 RefPtr<RegisterID> getterSetterObj = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound); 2432 RefPtr<RegisterID> getterFunction = generator.emitDirectGetById(generator.newTemporary(), getterSetterObj.get(), generator.propertyNames().builtinNames().getPrivateName()); 2433 CallArguments args(generator, nullptr); 2434 generator.move(args.thisRegister(), base.get()); 2435 value = generator.emitCall(generator.newTemporary(), getterFunction.get(), NoExpectedFunction, args, m_position, m_position, m_position, DebuggableCall::Yes); 2436 } else { 2437 generator.emitThrowTypeError("Trying to access an undefined private getter"); 2438 return generator.tempDestination(dst); 2439 } 2440 2296 2441 RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator); 2297 2442 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 2298 generator.emitPrivateFieldPut(base.get(), privateName.get(), value.get()); 2299 generator.emitProfileType(value.get(), divotStart(), divotEnd()); 2443 2444 if (privateTraits.isSetter()) { 2445 RefPtr<RegisterID> getterSetterObj = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound); 2446 RefPtr<RegisterID> setterFunction = generator.emitDirectGetById(generator.newTemporary(), getterSetterObj.get(), generator.propertyNames().builtinNames().setPrivateName()); 2447 CallArguments args(generator, nullptr, 1); 2448 generator.move(args.thisRegister(), base.get()); 2449 generator.move(args.argumentRegister(0), value.get()); 2450 generator.emitCall(generator.newTemporary(), setterFunction.get(), NoExpectedFunction, args, m_position, m_position, m_position, DebuggableCall::Yes); 2451 generator.emitProfileType(value.get(), divotStart(), divotEnd()); 2452 return generator.move(dst, oldValue.get()); 2453 } 2454 2455 generator.emitThrowTypeError("Trying to access an undefined private getter"); 2300 2456 return generator.move(dst, oldValue.get()); 2301 2457 } … … 2526 2682 RegisterID* value; 2527 2683 if (dotAccessor->isPrivateMember()) { 2528 ASSERT(!baseNode->isSuperNode()); 2684 auto privateTraits = generator.getPrivateTraits(ident); 2685 if (privateTraits.isField()) { 2686 ASSERT(!baseNode->isSuperNode()); 2687 Variable var = generator.variable(ident); 2688 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 2689 RefPtr<RegisterID> privateName = generator.newTemporary(); 2690 generator.emitGetFromScope(privateName.get(), scope.get(), var, DoNotThrowIfNotFound); 2691 2692 value = generator.emitGetPrivateName(propDst.get(), base.get(), privateName.get()); 2693 emitIncOrDec(generator, value, m_operator); 2694 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 2695 generator.emitPrivateFieldPut(base.get(), privateName.get(), value); 2696 generator.emitProfileType(value, divotStart(), divotEnd()); 2697 return generator.move(dst, propDst.get()); 2698 } 2699 2700 if (privateTraits.isMethod()) { 2701 Variable var = generator.variable(ident); 2702 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 2703 2704 RefPtr<RegisterID> privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get()); 2705 generator.emitCheckPrivateBrand(base.get(), privateBrandSymbol.get()); 2706 2707 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 2708 generator.emitThrowTypeError("Trying to access an undefined private setter"); 2709 return generator.move(dst, propDst.get()); 2710 } 2711 2529 2712 Variable var = generator.variable(ident); 2530 2713 RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var); 2531 RefPtr<RegisterID> privateName = generator.newTemporary(); 2532 generator.emitGetFromScope(privateName.get(), scope.get(), var, DoNotThrowIfNotFound); 2533 2534 value = generator.emitGetPrivateName(propDst.get(), base.get(), privateName.get()); 2714 2715 RefPtr<RegisterID> privateBrandSymbol = generator.emitGetPrivateBrand(generator.newTemporary(), scope.get()); 2716 generator.emitCheckPrivateBrand(base.get(), privateBrandSymbol.get()); 2717 2718 if (privateTraits.isGetter()) { 2719 RefPtr<RegisterID> getterSetterObj = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound); 2720 RefPtr<RegisterID> getterFunction = generator.emitDirectGetById(generator.newTemporary(), getterSetterObj.get(), generator.propertyNames().builtinNames().getPrivateName()); 2721 CallArguments args(generator, nullptr); 2722 generator.move(args.thisRegister(), base.get()); 2723 value = generator.emitCall(propDst.get(), getterFunction.get(), NoExpectedFunction, args, m_position, m_position, m_position, DebuggableCall::Yes); 2724 } else { 2725 generator.emitThrowTypeError("Trying to access an undefined private getter"); 2726 return generator.move(dst, propDst.get()); 2727 } 2728 2535 2729 emitIncOrDec(generator, value, m_operator); 2536 2730 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 2537 generator.emitPrivateFieldPut(base.get(), privateName.get(), value); 2538 generator.emitProfileType(value, divotStart(), divotEnd()); 2731 2732 if (privateTraits.isSetter()) { 2733 RefPtr<RegisterID> getterSetterObj = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound); 2734 RefPtr<RegisterID> setterFunction = generator.emitDirectGetById(generator.newTemporary(), getterSetterObj.get(), generator.propertyNames().builtinNames().setPrivateName()); 2735 CallArguments args(generator, nullptr, 1); 2736 generator.move(args.thisRegister(), base.get()); 2737 generator.move(args.argumentRegister(0), value); 2738 generator.emitCall(generator.newTemporary(), setterFunction.get(), NoExpectedFunction, args, m_position, m_position, m_position, DebuggableCall::Yes); 2739 generator.emitProfileType(value, divotStart(), divotEnd()); 2740 return generator.move(dst, propDst.get()); 2741 } 2742 2743 generator.emitThrowTypeError("Trying to access an undefined private getter"); 2539 2744 return generator.move(dst, propDst.get()); 2540 2745 }
Note:
See TracChangeset
for help on using the changeset viewer.