Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions modules/base/src/Resource.fz
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion standard library feature Resource
#
# -----------------------------------------------------------------------

module Resource/* NYI? (OR type : Resources)*/ ref : property.hashable, property.orderable is
res_id := unique_id
public fixed redef type.lteq(a, b Resource) bool => a.res_id <= b.res_id
public fixed redef type.hash_code(a Resource) u64 => a.res_id
module close outcome unit => abstract
9 changes: 5 additions & 4 deletions modules/base/src/io/file/mapped_buffer.fz
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ module:public mapped_buffer
# the length of this buffer
public redef length i64
)
: container.Buffer u8 mapped_buffer.this, mutate is
: container.Buffer u8 mapped_buffer.this, mutate, Resource is


# get byte at given index i
#
public redef index [ ] (I type : idx, i I) u8
=>
replace
resources0.register_usage mapped_buffer.this
fzE_mapped_buffer_get memory i.as_i64


Expand All @@ -48,11 +48,12 @@ module:public mapped_buffer
public redef set [ ] (I type : idx, i I, o u8) unit
=>
replace
resources0.register_usage mapped_buffer.this
fzE_mapped_buffer_set memory i.as_i64 o


# cleanup
#
public redef finally unit =>
module redef close outcome unit =>
if fzE_munmap memory length != 0
fuzion.runtime.fault.cause ("io.file.mapped_buffer.finally", "unmapping memory failed")
error "unmapping memory failed"
69 changes: 69 additions & 0 deletions modules/base/src/io/file/open2.fz
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
module:public file2(desc File_Descriptor) : Resource is

public read(n u64) outcome (Sequence u8) =>
resources0.register_usage file2.this
fuzion.sys.fileio.read desc n

# definition of read handler for file
#
read_handler : io.Read_Handler is
public redef read(count i32) choice (Sequence u8) io.end_of_file error =>
resources0.register_usage file2.this
match fuzion.sys.fileio.read desc count.as_u64
s Sequence => if s.is_empty then io.end_of_file else s
e error => e

public reader(R type, code ()->R) outcome R =>
file_mutate ! ()->
(io.buffered file_mutate).reader read_handler ! code

public write (bytes Sequence u8) outcome unit =>
resources0.register_usage file2.this
fuzion.sys.fileio.write desc bytes.as_array

# definition of write handler for file
#
write_handler : io.Write_Handler is
public redef write (bytes Sequence u8) outcome unit =>
resources0.register_usage file2.this
fuzion.sys.fileio.write desc bytes.as_array

public writer(R type, code ()->R) outcome R =>
file_mutate ! ()->
(io.buffered file_mutate).writer write_handler ! code

public seek(offset i64) outcome unit =>
resources0.register_usage file2.this
fuzion.sys.fileio.seek desc offset

public file_position outcome i64 =>
resources0.register_usage file2.this
fuzion.sys.fileio.file_position desc

public mmap(offset i64, size i64) outcome io.file.mapped_buffer
pre safety: offset % os.mmap_offset_multiple = 0
=>
resources0.register_usage file2.this
mapped_memory := fzE_mmap desc offset size

if fzE_is_valid_mapped_memory mapped_memory
error "mmap failed, error code: {fzE_last_error}"
else
res := io.file.mapped_buffer mapped_memory size
resources0.open res
res


module redef close =>
fuzion.sys.fileio.close desc

resources0.open file2.this


public open2(file_name path, m mode.val) outcome file2 ! resources =>
mode_num :=
match m
mode.read => 0
mode.write => 1
mode.append => 2
(fuzion.sys.fileio.open file_name mode_num).bind file2
67 changes: 67 additions & 0 deletions modules/base/src/resources.fz
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion standard library feature resources
#
# -----------------------------------------------------------------------

# resources is an effect to store open resources
#
# when deinstated it closes the resources in reverse order
# that they were opened.
#
public resources : effect is

# NYI:
_ := mut

# do not remove this type!
# it enforces boxing. Does not work without it.
#
s container.Stack Resource := container.stack mutate Resource

module register_usage(r Resource) unit =>
replace
if !s.as_sequence.contains r
fuzion.runtime.fault.cause ("resources.register_usage",
"Resource already closed or Resource owned by another thread.")

