From fab3e5991094e247c8ea3c5e0971236ff365f93f Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Sat, 14 Sep 2024 18:46:16 +0300 Subject: [PATCH] feat: implement a byte array --- .../jscript/runtime/values/Value.java | 12 ++- .../values/objects/ArrayLikeValue.java | 17 ++-- .../runtime/values/objects/ArrayValue.java | 15 +-- .../values/objects/ByteBufferValue.java | 96 +++++++++++++++++++ 4 files changed, 122 insertions(+), 18 deletions(-) create mode 100644 src/main/java/me/topchetoeu/jscript/runtime/values/objects/ByteBufferValue.java diff --git a/src/main/java/me/topchetoeu/jscript/runtime/values/Value.java b/src/main/java/me/topchetoeu/jscript/runtime/values/Value.java index 9a13d6d..222857a 100644 --- a/src/main/java/me/topchetoeu/jscript/runtime/values/Value.java +++ b/src/main/java/me/topchetoeu/jscript/runtime/values/Value.java @@ -54,17 +54,23 @@ public abstract class Value { public static final Key MAX_STACK_COUNT = Key.of(); public static final Key HIDE_STACK = Key.of(); - public static final Key OBJECT_PROTO = Key.of(); - public static final Key FUNCTION_PROTO = Key.of(); - public static final Key ARRAY_PROTO = Key.of(); + public static final Key BOOL_PROTO = Key.of(); public static final Key NUMBER_PROTO = Key.of(); public static final Key STRING_PROTO = Key.of(); public static final Key SYMBOL_PROTO = Key.of(); + + public static final Key OBJECT_PROTO = Key.of(); + public static final Key FUNCTION_PROTO = Key.of(); + + public static final Key ARRAY_PROTO = Key.of(); + public static final Key BYTE_BUFF_PROTO = Key.of(); + public static final Key ERROR_PROTO = Key.of(); public static final Key SYNTAX_ERR_PROTO = Key.of(); public static final Key TYPE_ERR_PROTO = Key.of(); public static final Key RANGE_ERR_PROTO = Key.of(); + public static final Key GLOBAL = Key.of(); public static final Key> INTRINSICS = Key.of(); diff --git a/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ArrayLikeValue.java b/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ArrayLikeValue.java index 6b4caf3..8b0e94a 100644 --- a/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ArrayLikeValue.java +++ b/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ArrayLikeValue.java @@ -19,8 +19,7 @@ public abstract class ArrayLikeValue extends ObjectValue { return arr.get(i); } @Override public boolean set(Environment env, Value val, Value self) { - arr.set(i, val); - return true; + return arr.set(env, i, val); } public IndexField(int i, ArrayLikeValue arr) { super(arr, true, true, true); @@ -42,9 +41,9 @@ public abstract class ArrayLikeValue extends ObjectValue { public abstract boolean setSize(int val); public abstract Value get(int i); - public abstract void set(int i, Value val); + public abstract boolean set(Environment env, int i, Value val); public abstract boolean has(int i); - public abstract void remove(int i); + public abstract boolean remove(int i); @Override public Member getOwnMember(Environment env, KeyCache key) { var res = super.getOwnMember(env, key); @@ -64,12 +63,12 @@ public abstract class ArrayLikeValue extends ObjectValue { var num = key.toNumber(env); var i = key.toInt(env); - if (i == num && i >= 0) { + if (i == num) { if (!getState().extendable && !has(i)) return false; - set(i, ((FieldMember)member).get(env, this)); - return true; + if (set(env, i, ((FieldMember)member).get(env, this))) return true; } - else return super.defineOwnMember(env, key, member); + + return super.defineOwnMember(env, key, member); } @Override public boolean deleteOwnMember(Environment env, KeyCache key) { if (!super.deleteOwnMember(env, key)) return false; @@ -77,7 +76,7 @@ public abstract class ArrayLikeValue extends ObjectValue { var num = key.toNumber(env); var i = key.toInt(env); - if (i == num && i >= 0 && i < size()) return super.deleteOwnMember(env, key); + if (i == num && i >= 0 && i < size()) return remove(i); else return true; } diff --git a/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ArrayValue.java b/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ArrayValue.java index 5ad0b56..32be51e 100644 --- a/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ArrayValue.java +++ b/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ArrayValue.java @@ -5,6 +5,7 @@ import java.util.Collection; import java.util.Comparator; import java.util.Iterator; +import me.topchetoeu.jscript.common.environment.Environment; import me.topchetoeu.jscript.runtime.values.Value; import me.topchetoeu.jscript.runtime.values.primitives.VoidValue; @@ -41,18 +42,20 @@ public class ArrayValue extends ArrayLikeValue implements Iterable { if (res == null) return Value.UNDEFINED; else return res; } - @Override public void set(int i, Value val) { - if (i < 0) return; + @Override public boolean set(Environment env, int i, Value val) { + if (i < 0) return false; alloc(i)[i] = val; if (i >= size) size = i + 1; + return true; } @Override public boolean has(int i) { return i >= 0 && i < size && values[i] != null; } - @Override public void remove(int i) { - if (i < 0 || i >= values.length) return; + @Override public boolean remove(int i) { + if (i < 0 || i >= values.length) return true; values[i] = null; + return false; } public void shrink(int n) { @@ -133,7 +136,7 @@ public class ArrayValue extends ArrayLikeValue implements Iterable { this(16); } public ArrayValue(int cap) { - setPrototype(env -> env.get(ARRAY_PROTO)); + setPrototype(ARRAY_PROTO); values = new Value[Math.min(cap, 16)]; size = 0; } @@ -143,6 +146,6 @@ public class ArrayValue extends ArrayLikeValue implements Iterable { } public static ArrayValue of(Collection values) { - return new ArrayValue(values.toArray(Value[]::new)); + return new ArrayValue(values.toArray(new Value[0])); } } diff --git a/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ByteBufferValue.java b/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ByteBufferValue.java new file mode 100644 index 0000000..eb8c2f7 --- /dev/null +++ b/src/main/java/me/topchetoeu/jscript/runtime/values/objects/ByteBufferValue.java @@ -0,0 +1,96 @@ +package me.topchetoeu.jscript.runtime.values.objects; + +import java.util.Comparator; +import java.util.Iterator; + +import me.topchetoeu.jscript.common.environment.Environment; +import me.topchetoeu.jscript.runtime.values.Value; +import me.topchetoeu.jscript.runtime.values.primitives.NumberValue; + +// TODO: Make methods generic +public class ByteBufferValue extends ArrayLikeValue implements Iterable { + public final byte[] values; + + // private Value[] alloc(int index) { + // index++; + // if (index < values.length) return values; + // if (index < values.length * 2) index = values.length * 2; + + // var arr = new Value[index]; + // System.arraycopy(values, 0, arr, 0, values.length); + // return values = arr; + // } + + public int size() { return values.length; } + public boolean setSize(int val) { return false; } + + @Override public Value get(int i) { + if (i < 0 || i >= values.length) return null; + return new NumberValue(values[i]); + } + @Override public boolean set(Environment env, int i, Value val) { + if (i < 0 || i >= values.length) return false; + values[i] = (byte)val.toNumber(env).value; + return true; + } + @Override public boolean has(int i) { + return i >= 0 && i < values.length; + } + @Override public boolean remove(int i) { + return false; + } + + public void copyTo(byte[] arr, int sourceStart, int destStart, int count) { + System.arraycopy(values, sourceStart, arr, destStart, count); + } + public void copyTo(ByteBufferValue arr, int sourceStart, int destStart, int count) { + arr.copyFrom(values, sourceStart, destStart, count); + } + public void copyFrom(byte[] arr, int sourceStart, int destStart, int count) { + System.arraycopy(arr, sourceStart, arr, destStart, count); + } + + public void move(int srcI, int dstI, int n) { + System.arraycopy(values, srcI, values, dstI, n); + } + + public void sort(Comparator comparator) { + throw new RuntimeException("not supported"); + // Arrays.sort(values, 0, values.length, (a, b) -> { + // var _a = 0; + // var _b = 0; + + // if (a == null) _a = 2; + // if (a instanceof VoidValue) _a = 1; + + // if (b == null) _b = 2; + // if (b instanceof VoidValue) _b = 1; + + // if (_a != 0 || _b != 0) return Integer.compare(_a, _b); + + // return comparator.compare(a, b); + // }); + } + + @Override public Iterator iterator() { + return new Iterator<>() { + private int i = 0; + + @Override public boolean hasNext() { + return i < size(); + } + @Override public Value next() { + if (!hasNext()) return null; + return get(i++); + } + }; + } + + public ByteBufferValue(int size) { + this(new byte[size]); + } + public ByteBufferValue(byte[] buffer) { + setPrototype(BYTE_BUFF_PROTO); + this.values = buffer; + } +}