Goose  Diff

Differences From Artifact [fc1ba776f0]:

  • File bs/builtins/types/func/invoke.cpp — part of check-in [bbd2c17c42] at 2021-09-01 23:26:05 on branch trunk — Some cleanup and small reorganization in preparation for implementing non builtin intrinsic functions (user: achavasse size: 4080)

To Artifact [8b080f07cf]:

  • File bs/builtins/types/func/invoke.cpp — part of check-in [121560d1c1] at 2021-09-09 18:12:35 on branch trunk — Implemented non-builtin intrinsic function invocation (user: achavasse size: 4958)

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 );
            }