Example #1
0
        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()}");
            }
        }