feat: implement a byte array

This commit is contained in:
TopchetoEU 2024-09-14 18:46:16 +03:00
parent d7e4e7a024
commit fab3e59910
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
4 changed files with 122 additions and 18 deletions

View File

@ -54,17 +54,23 @@ public abstract class Value {
public static final Key<Integer> MAX_STACK_COUNT = Key.of(); public static final Key<Integer> MAX_STACK_COUNT = Key.of();
public static final Key<Boolean> HIDE_STACK = Key.of(); public static final Key<Boolean> HIDE_STACK = Key.of();
public static final Key<ObjectValue> OBJECT_PROTO = Key.of();
public static final Key<ObjectValue> FUNCTION_PROTO = Key.of();
public static final Key<ObjectValue> ARRAY_PROTO = Key.of();
public static final Key<ObjectValue> BOOL_PROTO = Key.of(); public static final Key<ObjectValue> BOOL_PROTO = Key.of();
public static final Key<ObjectValue> NUMBER_PROTO = Key.of(); public static final Key<ObjectValue> NUMBER_PROTO = Key.of();
public static final Key<ObjectValue> STRING_PROTO = Key.of(); public static final Key<ObjectValue> STRING_PROTO = Key.of();
public static final Key<ObjectValue> SYMBOL_PROTO = Key.of(); public static final Key<ObjectValue> SYMBOL_PROTO = Key.of();
public static final Key<ObjectValue> OBJECT_PROTO = Key.of();
public static final Key<ObjectValue> FUNCTION_PROTO = Key.of();
public static final Key<ObjectValue> ARRAY_PROTO = Key.of();
public static final Key<ObjectValue> BYTE_BUFF_PROTO = Key.of();
public static final Key<ObjectValue> ERROR_PROTO = Key.of(); public static final Key<ObjectValue> ERROR_PROTO = Key.of();
public static final Key<ObjectValue> SYNTAX_ERR_PROTO = Key.of(); public static final Key<ObjectValue> SYNTAX_ERR_PROTO = Key.of();
public static final Key<ObjectValue> TYPE_ERR_PROTO = Key.of(); public static final Key<ObjectValue> TYPE_ERR_PROTO = Key.of();
public static final Key<ObjectValue> RANGE_ERR_PROTO = Key.of(); public static final Key<ObjectValue> RANGE_ERR_PROTO = Key.of();
public static final Key<ObjectValue> GLOBAL = Key.of(); public static final Key<ObjectValue> GLOBAL = Key.of();
public static final Key<Map<String, Value>> INTRINSICS = Key.of(); public static final Key<Map<String, Value>> INTRINSICS = Key.of();

View File

@ -19,8 +19,7 @@ public abstract class ArrayLikeValue extends ObjectValue {
return arr.get(i); return arr.get(i);
} }
@Override public boolean set(Environment env, Value val, Value self) { @Override public boolean set(Environment env, Value val, Value self) {
arr.set(i, val); return arr.set(env, i, val);
return true;
} }
public IndexField(int i, ArrayLikeValue arr) { public IndexField(int i, ArrayLikeValue arr) {
super(arr, true, true, true); super(arr, true, true, true);
@ -42,9 +41,9 @@ public abstract class ArrayLikeValue extends ObjectValue {
public abstract boolean setSize(int val); public abstract boolean setSize(int val);
public abstract Value get(int i); 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 boolean has(int i);
public abstract void remove(int i); public abstract boolean remove(int i);
@Override public Member getOwnMember(Environment env, KeyCache key) { @Override public Member getOwnMember(Environment env, KeyCache key) {
var res = super.getOwnMember(env, key); var res = super.getOwnMember(env, key);
@ -64,12 +63,12 @@ public abstract class ArrayLikeValue extends ObjectValue {
var num = key.toNumber(env); var num = key.toNumber(env);
var i = key.toInt(env); var i = key.toInt(env);
if (i == num && i >= 0) { if (i == num) {
if (!getState().extendable && !has(i)) return false; if (!getState().extendable && !has(i)) return false;
set(i, ((FieldMember)member).get(env, this)); if (set(env, i, ((FieldMember)member).get(env, this))) return true;
return true;
} }
else return super.defineOwnMember(env, key, member);
return super.defineOwnMember(env, key, member);
} }
@Override public boolean deleteOwnMember(Environment env, KeyCache key) { @Override public boolean deleteOwnMember(Environment env, KeyCache key) {
if (!super.deleteOwnMember(env, key)) return false; if (!super.deleteOwnMember(env, key)) return false;
@ -77,7 +76,7 @@ public abstract class ArrayLikeValue extends ObjectValue {
var num = key.toNumber(env); var num = key.toNumber(env);
var i = key.toInt(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; else return true;
} }

View File

@ -5,6 +5,7 @@ import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
import me.topchetoeu.jscript.common.environment.Environment;
import me.topchetoeu.jscript.runtime.values.Value; import me.topchetoeu.jscript.runtime.values.Value;
import me.topchetoeu.jscript.runtime.values.primitives.VoidValue; import me.topchetoeu.jscript.runtime.values.primitives.VoidValue;
@ -41,18 +42,20 @@ public class ArrayValue extends ArrayLikeValue implements Iterable<Value> {
if (res == null) return Value.UNDEFINED; if (res == null) return Value.UNDEFINED;
else return res; else return res;
} }
@Override public void set(int i, Value val) { @Override public boolean set(Environment env, int i, Value val) {
if (i < 0) return; if (i < 0) return false;
alloc(i)[i] = val; alloc(i)[i] = val;
if (i >= size) size = i + 1; if (i >= size) size = i + 1;
return true;
} }
@Override public boolean has(int i) { @Override public boolean has(int i) {
return i >= 0 && i < size && values[i] != null; return i >= 0 && i < size && values[i] != null;
} }
@Override public void remove(int i) { @Override public boolean remove(int i) {
if (i < 0 || i >= values.length) return; if (i < 0 || i >= values.length) return true;
values[i] = null; values[i] = null;
return false;
} }
public void shrink(int n) { public void shrink(int n) {
@ -133,7 +136,7 @@ public class ArrayValue extends ArrayLikeValue implements Iterable<Value> {
this(16); this(16);
} }
public ArrayValue(int cap) { public ArrayValue(int cap) {
setPrototype(env -> env.get(ARRAY_PROTO)); setPrototype(ARRAY_PROTO);
values = new Value[Math.min(cap, 16)]; values = new Value[Math.min(cap, 16)];
size = 0; size = 0;
} }
@ -143,6 +146,6 @@ public class ArrayValue extends ArrayLikeValue implements Iterable<Value> {
} }
public static ArrayValue of(Collection<? extends Value> values) { public static ArrayValue of(Collection<? extends Value> values) {
return new ArrayValue(values.toArray(Value[]::new)); return new ArrayValue(values.toArray(new Value[0]));
} }
} }

View File

@ -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<Value> {
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<Value> 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<Value> 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;
}
}