void compileAndRunModule(AST_Module* m, BoxedModule* bm) { Timer _t("for compileModule()"); ScopingAnalysis* scoping = runScopingAnalysis(m); SourceInfo* si = new SourceInfo(bm, scoping); si->cfg = computeCFG(AST_TYPE::Module, m->body); si->ast = m; si->liveness = computeLivenessInfo(si->cfg); si->phis = computeRequiredPhis(NULL, si->cfg, si->liveness, si->scoping->getScopeInfoForNode(si->ast)); CLFunction* cl_f = new CLFunction(si); EffortLevel::EffortLevel effort = initialEffort(); CompiledFunction* cf = compileFunction(cl_f, new FunctionSignature(VOID, &si->getArgNames(), 0, false, false), effort, NULL); assert(cf->clfunc->versions.size()); _t.end(); if (cf->is_interpreted) interpretFunction(cf->func, 0, NULL, NULL, NULL, NULL); else ((void (*)())cf->code)(); }
void compileAndRunModule(AST_Module* m, BoxedModule* bm) { CompiledFunction* cf; { // scope for limiting the locked region: LOCK_REGION(codegen_rwlock.asWrite()); Timer _t("for compileModule()"); bm->future_flags = getFutureFlags(m, bm->fn.c_str()); ScopingAnalysis* scoping = runScopingAnalysis(m); SourceInfo* si = new SourceInfo(bm, scoping, m, m->body); si->cfg = computeCFG(si, m->body); si->liveness = computeLivenessInfo(si->cfg); si->phis = computeRequiredPhis(si->arg_names, si->cfg, si->liveness, si->getScopeInfo()); CLFunction* cl_f = new CLFunction(0, 0, false, false, si); EffortLevel::EffortLevel effort = initialEffort(); cf = compileFunction(cl_f, new FunctionSpecialization(VOID), effort, NULL); assert(cf->clfunc->versions.size()); } if (cf->is_interpreted) interpretFunction(cf->func, 0, NULL, NULL, NULL, NULL, NULL, NULL); else ((void (*)())cf->code)(); }
Box* callCompiledFunc(CompiledFunction *cf, int64_t nargs, Box* arg1, Box* arg2, Box* arg3, Box**args) { assert(cf); // TODO these shouldn't have to be initialized, but I don't want to issue a #pragma // that disables the warning for the whole file: Box *rarg1 = arg1, *rarg2 = arg2, *rarg3 = arg3; Box **rargs = NULL; if (nargs > 3) { if (cf->sig->is_vararg) { // the +2 is for the varargs and kwargs rargs = (Box**)alloca((nargs - 3 + 2) * sizeof(Box*)); memcpy(rargs, args, (nargs - 3) * sizeof(Box*)); } else { rargs = args; } } int nsig_args = cf->sig->arg_types.size(); BoxedList* made_vararg = NULL; if (cf->sig->is_vararg) { made_vararg = (BoxedList*)createList(); if (nsig_args == 0) rarg1 = made_vararg; else if (nsig_args == 1) rarg2 = made_vararg; else if (nsig_args == 2) rarg3 = made_vararg; else rargs[nsig_args-3] = made_vararg; for (int i = nsig_args; i < nargs; i++) { if (i == 0) listAppendInternal(made_vararg, arg1); else if (i == 1) listAppendInternal(made_vararg, arg2); else if (i == 2) listAppendInternal(made_vararg, arg3); else listAppendInternal(made_vararg, args[i - 3]); } } if (!cf->is_interpreted) { if (cf->sig->is_vararg) { Box* rtn = cf->call(rarg1, rarg2, rarg3, rargs); return rtn; } else { return cf->call(rarg1, rarg2, rarg3, rargs); } } else { return interpretFunction(cf->func, nargs, rarg1, rarg2, rarg3, rargs); } }
/** * \brief This function interprets APIVSXML Code * * \param[in] pCode - Start of code to interpret * \return STATUS_PASS - Test conformance (PASS) * STATUS_FAIL - Test nonconformance (FAIL) */ int16_t interpretPcode(P_CODE *pCode) { int16_t status = STATUS_PASS; boolean done = FALSE; // Execute the pCode while (NULL != pCode) { // Execute current statment switch (pCode->type) { case PC_E_PRINT: { status = interpretPrint(pCode); } break; case PC_E_SET: { status = interpretSet(pCode); } break; case PC_E_FUNC: { status = interpretFunction(pCode); } break; case PC_E_IF: { status = interpretIf(pCode); } break; case PC_E_WHILE: { status = interpretWhile(pCode); } break; case PC_E_THEN: { outputXmlAttrAddCommon(LEVEL_TRACE, &pCode->common, A_NAME); outputXmlTagOpen(LEVEL_TRACE, P_THEN, outputXmlAttrGet()); status = interpretPcode(pCode->pCode); outputXmlTagClose(LEVEL_TRACE, P_THEN); // Note done with this tree branch done = TRUE; } break; case PC_E_ELSE: { outputXmlAttrAddCommon(LEVEL_TRACE, &pCode->common, A_NAME); outputXmlTagOpen(LEVEL_TRACE, P_ELSE, outputXmlAttrGet()); status = interpretPcode(pCode->pCode); outputXmlTagClose(LEVEL_TRACE, P_ELSE); // Note done with this tree branch done = TRUE; } break; case PC_E_CALL: { status = interpretCall(pCode); } break; case PC_E_SIG: { status = interpretSignal(pCode); } break; case PC_E_AUX: { status = interpretAux(pCode); } break; case PC_E_ABORT: { status = interpretAbort(pCode); } break; case PC_E_DUMP: { status = interpretDump(pCode); } break; case PC_E_LOAD: { status = interpretLoad(pCode); } break; case PC_E_FORMAT: { status = interpretFormat(pCode); } break; case PC_E_SLEEP: { status = interpretSleep(pCode); } break; case PC_E_FPUII: { status = interpretFPUII(pCode); } break; case PC_E_FIOR: { status = interpretFIOR(pCode); } break; default: { char string[OUTPUT_STRING_MAX]; sprintf(string, "Unknown P_CODE type[%d]", pCode->type); OUTPUT_ERR(pCode->common.lineNumber, string, NULL, pCode->common.pDesc); status = STATUS_FAIL; } break; } if ( done || (/*(pCode->type == PC_E_ABORT) &&*/ (STATUS_FAIL == status)) ) { break; // We failed or we are done } // Move to next P_CODE pCode = pCode->pCode; } return(status); }