示例#1
0
Expr* parse(std::vector<std::pair<calc::tType,char>> &vTok)
{
	auto i = vTok.begin();
	std::stack<tType> operStack;
	std::stack<Expr> ExprStack;
	while(i!=vTok.end())
	{
		switch (i->first)
		{
		case LPAREN:
			operStack.push(i->first);
			break;
		case NUM:
			ExprStack.push(calc::Num((int)i->second));
			break;
		case PLUS:
			while(precedence(operStack.top())>=precedence(PLUS))
			{
				auto o = operStack.top();
				operStack.pop();
				Expr r = ExprStack.top();
				ExprStack.pop();
				Expr l = ExprStack.top();
				ExprStack.pop();
				ExprStack.push(pushType(o,&l,&r));
			}
			operStack.push(i->first);
			break;
		case RPAREN:
			while(operStack.top() != LPAREN)
			{
				auto o = operStack.top();
				operStack.pop();
				Expr r = ExprStack.top();
				ExprStack.pop();
				Expr l = ExprStack.top();
				ExprStack.pop();
				ExprStack.push(pushType(o,&l,&r));
			}
			operStack.push(i->first);
			break;
		default:
			break;
		}
		i++;
	}
	return &ExprStack.top();
}
示例#2
0
void BytecodeTranslatorVisitor::visitLoadNode(LoadNode* node) {
    onVisitNode(node);

    EMIT_LOAD(node->var());

    pushType(node->var()->type());
}
示例#3
0
void BytecodeTranslatorVisitor::visitForNode(ForNode* node) {
    onVisitNode(node);

    const AstVar* i = node->var();
    if (i->type() != VT_INT)
        ERROR("Non-iterable type in for loop");

    const BinaryOpNode* expr = node->inExpr()->asBinaryOpNode();
    if (expr == NULL || expr->kind() != tRANGE)
        ERROR("Invalid range in for loop");

    CONTEXT(function(), locals(), node->body()->scope(), typeStack());

    beforeProcessBlock();

    bool needTempVar = !expr->right()->isIntLiteralNode();
    AstVar* temp = NULL;
    if (needTempVar) {
        if (!scope()->declareVariable("<tempForEnd>", VT_INT))
            ERROR("internal error: temp name is unavailable");
        temp = scope()->lookupVariable("<tempForEnd>", false);
    }

    Label L_Begin(bytecode());
    Label L_End(bytecode());

    VISIT(expr->left());
    EMIT_STORE(i);

    if (needTempVar) {
        VISIT(expr->right());
        EMIT_STORE(temp);
        popType(VT_INT);
    }

    popType(VT_INT);
    EMIT_BIND(L_Begin);
    if (needTempVar)
        EMIT_LOAD(temp);
    else
        VISIT(expr->right());
    EMIT_LOAD(i);
    EMIT_BRANCH(BC_IFICMPG, L_End);

    processBlockNode(node->body());
    afterProcessBlock();

    /* i += 1 */
    EMIT_LOAD(i);
    EMIT(BC_ILOAD1);
    EMIT(BC_IADD);
    EMIT_STORE(i);

    EMIT_BRANCH(BC_JA, L_Begin);
    EMIT_BIND(L_End);

    pushType(VT_VOID);
}
示例#4
0
void BytecodeTranslatorVisitor::castTopsToCommonType() {
    VarType hi = popType();
    VarType lo = popType();

    if (hi != lo) {
        if (hi == VT_DOUBLE) {
            EMIT(BC_SWAP);
            EMIT(BC_I2D);
            EMIT(BC_SWAP);
        } else {
            EMIT(BC_I2D);
        }
        hi = VT_DOUBLE;
    }

    pushType(hi);
    pushType(hi);
}
示例#5
0
void BytecodeTranslatorVisitor::visitBlockNode(BlockNode* node) {
    onVisitNode(node);

    CONTEXT(function(), locals(), node->scope(), typeStack());

    beforeProcessBlock();
    processBlockNode(node);
    afterProcessBlock();

    pushType(VT_VOID);
}
示例#6
0
void BytecodeTranslatorVisitor::visitStringLiteralNode(StringLiteralNode * node) {
    onVisitNode(node);

    if (node->literal().empty())
        EMIT(BC_SLOAD0);
    else {
        EMIT(BC_SLOAD);
        EMIT_ID(code()->makeStringConstant(node->literal()));
    }

    pushType(VT_STRING);
}
示例#7
0
void BytecodeTranslatorVisitor::visitReturnNode(ReturnNode* node) {
    onVisitNode(node);

    if (node->returnExpr() != NULL)
        visitTyped(node->returnExpr(), function()->returnType());
    else if (function()->returnType() != VT_VOID)
        ERROR("Missing return statement");

    EMIT(BC_RETURN);

    ensureTypeStackEmpty();
    pushType(function()->returnType());
}
示例#8
0
void BytecodeTranslatorVisitor::visitStoreNode(StoreNode* node) {
    onVisitNode(node);

    visitTyped(node->value(), node->var()->type());
    pushType(node->var()->type());

    if (node->op() == tINCRSET || node->op() == tDECRSET) {
        ensureTopIsNumeric();
        EMIT_LOAD(node->var());

        if (node->op() == tINCRSET)
            EMIT(TYPED(ADD));
        else
            EMIT(TYPED(SUB));

    } else if (node->op() != tASSIGN)
        ERROR("Invalid store operation");

    EMIT_STORE(node->var());
    popType();
    pushType(VT_VOID); /* a = b = c is forbidden */
}
示例#9
0
void BytecodeTranslatorVisitor::visitIntLiteralNode(IntLiteralNode* node) {
    onVisitNode(node);

    switch (node->literal()) {
    case -1: EMIT(BC_ILOADM1); break;
    case  0: EMIT(BC_ILOAD0);  break;
    case  1: EMIT(BC_ILOAD1);  break;
    default:
        EMIT(BC_ILOAD);
        EMIT_INT(node->literal());
        break;
    }

    pushType(VT_INT);
}
示例#10
0
void BytecodeTranslatorVisitor::visitDoubleLiteralNode(DoubleLiteralNode* node) {
    onVisitNode(node);

    const double value = node->literal();
    if (doubleEquals(value, -1.0))
        EMIT(BC_DLOADM1);
    else if (doubleEquals(value, 0.0))
        EMIT(BC_DLOAD0);
    else if (doubleEquals(value, 1.0))
        EMIT(BC_DLOAD1);
    else {
        EMIT(BC_DLOAD);
        EMIT_DOUBLE(value);
    }

    pushType(VT_DOUBLE);
}
示例#11
0
void BytecodeTranslatorVisitor::visitPrintNode(PrintNode * node) {
    onVisitNode(node);

    for (uint32_t i = 0; i < node->operands(); ++i) {
        VISIT(node->operandAt(i));

        switch (topType()) {
        case VT_INT:    EMIT(BC_IPRINT); break;
        case VT_DOUBLE: EMIT(BC_DPRINT); break;
        case VT_STRING: EMIT(BC_SPRINT); break;
        default: ERROR("Unprintable parameter");
        }

        popType();
    }

    pushType(VT_VOID);
}
示例#12
0
void BytecodeTranslatorVisitor::tryCast(VarType to) {
    static Instruction castTable[VAR_TYPES_NUMBER][VAR_TYPES_NUMBER] = {BC_INVALID};
    castTable[VT_INT][VT_DOUBLE] = BC_I2D;
    castTable[VT_DOUBLE][VT_INT] = BC_D2I;

    VarType from = topType();
    if (from == to) return;

    Instruction cast = castTable[from][to];
    if (!cast)
        ERROR(string("Cast error from ") + typeToName(from) +
              " to " + typeToName(to));

    warningIf(cast == BC_D2I, "Casting double to int. I warned you!");

    EMIT(cast);
    popType();
    pushType(to);
}
示例#13
0
void BytecodeTranslatorVisitor::visitCallNode(CallNode* node) {
    onVisitNode(node);

    AstFunction* f = scope()->lookupFunction(node->name());
    if (!f) ERROR("Unknown function " + f->name());
    checkSignature(node, f);

    for (uint16_t i = 0; i < node->parametersNumber(); i++)
        visitTyped(node->parameterAt(i), f->parameterType(i));

    if (isNative(f))
        EMIT(BC_CALLNATIVE);
    else
        EMIT(BC_CALL);

    EMIT_ID(getFunctionId(f));

    pushType(f->returnType());
}
示例#14
0
void BytecodeTranslatorVisitor::processComparison(TokenKind kind) {
    castTopsToCommonType();

    Instruction cmp = TYPED(CMP);
    int hack = topType() == VT_INT ? 3 : 0;
    popType();
    popType();
    pushType(VT_INT);

    if (kind == tNEQ) {
        EMIT(cmp);
        return;
    }

    if (!hack) {
        EMIT(cmp);
        EMIT(BC_ILOAD0);
    }

    Label L_Fail(bytecode());
    Label L_End(bytecode());

    switch (kind) {
    case tEQ: EMIT_BRANCH(BC_IFICMPE,  L_Fail); break;
    case tGT: EMIT_BRANCH(BC_IFICMPG,  L_Fail); break;
    case tGE: EMIT_BRANCH(BC_IFICMPGE, L_Fail); break;
    case tLT: EMIT_BRANCH(BC_IFICMPL,  L_Fail); break;
    default : EMIT_BRANCH(BC_IFICMPLE, L_Fail); break;
    }

    EMIT(BC_ILOAD1 - hack);
    EMIT_BRANCH(BC_JA, L_End);
    EMIT_BIND(L_Fail);
    EMIT(BC_ILOAD0 + hack);
    EMIT_BIND(L_End);
}
示例#15
0
/*
 * The generic solution to the multiplex operators is to translate
 * them to a MAL loop.
 * The call optimizer.multiplex(MOD,FCN,A1,...An) introduces the following code
 * structure:
 *
 * 	resB:= bat.new(A1);
 * barrier (h,t1):= iterator.new(A1);
 * 	t2:= algebra.fetch(A2,h)
 * 	...
 * 	cr:= MOD.FCN(t1,...,tn);
 * 	bat.append(resB,cr);
 * 	redo (h,t):= iterator.next(A1);
 * end h;
 *
 * The algorithm consists of two phases: phase one deals with
 * collecting the relevant information, phase two is the actual
 * code construction.
 */
