Skip to content

Commit

Permalink
Merge pull request #3423 from maxonfjvipon/feat/#3415/malloc-resize
Browse files Browse the repository at this point in the history
feat(#3415): `malloc.resize` introduced
  • Loading branch information
yegor256 authored Oct 16, 2024
2 parents af65518 + 1480adc commit 9c73436
Show file tree
Hide file tree
Showing 10 changed files with 338 additions and 20 deletions.
7 changes: 2 additions & 5 deletions .codacy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,5 @@
# package name contains capital letter and such names are conventional.
---
exclude_paths:
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/BindFuncCall.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/ListenFuncCall.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/AcceptFuncCall.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/SendFuncCall.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOsys/Win32/RecvFuncCall.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOmalloc$EOof$EOallocated$EOresize.java"
- "eo-runtime/src/main/java/EOorg/EOeolang/EOmalloc$EOof$EOallocated$EOsize.java"
14 changes: 10 additions & 4 deletions eo-runtime/src/main/eo/org/eolang/malloc.eo
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,24 @@

# Allocated block in memory that provides an API for writing and reading.
[id] > allocated
^.size > size
get > @
# Just get all the data from the allocated block in memory.
read 0 size > get

# Returns size of allocated block in memory.
[] > size /number

# Resizes allocated block in memory and returns `true`.
# Here `size` must be positive `number`.
# The `error` returned if failed to resize block in memory.
[size] > resize /true

# Read `length` bytes with `offset` from the allocated block in memory.
[offset length] > read /bytes

# Write `data` with `offset` to the allocated block in memory.
[offset data] > write /true

# Just get all the data from the allocated block in memory.
^.read 0 ^.size > [] > get

# Put `object` into the allocated block in memory. The `object` is supposed to be dataizable.
[object] > put
seq > @
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,11 @@ public final class EOmalloc$EOof$EOallocated$EOread extends PhDefault implements

@Override
public Phi lambda() throws Exception {
final int length = new Dataized(this.take("length")).asNumber().intValue();
return new Data.ToPhi(
Heaps.INSTANCE.read(
new Dataized(this.take(Attr.RHO).take("id")).asNumber().intValue(),
new Dataized(this.take("offset")).asNumber().intValue(),
length
new Dataized(this.take("length")).asNumber().intValue()
)
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2024 Objectionary.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/*
* @checkstyle PackageNameCheck (4 lines)
* @checkstyle TrailingCommentCheck (3 lines)
*/
package EOorg.EOeolang; // NOPMD

import org.eolang.AtVoid;
import org.eolang.Atom;
import org.eolang.Attr;
import org.eolang.Data;
import org.eolang.Dataized;
import org.eolang.PhDefault;
import org.eolang.Phi;
import org.eolang.Versionized;
import org.eolang.XmirObject;

/**
* Malloc.of.allocated.resize object.
* @since 0.41.0
* @checkstyle TypeNameCheck (5 lines)
*/
@Versionized
@XmirObject(oname = "malloc.of.allocated.resize")
@SuppressWarnings("PMD.AvoidDollarSigns")
public final class EOmalloc$EOof$EOallocated$EOresize extends PhDefault implements Atom {
/**
* Ctor.
*/
@SuppressWarnings("PMD.ConstructorOnlyInitializesOrCallOtherConstructors")
EOmalloc$EOof$EOallocated$EOresize() {
this.add("size", new AtVoid("size"));
}

@Override
public Phi lambda() throws Exception {
Heaps.INSTANCE.resize(
new Dataized(this.take(Attr.RHO).take("id")).asNumber().intValue(),
new Dataized(this.take("size")).asNumber().intValue()
);
return new Data.ToPhi(true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2024 Objectionary.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/*
* @checkstyle PackageNameCheck (4 lines)
* @checkstyle TrailingCommentCheck (3 lines)
*/
package EOorg.EOeolang; // NOPMD

import org.eolang.Atom;
import org.eolang.Attr;
import org.eolang.Data;
import org.eolang.Dataized;
import org.eolang.PhDefault;
import org.eolang.Phi;
import org.eolang.Versionized;
import org.eolang.XmirObject;

/**
* Malloc.of.allocated.size object.
* @since 0.41.0
* @checkstyle TypeNameCheck (5 lines)
*/
@Versionized
@XmirObject(oname = "malloc.of.allocated.size")
@SuppressWarnings("PMD.AvoidDollarSigns")
public final class EOmalloc$EOof$EOallocated$EOsize extends PhDefault implements Atom {
@Override
public Phi lambda() throws Exception {
return new Data.ToPhi(
Heaps.INSTANCE.size(
new Dataized(this.take(Attr.RHO).take("id")).asNumber().intValue()
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ public final class EOmalloc$EOof$EOφ extends PhDefault implements Atom {
@Override
public Phi lambda() {
final Phi rho = this.take(Attr.RHO);
final int size = new Dataized(rho.take("size")).asNumber().intValue();
final int identifier = Heaps.INSTANCE.malloc(this, size);
final int identifier = Heaps.INSTANCE.malloc(
this, new Dataized(rho.take("size")).asNumber().intValue()
);
final Phi res;
try {
final Phi allocated = rho.take("allocated");
Expand All @@ -59,7 +60,7 @@ public Phi lambda() {
scope.put(0, allocated);
new Dataized(scope).take();
res = new Data.ToPhi(
Heaps.INSTANCE.read(identifier, 0, size)
Heaps.INSTANCE.read(identifier, 0, Heaps.INSTANCE.size(identifier))
);
} finally {
Heaps.INSTANCE.free(identifier);
Expand Down
61 changes: 55 additions & 6 deletions eo-runtime/src/main/java/EOorg/EOeolang/Heaps.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ int malloc(final Phi phi, final int size) {
if (this.blocks.containsKey(identifier)) {
throw new ExFailure(
String.format(
"Can't allocate block in memory with identifier %d because it's already allocated",
"Can't allocate block in memory with identifier '%d' because it's already allocated",
identifier
)
);
Expand All @@ -81,6 +81,55 @@ int malloc(final Phi phi, final int size) {
return identifier;
}

/**
* Get size of allocated block in memory by provided identifier.
* @param identifier Identifier of block in memory
* @return Size
*/
int size(final int identifier) {
synchronized (this.blocks) {
if (!this.blocks.containsKey(identifier)) {
throw new ExFailure(
String.format(
"Block in memory by identifier '%d' is not allocated, can't get size",
identifier
)
);
}
return this.blocks.get(identifier).length;
}
}

/**
* Resize allocated block in memory.
* @param identifier Identifier of block
* @param size New size
*/
void resize(final int identifier, final int size) {
if (size < 0) {
throw new ExFailure(
String.format(
"Can't change size of block in memory by identifier '%d' to negative '%d'",
identifier, size
)
);
}
synchronized (this.blocks) {
if (!this.blocks.containsKey(identifier)) {
throw new ExFailure(
String.format(
"Block in memory by identifier '%d' is not allocated, can't get size",
identifier
)
);
}
final byte[] bytes = this.blocks.get(identifier);
final byte[] resized = new byte[size];
System.arraycopy(bytes, 0, resized, 0, Math.min(bytes.length, size));
this.blocks.put(identifier, resized);
}
}

/**
* Get data from the block in memory by identifier.
* @param identifier Identifier of the pointer
Expand All @@ -93,7 +142,7 @@ byte[] read(final int identifier, final int offset, final int length) {
if (!this.blocks.containsKey(identifier)) {
throw new ExFailure(
String.format(
"Block in memory by identifier %d is not allocated, can't read",
"Block in memory by identifier '%d' is not allocated, can't read",
identifier
)
);
Expand All @@ -102,7 +151,7 @@ byte[] read(final int identifier, final int offset, final int length) {
if (offset + length > bytes.length) {
throw new ExFailure(
String.format(
"Can't read %d bytes from offset %d, because only %d are allocated",
"Can't read '%d' bytes from offset '%d', because only '%d' are allocated",
length,
offset,
bytes.length
Expand All @@ -124,7 +173,7 @@ void write(final int identifier, final int offset, final byte[] data) {
if (!this.blocks.containsKey(identifier)) {
throw new ExFailure(
String.format(
"Can't read a block in memory with identifier %d because it's not allocated",
"Can't read a block in memory with identifier '%d' because it's not allocated",
identifier
)
);
Expand All @@ -134,7 +183,7 @@ void write(final int identifier, final int offset, final byte[] data) {
if (length < offset + data.length) {
throw new ExFailure(
String.format(
"Can't write %d bytes with offset %d to the block with identifier %d, because only %d were allocated",
"Can't write '%d' bytes with offset '%d' to the block with identifier '%d', because only '%d' were allocated",
data.length,
offset,
identifier,
Expand Down Expand Up @@ -169,7 +218,7 @@ void free(final int identifier) {
if (!this.blocks.containsKey(identifier)) {
throw new ExFailure(
String.format(
"Can't free a block in memory with identifier %d because it's not allocated",
"Can't free a block in memory with identifier '%d' because it's not allocated",
identifier
)
);
Expand Down
22 changes: 22 additions & 0 deletions eo-runtime/src/main/rust/eo/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# The MIT License (MIT)
#
# Copyright (c) 2016-2024 Objectionary.com
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

[package]
name = "eo"
version = "0.1.0"
Expand Down
38 changes: 38 additions & 0 deletions eo-runtime/src/test/eo/org/eolang/malloc-tests.eo
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,41 @@
m.write 2 "Hello"
b.put
(m.read 2 5).eq "Hello"

# Test.
[] > malloc-increases-block-size
malloc.of > @
1
[b]
malloc.for > @
01-02-03-04
[m] >>
seq > @
*
m.resize 6
^.b.put
and.
m.size.eq 6
m.get.eq 01-02-03-04-00-00

# Test.
[] > malloc-decreases-block-size
malloc.of > @
1
[b]
malloc.for > @
01-02-03-04-05
[m] >>
seq > @
*
m.resize 3
^.b.put
and.
m.size.eq 3
m.get.eq 01-02-03

# Test.
[] > throws-on-changing-size-to-negative
malloc.of > @
1
m.resize -1 > [m]
Loading

0 comments on commit 9c73436

Please sign in to comment.