# NYI: public close(r Resource) outcome unit =>

module open (r Resource) =>
replace
s.push r

public redef finally unit =>
_ :=
for r := s.pop
while r.ok
res := r.val.close

# NYI: UNDER DEVELOPMENT: what to do on error?

if resources_observer.is_instated
resources_observer.env.send res


module resources0 =>
if !resources.is_instated
resources.default resources
resources.env

26 changes: 26 additions & 0 deletions modules/base/src/resources_observer.fz
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion standard library feature resources_observer
#
# -----------------------------------------------------------------------

# resources_observer is a simple effect to observe results of closing a resource
#
public resources_observer(public send (outcome unit) -> unit) : effect is
25 changes: 25 additions & 0 deletions tests/resources/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion test Makefile
#
# -----------------------------------------------------------------------

override NAME = resources
include ../simple.mk
37 changes: 37 additions & 0 deletions tests/resources/resources.fz
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion test resources
#
# -----------------------------------------------------------------------

resources_test =>

_ := io.file.write "file" "Content"

f2 outcome io.file.file2 := (resources_observer say) ! ()->
# resources will be closed when this effect finishes
resources ! ()->
io.file
.open2 (path.of "file") io.file.mode.append
.bind f->
_ := f.mmap 0 7 .bind mb->
say <| String.from mb.as_array
f
say <| f2.bind (.read 1)
1 change: 1 addition & 0 deletions tests/resources/resources.fz.expected_err_c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*** failed resources.register_usage: `Resource already closed or Resource owned by another thread.`
29 changes: 29 additions & 0 deletions tests/resources/resources.fz.expected_err_int
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

error 1: FATAL FAULT `resources.register_usage`: Resource already closed or Resource owned by another thread.
Call stack:
fuzion.type.runtime.type.fault.type.install_default.λ.call#1: {base.fum}/fuzion/runtime/fault.fz:57:7:
fuzion.sys.fatal_fault kind msg
------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
fuzion.runtime.fault.cause#1: {base.fum}/eff/fallible.fz:35:6:
=> h e
-----^
resources.register_usage#1: {base.fum}/Resources.fz:14:7:
fuzion.runtime.fault.cause ("resources.register_usage",
------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"Resource already closed or Resource owned by another thread.")
----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
io.file.file2.read#1: {base.fum}/io/file/open.fz:88:5:
resources0.register_usage file2.this
----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
resources_test.λ.call#1: --CURDIR--/resources.fz:37:20:
say <| f2.bind (.read 1)
-------------------^^^^
(outcome io.file.file2).bind#2 (Sequence u8): {base.fum}/outcome.fz:111:27:
outcome.this ? v T => f v
--------------------------^
resources_test: --CURDIR--/resources.fz:37:10:
say <| f2.bind (.read 1)
---------^^^^^^^^^^^^^^^^^

*** fatal errors encountered, stopping.
one error.
14 changes: 14 additions & 0 deletions tests/resources/resources.fz.expected_err_jvm
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

error 1: FATAL FAULT `resources.register_usage`: Resource already closed or Resource owned by another thread.
Call stack:
fuzion.sys.fatal_fault#2 at {base.fum}/fuzion/sys.fz:55
fuzion.type.runtime.type.fault.type.install_default.λ.call#1 at {base.fum}/fuzion/runtime/fault.fz:57
fuzion.runtime.fault.cause#1 at {base.fum}/eff/fallible.fz:35
resources.register_usage#1 at {base.fum}/Resources.fz:14
io.file.file2.read#1 at {base.fum}/io/file/open.fz:88
resources_test.λ.call#1 at --CURDIR--/resources.fz:37
(outcome io.file.file2).bind#2 (Sequence u8) at {base.fum}/outcome.fz:111
resources_test at --CURDIR--/resources.fz:37

*** fatal errors encountered, stopping.
one error.
3 changes: 3 additions & 0 deletions tests/resources/resources.fz.expected_out_c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Content
unit
unit
3 changes: 3 additions & 0 deletions tests/resources/resources.fz.expected_out_int
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Content
unit
unit
3 changes: 3 additions & 0 deletions tests/resources/resources.fz.expected_out_jvm
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Content
unit
unit
Loading