static str
OPTexpandMultiplex(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	int i = 2, iter = 0;
	int hvar, tvar;
	str mod, fcn;
	int *alias, *resB;
	InstrPtr q;
	int tt;
	int bat = (getModuleId(pci) == batmalRef) ;

	//if ( optimizerIsApplied(mb,"multiplex"))
		//return 0;
	(void) cntxt;
	(void) stk;
	for (i = 0; i < pci->retc; i++) {
		tt = getBatType(getArgType(mb, pci, i));
		if (tt== TYPE_any)
			throw(MAL, "optimizer.multiplex", SQLSTATE(HY002) "Target tail type is missing");
		if (isAnyExpression(getArgType(mb, pci, i)))
			throw(MAL, "optimizer.multiplex", SQLSTATE(HY002) "Target type is missing");
	}

	mod = VALget(&getVar(mb, getArg(pci, pci->retc))->value);
	mod = putName(mod);
	fcn = VALget(&getVar(mb, getArg(pci, pci->retc+1))->value);
	fcn = putName(fcn);
	if(mod == NULL || fcn == NULL)
		throw(MAL, "optimizer.multiplex", SQLSTATE(HY001) MAL_MALLOC_FAIL);
#ifndef NDEBUG
	fprintf(stderr,"#WARNING To speedup %s.%s a bulk operator implementation is needed\n#", mod,fcn);
	fprintInstruction(stderr, mb, stk, pci, LIST_MAL_DEBUG);
#endif

	/* search the iterator bat */
	for (i = pci->retc+2; i < pci->argc; i++)
		if (isaBatType(getArgType(mb, pci, i))) {
			iter = getArg(pci, i);
			break;
		}
	if( i == pci->argc)
		throw(MAL, "optimizer.multiplex", SQLSTATE(HY002) "Iterator BAT type is missing");

#ifdef DEBUG_OPT_MULTIPLEX
	{	char *tpenme;
		fprintf(stderr,"#calling the optimize multiplex script routine\n");
		fprintFunction(stderr,mb, 0, LIST_MAL_ALL );
		tpenme = getTypeName(getVarType(mb,iter));
		fprintf(stderr,"#multiplex against operator %d %s\n",iter, tpenme);
		GDKfree(tpenme);
		fprintInstruction(stderr,mb, 0, pci,LIST_MAL_ALL);
	}
#endif
	/*
	 * Beware, the operator constant (arg=1) is passed along as well,
	 * because in the end we issue a recursive function call that should
	 * find the actual arguments at the proper place of the callee.
	 */

	alias= (int*) GDKmalloc(sizeof(int) * pci->maxarg);
	resB = (int*) GDKmalloc(sizeof(int) * pci->retc);
	if (alias == NULL || resB == NULL)  {
		GDKfree(alias);
		GDKfree(resB);
		return NULL;
	}

	/* resB := new(refBat) */
	for (i = 0; i < pci->retc; i++) {
		q = newFcnCall(mb, batRef, newRef);
		resB[i] = getArg(q, 0);

		tt = getBatType(getArgType(mb, pci, i));

		setVarType(mb, getArg(q, 0), newBatType(tt));
		q = pushType(mb, q, tt);
	}

	/* barrier (h,r) := iterator.new(refBat); */
	q = newFcnCall(mb, iteratorRef, newRef);
	q->barrier = BARRIERsymbol;
	hvar = newTmpVariable(mb, TYPE_any);
	getArg(q,0) = hvar;
	tvar = newTmpVariable(mb, TYPE_any);
	q= pushReturn(mb, q, tvar);
	(void) pushArgument(mb,q,iter);

	/* $1:= algebra.fetch(Ai,h) or constant */
	for (i = pci->retc+2; i < pci->argc; i++) {
		if (getArg(pci, i) != iter && isaBatType(getArgType(mb, pci, i))) {
			q = newFcnCall(mb, algebraRef, "fetch");
			alias[i] = newTmpVariable(mb, getBatType(getArgType(mb, pci, i)));
			getArg(q, 0) = alias[i];
			q= pushArgument(mb, q, getArg(pci, i));
			(void) pushArgument(mb, q, hvar);
		}
	}

	/* cr:= mod.CMD($1,...,$n); */
	q = newFcnCall(mb, mod, fcn);
	for (i = 0; i < pci->retc; i++) {
		int nvar = 0;
		if (bat) {
			tt = getBatType(getArgType(mb, pci, i));
			nvar = newTmpVariable(mb, newBatType(tt));
		} else {
			nvar = newTmpVariable(mb, TYPE_any);
		}
		if (i)
			q = pushReturn(mb, q, nvar);
		else
			getArg(q, 0) = nvar;
	}

	for (i = pci->retc+2; i < pci->argc; i++) {
		if (getArg(pci, i) == iter) {
			q = pushArgument(mb, q, tvar);
		} else if (isaBatType(getArgType(mb, pci, i))) {
			q = pushArgument(mb, q, alias[i]);
		} else {
			q = pushArgument(mb, q, getArg(pci, i));
		}
	}

	for (i = 0; i < pci->retc; i++) {
		InstrPtr a = newFcnCall(mb, batRef, appendRef);
		a = pushArgument(mb, a, resB[i]);
		(void) pushArgument(mb, a, getArg(q,i));
	}

/* redo (h,r):= iterator.next(refBat); */
	q = newFcnCall(mb, iteratorRef, nextRef);
	q->barrier = REDOsymbol;
	getArg(q,0) = hvar;
	q= pushReturn(mb, q, tvar);
	(void) pushArgument(mb,q,iter);

	q = newAssignment(mb);
	q->barrier = EXITsymbol;
	getArg(q,0) = hvar;
	(void) pushReturn(mb, q, tvar);

	for (i = 0; i < pci->retc; i++) {
		q = newAssignment(mb);
		getArg(q, 0) = getArg(pci, i);
		(void) pushArgument(mb, q, resB[i]);
	}
	GDKfree(alias);
	GDKfree(resB);
	return MAL_SUCCEED;
}
示例#16
0
bool run(ASTNode* mainNode, RuntimeError* error, ExternalFunctions externals, char** libsToLoad, int libsCount)
{
    assert(mainNode->nodeType == AST_MAIN);

    getValueFunc = getGetValueFuncPtr();

    MemoryStack stack = makeMemoryStack(MEGABYTE(16));
    Array<HINSTANCE> libraries = makeArray<HINSTANCE>(KILOBYTE(1));

    Scope scalarTypesScope = makeScope(nullptr);
    Scope globalScope = makeScope(&scalarTypesScope);

    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s64"), {}, 8 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u64"), {}, 8 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("f64"), {}, 8 });

    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s32"), {}, 4 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u32"), {}, 4 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("f32"), {}, 4 });

    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s16"), {}, 2 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u16"), {}, 2 });

    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s8"), {}, 1 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u8"), {}, 1 });

    ExternalArgumentDefinition binarys32Args[] = { { "a", "s32" }, { "b", "s32" } };
    ExternalArgumentDefinition binaryf32Args[] = { { "a", "f32" }, { "b", "f32" } };
    ExternalDefinition buildInExternals[] = {
        { &scalarS32FuncsHandler, "opAdd", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opSub", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opEqualsOrLess", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opEqualsOrsGreater", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opLess", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opGreater", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opEquals", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opNot", "s32", binarys32Args, ArrayCount(binarys32Args) },
    };

    loadExternals(&scalarTypesScope, &stack, ExternalFunctions{ buildInExternals, ArrayCount(buildInExternals) });
    loadExternals(&scalarTypesScope, &stack, externals);
    loadLibrariries(&libraries, &scalarTypesScope, &stack, libsToLoad, libsCount);

    bool stillWorking = true;

    // load all global function and type definitions
    ListIterator<ASTNode> iterator = makeIterator(&mainNode->main.statements);
    while (stillWorking && hasNext(&iterator))
    {
        ASTNode* statement = getNext(&iterator);
        if (statement->nodeType == AST_STATEMENT_FUNCTION_DEFINITION ||
            statement->nodeType == AST_STATEMENT_TYPE_DEFINITION)
            stillWorking = runStatement(statement, &stack, &globalScope, error);
        else
        {
            // TODO: illigal statement exception? Or do this on parsing stage? 
        }
    }

    if (stillWorking)
    {
        FunctionIdentifier mainIdentifier = {};
        mainIdentifier.name = makeSlice("main");

        Function* func = getFunction(&globalScope, mainIdentifier);

        if (func != nullptr)
            stillWorking = runStatement(func->body, &stack, &globalScope, error);
        else
        {
            stillWorking = false;
            *error = RuntimeError{ RET_UNDEFINED_FUNCTION, mainIdentifier.name, 0 };
        }
    }

    scopeFreeMemory(&globalScope, &stack);
    scopeFreeMemory(&scalarTypesScope, &stack);

    freeAllLibraries(&libraries);

    freeArray(&libraries);
    freeMemoryStack(&stack);
    return stillWorking;
}
示例#17
0
/*
 * The trace operation collects the events in the BATs
 * and creates a secondary result set upon termination
 * of the query. 
 */
