Changeset 271121 in webkit for trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
- Timestamp:
- Jan 2, 2021, 12:46:24 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r270874 r271121 5265 5265 const auto& target = m_targetPatterns[i]; 5266 5266 if (target.bindingType == BindingType::Element) { 5267 RefPtr<RegisterID> temp = generator.newTemporary(); 5267 // If the destructuring becomes get_by_id and mov, then we should store results directly to the local's binding. 5268 // From 5269 // get_by_id dst:loc10, base:loc9, property:0 5270 // mov dst:loc6, src:loc10 5271 // To 5272 // get_by_id dst:loc6, base:loc9, property:0 5273 auto writableDirectBindingIfPossible = [&]() -> RegisterID* { 5274 // The following pattern is possible. In that case, after setting |data| local variable, we need to store property name into the set. 5275 // So, old property name |data| result must be kept before setting it into |data|. 5276 // ({ [data]: data, ...obj } = object); 5277 if (m_containsRestElement && m_containsComputedProperty && target.propertyExpression) 5278 return nullptr; 5279 // default value can include a reference to local variable. So filling value to a local variable can differ result. 5280 // We give up fast path if default value includes non constant. 5281 // For example, 5282 // ({ data = data } = object); 5283 if (target.defaultValue && !target.defaultValue->isConstant()) 5284 return nullptr; 5285 return target.pattern->writableDirectBindingIfPossible(generator); 5286 }; 5287 5288 auto finishDirectBindingAssignment = [&]() { 5289 ASSERT(writableDirectBindingIfPossible()); 5290 target.pattern->finishDirectBindingAssignment(generator); 5291 }; 5292 5293 RefPtr<RegisterID> temp; 5294 RegisterID* directBinding = writableDirectBindingIfPossible(); 5295 if (directBinding) 5296 temp = directBinding; 5297 else 5298 temp = generator.newTemporary(); 5299 5268 5300 RefPtr<RegisterID> propertyName; 5269 5301 if (!target.propertyExpression) { … … 5297 5329 if (target.defaultValue) 5298 5330 assignDefaultValueIfUndefined(generator, temp.get(), target.defaultValue); 5299 target.pattern->bindValue(generator, temp.get()); 5331 if (directBinding) 5332 finishDirectBindingAssignment(); 5333 else 5334 target.pattern->bindValue(generator, temp.get()); 5300 5335 } else { 5301 5336 ASSERT(target.bindingType == BindingType::RestElement); … … 5332 5367 } 5333 5368 5369 RegisterID* BindingNode::writableDirectBindingIfPossible(BytecodeGenerator& generator) const 5370 { 5371 Variable var = generator.variable(m_boundProperty); 5372 bool isReadOnly = var.isReadOnly() && m_bindingContext != AssignmentContext::ConstDeclarationStatement; 5373 if (RegisterID* local = var.local()) { 5374 if (m_bindingContext == AssignmentContext::AssignmentExpression) { 5375 if (generator.needsTDZCheck(var)) 5376 return nullptr; 5377 } 5378 if (isReadOnly) 5379 return nullptr; 5380 return local; 5381 } 5382 return nullptr; 5383 } 5384 5385 void BindingNode::finishDirectBindingAssignment(BytecodeGenerator& generator) const 5386 { 5387 ASSERT(writableDirectBindingIfPossible(generator)); 5388 Variable var = generator.variable(m_boundProperty); 5389 RegisterID* local = var.local(); 5390 generator.emitProfileType(local, var, divotStart(), divotEnd()); 5391 if (m_bindingContext == AssignmentContext::DeclarationStatement || m_bindingContext == AssignmentContext::ConstDeclarationStatement) 5392 generator.liftTDZCheckIfPossible(var); 5393 } 5394 5334 5395 void BindingNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const 5335 5396 { … … 5374 5435 { 5375 5436 identifiers.append(m_boundProperty); 5437 } 5438 5439 RegisterID* AssignmentElementNode::writableDirectBindingIfPossible(BytecodeGenerator& generator) const 5440 { 5441 if (!m_assignmentTarget->isResolveNode()) 5442 return nullptr; 5443 ResolveNode* lhs = static_cast<ResolveNode*>(m_assignmentTarget); 5444 Variable var = generator.variable(lhs->identifier()); 5445 bool isReadOnly = var.isReadOnly(); 5446 if (RegisterID* local = var.local()) { 5447 if (generator.needsTDZCheck(var)) 5448 return nullptr; 5449 if (isReadOnly) 5450 return nullptr; 5451 return local; 5452 } 5453 return nullptr; 5454 } 5455 5456 void AssignmentElementNode::finishDirectBindingAssignment(BytecodeGenerator& generator) const 5457 { 5458 ASSERT_UNUSED(generator, writableDirectBindingIfPossible(generator)); 5459 ResolveNode* lhs = static_cast<ResolveNode*>(m_assignmentTarget); 5460 Variable var = generator.variable(lhs->identifier()); 5461 RegisterID* local = var.local(); 5462 generator.emitProfileType(local, divotStart(), divotEnd()); 5376 5463 } 5377 5464
Note:
See TracChangeset
for help on using the changeset viewer.