Пример #1
0
        private static async Task <Data> buildInternalDataAsync(ExecutionContext ctx, bool isNative, object value,
                                                                IEntityInstance typeInstance, bool isStatic)
        {
            EntityInstance runtime_instance = typeInstance.Cast <EntityInstance>();

            ObjectData primary_parent = null;

            if (!isStatic)
            {
                await ctx.TypeRegistry.RegisterAddAsync(ctx, runtime_instance).ConfigureAwait(false);
            }
            else
            {
                EntityInstance primary = runtime_instance.TargetType.Inheritance.GetTypeImplementationParent();
                if (primary != null)
                {
                    primary_parent = await ctx.TypeRegistry.RegisterGetAsync(ctx, primary).ConfigureAwait(false);
                }
            }

            var fields      = new Dictionary <VariableDeclaration, ObjectData>(ReferenceEqualityComparer <VariableDeclaration> .Instance);
            var translators = new List <EntityInstance>();

            IEnumerable <EntityInstance> source_types = new[] { runtime_instance };

            if (!isStatic)
            {
                source_types = source_types.Concat(runtime_instance.PrimaryAncestors(ctx.CreateBareComputation()));
            }

            foreach (EntityInstance type_instance in source_types)
            {
                translators.Add(type_instance);

                foreach (VariableDeclaration field in type_instance.TargetType.AllNestedFields
                         .Where(it => it.Modifier.HasStatic == isStatic))
                {
                    EntityInstance field_type = field.Evaluation.Components.Cast <EntityInstance>();
                    field_type = field_type.TranslateThrough((translators as IEnumerable <EntityInstance>).Reverse());
                    fields.Add(field, await ObjectData.CreateEmptyAsync(ctx, field_type).ConfigureAwait(false));
                }
            }

            Data data1 = new Data(isNative, value, runtime_instance, primary_parent, fields);

            return(data1);
        }
Пример #2
0
        private async Task <ExecValue> executeNativeChunkFunctionAsync(ExecutionContext ctx, FunctionDefinition func, ObjectData this_value)
        {
            if (func == ctx.Env.ChunkSizeConstructor)
            {
                IEntityInstance elem_type = this_value.RunTimeTypeInstance.TemplateArguments.Single();
                ObjectData      size_obj  = ctx.FunctionArguments.Single();
                var             size      = size_obj.NativeNat64;
                ObjectData[]    chunk     = (await Task.WhenAll(Enumerable.Range(0, (int)size).Select(_ => ObjectData.CreateEmptyAsync(ctx, elem_type))).ConfigureAwait(false)).ToArray();
                this_value.Assign(await createChunk(ctx, this_value.RunTimeTypeInstance, chunk).ConfigureAwait(false));
                return(ExecValue.CreateReturn(null));
            }
            else if (func == ctx.Env.ChunkResizeConstructor)
            {
                IEntityInstance elem_type  = this_value.RunTimeTypeInstance.TemplateArguments.Single();
                ObjectData      size_obj   = ctx.FunctionArguments[0];
                var             size       = size_obj.NativeNat64;
                ObjectData      source_obj = ctx.FunctionArguments[1];
                if (!source_obj.TryDereferenceAnyOnce(ctx.Env, out ObjectData val_obj))
                {
                    throw new Exception($"{ExceptionCode.SourceInfo()}");
                }
                Chunk source = val_obj.PlainValue.Cast <Chunk>();

                ObjectData[] chunk     = new ObjectData[size];
                var          copy_size = Math.Min(size, source.Count);
                for (UInt64 i = 0; i != copy_size; ++i)
                {
                    chunk[i] = source[i];
                    ctx.Heap.TryInc(ctx, source[i], RefCountIncReason.CopyingChunkElem, "");
                }
                for (var i = copy_size; i < size; ++i)
                {
                    chunk[i] = await ObjectData.CreateEmptyAsync(ctx, elem_type).ConfigureAwait(false);
                }
                this_value.Assign(await createChunk(ctx, this_value.RunTimeTypeInstance, chunk).ConfigureAwait(false));
                return(ExecValue.CreateReturn(null));
            }
            else if (func == ctx.Env.ChunkAtSet)
            {
                ObjectData idx_obj = ctx.GetArgument(func, NameFactory.IndexIndexerParameter);
                var        idx     = idx_obj.NativeNat64;
                Chunk      chunk   = this_value.PlainValue.Cast <Chunk>();
                ctx.Heap.TryRelease(ctx, chunk[idx], passingOutObject: null, isPassingOut: false, reason: RefCountDecReason.ReplacingChunkElem, comment: "");
                ObjectData arg_ref_object = ctx.GetArgument(func, NameFactory.PropertySetterValueParameter);
                // indexer takes reference to element
                if (!arg_ref_object.TryDereferenceAnyOnce(ctx.Env, out ObjectData arg_val))
                {
                    throw new Exception($"{ExceptionCode.SourceInfo()}");
                }
                if (!ctx.Heap.TryIncPointer(ctx, arg_val, RefCountIncReason.SettingChunkElem, ""))
                {
                    arg_val = arg_val.Copy();
                }
                chunk[idx] = arg_val;
                return(ExecValue.CreateReturn(null));
            }
            else if (func == ctx.Env.ChunkAtGet)
            {
                ObjectData idx_obj   = ctx.GetArgument(func, NameFactory.IndexIndexerParameter);
                var        idx       = idx_obj.NativeNat64;
                Chunk      chunk     = this_value.PlainValue.Cast <Chunk>();
                ObjectData obj_value = chunk[idx];
                // indexer returns reference to an element value
                ObjectData obj_ref = await obj_value.ReferenceAsync(ctx).ConfigureAwait(false);

                return(ExecValue.CreateReturn(obj_ref));
            }
            else if (func == ctx.Env.ChunkCount)
            {
                Chunk      chunk  = this_value.PlainValue.Cast <Chunk>();
                ObjectData result = await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components,
                                                                         chunk.Count).ConfigureAwait(false);

                return(ExecValue.CreateReturn(result));
            }
            else
            {
                throw new NotImplementedException($"{ExceptionCode.SourceInfo()}");
            }
        }