static void
SQLsetTrace(backend *be, Client cntxt, bit onoff)
{
	InstrPtr q, resultset;
	InstrPtr tbls, cols, types, clen, scale;
	MalBlkPtr mb = cntxt->curprg->def;
	int k;

	(void) be;
	if (onoff) {
		(void) newStmt(mb, "profiler", "start");
		initTrace();
	} else {
		(void) newStmt(mb, "profiler", "stop");
		/* cook a new resultSet instruction */
		resultset = newInstruction(mb,ASSIGNsymbol);
		setModuleId(resultset, sqlRef);
		setFunctionId(resultset, resultSetRef);
	    getArg(resultset,0)= newTmpVariable(mb,TYPE_int);


		/* build table defs */
		tbls = newStmt(mb,batRef, newRef);
		setVarType(mb, getArg(tbls,0), newBatType(TYPE_oid, TYPE_str));
		tbls = pushType(mb, tbls, TYPE_oid);
		tbls = pushType(mb, tbls, TYPE_str);
		resultset= pushArgument(mb,resultset, getArg(tbls,0));

		q= newStmt(mb,batRef,appendRef);
		q= pushArgument(mb,q,getArg(tbls,0));
		q= pushStr(mb,q,".trace");
		k= getArg(q,0);

		q= newStmt(mb,batRef,appendRef);
		q= pushArgument(mb,q,k);
		q= pushStr(mb,q,".trace");

		/* build colum defs */
		cols = newStmt(mb,batRef, newRef);
		setVarType(mb, getArg(cols,0), newBatType(TYPE_oid, TYPE_str));
		cols = pushType(mb, cols, TYPE_oid);
		cols = pushType(mb, cols, TYPE_str);
		resultset= pushArgument(mb,resultset, getArg(cols,0));

		q= newStmt(mb,batRef,appendRef);
		q= pushArgument(mb,q,getArg(cols,0));
		q= pushStr(mb,q,"usec");
		k= getArg(q,0);

		q= newStmt(mb,batRef,appendRef);
		q= pushArgument(mb,q, getArg(cols,0));
		q= pushStr(mb,q,"statement");

		/* build type defs */
		types = newStmt(mb,batRef, newRef);
		setVarType(mb, getArg(types,0), newBatType(TYPE_oid, TYPE_str));
		types = pushType(mb, types, TYPE_oid);
		types = pushType(mb, types, TYPE_str);
		resultset= pushArgument(mb,resultset, getArg(types,0));

		q= newStmt(mb,batRef,appendRef);
		q= pushArgument(mb,q, getArg(types,0));
		q= pushStr(mb,q,"bigint");
		k= getArg(q,0);

		q= newStmt(mb,batRef,appendRef);
		q= pushArgument(mb,q, k);
		q= pushStr(mb,q,"clob");

		/* build scale defs */
		clen = newStmt(mb,batRef, newRef);
		setVarType(mb, getArg(clen,0), newBatType(TYPE_oid, TYPE_int));
		clen = pushType(mb, clen, TYPE_oid);
		clen = pushType(mb, clen, TYPE_int);
		resultset= pushArgument(mb,resultset, getArg(clen,0));

		q= newStmt(mb,batRef,appendRef);
		q= pushArgument(mb,q, getArg(clen,0));
		q= pushInt(mb,q,64);
		k= getArg(q,0);

		q= newStmt(mb,batRef,appendRef);
		q= pushArgument(mb,q, k);
		q= pushInt(mb,q,0);

		/* build scale defs */
		scale = newStmt(mb,batRef, newRef);
		setVarType(mb, getArg(scale,0), newBatType(TYPE_oid, TYPE_int));
		scale = pushType(mb, scale, TYPE_oid);
		scale = pushType(mb, scale, TYPE_int);
		resultset= pushArgument(mb,resultset, getArg(scale,0));

		q= newStmt(mb,batRef,appendRef);
		q= pushArgument(mb,q, getArg(scale,0));
		q= pushInt(mb,q,0);
		k= getArg(q,0);

		q= newStmt(mb,batRef,appendRef);
		q= pushArgument(mb, q, k);
		q= pushInt(mb,q,0);

		/* add the ticks column */

		q = newStmt(mb, profilerRef, "getTrace");
		q = pushStr(mb, q, putName("usec",4));
		resultset= pushArgument(mb,resultset, getArg(q,0));

		/* add the stmt column */
		q = newStmt(mb, profilerRef, "getTrace");
		q = pushStr(mb, q, putName("stmt",4));
		resultset= pushArgument(mb,resultset, getArg(q,0));

		pushInstruction(mb,resultset);
	}
}
示例#18
0
/*
 * The generic solution to the multiplex operators is to translate
 * them to a MAL loop.
 * The call optimizer.multiplex(MOD,FCN,A1,...An) introduces the following code
 * structure:
 *
 * @verbatim
 *  A1rev:=bat.reverse(A1);
 * 	resB:= bat.new(A1);
 * barrier (h,t):= iterator.new(A1);
 * 	$1:= algebra.fetch(A1,h);
 * 	$2:= A2;	# in case of constant?
 * 	...
 * 	cr:= MOD.FCN($1,...,$n);
 *  y:=algebra.fetch(A1rev,h);
 * 	bat.insert(resB,y,cr);
 * 	redo (h,t):= iterator.next(A1);
 * end h;
 * @end verbatim
 *
 * The algorithm consists of two phases: phase one deals with
 * collecting the relevant information, phase two is the actual
 * code construction.
 */
