void insert(const QStringList &path, BranchNode *n) { BranchNode *current = this; for (int i = 0; i < path.count(); ++i) { BranchNode *c = current->childOfName(path.at(i)); if (c) current = c; else current = current->append(new BranchNode(path.at(i))); } current->append(n); }
Expr* PrimInliner::genCall(bool canFail) { // standard primitive call // // Note: If a primitive fails, it will return a marked symbol. One has to make sure that // this marked symbol is *never* stored on the stack but only kept in registers // (otherwise GC won't work correctly). Here this is established by using the dst() // of a pcall only which is pre-allocated to the result_reg. MergeNode* nlrTestPoint = _pdesc->can_perform_NLR() ? _scope->nlrTestPoint() : NULL; GrowableArray<PReg*>* args = _gen->pass_arguments(NULL, _pdesc->number_of_parameters()); GrowableArray<PReg*>* exprStack = _pdesc->can_walk_stack() ? _gen->copyCurrentExprStack() : NULL; PrimNode* pcall = NodeFactory::new_PrimNode(_pdesc, nlrTestPoint, args, exprStack); _gen->append(pcall); BranchNode* branch = NULL; if (_failure_block != NULL && canFail) { // primitive with failure block; failed if Mark_Tag_Bit is set in result -> add a branch node here _gen->append(NodeFactory::new_ArithRCNode(new NoPReg(_scope), pcall->dest(), TestArithOp, Mark_Tag_Bit)); branch = NodeFactory::new_BranchNode(NEBranchOp); _gen->append(branch); } // primitive didn't fail (with or without failure block) -> assign to resPReg & determine its expression SAPReg* resPReg = new SAPReg(_scope); _gen->append(NodeFactory::new_AssignNode(pcall->dst(), resPReg)); Node* ok_exit = _gen->_current; Expr* resExpr = _pdesc->return_klass(resPReg, ok_exit); if (resExpr == NULL) resExpr = new UnknownExpr(resPReg, ok_exit); if (branch != NULL) { // add failure block if primitive can fail -> reset Mark_Tag_Bit first SAPReg* errPReg = new SAPReg(_scope); ArithRCNode* failure_exit = NodeFactory::new_ArithRCNode(errPReg, pcall->dst(), AndArithOp, ~Mark_Tag_Bit); branch->append(1, failure_exit); resExpr = merge_failure_block(ok_exit, resExpr, failure_exit, new KlassExpr(Universe::symbolKlassObj(), errPReg, failure_exit), false); } return resExpr; }