zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #19554
[Merge] lp:~zorba-coders/zorba/hof-next into lp:zorba
Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/hof-next into lp:zorba.
Commit message:
moved function_item.h/cpp and dynamic_fncall_iterator.h/cpp to runtime/hof/ dir
Requested reviews:
Markos Zaharioudakis (markos-za)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/hof-next/+merge/155638
moved function_item.h/cpp and dynamic_fncall_iterator.h/cpp to runtime/hof/ dir
--
https://code.launchpad.net/~zorba-coders/zorba/hof-next/+merge/155638
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/compiler/codegen/plan_visitor.cpp'
--- src/compiler/codegen/plan_visitor.cpp 2013-03-26 22:31:03 +0000
+++ src/compiler/codegen/plan_visitor.cpp 2013-03-26 23:33:23 +0000
@@ -92,9 +92,9 @@
#include "runtime/debug/debug_iterator.h"
#endif
#include "runtime/eval/eval.h"
-#include "runtime/function_item/function_item.h"
+#include "runtime/hof/function_item.h"
#include "runtime/function_item/function_item_iter.h"
-#include "runtime/function_item/dynamic_fncall_iterator.h"
+#include "runtime/hof/dynamic_fncall_iterator.h"
#include "runtime/misc/materialize.h"
#ifdef ZORBA_WITH_DEBUGGER
=== modified file 'src/compiler/expression/function_item_expr.h'
--- src/compiler/expression/function_item_expr.h 2013-03-26 21:26:20 +0000
+++ src/compiler/expression/function_item_expr.h 2013-03-26 23:33:23 +0000
@@ -23,7 +23,7 @@
#include "store/naive/shared_types.h"
-#include "runtime/function_item/function_item.h"
+#include "runtime/hof/function_item.h"
namespace zorba {
@@ -38,7 +38,11 @@
friend class ExprManager;
protected:
- argument_placeholder_expr(CompilerCB* ccb, static_context* sctx, user_function* udf, const QueryLoc& loc)
+ argument_placeholder_expr(
+ CompilerCB* ccb,
+ static_context* sctx,
+ user_function* udf,
+ const QueryLoc& loc)
:
expr(ccb, sctx, udf, loc, argument_placeholder_expr_kind)
{
=== modified file 'src/runtime/CMakeLists.txt'
--- src/runtime/CMakeLists.txt 2013-03-03 15:33:57 +0000
+++ src/runtime/CMakeLists.txt 2013-03-26 23:33:23 +0000
@@ -140,8 +140,8 @@
util/timeout.cpp
util/flowctl_exception.cpp
util/doc_uri_heuristics.cpp
- function_item/function_item.cpp
- function_item/dynamic_fncall_iterator.cpp
+ hof/function_item.cpp
+ hof/dynamic_fncall_iterator.cpp
eval/eval.cpp
collections/collections_base.cpp
misc/materialize.cpp
=== modified file 'src/runtime/core/fncall_iterator.h'
--- src/runtime/core/fncall_iterator.h 2013-03-05 02:20:27 +0000
+++ src/runtime/core/fncall_iterator.h 2013-03-26 23:33:23 +0000
@@ -22,7 +22,7 @@
#include "common/shared_types.h"
-#include "runtime/function_item/function_item.h"
+#include "runtime/hof/function_item.h"
// TODO remove the next three includes
#include "api/unmarshaller.h"
@@ -107,7 +107,11 @@
~UDFunctionCallIteratorState();
- void open(PlanState& planState, user_function* udf, bool theIsDynamic, store::ItemHandle<FunctionItem>& theFunctionItem);
+ void open(
+ PlanState& planState,
+ user_function* udf,
+ bool theIsDynamic,
+ store::ItemHandle<FunctionItem>& theFunctionItem);
void reset(PlanState& planState);
};
=== removed file 'src/runtime/function_item/dynamic_fncall_iterator.cpp'
--- src/runtime/function_item/dynamic_fncall_iterator.cpp 2013-03-23 01:11:00 +0000
+++ src/runtime/function_item/dynamic_fncall_iterator.cpp 1970-01-01 00:00:00 +0000
@@ -1,396 +0,0 @@
-/*
- * Copyright 2006-2008 The FLWOR Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "stdafx.h"
-
-#include "diagnostics/util_macros.h"
-
-#include "runtime/function_item/dynamic_fncall_iterator.h"
-#include "runtime/function_item/function_item.h"
-#include "runtime/core/fncall_iterator.h"
-#include "runtime/api/plan_wrapper.h"
-#include "runtime/api/plan_iterator_wrapper.h"
-#include "runtime/visitors/planiter_visitor.h"
-
-#include "context/dynamic_context.h"
-#include "context/static_context.h"
-
-#include "store/api/item_factory.h"
-#include "store/api/store.h"
-#include "store/api/temp_seq.h"
-
-#include "types/root_typemanager.h"
-#include "types/casting.h"
-#include "types/typeops.h"
-
-#include "system/globalenv.h"
-
-
-namespace zorba
-{
-
-
-SERIALIZABLE_CLASS_VERSIONS(ArgumentPlaceholderIterator)
-
-NOARY_ACCEPT(ArgumentPlaceholderIterator)
-
-SERIALIZABLE_CLASS_VERSIONS(DynamicFnCallIterator)
-
-
-/*******************************************************************************
-
-********************************************************************************/
-DynamicFnCallIteratorState::DynamicFnCallIteratorState()
-{
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-DynamicFnCallIteratorState::~DynamicFnCallIteratorState()
-{
- if (theIsOpen)
- {
- thePlan->close(*thePlanState);
- }
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-void DynamicFnCallIteratorState::init(PlanState& planState)
-{
- PlanIteratorState::init(planState);
- thePlanState = &planState;
- thePlan = NULL;
- theIsOpen = false;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-void DynamicFnCallIteratorState::reset(PlanState& planState)
-{
- PlanIteratorState::reset(planState);
- if (theIsOpen)
- {
- thePlan->reset(planState);
- }
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-void DynamicFnCallIterator::serialize(::zorba::serialization::Archiver& ar)
-{
- serialize_baseclass(ar,
- (NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>*)this);
-
- ar & theDotVarsCount;
- ar & theIsPartialApply;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-uint32_t DynamicFnCallIterator::getStateSizeOfSubtree() const
-{
- uint32_t size = NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>::
- getStateSizeOfSubtree();
-
- return size + sizeof(UDFunctionCallIteratorState);
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-void DynamicFnCallIterator::openImpl(PlanState& planState, uint32_t& offset)
-{
- StateTraitsImpl<DynamicFnCallIteratorState>::
- createState(planState, theStateOffset, offset);
-
- StateTraitsImpl<DynamicFnCallIteratorState>::
- initState(planState, theStateOffset);
-
- DynamicFnCallIteratorState* state =
- StateTraitsImpl<DynamicFnCallIteratorState>::
- getState(planState, theStateOffset);
-
- state->theUDFStateOffset = offset;
-
- offset += sizeof(UDFunctionCallIteratorState);
-
- std::vector<PlanIter_t>::iterator lIter = theChildren.begin();
- std::vector<PlanIter_t>::iterator lEnd = theChildren.end();
- for ( ; lIter != lEnd; ++lIter )
- {
- (*lIter)->open(planState, offset);
- }
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-void DynamicFnCallIterator::resetImpl(PlanState& planState) const
-{
- DynamicFnCallIteratorState* state =
- StateTraitsImpl<DynamicFnCallIteratorState>::
- getState(planState, theStateOffset);
-
- if (state->theIsOpen)
- {
- state->thePlan->close(planState);
- state->theIsOpen = false;
- }
-
- NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>::
- resetImpl(planState);
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-bool DynamicFnCallIterator::nextImpl(
- store::Item_t& result,
- PlanState& planState) const
-{
- store::Item_t item;
- store::Item_t targetItem;
- FunctionItem* fnItem;
-#ifdef ZORBA_WITH_JSON
- store::Item_t selectorItem1;
- store::Item_t selectorItem2;
- store::Item_t selectorItem3;
- bool isObjectNav;
- bool selectorError;
-#endif
-
- TypeManager* tm = theSctx->get_typemanager();
-
- DynamicFnCallIteratorState* state;
-
- DEFAULT_STACK_INIT(DynamicFnCallIteratorState, state, planState);
-
- // first child must return exactly one item which is a function item
- // otherwise XPTY0004 is raised
- if (!consumeNext(targetItem, theChildren[0], planState) || targetItem == NULL)
- {
- RAISE_ERROR(err::XPTY0004, loc,
- ERROR_PARAMS(ZED(XPTY0004_NoTypePromote_23),
- "empty-sequence()",
- GENV_TYPESYSTEM.ANY_FUNCTION_TYPE_ONE->toSchemaString()));
- }
-
- if (targetItem->isFunction())
- {
- if (consumeNext(item, theChildren[0], planState))
- {
- RAISE_ERROR(err::XPTY0004, loc,
- ERROR_PARAMS(ZED(XPTY0004_NoMultiSeqTypePromotion_2),
- GENV_TYPESYSTEM.ANY_FUNCTION_TYPE_ONE->toSchemaString()));
- }
-
- fnItem = static_cast<FunctionItem*>(targetItem.getp());
-
- if ((!fnItem->needsContextItem() &&
- theChildren.size() - 1 - theDotVarsCount != fnItem->getArity())
- ||
- (fnItem->needsContextItem()
- && theChildren.size() - 1 != fnItem->getArity()))
- {
- RAISE_ERROR(err::XPTY0004, loc,
- ERROR_PARAMS("dynamic function invoked with incorrect number of arguments"));
- }
-
- if (theIsPartialApply)
- {
- for (csize i = 1, pos = 0; i < theChildren.size() - theDotVarsCount; ++i)
- {
- if (dynamic_cast<ArgumentPlaceholderIterator*>(theChildren[i].getp()) == NULL)
- {
- // The argument needs to be materialized only for local vars and only
- // if the function item is returned and used outside of the current
- // function. It might be impossible to determine if the partially
- // applied function item will be used outside of the current function,
- // so it is quite probable that it always needs to be materialized.
- std::vector<store::Item_t> argValues;
- store::Item_t tempItem;
-
- while (consumeNext(tempItem, theChildren[i], planState))
- argValues.push_back(tempItem);
-
- store::TempSeq_t argSeq = GENV_STORE.createTempSeq(argValues);
- store::Iterator_t argSeqIter = argSeq->getIterator();
- PlanIter_t value = new PlanStateIteratorWrapper(argSeqIter);
-
- fnItem->setArgumentValue(pos, value);
- }
- else
- pos++;
- }
-
- result = fnItem;
- STACK_PUSH(true, state);
- }
- else
- {
- state->thePlan = fnItem->getImplementation(theChildren, planState.theCompilerCB);
-
- // must be opened after vars and params are set
- state->thePlan->open(planState, state->theUDFStateOffset);
- state->theIsOpen = true;
-
- while (consumeNext(result, state->thePlan, planState))
- {
- STACK_PUSH(true, state);
- }
-
- // need to close here early in case the plan is completely
- // consumed. Otherwise, the plan would still be opened
- // if destroyed from the state's destructor.
- state->thePlan->close(planState);
- state->theIsOpen = false;
- } // if (theIsPartialApply)
-
- } // if (targetItem->isFunction())
-#ifdef ZORBA_WITH_JSON
- else if (targetItem->isJSONObject() || targetItem->isJSONArray())
- {
- if (theChildren.size() - theDotVarsCount > 2)
- {
- RAISE_ERROR_NO_PARAMS(jerr::JNTY0018, loc);
- }
- else if (theChildren.size() - theDotVarsCount == 2)
- {
- isObjectNav = targetItem->isJSONObject();
- selectorError = false;
-
- if (!consumeNext(selectorItem1, theChildren[1], planState))
- {
- selectorError = true;
- }
- else
- {
- try
- {
- if (selectorItem1->isNode())
- {
- store::Iterator_t iter;
-
- selectorItem1->getTypedValue(selectorItem2, iter);
-
- if (iter != NULL)
- {
- if (!iter->next(selectorItem2) || iter->next(item))
- {
- selectorError = true;
- }
- }
- }
- else
- {
- selectorItem2.transfer(selectorItem1);
- }
-
- if (!selectorError)
- {
- if (!selectorItem2->isAtomic())
- {
- selectorError = true;
- }
- else
- {
- store::SchemaTypeCode selectorType =
- (isObjectNav ? store::XS_STRING : store::XS_INTEGER);
-
- GenericCast::castToBuiltinAtomic(selectorItem3,
- selectorItem2,
- selectorType,
- NULL,
- loc);
- selectorError = false;
- }
- }
- }
- catch (...)
- {
- selectorError = true;
- }
- }
-
- if (selectorError)
- {
- item = (selectorItem1 == NULL ? selectorItem2 : selectorItem1);
-
- zstring selectorType = tm->create_value_type(item)->toSchemaString();
-
- RAISE_ERROR(err::XPTY0004, loc,
- ERROR_PARAMS(ZED(XPTY0004_JSONIQ_SELECTOR), selectorType));
- }
-
- if (isObjectNav)
- result = targetItem->getObjectValue(selectorItem3);
- else
- result = targetItem->getArrayValue(selectorItem3->getIntegerValue());
- STACK_PUSH(result != NULL, state);
- }
- else
- {
- if (targetItem->isJSONArray())
- state->theIterator = targetItem->getArrayValues();
- else if (targetItem->isJSONObject())
- state->theIterator = targetItem->getObjectKeys();
-
- state->theIterator->open();
-
- while (state->theIterator->next(result))
- {
- STACK_PUSH(true, state);
- }
-
- state->theIterator->close();
- }
- }
-#endif
- else
- {
- xqtref_t type = tm->create_value_type(targetItem);
-
- RAISE_ERROR(err::XPTY0004, loc,
- ERROR_PARAMS(ZED(XPTY0004_NoTypePromote_23),
- type->toSchemaString(),
- GENV_TYPESYSTEM.ANY_FUNCTION_TYPE_ONE->toSchemaString()));
- }
-
- STACK_END(state);
-};
-
-
-/*******************************************************************************
-
-********************************************************************************/
-NARY_ACCEPT(DynamicFnCallIterator)
-
-
-}//zorba namespace
-/* vim:set et sw=2 ts=2: */
=== removed file 'src/runtime/function_item/dynamic_fncall_iterator.h'
--- src/runtime/function_item/dynamic_fncall_iterator.h 2013-03-22 00:38:18 +0000
+++ src/runtime/function_item/dynamic_fncall_iterator.h 1970-01-01 00:00:00 +0000
@@ -1,141 +0,0 @@
-/*
- * Copyright 2006-2008 The FLWOR Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ZORBA_RUNTIME_DYNAMIC_FNCALL_ITERATOR
-#define ZORBA_RUNTIME_DYNAMIC_FNCALL_ITERATOR
-
-
-#include "common/shared_types.h"
-
-#include "runtime/base/narybase.h"
-
-#include "runtime/base/noarybase.h"
-
-
-namespace zorba
-{
-
-/*******************************************************************************
-
-********************************************************************************/
-class ArgumentPlaceholderIterator: public NoaryBaseIterator<ArgumentPlaceholderIterator,PlanIteratorState>
-{
-public:
- SERIALIZABLE_CLASS(ArgumentPlaceholderIterator);
- SERIALIZABLE_CLASS_CONSTRUCTOR2T(ArgumentPlaceholderIterator,
- NoaryBaseIterator<ArgumentPlaceholderIterator, PlanIteratorState>);
- void serialize( ::zorba::serialization::Archiver& ar)
- {
- serialize_baseclass(ar,
- (NoaryBaseIterator<ArgumentPlaceholderIterator, PlanIteratorState>*)this);
- }
-
-public:
- ArgumentPlaceholderIterator(
- static_context* sctx,
- const QueryLoc& loc)
- :
- NoaryBaseIterator<ArgumentPlaceholderIterator, PlanIteratorState>(sctx, loc)
- {
- }
-
- void accept(PlanIterVisitor& v) const;
-
- bool nextImpl(store::Item_t& result, PlanState& planState) const { return false; };
-};
-
-
-/*******************************************************************************
-
-********************************************************************************/
-class DynamicFnCallIteratorState : public PlanIteratorState
-{
-public:
- PlanState * thePlanState;
- PlanIter_t thePlan;
- bool theIsOpen;
-
- uint32_t theUDFStateOffset;
-
-#ifdef ZORBA_WITH_JSON
- store::Iterator_t theIterator;
-#endif
-
- DynamicFnCallIteratorState();
-
- ~DynamicFnCallIteratorState();
-
- void init(PlanState&);
- void reset(PlanState&);
-};
-
-
-/*******************************************************************************
- The 1st child iterator returns the functionItem obj to invoke. The rest of
- the child iterators compute the args to pass to the invocation.
-********************************************************************************/
-class DynamicFnCallIterator : public NaryBaseIterator<DynamicFnCallIterator,
- DynamicFnCallIteratorState>
-{
-protected:
- // This variable counts the number of children that hold DOT variables. They
- // are placed at the end of the children array.
- unsigned int theDotVarsCount;
- bool theIsPartialApply;
-
-public:
- SERIALIZABLE_CLASS(DynamicFnCallIterator);
-
- SERIALIZABLE_CLASS_CONSTRUCTOR2T(DynamicFnCallIterator,
- NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>);
-
- void serialize( ::zorba::serialization::Archiver& ar);
-
-public:
- DynamicFnCallIterator(
- static_context* sctx,
- const QueryLoc& loc,
- std::vector<PlanIter_t>& args,
- unsigned int dotVarsCount,
- bool isPartialApply,
- xqtref_t coercionTargetType = NULL)
- :
- NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>(sctx, loc, args),
- theDotVarsCount(dotVarsCount),
- theIsPartialApply(isPartialApply)
- {
- }
-
- void accept(PlanIterVisitor& v) const;
-
- uint32_t getStateSizeOfSubtree() const;
-
- void openImpl(PlanState& planState, uint32_t& offset);
-
- bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
-
- void resetImpl(PlanState& planState) const;
-};
-
-
-}
-
-#endif
-/*
- * Local variables:
- * mode: c++
- * End:
- */
-/* vim:set et sw=2 ts=2: */
=== removed file 'src/runtime/function_item/function_item.cpp'
--- src/runtime/function_item/function_item.cpp 2013-03-26 22:31:03 +0000
+++ src/runtime/function_item/function_item.cpp 1970-01-01 00:00:00 +0000
@@ -1,510 +0,0 @@
-/*
- * Copyright 2006-2008 The FLWOR Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "stdafx.h"
-
-// This include needs to be kept in order to make sure the
-// auto_ptr<dynamic_context> manages to dealocate the
-// dynamic_context object.
-#include "context/dynamic_context.h"
-
-#include "runtime/function_item/function_item.h"
-#include "runtime/core/fncall_iterator.h"
-#include "runtime/base/plan_iterator.h"
-#include "runtime/api/plan_iterator_wrapper.h"
-#include "runtime/visitors/planiter_visitor.h"
-
-#include "compiler/api/compilercb.h"
-#include "compiler/expression/var_expr.h"
-#include "compiler/expression/function_item_expr.h"
-#include "compiler/expression/expr_manager.h"
-
-#include "functions/signature.h"
-#include "functions/udf.h"
-
-#include "store/api/temp_seq.h"
-
-#include "zorbaserialization/serialize_template_types.h"
-#include "zorbaserialization/serialize_zorba_types.h"
-
-
-namespace zorba
-{
-
-SERIALIZABLE_CLASS_VERSIONS(FunctionItemInfo)
-
-SERIALIZABLE_CLASS_VERSIONS(FunctionItem)
-
-SERIALIZABLE_CLASS_VERSIONS(FunctionItemIterator)
-
-
-/*******************************************************************************
-
-********************************************************************************/
-FunctionItemInfo::FunctionItemInfo(
- static_context* closureSctx,
- const QueryLoc& loc,
- function* func,
- store::Item_t qname,
- uint32_t arity,
- bool isInline,
- bool needsContextItem,
- bool isCoercion)
- :
- theMustDeleteCCB(false),
- theLoc(loc),
- theClosureSctx(closureSctx),
- theFunction(func),
- theQName(qname),
- theArity(arity),
- theIsInline(isInline),
- theNeedsContextItem(needsContextItem),
- theIsCoercion(isCoercion)
-{
-}
-
-
-FunctionItemInfo::FunctionItemInfo(::zorba::serialization::Archiver& ar)
-{
-}
-
-
-FunctionItemInfo::~FunctionItemInfo()
-{
- if (theMustDeleteCCB)
- delete theCCB;
-}
-
-
-void FunctionItemInfo::serialize(::zorba::serialization::Archiver& ar)
-{
- ar & theCCB;
- ar & theMustDeleteCCB;
- ar & theClosureSctx;
- ar & theLoc;
- ar & theFunction;
- ar & theQName;
- ar & theArity;
- ar & theIsInline;
- ar & theNeedsContextItem;
- ar & theIsCoercion;
-
- // These are not serialized
- // ar & theScopedVarsValues;
- // ar & theSubstVarsValues;
-
- ar & theScopedVarsNames;
- ar & theIsGlobalVar;
- ar & theVarId;
-
- ar & theScopedVarsIterators;
-
- if (ar.is_serializing_out())
- {
- uint32_t planStateSize;
- (void)static_cast<user_function*>(theFunction.getp())->getPlan(planStateSize);
- }
-}
-
-
-void FunctionItemInfo::add_variable(
- expr* var,
- var_expr* substVar,
- const store::Item_t& name,
- int isGlobal)
-{
- theScopedVarsValues.push_back(var);
- theSubstVarsValues.push_back(substVar);
- theScopedVarsNames.push_back(name);
- theIsGlobalVar.push_back(isGlobal);
- theVarId.push_back(0);
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-FunctionItem::FunctionItem(::zorba::serialization::Archiver& ar)
- :
- store::Item(store::Item::FUNCTION)
-{
-}
-
-
-FunctionItem::FunctionItem(
- const FunctionItemInfo_t& dynamicFunctionInfo,
- dynamic_context* dctx)
- :
- store::Item(store::Item::FUNCTION),
- theFunctionItemInfo(dynamicFunctionInfo),
- theArity(dynamicFunctionInfo->theArity),
- theClosureDctx(dctx)
-{
- assert(theFunctionItemInfo->theFunction->isUdf());
- theArgumentsValues.resize(theFunctionItemInfo->theArity);
-}
-
-
-void FunctionItem::serialize(::zorba::serialization::Archiver& ar)
-{
- ar & theFunctionItemInfo;
- ar & theArity;
- ar & theArgumentsValues;
-}
-
-
-const store::Item_t FunctionItem::getFunctionName() const
-{
- return theFunctionItemInfo->theQName;
-}
-
-
-uint32_t FunctionItem::getArity() const
-{
- return theArity;
-}
-
-
-uint32_t FunctionItem::getStartArity() const
-{
- return theFunctionItemInfo->theArity;
-}
-
-
-const signature& FunctionItem::getSignature() const
-{
- return theFunctionItemInfo->theFunction->getSignature();
-}
-
-
-const std::vector<PlanIter_t>& FunctionItem::getArgumentsValues() const
-{
- return theArgumentsValues;
-}
-
-
-bool FunctionItem::isArgumentApplied(unsigned int pos) const
-{
- assert(pos < theArgumentsValues.size());
- return (theArgumentsValues[pos].getp() != NULL);
-}
-
-
-void FunctionItem::setArgumentValue(unsigned int pos, const PlanIter_t& value)
-{
- theArity--;
-
- // find the pos-th NULL value and fill it
- for (unsigned int i=0; i<theArgumentsValues.size(); i++)
- if (theArgumentsValues[i] == NULL)
- {
- if (pos == 0)
- {
- theArgumentsValues[i] = value;
- return;
- }
- else
- pos--;
- }
-
- assert(false);
-}
-
-
-PlanIter_t FunctionItem::getImplementation(
- const std::vector<PlanIter_t>& dynChildren,
- CompilerCB* ccb)
-{
- std::vector<PlanIter_t> args;
- args.resize(theArgumentsValues.size());
-
- std::vector<PlanIter_t>::iterator argsIte = args.begin();
- std::vector<PlanIter_t>::iterator ite = theArgumentsValues.begin();
- std::vector<PlanIter_t>::const_iterator ite2 = dynChildren.begin();
- ++ite2; // skip the first child because it's the function item
-
- for( ; argsIte != args.end(); ++argsIte, ++ite)
- {
- if (*ite != NULL)
- {
- *argsIte = *ite;
- static_cast<PlanStateIteratorWrapper*>(ite->getp())->reset();
- }
- else
- {
- *argsIte = *ite2;
- ++ite2;
- }
- }
-
- expr* dummy = ccb->theEM->
- create_function_item_expr(NULL,
- NULL,
- theFunctionItemInfo->theLoc,
- false,
- false,
- false);
-
- PlanIter_t udfCallIterator = theFunctionItemInfo->theFunction->
- codegen(ccb,
- theFunctionItemInfo->theClosureSctx,
- theFunctionItemInfo->theLoc,
- args,
- *dummy);
-
- UDFunctionCallIterator* udfIter =
- static_cast<UDFunctionCallIterator*>(udfCallIterator.getp());
-
- udfIter->setDynamic();
- udfIter->setFunctionItem(this);
- return udfCallIterator;
-}
-
-
-zstring FunctionItem::show() const
-{
- std::ostringstream lRes;
- lRes << getFunctionName()->getStringValue();
- if (!isInline())
- lRes << "#" << getArity() << " (" << theFunctionItemInfo->theLoc << ")";
- return lRes.str();
-}
-
-
-
-/*******************************************************************************
-
-********************************************************************************/
-FunctionItemIterator::FunctionItemIterator(
- static_context* sctx,
- const QueryLoc& loc,
- FunctionItemInfo* fnInfo)
- :
- NaryBaseIterator<FunctionItemIterator, PlanIteratorState>(sctx, loc, fnInfo->theScopedVarsIterators),
- theFunctionItemInfo(fnInfo)
-{
-}
-
-
-FunctionItemIterator::~FunctionItemIterator()
-{
-}
-
-
-void FunctionItemIterator::serialize(::zorba::serialization::Archiver& ar)
-{
- serialize_baseclass(ar,
- (NaryBaseIterator<FunctionItemIterator, PlanIteratorState>*)this);
- ar & theFunctionItemInfo;
-}
-
-
-bool FunctionItemIterator::nextImpl(store::Item_t& result, PlanState& planState) const
-{
- PlanIteratorState* state;
- DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
-
- // This portion is taken from the eval iterator
- {
- // Create the dynamic context for the eval query
- std::auto_ptr<dynamic_context> evalDctx;
- evalDctx.reset(new dynamic_context(planState.theGlobalDynCtx));
-
- // Import the outer environment.
- importOuterEnv(planState,
- theFunctionItemInfo->theCCB,
- theFunctionItemInfo->theClosureSctx,
- evalDctx.get());
-
- if (theFunctionItemInfo->theIsCoercion)
- {
- FunctionItemIterator* child = dynamic_cast<FunctionItemIterator*>(theChildren[0].getp());
- if (child != NULL)
- theFunctionItemInfo->theQName = child->theFunctionItemInfo->theQName;
- }
-
- result = new FunctionItem(theFunctionItemInfo, evalDctx.release());
- }
-
- STACK_PUSH ( result != NULL, state );
- STACK_END (state);
-}
-
-
-/********************************************************************************
-
- These functions are copied from the EvalIterator -- maybe they could be shared.
-
-********************************************************************************/
-
-/****************************************************************************//**
- This method imports a static and dynamic environment from the quter query into
- the eval query. In particular:
-
- (a) imports into the importSctx all the outer vars of the eval query
- (b) imports into the importSctx all the ns bindings of the outer query at the
- place where the eval call appears at
- (c) Copies all the var values from the outer-query global dctx into the eval-
- query dctx.
- (d) For each of the non-global outer vars, places its value into the eval dctx.
- The var value is represented as a PlanIteratorWrapper over the subplan that
- evaluates the domain expr of the eval var.
- (e) Computes the max var id of all the var values set in steps (c) and (d).
- This max varid will be passed to the compiler of the eval query so that
- the varids that will be generated for the eval query will not conflict with
- the varids of the outer vars and the outer-query global vars.
-********************************************************************************/
-void FunctionItemIterator::importOuterEnv(
- PlanState& planState,
- CompilerCB* evalCCB,
- static_context* importSctx,
- dynamic_context* evalDctx) const
-{
- ulong maxOuterVarId = 1;
-
- // Copy all the var values from the outer-query global dctx into the eval-query
- // dctx. This is need to handle the following scenario: (a) $x is an outer-query
- // global var that is not among the outer vars of the eval query (because $x was
- // hidden at the point where the eval call is made inside the outer query), and
- // (b) foo() is a function decalred in the outer query that accessed $x and is
- // invoked by the eval query. The copying must be done using the same positions
- // (i.e., var ids) in the eval dctx as in the outer-query dctx.
-
- dynamic_context* outerDctx = evalDctx->getParent();
-
- const std::vector<dynamic_context::VarValue>& outerGlobalValues =
- outerDctx->get_variables();
-
- csize numOuterGlobalVars = outerGlobalValues.size();
-
- for (csize i = 0; i < numOuterGlobalVars; ++i)
- {
- const dynamic_context::VarValue& outerVar = outerGlobalValues[i];
-
- if (!outerVar.isSet())
- continue;
-
- ulong outerVarId = static_cast<ulong>(i);
-
- if (outerVarId > maxOuterVarId)
- maxOuterVarId = outerVarId;
-
- store::Item_t itemValue;
- store::TempSeq_t seqValue;
-
- if (outerVar.hasItemValue())
- {
- store::Item_t value = outerVar.theValue.item;
- evalDctx->add_variable(outerVarId, value);
- }
- else
- {
- store::Iterator_t iteValue = outerVar.theValue.temp_seq->getIterator();
- evalDctx->add_variable(outerVarId, iteValue);
- }
- }
-
- ++maxOuterVarId;
-
- // Import the outer vars. Specifically, for each outer var:
- // (a) create a declaration inside the importSctx.
- // (b) Set its var id
- // (c) If it is not a global one, set its value within the eval dctx.
- csize curChild = -1;
-
- csize numOuterVars = theFunctionItemInfo->theScopedVarsNames.size();
-
-
- for (csize i = 0; i < numOuterVars; ++i)
- {
- if (!theFunctionItemInfo->theIsGlobalVar[i])
- {
- ++curChild;
-
- store::Iterator_t iter = new PlanIteratorWrapper(theChildren[curChild], planState);
-
- evalDctx->add_variable(theFunctionItemInfo->theVarId[i], iter);
- }
- }
-
- // Import the outer-query ns bindings
- store::NsBindings::const_iterator ite = theFunctionItemInfo->theLocalBindings.begin();
- store::NsBindings::const_iterator end = theFunctionItemInfo->theLocalBindings.end();
-
- for (; ite != end; ++ite)
- {
- importSctx->bind_ns(ite->first, ite->second, loc);
- }
-}
-
-
-/****************************************************************************//**
-
-********************************************************************************/
-void FunctionItemIterator::setExternalVariables(
- CompilerCB* ccb,
- static_context* importSctx,
- dynamic_context* evalDctx) const
-{
- std::vector<VarInfo*> innerVars;
-
- CompilerCB::SctxMap::const_iterator sctxIte = ccb->theSctxMap.begin();
- CompilerCB::SctxMap::const_iterator sctxEnd = ccb->theSctxMap.end();
-
- for (; sctxIte != sctxEnd; ++sctxIte)
- {
- sctxIte->second->getVariables(innerVars, true, false, true);
- }
-
- FOR_EACH(std::vector<VarInfo*>, ite, innerVars)
- {
- VarInfo* innerVar = (*ite);
-
- if (!innerVar->isExternal())
- continue;
-
- ulong innerVarId = innerVar->getId();
-
- VarInfo* outerVar = importSctx->lookup_var(innerVar->getName());
-
- if (!outerVar)
- continue;
-
- store::Item_t itemValue;
- store::TempSeq_t seqValue;
-
- evalDctx->get_variable(outerVar->getId(),
- outerVar->getName(),
- loc,
- itemValue,
- seqValue);
-
- if (itemValue != NULL)
- {
- evalDctx->add_variable(innerVarId, itemValue);
- }
- else
- {
- store::Iterator_t iteValue = seqValue->getIterator();
- evalDctx->add_variable(innerVarId, iteValue);
- }
- }
-}
-
-NARY_ACCEPT(FunctionItemIterator)
-
-
-} //namespace zorba
-/* vim:set et sw=2 ts=2: */
=== removed file 'src/runtime/function_item/function_item.h'
--- src/runtime/function_item/function_item.h 2013-03-26 22:31:03 +0000
+++ src/runtime/function_item/function_item.h 1970-01-01 00:00:00 +0000
@@ -1,286 +0,0 @@
-/*
- * Copyright 2006-2008 The FLWOR Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ZORBA_RUNTIME_FUNCTION_ITEM_H
-#define ZORBA_RUNTIME_FUNCTION_ITEM_H
-
-#include "common/shared_types.h"
-
-#include "compiler/parser/query_loc.h"
-
-#include "store/api/item.h"
-
-#include "runtime/base/narybase.h"
-
-
-namespace zorba
-{
-
-class signature;
-class function_item_expr;
-class FunctionItemInfo;
-
-typedef rchandle<FunctionItemInfo> FunctionItemInfo_t;
-
-/*******************************************************************************
- A class to hold information about a dynamic function. This info is shared
- between the FunctionItemIterator and the FunctionItems it creates.
-
- theCCB :
- --------
-
- theMustDeleteCCB :
- ------------------
- This is set to true if the FunctionItemInfo is the owner of the CCB,
- and must delete it upon destruction.
-
- theLoc:
- -------
- The location where the function item expr or inline function expr appear at.
-
- theClosureSctx:
- ---------------
- The static context to be used when the function item is actually invoked.
-
- theFunction:
- ------------
- The function obj that represents the implementation of this function item.
- This is always a pointer to a user_function obj. In case of an inline function
- expr, it is an anonymous user_function obj that is created on-the-fly by the
- translator to represent the body and signature of the inline function. In case
- of a function item expr where the named function is a UDF, it is the
- user_function obj of that UDF. Finally, in case of a function item expr where
- the named function F is not a UDF, it is a user_function obj UF that is created
- on-the-fly by the translator. The signature of UF is the same as that of F, and
- its body simply invokes F. The reason why UF is built is to unify the
- implemenation of dynamic function invocation.
-
- theQName:
- ---------
-
- theArity:
- ---------
- We need to store the arity also here because the function obj above doesn't
- know about its arity in case it's a variadic function.
-
- theIsInline:
- ------------
-
- theNeedsContextItem:
- --------------------
- Whether the function is a contextual one, i.e., accesses the context item, or
- context position, or context size directly.
-
- theIsCoercion:
- --------------
- This is set to true if the function item is a function coercion. In this
- case the newly created function item's name is taken from the coerced
- function.
-
- theScopedVarsValues:
- --------------------
- Empty in the case of LiteralFunctionItem. Otherwise, the vars that are in
- scope at the place where the InlineFunction expr appears at.
-
- theSubstVarsValues:
- -------------------
-
- theScopedVarsNames:
- -------------------
-
- theIsGlobalVar:
- ---------------
-
- theVarId:
- ---------
-
- theScopedVarsIteratosr:
- -----------------------
-
-********************************************************************************/
-class FunctionItemInfo : public SimpleRCObject
-{
-public:
- CompilerCB * theCCB;
- bool theMustDeleteCCB;
-
- QueryLoc theLoc;
- static_context * theClosureSctx;
- function_t theFunction;
- store::Item_t theQName;
- unsigned int theArity;
- bool theIsInline;
- bool theNeedsContextItem;
- bool theIsCoercion;
-
- std::vector<expr*> theScopedVarsValues;
- std::vector<var_expr*> theSubstVarsValues;
- std::vector<store::Item_t> theScopedVarsNames;
- std::vector<int> theIsGlobalVar;
- std::vector<ulong> theVarId;
-
- std::vector<PlanIter_t> theScopedVarsIterators;
-
- store::NsBindings theLocalBindings;
-
-public:
- SERIALIZABLE_CLASS(FunctionItemInfo)
- FunctionItemInfo(::zorba::serialization::Archiver& ar);
- void serialize(::zorba::serialization::Archiver& ar);
-
-public:
- FunctionItemInfo(
- static_context* closureSctx,
- const QueryLoc& loc,
- function* func,
- store::Item_t qname,
- uint32_t arity,
- bool isInline,
- bool needsContextItem,
- bool isCoercion);
-
- virtual ~FunctionItemInfo();
-
- void add_variable(
- expr* var,
- var_expr* substVar,
- const store::Item_t& name,
- int isGlobal);
-};
-
-
-/*******************************************************************************
- A FunctionItem is created during codegen, when a function_item_expr is reached.
-
- theSctx : The static context of the function_item_expr.
- theExpr : The associated function_item_expr.
- theVariableValues : Vector of var iterators representing the values of the
- in-scope FLWOR variables for inline function items.
-********************************************************************************/
-class FunctionItem : public store::Item, public zorba::serialization::SerializeBaseClass
-{
-protected:
- FunctionItemInfo_t theFunctionItemInfo;
-
- unsigned int theArity; // The arity of the function
- // item will decrease when a
- // partial application is used.
-
- std::vector<PlanIter_t> theArgumentsValues;
-
- std::auto_ptr<dynamic_context> theClosureDctx;
-
- SYNC_CODE(mutable RCLock theRCLock;)
-
-public:
- SERIALIZABLE_CLASS(FunctionItem)
- FunctionItem(::zorba::serialization::Archiver& ar);
- void serialize(::zorba::serialization::Archiver& ar);
-
-public:
- FunctionItem(
- const FunctionItemInfo_t& dynamicFunctionInfo,
- dynamic_context* dctx);
-
- SYNC_CODE(RCLock* getRCLock() const { return &theRCLock; })
-
- dynamic_context* getDctx() const { return theClosureDctx.get(); }
-
- void setDctx(dynamic_context* dctx) { theClosureDctx.reset(dctx); }
-
- const std::vector<PlanIter_t>& getArgumentsValues() const;
-
- void setArgumentValue(unsigned int pos, const PlanIter_t& value);
-
- // This function will return true if the pos-th argument of the function
- // has been partially applied, i.e. theArgumentsValues[pos] is not NULL
- bool isArgumentApplied(unsigned int pos) const;
-
- // The getImplementation function assumes the dynChildren vector comes from a
- // DynamicFnCallIterator, and as such, the first element of dynChildren is
- // the function item itself, so it will be skipped.
- // The last element(s) of dynChildren might contain DOT vars iterators. They
- // will be picked up automatically if needed.
- PlanIter_t getImplementation(const std::vector<PlanIter_t>& dynChildren, CompilerCB* ccb);
-
- const store::Item_t getFunctionName() const;
-
- unsigned int getArity() const;
-
- // returns the arity of the function before any partial application
- unsigned int getStartArity() const;
-
- const signature& getSignature() const;
-
- bool isInline() const { return theFunctionItemInfo->theIsInline; }
-
- bool needsContextItem() const { return theFunctionItemInfo->theNeedsContextItem; }
-
- bool isCoercion() const { return theFunctionItemInfo->theIsCoercion; }
-
- zstring show() const;
-};
-
-
-/*******************************************************************************
- An iterator that creates and returns dynamic function items
-********************************************************************************/
-class FunctionItemIterator : public NaryBaseIterator<FunctionItemIterator, PlanIteratorState>
-{
-protected:
- FunctionItemInfo_t theFunctionItemInfo;
-
-public:
- SERIALIZABLE_CLASS(FunctionItemIterator)
- SERIALIZABLE_CLASS_CONSTRUCTOR2T(FunctionItemIterator,
- NaryBaseIterator<FunctionItemIterator, PlanIteratorState>)
- void serialize(::zorba::serialization::Archiver& ar);
-
-public:
- FunctionItemIterator(
- static_context* sctx,
- const QueryLoc& loc,
- FunctionItemInfo* fnInfo);
-
- virtual ~FunctionItemIterator();
-
- // Used for pretty-printing of the iterator tree
- const FunctionItemInfo_t getFunctionItemInfo() const
- {
- return theFunctionItemInfo;
- }
-
- void accept(PlanIterVisitor& v) const;
-
- bool nextImpl(store::Item_t& result, PlanState& planState) const;
-
-public:
- void importOuterEnv(PlanState& planState,
- CompilerCB* evalCCB,
- static_context* importSctx,
- dynamic_context* evalDctx) const;
-
-private:
- void setExternalVariables(
- CompilerCB* ccb,
- static_context* importSctx,
- dynamic_context* evalDctx) const;
-};
-
-
-}//end of zorba namespace
-
-#endif
-/* vim:set et sw=2 ts=2: */
=== modified file 'src/runtime/function_item/function_item_iter_impl.cpp'
--- src/runtime/function_item/function_item_iter_impl.cpp 2013-03-26 21:26:20 +0000
+++ src/runtime/function_item/function_item_iter_impl.cpp 2013-03-26 23:33:23 +0000
@@ -25,7 +25,7 @@
#include "runtime/function_item/function_item_iter.h"
#include "runtime/api/plan_iterator_wrapper.h"
#include "runtime/util/iterator_impl.h"
-#include "runtime/function_item/function_item.h"
+#include "runtime/hof/function_item.h"
#include "runtime/core/fncall_iterator.h"
#include "context/dynamic_context.h"
=== added directory 'src/runtime/hof'
=== added file 'src/runtime/hof/dynamic_fncall_iterator.cpp'
--- src/runtime/hof/dynamic_fncall_iterator.cpp 1970-01-01 00:00:00 +0000
+++ src/runtime/hof/dynamic_fncall_iterator.cpp 2013-03-26 23:33:23 +0000
@@ -0,0 +1,396 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "stdafx.h"
+
+#include "diagnostics/util_macros.h"
+
+#include "runtime/hof/dynamic_fncall_iterator.h"
+#include "runtime/hof/function_item.h"
+#include "runtime/core/fncall_iterator.h"
+#include "runtime/api/plan_wrapper.h"
+#include "runtime/api/plan_iterator_wrapper.h"
+#include "runtime/visitors/planiter_visitor.h"
+
+#include "context/dynamic_context.h"
+#include "context/static_context.h"
+
+#include "store/api/item_factory.h"
+#include "store/api/store.h"
+#include "store/api/temp_seq.h"
+
+#include "types/root_typemanager.h"
+#include "types/casting.h"
+#include "types/typeops.h"
+
+#include "system/globalenv.h"
+
+
+namespace zorba
+{
+
+
+SERIALIZABLE_CLASS_VERSIONS(ArgumentPlaceholderIterator)
+
+NOARY_ACCEPT(ArgumentPlaceholderIterator)
+
+SERIALIZABLE_CLASS_VERSIONS(DynamicFnCallIterator)
+
+
+/*******************************************************************************
+
+********************************************************************************/
+DynamicFnCallIteratorState::DynamicFnCallIteratorState()
+{
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+DynamicFnCallIteratorState::~DynamicFnCallIteratorState()
+{
+ if (theIsOpen)
+ {
+ thePlan->close(*thePlanState);
+ }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void DynamicFnCallIteratorState::init(PlanState& planState)
+{
+ PlanIteratorState::init(planState);
+ thePlanState = &planState;
+ thePlan = NULL;
+ theIsOpen = false;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void DynamicFnCallIteratorState::reset(PlanState& planState)
+{
+ PlanIteratorState::reset(planState);
+ if (theIsOpen)
+ {
+ thePlan->reset(planState);
+ }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void DynamicFnCallIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+ serialize_baseclass(ar,
+ (NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>*)this);
+
+ ar & theDotVarsCount;
+ ar & theIsPartialApply;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+uint32_t DynamicFnCallIterator::getStateSizeOfSubtree() const
+{
+ uint32_t size = NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>::
+ getStateSizeOfSubtree();
+
+ return size + sizeof(UDFunctionCallIteratorState);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void DynamicFnCallIterator::openImpl(PlanState& planState, uint32_t& offset)
+{
+ StateTraitsImpl<DynamicFnCallIteratorState>::
+ createState(planState, theStateOffset, offset);
+
+ StateTraitsImpl<DynamicFnCallIteratorState>::
+ initState(planState, theStateOffset);
+
+ DynamicFnCallIteratorState* state =
+ StateTraitsImpl<DynamicFnCallIteratorState>::
+ getState(planState, theStateOffset);
+
+ state->theUDFStateOffset = offset;
+
+ offset += sizeof(UDFunctionCallIteratorState);
+
+ std::vector<PlanIter_t>::iterator lIter = theChildren.begin();
+ std::vector<PlanIter_t>::iterator lEnd = theChildren.end();
+ for ( ; lIter != lEnd; ++lIter )
+ {
+ (*lIter)->open(planState, offset);
+ }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void DynamicFnCallIterator::resetImpl(PlanState& planState) const
+{
+ DynamicFnCallIteratorState* state =
+ StateTraitsImpl<DynamicFnCallIteratorState>::
+ getState(planState, theStateOffset);
+
+ if (state->theIsOpen)
+ {
+ state->thePlan->close(planState);
+ state->theIsOpen = false;
+ }
+
+ NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>::
+ resetImpl(planState);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+bool DynamicFnCallIterator::nextImpl(
+ store::Item_t& result,
+ PlanState& planState) const
+{
+ store::Item_t item;
+ store::Item_t targetItem;
+ FunctionItem* fnItem;
+#ifdef ZORBA_WITH_JSON
+ store::Item_t selectorItem1;
+ store::Item_t selectorItem2;
+ store::Item_t selectorItem3;
+ bool isObjectNav;
+ bool selectorError;
+#endif
+
+ TypeManager* tm = theSctx->get_typemanager();
+
+ DynamicFnCallIteratorState* state;
+
+ DEFAULT_STACK_INIT(DynamicFnCallIteratorState, state, planState);
+
+ // first child must return exactly one item which is a function item
+ // otherwise XPTY0004 is raised
+ if (!consumeNext(targetItem, theChildren[0], planState) || targetItem == NULL)
+ {
+ RAISE_ERROR(err::XPTY0004, loc,
+ ERROR_PARAMS(ZED(XPTY0004_NoTypePromote_23),
+ "empty-sequence()",
+ GENV_TYPESYSTEM.ANY_FUNCTION_TYPE_ONE->toSchemaString()));
+ }
+
+ if (targetItem->isFunction())
+ {
+ if (consumeNext(item, theChildren[0], planState))
+ {
+ RAISE_ERROR(err::XPTY0004, loc,
+ ERROR_PARAMS(ZED(XPTY0004_NoMultiSeqTypePromotion_2),
+ GENV_TYPESYSTEM.ANY_FUNCTION_TYPE_ONE->toSchemaString()));
+ }
+
+ fnItem = static_cast<FunctionItem*>(targetItem.getp());
+
+ if ((!fnItem->needsContextItem() &&
+ theChildren.size() - 1 - theDotVarsCount != fnItem->getArity())
+ ||
+ (fnItem->needsContextItem()
+ && theChildren.size() - 1 != fnItem->getArity()))
+ {
+ RAISE_ERROR(err::XPTY0004, loc,
+ ERROR_PARAMS("dynamic function invoked with incorrect number of arguments"));
+ }
+
+ if (theIsPartialApply)
+ {
+ for (csize i = 1, pos = 0; i < theChildren.size() - theDotVarsCount; ++i)
+ {
+ if (dynamic_cast<ArgumentPlaceholderIterator*>(theChildren[i].getp()) == NULL)
+ {
+ // The argument needs to be materialized only for local vars and only
+ // if the function item is returned and used outside of the current
+ // function. It might be impossible to determine if the partially
+ // applied function item will be used outside of the current function,
+ // so it is quite probable that it always needs to be materialized.
+ std::vector<store::Item_t> argValues;
+ store::Item_t tempItem;
+
+ while (consumeNext(tempItem, theChildren[i], planState))
+ argValues.push_back(tempItem);
+
+ store::TempSeq_t argSeq = GENV_STORE.createTempSeq(argValues);
+ store::Iterator_t argSeqIter = argSeq->getIterator();
+ PlanIter_t value = new PlanStateIteratorWrapper(argSeqIter);
+
+ fnItem->setArgumentValue(pos, value);
+ }
+ else
+ pos++;
+ }
+
+ result = fnItem;
+ STACK_PUSH(true, state);
+ }
+ else
+ {
+ state->thePlan = fnItem->getImplementation(theChildren, planState.theCompilerCB);
+
+ // must be opened after vars and params are set
+ state->thePlan->open(planState, state->theUDFStateOffset);
+ state->theIsOpen = true;
+
+ while (consumeNext(result, state->thePlan, planState))
+ {
+ STACK_PUSH(true, state);
+ }
+
+ // need to close here early in case the plan is completely
+ // consumed. Otherwise, the plan would still be opened
+ // if destroyed from the state's destructor.
+ state->thePlan->close(planState);
+ state->theIsOpen = false;
+ } // if (theIsPartialApply)
+
+ } // if (targetItem->isFunction())
+#ifdef ZORBA_WITH_JSON
+ else if (targetItem->isJSONObject() || targetItem->isJSONArray())
+ {
+ if (theChildren.size() - theDotVarsCount > 2)
+ {
+ RAISE_ERROR_NO_PARAMS(jerr::JNTY0018, loc);
+ }
+ else if (theChildren.size() - theDotVarsCount == 2)
+ {
+ isObjectNav = targetItem->isJSONObject();
+ selectorError = false;
+
+ if (!consumeNext(selectorItem1, theChildren[1], planState))
+ {
+ selectorError = true;
+ }
+ else
+ {
+ try
+ {
+ if (selectorItem1->isNode())
+ {
+ store::Iterator_t iter;
+
+ selectorItem1->getTypedValue(selectorItem2, iter);
+
+ if (iter != NULL)
+ {
+ if (!iter->next(selectorItem2) || iter->next(item))
+ {
+ selectorError = true;
+ }
+ }
+ }
+ else
+ {
+ selectorItem2.transfer(selectorItem1);
+ }
+
+ if (!selectorError)
+ {
+ if (!selectorItem2->isAtomic())
+ {
+ selectorError = true;
+ }
+ else
+ {
+ store::SchemaTypeCode selectorType =
+ (isObjectNav ? store::XS_STRING : store::XS_INTEGER);
+
+ GenericCast::castToBuiltinAtomic(selectorItem3,
+ selectorItem2,
+ selectorType,
+ NULL,
+ loc);
+ selectorError = false;
+ }
+ }
+ }
+ catch (...)
+ {
+ selectorError = true;
+ }
+ }
+
+ if (selectorError)
+ {
+ item = (selectorItem1 == NULL ? selectorItem2 : selectorItem1);
+
+ zstring selectorType = tm->create_value_type(item)->toSchemaString();
+
+ RAISE_ERROR(err::XPTY0004, loc,
+ ERROR_PARAMS(ZED(XPTY0004_JSONIQ_SELECTOR), selectorType));
+ }
+
+ if (isObjectNav)
+ result = targetItem->getObjectValue(selectorItem3);
+ else
+ result = targetItem->getArrayValue(selectorItem3->getIntegerValue());
+ STACK_PUSH(result != NULL, state);
+ }
+ else
+ {
+ if (targetItem->isJSONArray())
+ state->theIterator = targetItem->getArrayValues();
+ else if (targetItem->isJSONObject())
+ state->theIterator = targetItem->getObjectKeys();
+
+ state->theIterator->open();
+
+ while (state->theIterator->next(result))
+ {
+ STACK_PUSH(true, state);
+ }
+
+ state->theIterator->close();
+ }
+ }
+#endif
+ else
+ {
+ xqtref_t type = tm->create_value_type(targetItem);
+
+ RAISE_ERROR(err::XPTY0004, loc,
+ ERROR_PARAMS(ZED(XPTY0004_NoTypePromote_23),
+ type->toSchemaString(),
+ GENV_TYPESYSTEM.ANY_FUNCTION_TYPE_ONE->toSchemaString()));
+ }
+
+ STACK_END(state);
+};
+
+
+/*******************************************************************************
+
+********************************************************************************/
+NARY_ACCEPT(DynamicFnCallIterator)
+
+
+}//zorba namespace
+/* vim:set et sw=2 ts=2: */
=== added file 'src/runtime/hof/dynamic_fncall_iterator.h'
--- src/runtime/hof/dynamic_fncall_iterator.h 1970-01-01 00:00:00 +0000
+++ src/runtime/hof/dynamic_fncall_iterator.h 2013-03-26 23:33:23 +0000
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ZORBA_RUNTIME_DYNAMIC_FNCALL_ITERATOR
+#define ZORBA_RUNTIME_DYNAMIC_FNCALL_ITERATOR
+
+
+#include "common/shared_types.h"
+
+#include "runtime/base/narybase.h"
+
+#include "runtime/base/noarybase.h"
+
+
+namespace zorba
+{
+
+/*******************************************************************************
+
+********************************************************************************/
+class ArgumentPlaceholderIterator: public NoaryBaseIterator<ArgumentPlaceholderIterator,PlanIteratorState>
+{
+public:
+ SERIALIZABLE_CLASS(ArgumentPlaceholderIterator);
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(ArgumentPlaceholderIterator,
+ NoaryBaseIterator<ArgumentPlaceholderIterator, PlanIteratorState>);
+ void serialize( ::zorba::serialization::Archiver& ar)
+ {
+ serialize_baseclass(ar,
+ (NoaryBaseIterator<ArgumentPlaceholderIterator, PlanIteratorState>*)this);
+ }
+
+public:
+ ArgumentPlaceholderIterator(
+ static_context* sctx,
+ const QueryLoc& loc)
+ :
+ NoaryBaseIterator<ArgumentPlaceholderIterator, PlanIteratorState>(sctx, loc)
+ {
+ }
+
+ void accept(PlanIterVisitor& v) const;
+
+ bool nextImpl(store::Item_t& result, PlanState& planState) const { return false; };
+};
+
+
+/*******************************************************************************
+
+********************************************************************************/
+class DynamicFnCallIteratorState : public PlanIteratorState
+{
+public:
+ PlanState * thePlanState;
+ PlanIter_t thePlan;
+ bool theIsOpen;
+
+ uint32_t theUDFStateOffset;
+
+#ifdef ZORBA_WITH_JSON
+ store::Iterator_t theIterator;
+#endif
+
+ DynamicFnCallIteratorState();
+
+ ~DynamicFnCallIteratorState();
+
+ void init(PlanState&);
+ void reset(PlanState&);
+};
+
+
+/*******************************************************************************
+ The 1st child iterator returns the functionItem obj to invoke. The rest of
+ the child iterators compute the args to pass to the invocation.
+********************************************************************************/
+class DynamicFnCallIterator : public NaryBaseIterator<DynamicFnCallIterator,
+ DynamicFnCallIteratorState>
+{
+protected:
+ // This variable counts the number of children that hold DOT variables. They
+ // are placed at the end of the children array.
+ unsigned int theDotVarsCount;
+ bool theIsPartialApply;
+
+public:
+ SERIALIZABLE_CLASS(DynamicFnCallIterator);
+
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(DynamicFnCallIterator,
+ NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>);
+
+ void serialize( ::zorba::serialization::Archiver& ar);
+
+public:
+ DynamicFnCallIterator(
+ static_context* sctx,
+ const QueryLoc& loc,
+ std::vector<PlanIter_t>& args,
+ unsigned int dotVarsCount,
+ bool isPartialApply,
+ xqtref_t coercionTargetType = NULL)
+ :
+ NaryBaseIterator<DynamicFnCallIterator, DynamicFnCallIteratorState>(sctx, loc, args),
+ theDotVarsCount(dotVarsCount),
+ theIsPartialApply(isPartialApply)
+ {
+ }
+
+ void accept(PlanIterVisitor& v) const;
+
+ uint32_t getStateSizeOfSubtree() const;
+
+ void openImpl(PlanState& planState, uint32_t& offset);
+
+ bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+
+ void resetImpl(PlanState& planState) const;
+};
+
+
+}
+
+#endif
+/*
+ * Local variables:
+ * mode: c++
+ * End:
+ */
+/* vim:set et sw=2 ts=2: */
=== added file 'src/runtime/hof/function_item.cpp'
--- src/runtime/hof/function_item.cpp 1970-01-01 00:00:00 +0000
+++ src/runtime/hof/function_item.cpp 2013-03-26 23:33:23 +0000
@@ -0,0 +1,510 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "stdafx.h"
+
+// This include needs to be kept in order to make sure the
+// auto_ptr<dynamic_context> manages to dealocate the
+// dynamic_context object.
+#include "context/dynamic_context.h"
+
+#include "runtime/hof/function_item.h"
+#include "runtime/core/fncall_iterator.h"
+#include "runtime/base/plan_iterator.h"
+#include "runtime/api/plan_iterator_wrapper.h"
+#include "runtime/visitors/planiter_visitor.h"
+
+#include "compiler/api/compilercb.h"
+#include "compiler/expression/var_expr.h"
+#include "compiler/expression/function_item_expr.h"
+#include "compiler/expression/expr_manager.h"
+
+#include "functions/signature.h"
+#include "functions/udf.h"
+
+#include "store/api/temp_seq.h"
+
+#include "zorbaserialization/serialize_template_types.h"
+#include "zorbaserialization/serialize_zorba_types.h"
+
+
+namespace zorba
+{
+
+SERIALIZABLE_CLASS_VERSIONS(FunctionItemInfo)
+
+SERIALIZABLE_CLASS_VERSIONS(FunctionItem)
+
+SERIALIZABLE_CLASS_VERSIONS(FunctionItemIterator)
+
+
+/*******************************************************************************
+
+********************************************************************************/
+FunctionItemInfo::FunctionItemInfo(
+ static_context* closureSctx,
+ const QueryLoc& loc,
+ function* func,
+ store::Item_t qname,
+ uint32_t arity,
+ bool isInline,
+ bool needsContextItem,
+ bool isCoercion)
+ :
+ theMustDeleteCCB(false),
+ theLoc(loc),
+ theClosureSctx(closureSctx),
+ theFunction(func),
+ theQName(qname),
+ theArity(arity),
+ theIsInline(isInline),
+ theNeedsContextItem(needsContextItem),
+ theIsCoercion(isCoercion)
+{
+}
+
+
+FunctionItemInfo::FunctionItemInfo(::zorba::serialization::Archiver& ar)
+{
+}
+
+
+FunctionItemInfo::~FunctionItemInfo()
+{
+ if (theMustDeleteCCB)
+ delete theCCB;
+}
+
+
+void FunctionItemInfo::serialize(::zorba::serialization::Archiver& ar)
+{
+ ar & theCCB;
+ ar & theMustDeleteCCB;
+ ar & theClosureSctx;
+ ar & theLoc;
+ ar & theFunction;
+ ar & theQName;
+ ar & theArity;
+ ar & theIsInline;
+ ar & theNeedsContextItem;
+ ar & theIsCoercion;
+
+ // These are not serialized
+ // ar & theScopedVarsValues;
+ // ar & theSubstVarsValues;
+
+ ar & theScopedVarsNames;
+ ar & theIsGlobalVar;
+ ar & theVarId;
+
+ ar & theScopedVarsIterators;
+
+ if (ar.is_serializing_out())
+ {
+ uint32_t planStateSize;
+ (void)static_cast<user_function*>(theFunction.getp())->getPlan(planStateSize);
+ }
+}
+
+
+void FunctionItemInfo::add_variable(
+ expr* var,
+ var_expr* substVar,
+ const store::Item_t& name,
+ int isGlobal)
+{
+ theScopedVarsValues.push_back(var);
+ theSubstVarsValues.push_back(substVar);
+ theScopedVarsNames.push_back(name);
+ theIsGlobalVar.push_back(isGlobal);
+ theVarId.push_back(0);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+FunctionItem::FunctionItem(::zorba::serialization::Archiver& ar)
+ :
+ store::Item(store::Item::FUNCTION)
+{
+}
+
+
+FunctionItem::FunctionItem(
+ const FunctionItemInfo_t& dynamicFunctionInfo,
+ dynamic_context* dctx)
+ :
+ store::Item(store::Item::FUNCTION),
+ theFunctionItemInfo(dynamicFunctionInfo),
+ theArity(dynamicFunctionInfo->theArity),
+ theClosureDctx(dctx)
+{
+ assert(theFunctionItemInfo->theFunction->isUdf());
+ theArgumentsValues.resize(theFunctionItemInfo->theArity);
+}
+
+
+void FunctionItem::serialize(::zorba::serialization::Archiver& ar)
+{
+ ar & theFunctionItemInfo;
+ ar & theArity;
+ ar & theArgumentsValues;
+}
+
+
+const store::Item_t FunctionItem::getFunctionName() const
+{
+ return theFunctionItemInfo->theQName;
+}
+
+
+uint32_t FunctionItem::getArity() const
+{
+ return theArity;
+}
+
+
+uint32_t FunctionItem::getStartArity() const
+{
+ return theFunctionItemInfo->theArity;
+}
+
+
+const signature& FunctionItem::getSignature() const
+{
+ return theFunctionItemInfo->theFunction->getSignature();
+}
+
+
+const std::vector<PlanIter_t>& FunctionItem::getArgumentsValues() const
+{
+ return theArgumentsValues;
+}
+
+
+bool FunctionItem::isArgumentApplied(unsigned int pos) const
+{
+ assert(pos < theArgumentsValues.size());
+ return (theArgumentsValues[pos].getp() != NULL);
+}
+
+
+void FunctionItem::setArgumentValue(unsigned int pos, const PlanIter_t& value)
+{
+ theArity--;
+
+ // find the pos-th NULL value and fill it
+ for (unsigned int i=0; i<theArgumentsValues.size(); i++)
+ if (theArgumentsValues[i] == NULL)
+ {
+ if (pos == 0)
+ {
+ theArgumentsValues[i] = value;
+ return;
+ }
+ else
+ pos--;
+ }
+
+ assert(false);
+}
+
+
+PlanIter_t FunctionItem::getImplementation(
+ const std::vector<PlanIter_t>& dynChildren,
+ CompilerCB* ccb)
+{
+ std::vector<PlanIter_t> args;
+ args.resize(theArgumentsValues.size());
+
+ std::vector<PlanIter_t>::iterator argsIte = args.begin();
+ std::vector<PlanIter_t>::iterator ite = theArgumentsValues.begin();
+ std::vector<PlanIter_t>::const_iterator ite2 = dynChildren.begin();
+ ++ite2; // skip the first child because it's the function item
+
+ for( ; argsIte != args.end(); ++argsIte, ++ite)
+ {
+ if (*ite != NULL)
+ {
+ *argsIte = *ite;
+ static_cast<PlanStateIteratorWrapper*>(ite->getp())->reset();
+ }
+ else
+ {
+ *argsIte = *ite2;
+ ++ite2;
+ }
+ }
+
+ expr* dummy = ccb->theEM->
+ create_function_item_expr(NULL,
+ NULL,
+ theFunctionItemInfo->theLoc,
+ false,
+ false,
+ false);
+
+ PlanIter_t udfCallIterator = theFunctionItemInfo->theFunction->
+ codegen(ccb,
+ theFunctionItemInfo->theClosureSctx,
+ theFunctionItemInfo->theLoc,
+ args,
+ *dummy);
+
+ UDFunctionCallIterator* udfIter =
+ static_cast<UDFunctionCallIterator*>(udfCallIterator.getp());
+
+ udfIter->setDynamic();
+ udfIter->setFunctionItem(this);
+ return udfCallIterator;
+}
+
+
+zstring FunctionItem::show() const
+{
+ std::ostringstream lRes;
+ lRes << getFunctionName()->getStringValue();
+ if (!isInline())
+ lRes << "#" << getArity() << " (" << theFunctionItemInfo->theLoc << ")";
+ return lRes.str();
+}
+
+
+
+/*******************************************************************************
+
+********************************************************************************/
+FunctionItemIterator::FunctionItemIterator(
+ static_context* sctx,
+ const QueryLoc& loc,
+ FunctionItemInfo* fnInfo)
+ :
+ NaryBaseIterator<FunctionItemIterator, PlanIteratorState>(sctx, loc, fnInfo->theScopedVarsIterators),
+ theFunctionItemInfo(fnInfo)
+{
+}
+
+
+FunctionItemIterator::~FunctionItemIterator()
+{
+}
+
+
+void FunctionItemIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+ serialize_baseclass(ar,
+ (NaryBaseIterator<FunctionItemIterator, PlanIteratorState>*)this);
+ ar & theFunctionItemInfo;
+}
+
+
+bool FunctionItemIterator::nextImpl(store::Item_t& result, PlanState& planState) const
+{
+ PlanIteratorState* state;
+ DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
+
+ // This portion is taken from the eval iterator
+ {
+ // Create the dynamic context for the eval query
+ std::auto_ptr<dynamic_context> evalDctx;
+ evalDctx.reset(new dynamic_context(planState.theGlobalDynCtx));
+
+ // Import the outer environment.
+ importOuterEnv(planState,
+ theFunctionItemInfo->theCCB,
+ theFunctionItemInfo->theClosureSctx,
+ evalDctx.get());
+
+ if (theFunctionItemInfo->theIsCoercion)
+ {
+ FunctionItemIterator* child = dynamic_cast<FunctionItemIterator*>(theChildren[0].getp());
+ if (child != NULL)
+ theFunctionItemInfo->theQName = child->theFunctionItemInfo->theQName;
+ }
+
+ result = new FunctionItem(theFunctionItemInfo, evalDctx.release());
+ }
+
+ STACK_PUSH ( result != NULL, state );
+ STACK_END (state);
+}
+
+
+/********************************************************************************
+
+ These functions are copied from the EvalIterator -- maybe they could be shared.
+
+********************************************************************************/
+
+/****************************************************************************//**
+ This method imports a static and dynamic environment from the quter query into
+ the eval query. In particular:
+
+ (a) imports into the importSctx all the outer vars of the eval query
+ (b) imports into the importSctx all the ns bindings of the outer query at the
+ place where the eval call appears at
+ (c) Copies all the var values from the outer-query global dctx into the eval-
+ query dctx.
+ (d) For each of the non-global outer vars, places its value into the eval dctx.
+ The var value is represented as a PlanIteratorWrapper over the subplan that
+ evaluates the domain expr of the eval var.
+ (e) Computes the max var id of all the var values set in steps (c) and (d).
+ This max varid will be passed to the compiler of the eval query so that
+ the varids that will be generated for the eval query will not conflict with
+ the varids of the outer vars and the outer-query global vars.
+********************************************************************************/
+void FunctionItemIterator::importOuterEnv(
+ PlanState& planState,
+ CompilerCB* evalCCB,
+ static_context* importSctx,
+ dynamic_context* evalDctx) const
+{
+ ulong maxOuterVarId = 1;
+
+ // Copy all the var values from the outer-query global dctx into the eval-query
+ // dctx. This is need to handle the following scenario: (a) $x is an outer-query
+ // global var that is not among the outer vars of the eval query (because $x was
+ // hidden at the point where the eval call is made inside the outer query), and
+ // (b) foo() is a function decalred in the outer query that accessed $x and is
+ // invoked by the eval query. The copying must be done using the same positions
+ // (i.e., var ids) in the eval dctx as in the outer-query dctx.
+
+ dynamic_context* outerDctx = evalDctx->getParent();
+
+ const std::vector<dynamic_context::VarValue>& outerGlobalValues =
+ outerDctx->get_variables();
+
+ csize numOuterGlobalVars = outerGlobalValues.size();
+
+ for (csize i = 0; i < numOuterGlobalVars; ++i)
+ {
+ const dynamic_context::VarValue& outerVar = outerGlobalValues[i];
+
+ if (!outerVar.isSet())
+ continue;
+
+ ulong outerVarId = static_cast<ulong>(i);
+
+ if (outerVarId > maxOuterVarId)
+ maxOuterVarId = outerVarId;
+
+ store::Item_t itemValue;
+ store::TempSeq_t seqValue;
+
+ if (outerVar.hasItemValue())
+ {
+ store::Item_t value = outerVar.theValue.item;
+ evalDctx->add_variable(outerVarId, value);
+ }
+ else
+ {
+ store::Iterator_t iteValue = outerVar.theValue.temp_seq->getIterator();
+ evalDctx->add_variable(outerVarId, iteValue);
+ }
+ }
+
+ ++maxOuterVarId;
+
+ // Import the outer vars. Specifically, for each outer var:
+ // (a) create a declaration inside the importSctx.
+ // (b) Set its var id
+ // (c) If it is not a global one, set its value within the eval dctx.
+ csize curChild = -1;
+
+ csize numOuterVars = theFunctionItemInfo->theScopedVarsNames.size();
+
+
+ for (csize i = 0; i < numOuterVars; ++i)
+ {
+ if (!theFunctionItemInfo->theIsGlobalVar[i])
+ {
+ ++curChild;
+
+ store::Iterator_t iter = new PlanIteratorWrapper(theChildren[curChild], planState);
+
+ evalDctx->add_variable(theFunctionItemInfo->theVarId[i], iter);
+ }
+ }
+
+ // Import the outer-query ns bindings
+ store::NsBindings::const_iterator ite = theFunctionItemInfo->theLocalBindings.begin();
+ store::NsBindings::const_iterator end = theFunctionItemInfo->theLocalBindings.end();
+
+ for (; ite != end; ++ite)
+ {
+ importSctx->bind_ns(ite->first, ite->second, loc);
+ }
+}
+
+
+/****************************************************************************//**
+
+********************************************************************************/
+void FunctionItemIterator::setExternalVariables(
+ CompilerCB* ccb,
+ static_context* importSctx,
+ dynamic_context* evalDctx) const
+{
+ std::vector<VarInfo*> innerVars;
+
+ CompilerCB::SctxMap::const_iterator sctxIte = ccb->theSctxMap.begin();
+ CompilerCB::SctxMap::const_iterator sctxEnd = ccb->theSctxMap.end();
+
+ for (; sctxIte != sctxEnd; ++sctxIte)
+ {
+ sctxIte->second->getVariables(innerVars, true, false, true);
+ }
+
+ FOR_EACH(std::vector<VarInfo*>, ite, innerVars)
+ {
+ VarInfo* innerVar = (*ite);
+
+ if (!innerVar->isExternal())
+ continue;
+
+ ulong innerVarId = innerVar->getId();
+
+ VarInfo* outerVar = importSctx->lookup_var(innerVar->getName());
+
+ if (!outerVar)
+ continue;
+
+ store::Item_t itemValue;
+ store::TempSeq_t seqValue;
+
+ evalDctx->get_variable(outerVar->getId(),
+ outerVar->getName(),
+ loc,
+ itemValue,
+ seqValue);
+
+ if (itemValue != NULL)
+ {
+ evalDctx->add_variable(innerVarId, itemValue);
+ }
+ else
+ {
+ store::Iterator_t iteValue = seqValue->getIterator();
+ evalDctx->add_variable(innerVarId, iteValue);
+ }
+ }
+}
+
+NARY_ACCEPT(FunctionItemIterator)
+
+
+} //namespace zorba
+/* vim:set et sw=2 ts=2: */
=== added file 'src/runtime/hof/function_item.h'
--- src/runtime/hof/function_item.h 1970-01-01 00:00:00 +0000
+++ src/runtime/hof/function_item.h 2013-03-26 23:33:23 +0000
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ZORBA_RUNTIME_FUNCTION_ITEM_H
+#define ZORBA_RUNTIME_FUNCTION_ITEM_H
+
+#include "common/shared_types.h"
+
+#include "compiler/parser/query_loc.h"
+
+#include "store/api/item.h"
+
+#include "runtime/base/narybase.h"
+
+
+namespace zorba
+{
+
+class signature;
+class function_item_expr;
+class FunctionItemInfo;
+
+typedef rchandle<FunctionItemInfo> FunctionItemInfo_t;
+
+/*******************************************************************************
+ A class to hold information about a dynamic function. This info is shared
+ between the FunctionItemIterator and the FunctionItems it creates.
+
+ theCCB :
+ --------
+
+ theMustDeleteCCB :
+ ------------------
+ This is set to true if the FunctionItemInfo is the owner of the CCB,
+ and must delete it upon destruction.
+
+ theLoc:
+ -------
+ The location where the function item expr or inline function expr appear at.
+
+ theClosureSctx:
+ ---------------
+ The static context to be used when the function item is actually invoked.
+
+ theFunction:
+ ------------
+ The function obj that represents the implementation of this function item.
+ This is always a pointer to a user_function obj. In case of an inline function
+ expr, it is an anonymous user_function obj that is created on-the-fly by the
+ translator to represent the body and signature of the inline function. In case
+ of a function item expr where the named function is a UDF, it is the
+ user_function obj of that UDF. Finally, in case of a function item expr where
+ the named function F is not a UDF, it is a user_function obj UF that is created
+ on-the-fly by the translator. The signature of UF is the same as that of F, and
+ its body simply invokes F. The reason why UF is built is to unify the
+ implemenation of dynamic function invocation.
+
+ theQName:
+ ---------
+
+ theArity:
+ ---------
+ We need to store the arity also here because the function obj above doesn't
+ know about its arity in case it's a variadic function.
+
+ theIsInline:
+ ------------
+
+ theNeedsContextItem:
+ --------------------
+ Whether the function is a contextual one, i.e., accesses the context item, or
+ context position, or context size directly.
+
+ theIsCoercion:
+ --------------
+ This is set to true if the function item is a function coercion. In this
+ case the newly created function item's name is taken from the coerced
+ function.
+
+ theScopedVarsValues:
+ --------------------
+ Empty in the case of LiteralFunctionItem. Otherwise, the vars that are in
+ scope at the place where the InlineFunction expr appears at.
+
+ theSubstVarsValues:
+ -------------------
+
+ theScopedVarsNames:
+ -------------------
+
+ theIsGlobalVar:
+ ---------------
+
+ theVarId:
+ ---------
+
+ theScopedVarsIteratosr:
+ -----------------------
+
+********************************************************************************/
+class FunctionItemInfo : public SimpleRCObject
+{
+public:
+ CompilerCB * theCCB;
+ bool theMustDeleteCCB;
+
+ QueryLoc theLoc;
+ static_context * theClosureSctx;
+ function_t theFunction;
+ store::Item_t theQName;
+ unsigned int theArity;
+ bool theIsInline;
+ bool theNeedsContextItem;
+ bool theIsCoercion;
+
+ std::vector<expr*> theScopedVarsValues;
+ std::vector<var_expr*> theSubstVarsValues;
+ std::vector<store::Item_t> theScopedVarsNames;
+ std::vector<int> theIsGlobalVar;
+ std::vector<ulong> theVarId;
+
+ std::vector<PlanIter_t> theScopedVarsIterators;
+
+ store::NsBindings theLocalBindings;
+
+public:
+ SERIALIZABLE_CLASS(FunctionItemInfo)
+ FunctionItemInfo(::zorba::serialization::Archiver& ar);
+ void serialize(::zorba::serialization::Archiver& ar);
+
+public:
+ FunctionItemInfo(
+ static_context* closureSctx,
+ const QueryLoc& loc,
+ function* func,
+ store::Item_t qname,
+ uint32_t arity,
+ bool isInline,
+ bool needsContextItem,
+ bool isCoercion);
+
+ virtual ~FunctionItemInfo();
+
+ void add_variable(
+ expr* var,
+ var_expr* substVar,
+ const store::Item_t& name,
+ int isGlobal);
+};
+
+
+/*******************************************************************************
+ A FunctionItem is created during codegen, when a function_item_expr is reached.
+
+ theSctx : The static context of the function_item_expr.
+ theExpr : The associated function_item_expr.
+ theVariableValues : Vector of var iterators representing the values of the
+ in-scope FLWOR variables for inline function items.
+********************************************************************************/
+class FunctionItem : public store::Item, public zorba::serialization::SerializeBaseClass
+{
+protected:
+ FunctionItemInfo_t theFunctionItemInfo;
+
+ unsigned int theArity; // The arity of the function
+ // item will decrease when a
+ // partial application is used.
+
+ std::vector<PlanIter_t> theArgumentsValues;
+
+ std::auto_ptr<dynamic_context> theClosureDctx;
+
+ SYNC_CODE(mutable RCLock theRCLock;)
+
+public:
+ SERIALIZABLE_CLASS(FunctionItem)
+ FunctionItem(::zorba::serialization::Archiver& ar);
+ void serialize(::zorba::serialization::Archiver& ar);
+
+public:
+ FunctionItem(
+ const FunctionItemInfo_t& dynamicFunctionInfo,
+ dynamic_context* dctx);
+
+ SYNC_CODE(RCLock* getRCLock() const { return &theRCLock; })
+
+ dynamic_context* getDctx() const { return theClosureDctx.get(); }
+
+ void setDctx(dynamic_context* dctx) { theClosureDctx.reset(dctx); }
+
+ const std::vector<PlanIter_t>& getArgumentsValues() const;
+
+ void setArgumentValue(unsigned int pos, const PlanIter_t& value);
+
+ // This function will return true if the pos-th argument of the function
+ // has been partially applied, i.e. theArgumentsValues[pos] is not NULL
+ bool isArgumentApplied(unsigned int pos) const;
+
+ // The getImplementation function assumes the dynChildren vector comes from a
+ // DynamicFnCallIterator, and as such, the first element of dynChildren is
+ // the function item itself, so it will be skipped.
+ // The last element(s) of dynChildren might contain DOT vars iterators. They
+ // will be picked up automatically if needed.
+ PlanIter_t getImplementation(const std::vector<PlanIter_t>& dynChildren, CompilerCB* ccb);
+
+ const store::Item_t getFunctionName() const;
+
+ unsigned int getArity() const;
+
+ // returns the arity of the function before any partial application
+ unsigned int getStartArity() const;
+
+ const signature& getSignature() const;
+
+ bool isInline() const { return theFunctionItemInfo->theIsInline; }
+
+ bool needsContextItem() const { return theFunctionItemInfo->theNeedsContextItem; }
+
+ bool isCoercion() const { return theFunctionItemInfo->theIsCoercion; }
+
+ zstring show() const;
+};
+
+
+/*******************************************************************************
+ An iterator that creates and returns dynamic function items
+********************************************************************************/
+class FunctionItemIterator : public NaryBaseIterator<FunctionItemIterator, PlanIteratorState>
+{
+protected:
+ FunctionItemInfo_t theFunctionItemInfo;
+
+public:
+ SERIALIZABLE_CLASS(FunctionItemIterator)
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(FunctionItemIterator,
+ NaryBaseIterator<FunctionItemIterator, PlanIteratorState>)
+ void serialize(::zorba::serialization::Archiver& ar);
+
+public:
+ FunctionItemIterator(
+ static_context* sctx,
+ const QueryLoc& loc,
+ FunctionItemInfo* fnInfo);
+
+ virtual ~FunctionItemIterator();
+
+ // Used for pretty-printing of the iterator tree
+ const FunctionItemInfo_t getFunctionItemInfo() const
+ {
+ return theFunctionItemInfo;
+ }
+
+ void accept(PlanIterVisitor& v) const;
+
+ bool nextImpl(store::Item_t& result, PlanState& planState) const;
+
+public:
+ void importOuterEnv(PlanState& planState,
+ CompilerCB* evalCCB,
+ static_context* importSctx,
+ dynamic_context* evalDctx) const;
+
+private:
+ void setExternalVariables(
+ CompilerCB* ccb,
+ static_context* importSctx,
+ dynamic_context* evalDctx) const;
+};
+
+
+}//end of zorba namespace
+
+#endif
+/* vim:set et sw=2 ts=2: */
=== modified file 'src/runtime/visitors/printer_visitor_impl.cpp'
--- src/runtime/visitors/printer_visitor_impl.cpp 2013-03-26 22:31:03 +0000
+++ src/runtime/visitors/printer_visitor_impl.cpp 2013-03-26 23:33:23 +0000
@@ -51,7 +51,7 @@
#include "runtime/debug/debug_iterator.h"
#endif
#include "runtime/indexing/index_ddl.h"
-#include "runtime/function_item/dynamic_fncall_iterator.h"
+#include "runtime/hof/dynamic_fncall_iterator.h"
#include "runtime/visitors/iterprinter.h"
#include "runtime/update/update.h"
#include "runtime/eval/eval.h"
=== modified file 'src/store/naive/item.cpp'
--- src/store/naive/item.cpp 2013-03-24 20:40:03 +0000
+++ src/store/naive/item.cpp 2013-03-26 23:33:23 +0000
@@ -32,7 +32,7 @@
# include "json_items.h"
#endif
-#include "runtime/function_item/function_item.h"
+#include "runtime/hof/function_item.h"
namespace zorba
=== modified file 'src/types/typemanagerimpl.cpp'
--- src/types/typemanagerimpl.cpp 2013-03-15 08:22:41 +0000
+++ src/types/typemanagerimpl.cpp 2013-03-26 23:33:23 +0000
@@ -35,7 +35,7 @@
#include "store/api/iterator.h"
#include "store/api/item_factory.h"
-#include "runtime/function_item/function_item.h"
+#include "runtime/hof/function_item.h"
#include "compiler/parser/query_loc.h"
=== modified file 'src/zorbaserialization/serialize_zorba_types.cpp'
--- src/zorbaserialization/serialize_zorba_types.cpp 2013-03-17 04:02:46 +0000
+++ src/zorbaserialization/serialize_zorba_types.cpp 2013-03-26 23:33:23 +0000
@@ -45,7 +45,7 @@
#include "zorbatypes/decimal.h"
#include "functions/function.h"
-#include "runtime/function_item/function_item.h"
+#include "runtime/hof/function_item.h"
#include "context/static_context.h"
Follow ups