static str
OPTexpandMultiplex(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	int i = 2, resB, iter = 0, cr;
	int hvar, tvar;
	int x, y;
	str mod, fcn;
	int *alias;
	InstrPtr q;
	int ht, tt;

	(void) cntxt;
	(void) stk;

	ht = getHeadType(getArgType(mb, pci, 0));
	if (ht != TYPE_oid)
		throw(MAL, "optimizer.multiplex", "Target head type is missing");
	tt = getTailType(getArgType(mb, pci, 0));
	if (tt== TYPE_any)
		throw(MAL, "optimizer.multiplex", "Target tail type is missing");
	if (isAnyExpression(getArgType(mb, pci, 0)))
		throw(MAL, "optimizer.multiplex", "Target type is missing");

	mod = VALget(&getVar(mb, getArg(pci, 1))->value);
	mod = putName(mod,strlen(mod));
	fcn = VALget(&getVar(mb, getArg(pci, 2))->value);
	fcn = putName(fcn,strlen(fcn));

	/* search the iterator bat */
	for (i = 3; i < pci->argc; i++)
		if (isaBatType(getArgType(mb, pci, i))) {
			iter = getArg(pci, i);
			if (getHeadType(getVarType(mb,iter)) != TYPE_oid)
				throw(MAL, "optimizer.multiplex", "Iterator BAT is not OID-headed");
			break;
		}
	if( i == pci->argc)
		throw(MAL, "optimizer.multiplex", "Iterator BAT type is missing");

	OPTDEBUGmultiplex {
		mnstr_printf(cntxt->fdout,"#calling the optimize multiplex script routine\n");
		printFunction(cntxt->fdout,mb, 0, LIST_MAL_ALL );
		mnstr_printf(cntxt->fdout,"#multiplex against operator %d %s\n",iter, getTypeName(getVarType(mb,iter)));
		printInstruction(cntxt->fdout,mb, 0, pci,LIST_MAL_ALL);
	}
	/*
	 * Beware, the operator constant (arg=1) is passed along as well,
	 * because in the end we issue a recursive function call that should
	 * find the actual arguments at the proper place of the callee.
	 */

	alias= (int*) GDKmalloc(sizeof(int) * pci->maxarg);
	if (alias == NULL)
		return NULL;

	/* x := bat.reverse(A1); */
	x = newTmpVariable(mb, newBatType(getTailType(getVarType(mb,iter)),
									  getHeadType(getVarType(mb,iter))));
	q = newFcnCall(mb, batRef, reverseRef);
	getArg(q, 0) = x;
	q = pushArgument(mb, q, iter);

	/* resB := new(refBat) */
	q = newFcnCall(mb, batRef, newRef);
	resB = getArg(q, 0);

	setVarType(mb, getArg(q, 0), newBatType(ht, tt));
	q = pushType(mb, q, ht);
	q = pushType(mb, q, tt);
	/* barrier (h,r) := iterator.new(refBat); */
	q = newFcnCall(mb, iteratorRef, newRef);
	q->barrier = BARRIERsymbol;
	hvar = newTmpVariable(mb, TYPE_any);
	getArg(q,0) = hvar;
	tvar = newTmpVariable(mb, TYPE_any);
	q= pushReturn(mb, q, tvar);
	(void) pushArgument(mb,q,iter);

	/* $1:= algebra.fetch(Ai,h) or constant */
	alias[i] = tvar;

	for (i++; i < pci->argc; i++)
		if (isaBatType(getArgType(mb, pci, i))) {
			q = newFcnCall(mb, algebraRef, "fetch");
			alias[i] = newTmpVariable(mb, getTailType(getArgType(mb, pci, i)));
			getArg(q, 0) = alias[i];
			q= pushArgument(mb, q, getArg(pci, i));
			(void) pushArgument(mb, q, hvar);
		}

	/* cr:= mod.CMD($1,...,$n); */
	q = newFcnCall(mb, mod, fcn);
	cr = getArg(q, 0) = newTmpVariable(mb, TYPE_any);

	for (i = 3; i < pci->argc; i++)
		if (isaBatType(getArgType(mb, pci, i))) {
			q= pushArgument(mb, q, alias[i]);
		} else {
			q = pushArgument(mb, q, getArg(pci, i));
		}

	/* y := algebra.fetch(x,h); */
	y = newTmpVariable(mb, getHeadType(getVarType(mb,iter)));
	q = newFcnCall(mb, algebraRef, "fetch");
	getArg(q, 0) = y;
	q = pushArgument(mb, q, x);
	q = pushArgument(mb, q, hvar);

	/* insert(resB,h,cr);
	   not append(resB, cr); the head type (oid) may dynamically change */

	q = newFcnCall(mb, batRef, insertRef);
	q= pushArgument(mb, q, resB);
	q= pushArgument(mb, q, y);
	(void) pushArgument(mb, q, cr);

/* redo (h,r):= iterator.next(refBat); */
	q = newFcnCall(mb, iteratorRef, nextRef);
	q->barrier = REDOsymbol;
	getArg(q,0) = hvar;
	q= pushReturn(mb, q, tvar);
	(void) pushArgument(mb,q,iter);

	q = newAssignment(mb);
	q->barrier = EXITsymbol;
	getArg(q,0) = hvar;
	(void) pushReturn(mb, q, tvar);

	q = newAssignment(mb);
	getArg(q, 0) = getArg(pci, 0);
	(void) pushArgument(mb, q, resB);
	GDKfree(alias);
	return MAL_SUCCEED;
}
int pushDisk(lua_State* luaSt, const Disk* p)
{
    return pushType(luaSt, DISK_TYPE, sizeof(Disk), (void*) p);
}
int pushNBodyCtx(lua_State* luaSt, const NBodyCtx* p)
{
    return pushType(luaSt, NBODYCTX_TYPE, sizeof(NBodyCtx), (void*) p);
}
int pushSpherical(lua_State* luaSt, const Spherical* p)
{
    return pushType(luaSt, SPHERICAL_TYPE, sizeof(Spherical), (void*) p);
}