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(); }
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(); }