Пример #1
0
 const ConstOperator* ESolver::CreateConstant(const string& ConstantName,
                                              const ESFixedTypeBase* Type,
                                              const string& ConstantString)
 {
     const ConcreteValueBase* TheValue = CreateValue(Type, ConstantString);
     return CreateConstant(ConstantName, TheValue);
 }
Пример #2
0
    const ESFixedTypeBase* ESolver::CreateEnumType(const string& TypeName,
                                                   const vector<string>& EnumConstructors)
    {
        if(TypeMgr->LookupType(TypeName) != NULL) {
            throw TypeException("Redeclaration of Type \"" + TypeName + "\"");
        }

        // Safety check to ensure that enum constructors are not
        // repeated
        set<string> EnumConstructorSet;
        const uint32 NumEnumConstructors = EnumConstructors.size();
        for(uint32 i = 0; i < NumEnumConstructors; ++i) {
            if(EnumConstructorSet.find(EnumConstructors[i]) != EnumConstructorSet.end()) {
                throw TypeException((string)"Duplicate Enum constructor \"" + EnumConstructors[i] + "\"");
            }
            EnumConstructorSet.insert(EnumConstructors[i]);
        }

        auto Retval = TypeMgr->CreateType<ESEnumType>(TypeName, EnumConstructors);
        TypeMgr->BindType(TypeName, Retval);

        RegisterType(Retval);
        
        // Create values and constant operators for each constructor
        // Push a bunch of constant operators into the fray. One for each enum constructor
        for(auto const& EnumConstructor : EnumConstructors) {
            CreateConstant(TypeName + "::" + EnumConstructor,
                           Retval, EnumConstructor);
        }

        return Retval;
    }
Пример #3
0
static struct KVirtualCode *FuelVM_GenerateVirtualCode(KonohaContext *kctx, kMethod *mtd, kNode *block, int option)
{
	if(unlikely(AbstractMethodPtr == 0)) {
		AbstractMethodPtr = mtd->invokeKMethodFunc;
	}

	kNameSpace *ns = kNode_ns(block);
	KBuilder builderbuf = {}, *builder = &builderbuf;
	FuelIRBuilder Builder = {};
	INIT_GCSTACK();
	IRBuilder_Init(&Builder, kctx, ns);
	builder->builder = &Builder;
	builder->common.api = ns->builderApi;
	Block *EntryBlock = CreateBlock(BLD(builder));
	IRBuilder_setBlock(BLD(builder), EntryBlock);
	INode *Self = SetUpArguments(kctx, &Builder, mtd);

	SUGAR VisitNode(kctx, builder, block, NULL);

