Changeset 282385 in webkit
- Timestamp:
- Sep 14, 2021 3:13:23 AM (3 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r282336 r282385 1 2021-09-14 Xan López <xan@igalia.com> 2 3 [JSC] ASSERT failed in stress/for-in-tests.js (32bit) 4 https://bugs.webkit.org/show_bug.cgi?id=229543 5 6 Reviewed by Yusuke Suzuki. 7 8 Since r280760 DFG::SpeculativeJIT::compileEnumeratorGetByVal uses 9 too many registers for 32bit. Revert to the slow path as a 10 temporary measure to avoid crashes, we'll try to reenable the 11 optimizations later on (see bug #230189). 12 13 * dfg/DFGOperations.cpp: 14 (JSC::DFG::JSC_DEFINE_JIT_OPERATION): define a generic call 15 operation for compileEnumeratorGetByVal. 16 * dfg/DFGOperations.h: 17 * dfg/DFGSpeculativeJIT.cpp: move the current version of 18 compileEnumeratorGetByVal to 64bit, since it won't work on 32bit. 19 * dfg/DFGSpeculativeJIT32_64.cpp: 20 (JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal): call the generic call op always. 21 * dfg/DFGSpeculativeJIT64.cpp: 22 (JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal): use the previous version here. 23 * runtime/CommonSlowPaths.cpp: 24 (JSC::JSC_DEFINE_COMMON_SLOW_PATH): refactor a bit the slow path 25 for enumeratorGetByVal so it can be called from DFG as a call 26 operation. 27 * runtime/CommonSlowPaths.h: 28 (JSC::CommonSlowPaths::opEnumeratorGetByVal): 29 1 30 2021-09-13 Xan López <xan@igalia.com> 2 31 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r282014 r282385 2539 2539 } 2540 2540 2541 JSC_DEFINE_JIT_OPERATION(operationEnumeratorGetByValGeneric, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* baseCell, EncodedJSValue propertyNameValue, uint32_t index, int32_t modeNumber, JSPropertyNameEnumerator* enumerator)) 2542 { 2543 VM& vm = globalObject->vm(); 2544 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 2545 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2546 auto scope = DECLARE_THROW_SCOPE(vm); 2547 2548 JSValue property = JSValue::decode(propertyNameValue); 2549 JSPropertyNameEnumerator::Flag mode = static_cast<JSPropertyNameEnumerator::Flag>(modeNumber); 2550 RELEASE_AND_RETURN(scope, JSValue::encode(CommonSlowPaths::opEnumeratorGetByVal(globalObject, baseCell, property, index, mode, enumerator))); 2551 } 2552 2541 2553 JSC_DEFINE_JIT_OPERATION(operationEnumeratorHasOwnProperty, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue baseValue, EncodedJSValue propertyNameValue, uint32_t index, int32_t modeNumber)) 2542 2554 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r280760 r282385 113 113 JSC_DECLARE_JIT_OPERATION(operationEnumeratorHasOwnProperty, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, EncodedJSValue, uint32_t, int32_t)); 114 114 JSC_DECLARE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject*, JSCell*, uint32_t, JSPropertyNameEnumerator*)); 115 JSC_DECLARE_JIT_OPERATION(operationEnumeratorGetByValGeneric, EncodedJSValue, (JSGlobalObject*, JSCell*, EncodedJSValue, uint32_t, int32_t, JSPropertyNameEnumerator*)); 115 116 116 117 JSC_DECLARE_JIT_OPERATION(operationNewRegexpWithLastIndex, JSCell*, (JSGlobalObject*, JSCell*, EncodedJSValue)); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r282336 r282385 13688 13688 } 13689 13689 13690 void SpeculativeJIT::compileEnumeratorGetByVal(Node* node)13691 {13692 Edge baseEdge = m_graph.varArgChild(node, 0);13693 auto generate = [&] (GPRReg baseCellGPR) {13694 MacroAssembler::JumpList doneCases;13695 JSValueRegsTemporary result;13696 JSValueRegs resultRegs;13697 GPRReg indexGPR;13698 GPRReg enumeratorGPR;13699 MacroAssembler::Jump badStructureSlowPath;13700 13701 compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat)>([&] (DataFormat) {13702 Edge storageEdge = m_graph.varArgChild(node, 2);13703 StorageOperand storage;13704 if (storageEdge)13705 storage.emplace(this, storageEdge);13706 SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 3));13707 SpeculateStrictInt32Operand mode(this, m_graph.varArgChild(node, 4));13708 SpeculateCellOperand enumerator(this, m_graph.varArgChild(node, 5));13709 13710 GPRReg modeGPR = mode.gpr();13711 indexGPR = index.gpr();13712 enumeratorGPR = enumerator.gpr();13713 13714 result = JSValueRegsTemporary(this);13715 resultRegs = result.regs();13716 GPRReg scratchGPR = resultRegs.payloadGPR();13717 13718 bool haveStorage = !!storageEdge;13719 GPRTemporary storageTemporary;13720 GPRReg storageGPR;13721 if (!haveStorage) {13722 storageTemporary = GPRTemporary(this, Reuse, enumerator);13723 storageGPR = storageTemporary.gpr();13724 } else13725 storageGPR = storage.gpr();13726 13727 MacroAssembler::JumpList notFastNamedCases;13728 13729 // FIXME: We shouldn't generate this code if we know base is not an object.13730 notFastNamedCases.append(m_jit.branchTest32(MacroAssembler::NonZero, modeGPR, TrustedImm32(JSPropertyNameEnumerator::IndexedMode | JSPropertyNameEnumerator::GenericMode)));13731 {13732 if (!m_state.forNode(baseEdge).isType(SpecCell))13733 notFastNamedCases.append(m_jit.branchIfNotCell(baseCellGPR));13734 13735 // Check the structure13736 // FIXME: If we know there's only one structure for base we can just embed it here.13737 m_jit.load32(MacroAssembler::Address(baseCellGPR, JSCell::structureIDOffset()), scratchGPR);13738 13739 auto badStructure = m_jit.branch32(13740 MacroAssembler::NotEqual,13741 scratchGPR,13742 MacroAssembler::Address(13743 enumeratorGPR, JSPropertyNameEnumerator::cachedStructureIDOffset()));13744 13745 // FIXME: Maybe we should have a better way to represent Indexed+Named?13746 if (m_graph.varArgChild(node, 1).node() == m_graph.varArgChild(node, 3).node())13747 badStructureSlowPath = badStructure;13748 else13749 notFastNamedCases.append(badStructure);13750 13751 // Compute the offset13752 // If index is less than the enumerator's cached inline storage, then it's an inline access13753 MacroAssembler::Jump outOfLineAccess = m_jit.branch32(MacroAssembler::AboveOrEqual,13754 indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()));13755 13756 m_jit.loadValue(MacroAssembler::BaseIndex(baseCellGPR, indexGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage()), resultRegs);13757 13758 doneCases.append(m_jit.jump());13759 13760 // Otherwise it's out of line13761 outOfLineAccess.link(&m_jit);13762 m_jit.move(indexGPR, scratchGPR);13763 m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratchGPR);13764 m_jit.neg32(scratchGPR);13765 m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);13766 if (!haveStorage)13767 m_jit.loadPtr(MacroAssembler::Address(baseCellGPR, JSObject::butterflyOffset()), storageGPR);13768 constexpr intptr_t offsetOfFirstProperty = offsetInButterfly(firstOutOfLineOffset) * static_cast<intptr_t>(sizeof(EncodedJSValue));13769 m_jit.loadValue(MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty), resultRegs);13770 doneCases.append(m_jit.jump());13771 }13772 13773 notFastNamedCases.link(&m_jit);13774 return std::make_pair(resultRegs, DataFormatJS);13775 }));13776 13777 // We rely on compileGetByVal to call jsValueResult for us.13778 // FIXME: This is kinda hacky...13779 ASSERT(generationInfo(node).jsValueRegs() == resultRegs && generationInfo(node).registerFormat() == DataFormatJS);13780 13781 if (badStructureSlowPath.isSet())13782 addSlowPathGenerator(slowPathCall(badStructureSlowPath, this, operationEnumeratorRecoverNameAndGetByVal, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseCellGPR, indexGPR, enumeratorGPR));13783 13784 doneCases.link(&m_jit);13785 };13786 13787 if (isCell(baseEdge.useKind())) {13788 // Use manual operand speculation since Fixup may have picked a UseKind more restrictive than CellUse.13789 speculate(node, baseEdge);13790 SpeculateCellOperand baseOperand(this, baseEdge, ManualOperandSpeculation);13791 generate(baseOperand.gpr());13792 } else {13793 JSValueOperand baseOperand(this, baseEdge);13794 generate(baseOperand.gpr());13795 }13796 }13797 13798 13690 template<typename SlowPathFunctionType> 13799 13691 void SpeculativeJIT::compileEnumeratorHasProperty(Node* node, SlowPathFunctionType slowPathFunction) -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r281684 r282385 4481 4481 } 4482 4482 4483 // FIXME: we are always taking the slow path here, we should be able to do the equivalent to the 64bit version if we add more available (callee-save registers) to ARMv7 and/or if we reduce the number of registers compileEnumeratorGetByVal uses. See bug #230189. 4484 void SpeculativeJIT::compileEnumeratorGetByVal(Node* node) 4485 { 4486 SpeculateCellOperand baseOperand(this, m_graph.varArgChild(node, 0)); 4487 JSValueOperand property(this, m_graph.varArgChild(node, 1)); 4488 SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 3)); 4489 SpeculateStrictInt32Operand mode(this, m_graph.varArgChild(node, 4)); 4490 SpeculateCellOperand enumerator(this, m_graph.varArgChild(node, 5)); 4491 GPRReg baseOperandGPR = baseOperand.gpr(); 4492 JSValueRegs propertyRegs = property.jsValueRegs(); 4493 GPRReg indexGPR = index.gpr(); 4494 GPRReg modeGPR = mode.gpr(); 4495 GPRReg enumeratorGPR = enumerator.gpr(); 4496 4497 flushRegisters(); 4498 4499 JSValueRegsFlushedCallResult result(this); 4500 JSValueRegs resultRegs = result.regs(); 4501 4502 callOperation(operationEnumeratorGetByValGeneric, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseOperandGPR, propertyRegs, indexGPR, modeGPR, enumeratorGPR); 4503 m_jit.exceptionCheck(); 4504 jsValueResult(resultRegs, node); 4505 } 4483 4506 #endif 4484 4507 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r282200 r282385 6353 6353 } 6354 6354 6355 void SpeculativeJIT::compileEnumeratorGetByVal(Node* node) 6356 { 6357 Edge baseEdge = m_graph.varArgChild(node, 0); 6358 auto generate = [&] (GPRReg baseCellGPR) { 6359 MacroAssembler::JumpList doneCases; 6360 JSValueRegsTemporary result; 6361 JSValueRegs resultRegs; 6362 GPRReg indexGPR; 6363 GPRReg enumeratorGPR; 6364 MacroAssembler::Jump badStructureSlowPath; 6365 6366 compileGetByVal(node, scopedLambda<std::tuple<JSValueRegs, DataFormat>(DataFormat)>([&] (DataFormat) { 6367 Edge storageEdge = m_graph.varArgChild(node, 2); 6368 StorageOperand storage; 6369 if (storageEdge) 6370 storage.emplace(this, storageEdge); 6371 SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 3)); 6372 SpeculateStrictInt32Operand mode(this, m_graph.varArgChild(node, 4)); 6373 SpeculateCellOperand enumerator(this, m_graph.varArgChild(node, 5)); 6374 6375 GPRReg modeGPR = mode.gpr(); 6376 indexGPR = index.gpr(); 6377 enumeratorGPR = enumerator.gpr(); 6378 6379 result = JSValueRegsTemporary(this); 6380 resultRegs = result.regs(); 6381 GPRReg scratchGPR = resultRegs.payloadGPR(); 6382 6383 bool haveStorage = !!storageEdge; 6384 GPRTemporary storageTemporary; 6385 GPRReg storageGPR; 6386 if (!haveStorage) { 6387 storageTemporary = GPRTemporary(this, Reuse, enumerator); 6388 storageGPR = storageTemporary.gpr(); 6389 } else 6390 storageGPR = storage.gpr(); 6391 6392 MacroAssembler::JumpList notFastNamedCases; 6393 6394 // FIXME: We shouldn't generate this code if we know base is not an object. 6395 notFastNamedCases.append(m_jit.branchTest32(MacroAssembler::NonZero, modeGPR, TrustedImm32(JSPropertyNameEnumerator::IndexedMode | JSPropertyNameEnumerator::GenericMode))); 6396 { 6397 if (!m_state.forNode(baseEdge).isType(SpecCell)) 6398 notFastNamedCases.append(m_jit.branchIfNotCell(baseCellGPR)); 6399 6400 // Check the structure 6401 // FIXME: If we know there's only one structure for base we can just embed it here. 6402 m_jit.load32(MacroAssembler::Address(baseCellGPR, JSCell::structureIDOffset()), scratchGPR); 6403 6404 auto badStructure = m_jit.branch32( 6405 MacroAssembler::NotEqual, 6406 scratchGPR, 6407 MacroAssembler::Address( 6408 enumeratorGPR, JSPropertyNameEnumerator::cachedStructureIDOffset())); 6409 6410 // FIXME: Maybe we should have a better way to represent Indexed+Named? 6411 if (m_graph.varArgChild(node, 1).node() == m_graph.varArgChild(node, 3).node()) 6412 badStructureSlowPath = badStructure; 6413 else 6414 notFastNamedCases.append(badStructure); 6415 6416 // Compute the offset 6417 // If index is less than the enumerator's cached inline storage, then it's an inline access 6418 MacroAssembler::Jump outOfLineAccess = m_jit.branch32(MacroAssembler::AboveOrEqual, 6419 indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset())); 6420 6421 m_jit.loadValue(MacroAssembler::BaseIndex(baseCellGPR, indexGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage()), resultRegs); 6422 6423 doneCases.append(m_jit.jump()); 6424 6425 // Otherwise it's out of line 6426 outOfLineAccess.link(&m_jit); 6427 m_jit.move(indexGPR, scratchGPR); 6428 m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratchGPR); 6429 m_jit.neg32(scratchGPR); 6430 m_jit.signExtend32ToPtr(scratchGPR, scratchGPR); 6431 if (!haveStorage) 6432 m_jit.loadPtr(MacroAssembler::Address(baseCellGPR, JSObject::butterflyOffset()), storageGPR); 6433 constexpr intptr_t offsetOfFirstProperty = offsetInButterfly(firstOutOfLineOffset) * static_cast<intptr_t>(sizeof(EncodedJSValue)); 6434 m_jit.loadValue(MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty), resultRegs); 6435 doneCases.append(m_jit.jump()); 6436 } 6437 6438 notFastNamedCases.link(&m_jit); 6439 return std::make_pair(resultRegs, DataFormatJS); 6440 })); 6441 6442 // We rely on compileGetByVal to call jsValueResult for us. 6443 // FIXME: This is kinda hacky... 6444 ASSERT(generationInfo(node).jsValueRegs() == resultRegs && generationInfo(node).registerFormat() == DataFormatJS); 6445 6446 if (badStructureSlowPath.isSet()) 6447 addSlowPathGenerator(slowPathCall(badStructureSlowPath, this, operationEnumeratorRecoverNameAndGetByVal, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseCellGPR, indexGPR, enumeratorGPR)); 6448 6449 doneCases.link(&m_jit); 6450 }; 6451 6452 if (isCell(baseEdge.useKind())) { 6453 // Use manual operand speculation since Fixup may have picked a UseKind more restrictive than CellUse. 6454 speculate(node, baseEdge); 6455 SpeculateCellOperand baseOperand(this, baseEdge, ManualOperandSpeculation); 6456 generate(baseOperand.gpr()); 6457 } else { 6458 JSValueOperand baseOperand(this, baseEdge); 6459 generate(baseOperand.gpr()); 6460 } 6461 } 6462 6355 6463 #endif 6356 6464 -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r282014 r282385 1011 1011 auto bytecode = pc->as<OpEnumeratorGetByVal>(); 1012 1012 JSValue baseValue = GET_C(bytecode.m_base).jsValue(); 1013 JSValue propertyName = GET(bytecode.m_propertyName).jsValue(); 1013 1014 auto& metadata = bytecode.metadata(codeBlock); 1014 1015 auto mode = static_cast<JSPropertyNameEnumerator::Flag>(GET(bytecode.m_mode).jsValue().asUInt32()); 1015 1016 metadata.m_enumeratorMetadata |= static_cast<uint8_t>(mode); 1016 1017 1017 JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(GET(bytecode.m_enumerator).jsValue()); 1018 1018 unsigned index = GET(bytecode.m_index).jsValue().asInt32(); 1019 switch (mode) { 1020 case JSPropertyNameEnumerator::IndexedMode: { 1021 if (LIKELY(baseValue.isCell())) 1022 metadata.m_arrayProfile.observeStructureID(baseValue.asCell()->structureID()); 1023 RETURN_PROFILED(baseValue.get(globalObject, static_cast<unsigned>(index))); 1024 } 1025 case JSPropertyNameEnumerator::OwnStructureMode: { 1026 if (LIKELY(baseValue.isCell()) && baseValue.asCell()->structureID() == enumerator->cachedStructureID()) { 1027 // We'll only match the structure ID if the base is an object. 1028 ASSERT(index < enumerator->endStructurePropertyIndex()); 1029 RETURN_PROFILED(baseValue.getObject()->getDirect(index < enumerator->cachedInlineCapacity() ? index : index - enumerator->cachedInlineCapacity() + firstOutOfLineOffset)); 1030 } else 1031 metadata.m_enumeratorMetadata |= static_cast<uint8_t>(JSPropertyNameEnumerator::HasSeenOwnStructureModeStructureMismatch); 1032 FALLTHROUGH; 1033 } 1034 1035 case JSPropertyNameEnumerator::GenericMode: { 1036 if (baseValue.isCell() && mode != JSPropertyNameEnumerator::OwnStructureMode) 1037 metadata.m_arrayProfile.observeStructureID(baseValue.asCell()->structureID()); 1038 JSString* string = asString(GET(bytecode.m_propertyName).jsValue()); 1039 auto propertyName = string->toIdentifier(globalObject); 1040 CHECK_EXCEPTION(); 1041 RETURN_PROFILED(baseValue.get(globalObject, propertyName)); 1042 } 1043 1044 default: 1045 RELEASE_ASSERT_NOT_REACHED(); 1046 break; 1047 }; 1048 RELEASE_ASSERT_NOT_REACHED(); 1019 1020 RETURN_PROFILED(CommonSlowPaths::opEnumeratorGetByVal(globalObject, baseValue, propertyName, index, mode, enumerator, &metadata.m_arrayProfile, &metadata.m_enumeratorMetadata)); 1049 1021 } 1050 1022 -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h
r281910 r282385 32 32 #include "FunctionCodeBlock.h" 33 33 #include "JSImmutableButterfly.h" 34 #include "JSPropertyNameEnumerator.h" 34 35 #include "ScopedArguments.h" 35 36 #include "SlowPathFunction.h" … … 90 91 return -1; 91 92 return padding; 93 } 94 95 inline JSValue opEnumeratorGetByVal(JSGlobalObject* globalObject, JSValue baseValue, JSValue propertyNameValue, unsigned index, JSPropertyNameEnumerator::Flag mode, JSPropertyNameEnumerator* enumerator, ArrayProfile* arrayProfile = nullptr, uint8_t* enumeratorMetadata = nullptr) 96 { 97 VM& vm = getVM(globalObject); 98 auto scope = DECLARE_THROW_SCOPE(vm); 99 100 switch (mode) { 101 case JSPropertyNameEnumerator::IndexedMode: { 102 if (arrayProfile && LIKELY(baseValue.isCell())) 103 arrayProfile->observeStructureID(baseValue.asCell()->structureID()); 104 RELEASE_AND_RETURN(scope, baseValue.get(globalObject, static_cast<unsigned>(index))); 105 } 106 case JSPropertyNameEnumerator::OwnStructureMode: { 107 if (LIKELY(baseValue.isCell()) && baseValue.asCell()->structureID() == enumerator->cachedStructureID()) { 108 // We'll only match the structure ID if the base is an object. 109 ASSERT(index < enumerator->endStructurePropertyIndex()); 110 RELEASE_AND_RETURN(scope, baseValue.getObject()->getDirect(index < enumerator->cachedInlineCapacity() ? index : index - enumerator->cachedInlineCapacity() + firstOutOfLineOffset)); 111 } else { 112 if (enumeratorMetadata) 113 *enumeratorMetadata |= static_cast<uint8_t>(JSPropertyNameEnumerator::HasSeenOwnStructureModeStructureMismatch); 114 } 115 FALLTHROUGH; 116 } 117 118 case JSPropertyNameEnumerator::GenericMode: { 119 if (arrayProfile && baseValue.isCell() && mode != JSPropertyNameEnumerator::OwnStructureMode) 120 arrayProfile->observeStructureID(baseValue.asCell()->structureID()); 121 #if USE(JSVALUE32_64) 122 if (!propertyNameValue.isCell()) { 123 // This branch is only needed because we use this method 124 // both as a slow_path and as a DFG call op. We'll end up 125 // here if propertyName is not a cell then we are in 126 // index+named mode, so do what RecoverNameAndGetVal 127 // does. This can probably be removed if we re-enable the 128 // optimizations for enumeratorGetByVal in DFG, see bug 129 // #230189. 130 JSString* string = enumerator->propertyNameAtIndex(index); 131 auto propertyName = string->toIdentifier(globalObject); 132 RETURN_IF_EXCEPTION(scope, { }); 133 RELEASE_AND_RETURN(scope, baseValue.get(globalObject, propertyName)); 134 } 135 #endif 136 JSString* string = asString(propertyNameValue); 137 auto propertyName = string->toIdentifier(globalObject); 138 RETURN_IF_EXCEPTION(scope, { }); 139 RELEASE_AND_RETURN(scope, baseValue.get(globalObject, propertyName)); 140 } 141 142 default: 143 RELEASE_ASSERT_NOT_REACHED(); 144 break; 145 }; 146 RELEASE_ASSERT_NOT_REACHED(); 92 147 } 93 148
Note: See TracChangeset
for help on using the changeset viewer.