Esempio n. 1
0
void o_bootstrap_thread_context_init_llvm_type(oThreadContextRef ctx) {
	LLVMTypeRef types[6];
	char* un;
	// runtime, opaque pointer. The runtime object is not part of the type system
	types[0] = ctx->runtime->builtInTypes.pointer->llvmType;
	// heap, also opaque
	types[1] = ctx->runtime->builtInTypes.pointer->llvmType;
	// error type, not initialized yet so we create a prototype for it
	un = oGenUniqueName(ctx);
	ctx->runtime->builtInTypes.error->llvmType = LLVMStructCreateNamed(ctx->runtime->llvmCtx, un);
	oFree(un);
	types[2] = ctx->runtime->builtInTypes.error->llvmType;
	// namespace, also needs a prototype
	un = oGenUniqueName(ctx);
	ctx->runtime->builtInTypes.name_space->llvmType = LLVMStructCreateNamed(ctx->runtime->llvmCtx, un);
	oFree(un);
	types[3] = ctx->runtime->builtInTypes.name_space->llvmType;
	// root set, opaque
	types[4] = ctx->runtime->builtInTypes.pointer->llvmType;
	// root set semaphore. This is volatile in the C code but llvm uses volatile
	// on instructions rather than data so this is a regular uword here.
	types[5] = ctx->runtime->builtInTypes.uword->llvmType;

	ctx->runtime->builtInTypes.threadContext->llvmType = LLVMStructTypeInContext(ctx->runtime->llvmCtx, types, 6, o_false);
}
Esempio n. 2
0
static LLVMTypeRef llvmTypeForSignature(oThreadContextRef ctx, oSignatureRef sig) {
	uword i;
	LLVMTypeRef fnType, retType;
	oParameterRef* params = (oParameterRef*)oArrayDataPointer(sig->parameters);
	LLVMTypeRef* paramTypes = (LLVMTypeRef*)oMalloc(sizeof(LLVMTypeRef) * sig->parameters->num_elements);

	if(sig->retType->kind == o_T_OBJECT) {
		retType = LLVMPointerType(sig->retType->llvmType, 0);
	} else {
		retType = sig->retType->llvmType;
	}
	for(i = 0; i < sig->parameters->num_elements; ++i) {
		if(params[i]->type->kind == o_T_OBJECT) {
			paramTypes[i] = LLVMPointerType(params[i]->type->llvmType, 0);
		} else {
			paramTypes[i] = params[i]->type->llvmType;
		}
	}
	fnType = LLVMFunctionType(retType, paramTypes, sig->parameters->num_elements, o_false);
	oFree(paramTypes);
	return fnType;
}
Esempio n. 3
0
oFunctionOverloadRef _oFunctionOverloadRegisterNative(oThreadContextRef ctx,
                                                      oSignatureRef sig,
                                                      oArrayRef attributes,
                                                      pointer fn) {
    oFunctionOverloadRef overload;
	char* un;
    
    // Allocate in shared heap
    overload = (oFunctionOverloadRef)o_bootstrap_object_alloc(ctx->runtime, ctx->runtime->builtInTypes.functionOverload, sizeof(oFunctionOverload));
    if(overload == NULL) {
        ctx->error = ctx->runtime->builtInErrors.outOfMemory;
        return NULL;
    }

	if(attributes) {
		overload->attributes = _oHeapCopyObjectShared(ctx, attributes);
		if(overload->attributes == NULL) {
			return NULL;
		}
	}

    overload->signature = _oHeapCopyObjectShared(ctx, sig);
    if(overload->signature == NULL) {
        return NULL;
    }

    overload->code = fn;
	un = oGenUniqueName(ctx);
    if(un == NULL) {
        ctx->error = ctx->runtime->builtInErrors.outOfMemory;
        return NULL;
    }
	overload->llvmFunction = LLVMAddFunction(ctx->runtime->llvmModule, un, llvmTypeForSignature(ctx, sig));
	oFree(un);
	LLVMAddGlobalMapping(ctx->runtime->llvmEE, overload->llvmFunction, fn);
    return overload;
}
Esempio n. 4
0
void genfunc(SYMBOL *funcsp)
/*
 *      generate a function body and dump the icode
 */
{
    IMODE *allocaAP = NULL;
    SYMBOL *oldCurrentFunc;
    EXPRESSION *funcexp = varNode(en_global, funcsp);
    if (total_errors)
        return;
//	//printf("%s\n", funcsp->name);
    contlab = breaklab =  - 1;
    structret_imode = 0 ;
    tempCount = 0;
    blockCount = 0;
    blockMax = 0;
    exitBlock = 0;
    oldCurrentFunc = theCurrentFunc;
    theCurrentFunc = funcsp;
    iexpr_func_init();
    /*      firstlabel = nextLabel;*/
    cseg();
    gen_line(funcsp->linedata);
    gen_func(funcexp, 1);
    /* in C99 inlines can clash if declared 'extern' in multiple modules */
    /* in C++ we introduce virtual functions that get coalesced at link time */
    if (cparams.prm_cplusplus && funcsp->linkage == lk_inline)
        gen_virtual(funcsp, FALSE);
    else
    {
        if (funcsp->storage_class == sc_global)
                globaldef(funcsp);
        else
            localdef(funcsp);
        gen_strlab(funcsp); /* name of function */
    }
    addblock( - 1);
       if (funcsp->linkage == lk_interrupt || funcsp->linkage == lk_fault) {
        gen_icode(i_pushcontext, 0,0,0);
/*		if (funcsp->loadds) */
/*	        gen_icode(i_loadcontext, 0,0,0); */
    }
    gen_icode(i_prologue,0,0,0);
    gen_label(startlab);
/*    if (funcsp->loadds && funcsp->farproc) */
/*	        gen_icode(i_loadcontext, 0,0,0); */
    AllocateLocalContext(NULL, funcsp);
    if (funcsp->allocaUsed)
    {
            EXPRESSION *allocaExp = varNode(en_auto, anonymousVar(sc_auto, &stdpointer));
            allocaAP = gen_expr(funcsp, allocaExp, 0, ISZ_ADDR);
            gen_icode(i_savestack, 0, allocaAP, 0);
    }
    /* Generate the icode */
    /* LCSE is done while code is generated */
    genstmt(funcsp->inlineFunc.stmt->lower, funcsp);
    if (funcsp->inlineFunc.stmt->blockTail)
    {
        gen_icode(i_functailstart, 0, 0, 0);
        genstmt(funcsp->inlineFunc.stmt->blockTail, funcsp);
        gen_icode(i_functailend, 0, 0, 0);
    }
    genreturn(0, funcsp, 1, 0, allocaAP);
    gen_func(funcexp, 0);
    tFree();
    InsertParameterThunks(funcsp, blockArray[1]);
    optimize(funcsp);
    FreeLocalContext(NULL, funcsp);
        
    AllocateStackSpace(funcsp);
    FillInPrologue(intermed_head, funcsp);
    /* Code gen from icode */
    rewrite_icode(); /* Translate to machine code & dump */
    if (chosenAssembler->gen->post_function_gen)
        chosenAssembler->gen->post_function_gen(funcsp, intermed_head);
    if (cparams.prm_cplusplus && funcsp->linkage == lk_inline)
        gen_endvirtual(funcsp);
    intermed_head = NULL;
    dag_rundown();
    oFree();
    theCurrentFunc = oldCurrentFunc;
    if (blockCount > maxBlocks)
        maxBlocks = blockCount;
    if (tempCount > maxTemps)
        maxTemps = tempCount;
}