	if(!Block_HasTerminatorInst(BLD(builder)->Current)) {
		if(mtd->mn == MN_new) {
			INode *Ret = CreateReturn(BLD(builder), Self);
			INode_setType(Ret, ConvertToTypeId(kctx, mtd->typeId));
		} else {
			ktypeattr_t retTy = kMethod_GetReturnType(mtd)->typeId;
			if(retTy == KType_void) {
				CreateReturn(BLD(builder), 0);
			} else {
				enum TypeId Type = ConvertToTypeId(kctx, retTy);
				INode *Ret;
				if(KType_Is(UnboxType, retTy)) {
					SValue V; V.bits = 0;
					Ret = CreateConstant(BLD(builder), Type, V);
				} else {
					kObject *obj = KLIB Knull(kctx, KClass_(retTy));
					Ret = CreateObject(BLD(builder), Type, (void *)obj);
				}
				Ret = CreateReturn(BLD(builder), Ret);
				INode_setType(Ret, Type);
				CreateReturn(BLD(builder), 0);
			}
		}
	}
	RESET_GCSTACK();
	IMethod Mtd = {kctx, mtd, EntryBlock, ns};
	BLD(builder)->Method = &Mtd;
	bool JITCompiled = false;
	union ByteCode *code = IRBuilder_Compile(BLD(builder), &Mtd, option, &JITCompiled);
	if(mtd->invokeKMethodFunc == FuelVM_RunVirtualMachine) {
		mtd->virtualCodeApi_plus1[-1]->FreeVirtualCode(kctx, mtd->vcode_start);
	}
	KLIB kMethod_SetFunc(kctx, mtd, 0);
	if(JITCompiled) {
		KLIB kMethod_SetFunc(kctx, mtd, (KMethodFunc) code);
	}
	KFieldSet(mtd, ((kMethodVar *)mtd)->CompiledNode, block);
	IRBuilder_Exit(&Builder);
	return (struct KVirtualCode *) code;
}
Пример #4
0
static kbool_t FuelVM_VisitUnboxConstNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk)
{
	DBG_ASSERT(KType_Is(UnboxType, expr->attrTypeId));
	//DBG_ASSERT(!kNode_HasObjectConstValue(expr));

	SValue Val = {};
	Val.bits = expr->unboxConstValue;
	builder->Value = CreateConstant(BLD(builder), ConvertToTypeId(kctx, expr->attrTypeId), Val);
	return true;
}
Пример #5
0
static kbool_t FuelVM_VisitNullNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk)
{
	SValue Val = {};
	ktypeattr_t type = expr->attrTypeId;
	if(KType_Is(UnboxType, type)) {
		Val.bits = 0;
	} else {
		Val.ptr = (void *) KLIB Knull(kctx, KClass_(type));
	}
	builder->Value = CreateConstant(BLD(builder), ConvertToTypeId(kctx, expr->attrTypeId), Val);
	return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AggregateCopyPropagation::ReplaceWithOriginal(LoadInstr* instr, 
                                                   TOperandToIdDict& availableCopies,
                                                   BitVector& killSet) {
    if(availableCopies.Count() == 0) {
        return;
    }

    // Try to replace each operand with the original one
    // (the one from which the copy was made).
    Instruction* lastInstr = nullptr;
    auto candidateOp = GetBaseOperand(instr->SourceOp(), &lastInstr);

    // Give up if we couldn't find a candidate,
    // or if the candidate is an instruction whose result
    // is used in more than one place.
    if((candidateOp == nullptr) || (lastInstr == nullptr) || 
       (lastInstr->GetDestinationOp()->HasSingleUser() == false)) {
        return;
    }
        
    // We can replace the operand if it's a copy
    // (found in 'availableCopies') and the source or copy
    // was not killed until this point.
    CopySetInfo info;

    if(GetOldestAvailable(candidateOp, availableCopies, killSet, info)) {
        if(info.IsCopy) {
            // Replace the operand with the original.
            auto originalOp = info.Source;
            lastInstr->ReplaceSourceOp(0, originalOp);
            info.Replacements++;
            CopyPropagated(instr);
        }
        else if(instr->HasDestinationOp()) {
            // The load itself is replaced by the value
            // to which the record/array was set.
            auto requiredType = instr->GetDestinationOp()->GetType();
            auto constantOp = CreateConstant(requiredType, info);
            instr->GetDestinationOp()->ReplaceWith(constantOp);
            info.Replacements++;
            CopyPropagated(instr);
        }
    }
}
Пример #7
0
EvalAtom::EvalAtom(std::wstring& src, 
						 EvalAtomType atomType)
{
	AtomType = atomType;
	Value    = 0.0;
	Index    = -1;
	Function = NULL;
	Operator = NULL;

	switch (atomType)
	{
		case EvalAtomType::Operator:
			CreateOperator(src);
			break;

		case EvalAtomType::Function:
			CreateFunction(src);
			break;

		case EvalAtomType::Variable:
			/**
			 * If identifier of variable will be found in 
			 * internal constants table we will store this
			 * constant, not variable. 
			 */
			if (EvalTable::IsConstExists(src))
			{
				AtomType = EvalAtomType::Constant;
				CreateNamedConstant(src);
			}
			else
			{ CreateVariable(src); }
			break;

		case EvalAtomType::Constant:
			CreateConstant(src);
			break;
	}
}
Пример #8
0
/* PreprocessLine() is the "preprocessor".
 * 1. the line is tokenized with Tokenize(), Token_Count set
 * 2. (text) macros are expanded by ExpandLine()
 * 3. "preprocessor" directives are executed
 */
int PreprocessLine( char *line, struct asm_tok tokenarray[] )
/***********************************************************/
{
    int i;

    /* v2.11: GetTextLine() removed - this is now done in ProcessFile() */

    /* v2.08: moved here from GetTextLine() */
    ModuleInfo.CurrComment = NULL;
    /* v2.06: moved here from Tokenize() */
    ModuleInfo.line_flags = 0;
    /* Token_Count is the number of tokens scanned */
    Token_Count = Tokenize( line, 0, tokenarray, TOK_DEFAULT );

#ifdef DEBUG_OUT
    cntppl0++;
    if ( ModuleInfo.GeneratedCode )
        DebugMsg1(("PreprocessLine: >%s<\n", line ));
    else
        DebugMsg1(("PreprocessLine(%s): >%s< cmt=%s\n", GetTopSrcName(), line, ModuleInfo.CurrComment ? ModuleInfo.CurrComment : "" ));
#endif

#if REMOVECOMENT == 0
    if ( Token_Count == 0 && ( CurrIfState == BLOCK_ACTIVE || ModuleInfo.listif ) )
        LstWriteSrcLine();
#endif

    if ( Token_Count == 0 )
        return( 0 );

#ifdef DEBUG_OUT
    /* option -np, skip preprocessor? */
    if ( Options.skip_preprocessor )
        return( Token_Count );
#endif

    /* CurrIfState != BLOCK_ACTIVE && Token_Count == 1 | 3 may happen
     * if a conditional assembly directive has been detected by Tokenize().
     * However, it's important NOT to expand then */
    if ( CurrIfState == BLOCK_ACTIVE ) {
        if ( ( tokenarray[Token_Count].bytval & TF3_EXPANSION ? ExpandText( line, tokenarray, TRUE ) : ExpandLine( line, tokenarray ) ) < NOT_ERROR )
            return( 0 );
    }

    DebugCmd( cntppl1++ );

    i = 0;
    if ( Token_Count > 2 && ( tokenarray[1].token == T_COLON || tokenarray[1].token == T_DBL_COLON ) )
        i = 2;

    /* handle "preprocessor" directives:
     * IF, ELSE, ENDIF, ...
     * FOR, REPEAT, WHILE, ...
     * PURGE
     * INCLUDE
     * since v2.05, error directives are no longer handled here!
     */
    if ( tokenarray[i].token == T_DIRECTIVE &&
        tokenarray[i].dirtype <= DRT_INCLUDE ) {

        /* if i != 0, then a code label is located before the directive */
        if ( i > 1 ) {
            if ( ERROR == WriteCodeLabel( line, tokenarray ) )
                return( 0 );
        }
        directive_tab[tokenarray[i].dirtype]( i, tokenarray );
        return( 0 );
    }

    /* handle preprocessor directives which need a label */

    if ( tokenarray[0].token == T_ID && tokenarray[1].token == T_DIRECTIVE ) {
        struct asym *sym;
        switch ( tokenarray[1].dirtype ) {
        case DRT_EQU:
            /*
             * EQU is a special case:
             * If an EQU directive defines a text equate
             * it MUST be handled HERE and 0 must be returned to the caller.
             * This will prevent further processing, nothing will be stored
             * if FASTPASS is on.
             * Since one cannot decide whether EQU defines a text equate or
             * a number before it has scanned its argument, we'll have to
             * handle it in ANY case and if it defines a number, the line
             * must be stored and, if -EP is set, written to stdout.
             */
            if ( sym = CreateConstant( tokenarray ) ) {
                if ( sym->state != SYM_TMACRO ) {
#if FASTPASS
                    if ( StoreState ) FStoreLine( 0 );
#endif
                    if ( Options.preprocessor_stdout == TRUE )
                        WritePreprocessedLine( line );
                }
                /* v2.03: LstWrite() must be called AFTER StoreLine()! */
                if ( ModuleInfo.list == TRUE ) {
                    LstWrite( sym->state == SYM_INTERNAL ? LSTTYPE_EQUATE : LSTTYPE_TMACRO, 0, sym );
                }
            }
            return( 0 );
        case DRT_MACRO:
        case DRT_CATSTR: /* CATSTR + TEXTEQU directives */
        case DRT_SUBSTR:
            directive_tab[tokenarray[1].dirtype]( 1, tokenarray );
            return( 0 );
        }
    }

    DebugCmd( cntppl2++ );
    return( Token_Count );
}