static inline AbstractQoreNode* crlr_fcall_copy(const FunctionCallNode* n, ExceptionSink* xsink) { QoreListNode* na = const_cast<QoreListNode*>(n->getArgs()); if (na) na = crlr_list_copy(na, xsink); return new FunctionCallNode(n->getFunction(), na, n->getProgram()); }
static inline AbstractQoreNode* crlr_selfcall_copy(const SelfFunctionCallNode* n, ExceptionSink* xsink) { QoreListNode* na = const_cast<QoreListNode*>(n->getArgs()); if (na) na = crlr_list_copy(na, xsink); return new SelfFunctionCallNode(*n, na); }
static inline AbstractQoreNode* crlr_smcall_copy(const StaticMethodCallNode* m, ExceptionSink* xsink) { QoreListNode* args = const_cast<QoreListNode*>(m->getArgs()); //printd(5, "crlr_mcall_copy() m: %p (%s) args: %p (len: %d)\n", m, m->getName(), args, args ? args->size() : 0); if (args) { ReferenceHolder<QoreListNode> args_holder(crlr_list_copy(args, xsink), xsink); if (*xsink) return 0; args = args_holder.release(); } return new StaticMethodCallNode(m->getMethod(), args); }
AbstractQoreNode* copy_and_resolve_lvar_refs(const AbstractQoreNode* n, ExceptionSink* xsink) { if (!n) return 0; qore_type_t ntype = n->getType(); if (ntype == NT_LIST) return crlr_list_copy(reinterpret_cast<const QoreListNode*>(n), xsink); if (ntype == NT_HASH) return crlr_hash_copy(reinterpret_cast<const QoreHashNode*>(n), xsink); if (ntype == NT_TREE) return crlr_tree_copy(reinterpret_cast<const QoreTreeNode*>(n), xsink); if (ntype == NT_OPERATOR) return reinterpret_cast<const QoreOperatorNode*>(n)->copyBackground(xsink); if (ntype == NT_SELF_CALL) return crlr_selfcall_copy(reinterpret_cast<const SelfFunctionCallNode*>(n), xsink); if (ntype == NT_FUNCTION_CALL || ntype == NT_PROGRAM_FUNC_CALL) return crlr_fcall_copy(reinterpret_cast<const FunctionCallNode*>(n), xsink); // must make sure to return a value here or it could cause a segfault - parse expressions expect non-NULL values for the operands if (ntype == NT_FIND) return eval_notnull(n, xsink); if (ntype == NT_VARREF && reinterpret_cast<const VarRefNode*>(n)->getType() != VT_GLOBAL) return eval_notnull(n, xsink); if (ntype == NT_FUNCREFCALL) return call_ref_call_copy(reinterpret_cast<const CallReferenceCallNode*>(n), xsink); if (ntype == NT_METHOD_CALL) return crlr_mcall_copy(reinterpret_cast<const MethodCallNode*>(n), xsink); if (ntype == NT_STATIC_METHOD_CALL) return crlr_smcall_copy(reinterpret_cast<const StaticMethodCallNode*>(n), xsink); if (ntype == NT_PARSEREFERENCE) return reinterpret_cast<const ParseReferenceNode*>(n)->evalToIntermediate(xsink); // ensure closures are evaluated in the parent thread so closure-bound local vars can be found and bound before // launching the background thread (fixes https://github.com/qorelanguage/qore/issues/12) if (ntype == NT_CLOSURE) return reinterpret_cast<const QoreClosureParseNode*>(n)->evalBackground(xsink); assert(ntype != NT_VALUE_LIST); return n->refSelf(); }
static AbstractQoreNode* call_ref_call_copy(const CallReferenceCallNode* n, ExceptionSink* xsink) { ReferenceHolder<AbstractQoreNode> exp(copy_and_resolve_lvar_refs(n->getExp(), xsink), xsink); if (*xsink) return 0; QoreListNode* args = const_cast<QoreListNode*>(n->getArgs()); if (args) { ReferenceHolder<QoreListNode> args_holder(crlr_list_copy(args, xsink), xsink); if (*xsink) return 0; args = args_holder.release(); } return new CallReferenceCallNode(exp.release(), args); }
AbstractQoreNode* copy_and_resolve_lvar_refs(const AbstractQoreNode* n, ExceptionSink* xsink) { if (!n) return 0; qore_type_t ntype = n->getType(); if (ntype == NT_LIST) return crlr_list_copy(reinterpret_cast<const QoreListNode*>(n), xsink); if (ntype == NT_HASH) return crlr_hash_copy(reinterpret_cast<const QoreHashNode*>(n), xsink); if (ntype == NT_TREE) return crlr_tree_copy(reinterpret_cast<const QoreTreeNode*>(n), xsink); if (ntype == NT_OPERATOR) return reinterpret_cast<const QoreOperatorNode*>(n)->copyBackground(xsink); else if (ntype == NT_SELF_CALL) return crlr_selfcall_copy(reinterpret_cast<const SelfFunctionCallNode*>(n), xsink); else if (ntype == NT_FUNCTION_CALL || ntype == NT_PROGRAM_FUNC_CALL) return crlr_fcall_copy(reinterpret_cast<const FunctionCallNode*>(n), xsink); // must make sure to return a value here or it could cause a segfault - parse expressions expect non-NULL values for the operands else if (ntype == NT_FIND) return eval_notnull(n, xsink); else if (ntype == NT_VARREF && reinterpret_cast<const VarRefNode*>(n)->getType() != VT_GLOBAL) return eval_notnull(n, xsink); else if (ntype == NT_FUNCREFCALL) return call_ref_call_copy(reinterpret_cast<const CallReferenceCallNode*>(n), xsink); else if (ntype == NT_METHOD_CALL) return crlr_mcall_copy(reinterpret_cast<const MethodCallNode*>(n), xsink); else if (ntype == NT_STATIC_METHOD_CALL) return crlr_smcall_copy(reinterpret_cast<const StaticMethodCallNode*>(n), xsink); else if (ntype == NT_PARSEREFERENCE) return reinterpret_cast<const ParseReferenceNode*>(n)->evalToIntermediate(xsink); return n->refSelf(); }
static inline AbstractQoreNode* crlr_selfcall_copy(const SelfFunctionCallNode* n, ExceptionSink* xsink) { QoreListNode* na = n->getArgs() ? crlr_list_copy(n->getArgs(), xsink) : 0; return new SelfFunctionCallNode(*n, na); }