36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
auto&& [s,tcc] = get< TCSol >( us );
return invoke( c, loc, callee, args, s, tcc );
}
Value invoke( const Context& c, uint32_t loc, const Value& callee, const Term& args, const Term& typeCheckedCallPat, TypeCheckingContext& tcc ) const final
{
auto newCallee = prepareFunc( c, 0, callee, typeCheckedCallPat, tcc );
if( newCallee.isPoison() )
return PoisonValue();
auto callDecomp = Decompose( typeCheckedCallPat,
Val< pvec >()
);
const auto& typeCheckedRType = callDecomp->get()->terms().front();
auto typeCheckedArgs = DropVectorTerm( typeCheckedCallPat, 1 );
newCallee.setLocationId( loc );
if( IsBuiltinFunc( newCallee ) )
return BuildComputedValue( typeCheckedRType, cir::Call( newCallee, move( typeCheckedArgs ) ) );
if( IsBuiltinIntrinsicFunc( newCallee ) )
return GetBuiltinIntrinsicFuncWrapper( newCallee )( c, move( typeCheckedArgs ) );
auto ft = *FromValue< FuncType >( *ValueFromEIR( newCallee.type() ) );
auto argList = BuildArgListForCall( c, ft, typeCheckedArgs );
if( !argList )
return PoisonValue();
return BuildComputedValue( typeCheckedRType, cir::Call( newCallee, move( *argList ) ) );
}
optional< Term > getSignature( const Value& callee ) const final
{
return GetFuncSig( callee );
}
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
auto&& [s,tcc] = get< TCSol >( us );
return invoke( c, loc, callee, args, s, tcc );
}
Value invoke( const Context& c, uint32_t loc, const Value& callee, const Term& args, const Term& typeCheckedCallPat, TypeCheckingContext& tcc ) const final
{
auto preparedCallee = prepareFunc( c, 0, callee, typeCheckedCallPat, tcc );
if( preparedCallee.isPoison() )
return PoisonValue();
auto callDecomp = Decompose( typeCheckedCallPat,
Val< pvec >()
);
const auto& typeCheckedRType = callDecomp->get()->terms().front();
auto typeCheckedArgs = DropVectorTerm( typeCheckedCallPat, 1 );
preparedCallee.setLocationId( loc );
if( IsBuiltinFunc( preparedCallee ) )
return BuildComputedValue( typeCheckedRType, cir::Call( preparedCallee, move( typeCheckedArgs ) ) );
if( IsBuiltinIntrinsicFunc( preparedCallee ) )
return GetBuiltinIntrinsicFuncWrapper( preparedCallee )( c, move( typeCheckedArgs ) );
auto ft = *FromValue< FuncType >( *ValueFromEIR( preparedCallee.type() ) );
if( ft.intrinsic() )
{
// Intrinsic call: we insert the code builder wrapper as first param,
// wrap all args with ValueWrapper, and execute the function directly.
auto argList = BuildArgListForIntrinsicCall( c, ft, typeCheckedArgs );
if( !argList )
return PoisonValue();
execute::VM vm;
auto result = vm.execute( cir::Call( preparedCallee, move( *argList ) ) );
if( !result )
return PoisonValue();
// Unwrap the returned value
auto unwrapped = FromValue< ValueWrapper >( *result );
return unwrapped ? *unwrapped : PoisonValue();
}
auto argList = BuildArgListForCall( c, ft, typeCheckedArgs );
if( !argList )
return PoisonValue();
return BuildComputedValue( typeCheckedRType, cir::Call( preparedCallee, move( *argList ) ) );
}
optional< Term > getSignature( const Value& callee ) const final
{
return GetFuncSig( callee );
}
|