private async Task <ExecValue> executeNativeChannelFunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData this_value) { if (func.IsDefaultInitConstructor()) { Channels.IChannel <ObjectData> channel = Channels.Channel.Create <ObjectData>(); ctx.Heap.TryAddDisposable(channel); ObjectData channel_obj = await ObjectData.CreateInstanceAsync(ctx, this_value.RunTimeTypeInstance, channel).ConfigureAwait(false); this_value.Assign(channel_obj); return(ExecValue.CreateReturn(null)); } else if (func.Name.Name == NameFactory.ChannelSend) { ObjectData arg = ctx.FunctionArguments.Single(); if (!ctx.Env.IsPointerOfType(arg.RunTimeTypeInstance)) { arg = arg.Copy(); } Channels.IChannel <ObjectData> channel = this_value.PlainValue.Cast <Channels.IChannel <ObjectData> >(); bool result = await channel.SendAsync(arg).ConfigureAwait(false); return(ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx, this_value.RunTimeTypeInstance, result).ConfigureAwait(false))); } else if (func.Name.Name == NameFactory.ChannelReceive) { Channels.IChannel <ObjectData> channel = this_value.PlainValue.Cast <Channels.IChannel <ObjectData> >(); EntityInstance channel_type = this_value.RunTimeTypeInstance; IEntityInstance value_type = channel_type.TemplateArguments.Single(); Option <ObjectData> received = await channel.ReceiveAsync().ConfigureAwait(false); // we have to compute Skila Option type (not C# one we use for C# channel type) EntityInstance option_type = ctx.Env.OptionType.GetInstance( TypeMutability.None, TemplateTranslation.Create(ctx.Env.OptionType.InstanceOf, value_type), Lifetime.Timeless); ExecValue opt_exec = await createOption(ctx, option_type, received).ConfigureAwait(false); if (opt_exec.IsThrow) { return(opt_exec); } ObjectData result = opt_exec.ExprValue; // at this point Skila option is initialized so we can return it return(ExecValue.CreateReturn(result)); } else { throw new NotImplementedException($"{ExceptionCode.SourceInfo()}"); } }