Skip to content

Commit 9af5430

Browse files
author
Andres Madrid Ucha
committed
CheerpWriter: changed checkDefined to checkTrue
The previous logic of checkDefined was causing issues when compiling with the no-optimization flag together with -cheep-bounds-check. Instead of checking if a value is undefined and throwing an error, it is better to check if the member of a struct exists.
1 parent 44276c1 commit 9af5430

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

llvm/include/llvm/Cheerp/Writer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,11 +750,11 @@ class CheerpWriter final : public CheerpBaseWriter
750750
/**
751751
* Compile a function to assure a GEP property access is defined
752752
*/
753-
void compileCheckDefined(const llvm::Value* p, bool needsOffset);
753+
void compileCheckTrue(const llvm::Value* p, bool needsOffset);
754754
/**
755755
* Compile a function for checking if a reference is defined
756756
*/
757-
void compileCheckDefinedHelper();
757+
void compileCheckTrueHelper();
758758
/**
759759
* Compile a JS string while escaping special characters
760760
*/

llvm/lib/CheerpWriter/CheerpWriter.cpp

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

62766298
void 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

Comments
 (0)