private async Task <ExecValue> executeNativeFileFunctionAsync(ExecutionContext ctx, FunctionDefinition func) { if (func == ctx.Env.FileReadLines) { ObjectData filepath_obj = ctx.GetArgument(func, NameFactory.FileFilePathParameter); if (!filepath_obj.TryDereferenceAnyOnce(ctx.Env, out ObjectData filepath_val)) { throw new Exception($"{ExceptionCode.SourceInfo()}"); } string filepath = filepath_val.PlainValue.Cast <string>(); string[] lines = null; try { // todo: change it to ReadLines once we have deferred execution lines = System.IO.File.ReadAllLines(filepath); } #pragma warning disable 0168 catch (Exception ex) // we would use it when debugging #pragma warning restore 0168 { } Option <ObjectData> opt_lines_obj; ObjectData chunk_ptr; if (lines == null) { chunk_ptr = null; opt_lines_obj = new Option <ObjectData>(); } else { IEntityInstance string_ptr_instance; { IEntityInstance ptr_iterable_instance = func.ResultTypeName.Evaluation.Components.Cast <EntityInstance>().TemplateArguments.Single(); IEntityInstance iterable_str_ptr_instance = ptr_iterable_instance.Cast <EntityInstance>().TemplateArguments.Single(); string_ptr_instance = iterable_str_ptr_instance.Cast <EntityInstance>().TemplateArguments.Single(); } var lines_obj = new ObjectData[lines.Length]; int i = 0; foreach (string s in lines) { ObjectData s_ptr = await createStringAsync(ctx, s).ConfigureAwait(false); if (!ctx.Heap.TryInc(ctx, s_ptr, RefCountIncReason.FileLine, $"{filepath}")) { throw new Exception($"{ExceptionCode.SourceInfo()}"); } lines_obj[i] = s_ptr; ++i; } chunk_ptr = await createChunkOnHeap(ctx, string_ptr_instance, lines_obj).ConfigureAwait(false); opt_lines_obj = new Option <ObjectData>(chunk_ptr); } ExecValue opt_exec = await createOption(ctx, func.ResultTypeName.Evaluation.Components, opt_lines_obj).ConfigureAwait(false); if (chunk_ptr != null) { ctx.Heap.TryRelease(ctx, chunk_ptr, null, false, RefCountDecReason.DroppingLocalPointer, ""); } if (opt_exec.IsThrow) { return(opt_exec); } ObjectData result = opt_exec.ExprValue; return(ExecValue.CreateReturn(result)); } else if (func == ctx.Env.FileExists) { ObjectData filepath_obj = ctx.GetArgument(func, NameFactory.FileFilePathParameter); if (!filepath_obj.TryDereferenceAnyOnce(ctx.Env, out ObjectData filepath_val)) { throw new Exception($"{ExceptionCode.SourceInfo()}"); } string filepath = filepath_val.PlainValue.Cast <string>(); bool exists = System.IO.File.Exists(filepath); ExecValue result = ExecValue.CreateReturn(await ObjectData.CreateInstanceAsync(ctx, func.ResultTypeName.Evaluation.Components, exists).ConfigureAwait(false)); return(result); } else { throw new NotImplementedException($"{ExceptionCode.SourceInfo()}"); } }
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()}"); } }