@@ -4550,7 +4550,7 @@ void CheerpWriter::compileLoad(const LoadInst& li, PARENT_PRIORITY parentPrio)
45504550 needsCheckBounds = true ;
45514551 bool needsOffset = !li.use_empty () && Ty->isPointerTy () && PA.getPointerKindAssert (&li) == SPLIT_REGULAR && !PA.getConstantOffsetForPointer (&li);
45524552 stream<<" (" ;
4553- compileCheckDefined (ptrOp, needsOffset);
4553+ compileCheckTrue (ptrOp, needsOffset);
45544554 stream<<" ," ;
45554555 }
45564556 }
@@ -4765,7 +4765,7 @@ void CheerpWriter::compileStore(const StoreInst& si)
47654765 else if (ptrKind == COMPLETE_OBJECT && isGEP (ptrOp))
47664766 {
47674767 bool needsOffset = Ty->isPointerTy () && PA.getPointerKindAssert (&si) == SPLIT_REGULAR && !PA.getConstantOffsetForPointer (&si);
4768- compileCheckDefined (ptrOp, needsOffset);
4768+ compileCheckTrue (ptrOp, needsOffset);
47694769 stream<<" ," ;
47704770 }
47714771 }
@@ -6257,20 +6257,42 @@ void CheerpWriter::compileCheckBounds(const Value* p)
62576257 stream<<" )" ;
62586258}
62596259
6260- void CheerpWriter::compileCheckDefinedHelper ()
6260+ void CheerpWriter::compileCheckTrueHelper ()
62616261{
6262- stream << " function checkDefined (m){if(m===undefined ) throw new Error('UndefinedMemberAccess');}" << NewLine;
6262+ stream << " function checkTrue (m){if(!m ) throw new Error('UndefinedMemberAccess');}" << NewLine;
62636263}
62646264
6265- void CheerpWriter::compileCheckDefined (const Value* p, bool needsOffset)
6265+ void CheerpWriter::compileCheckTrue (const Value* p, bool needsOffset)
62666266{
6267- // When compiling a SPIT_REGULAR, if there is an offset, we only check that.
6268- // If the offset exists the base is guaranteed to exists in the type.
6269- stream<<" checkDefined(" ;
6270- compileGEP (cast<User>(p),COMPLETE_OBJECT, HIGHEST);
6271- if (needsOffset)
6272- stream << " o" ;
6273- stream<<" )" ;
6267+ const llvm::User* gep_inst = cast<User>(p);
6268+ SmallVector< const Value*, 8 > indices (std::next (gep_inst->op_begin ()), gep_inst->op_end ());
6269+ Type* basePointedType = cast<GEPOperator>(gep_inst)->getSourceElementType ();
6270+
6271+ StructType* containerStructType = dyn_cast<StructType>(GetElementPtrInst::getIndexedType (basePointedType,
6272+ makeArrayRef (const_cast <Value* const *>(indices.begin ()),
6273+ const_cast <Value* const *>(indices.end () - 1 ))));
6274+
6275+ if (containerStructType && indices.size () > 1 )
6276+ {
6277+ assert (isa<ConstantInt>(indices.back ()));
6278+ }
6279+
6280+ if (containerStructType) {
6281+ stream << " checkTrue('" ;
6282+ const Value* lastOperand = gep_inst->getOperand (gep_inst->getNumOperands () - 1 );
6283+ const APInt& index = cast<Constant>(lastOperand)->getUniqueInteger ();
6284+ uint64_t idxVal = index.getLimitedValue ();
6285+
6286+ stream << types.getPrefixCharForMember (PA, containerStructType, idxVal) << idxVal;
6287+ if (needsOffset)
6288+ stream << " o" ;
6289+ stream << " ' in " ;
6290+ compileCompleteObject (gep_inst->getOperand (0 ) , indices.front ());
6291+ if (indices.size () > 1 ) {
6292+ compileAccessToElement (basePointedType, makeArrayRef (std::next (indices.begin ()), std::prev (indices.end ())), false );
6293+ }
6294+ stream << " )" ;
6295+ }
62746296}
62756297
62766298void CheerpWriter::compileCheckBoundsAsmJSHelper ()
@@ -6617,7 +6639,7 @@ void CheerpWriter::compileHelpers()
66176639 if ( checkBounds )
66186640 {
66196641 compileCheckBoundsHelper ();
6620- compileCheckDefinedHelper ();
6642+ compileCheckTrueHelper ();
66216643 }
66226644
66236645 compileBuiltins (false );
0 commit comments