mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 18:34:03 +03:00
Avoid nulls in Array.items (#5736)
Put `Nothing` into an empty array rather than `null`. When running with `assert` on (unit tests), check the content of the array and `AssertError` quickly when a `null` is found.
This commit is contained in:
parent
dfea59c24d
commit
78aab133c7
@ -21,7 +21,7 @@ public class GetStackTraceNode extends Node {
|
||||
public static Array stackTraceToArray(Throwable exception) {
|
||||
var elements = TruffleStackTrace.getStackTrace(exception);
|
||||
if (elements == null) return new Array();
|
||||
var ret = new Array(elements.size());
|
||||
var ret = Array.allocate(elements.size());
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
var element = elements.get(i);
|
||||
ret.getItems()[i] = element.getGuestObject();
|
||||
|
@ -133,7 +133,7 @@ public abstract class Atom implements TruffleObject {
|
||||
public Array getMembers(boolean includeInternal) {
|
||||
Map<String, Function> members = constructor.getDefinitionScope().getMethods().get(constructor.getType());
|
||||
if (members == null) {
|
||||
return new Array(0);
|
||||
return Array.allocate(0);
|
||||
}
|
||||
Object[] mems = members.keySet().toArray();
|
||||
return new Array(mems);
|
||||
|
@ -39,6 +39,7 @@ public final class Array implements TruffleObject {
|
||||
description = "Creates an array with given elements.",
|
||||
autoRegister = false)
|
||||
public Array(Object... items) {
|
||||
assert noNulls(items);
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@ -49,9 +50,25 @@ public final class Array implements TruffleObject {
|
||||
*/
|
||||
@Builtin.Method(
|
||||
description = "Creates an uninitialized array of a given size.",
|
||||
autoRegister = false)
|
||||
public Array(long size) {
|
||||
this.items = new Object[(int) size];
|
||||
autoRegister = false,
|
||||
name = "new")
|
||||
public static Array allocate(long size) {
|
||||
var arr = new Object[(int) size];
|
||||
var ctx = EnsoContext.get(null);
|
||||
var nothing = ctx.getBuiltins().nothing();
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = nothing;
|
||||
}
|
||||
return new Array(arr);
|
||||
}
|
||||
|
||||
private static final boolean noNulls(Object[] arr) {
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (arr[i] == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @return the elements of this array as a java array. */
|
||||
@ -107,7 +124,7 @@ public final class Array implements TruffleObject {
|
||||
/** @return an empty array */
|
||||
@Builtin.Method(description = "Creates an empty Array", autoRegister = false)
|
||||
public static Object empty() {
|
||||
return new Array();
|
||||
return allocate(0);
|
||||
}
|
||||
|
||||
/** @return an identity array */
|
||||
|
@ -74,7 +74,7 @@ public final class Vector implements TruffleObject {
|
||||
long slice_end = Math.min(this_length, end);
|
||||
|
||||
if (slice_start >= slice_end) {
|
||||
return new Vector(new Array(0));
|
||||
return new Vector(Array.allocate(0));
|
||||
}
|
||||
|
||||
if ((slice_start == 0) && (slice_end == this_length)) {
|
||||
|
@ -0,0 +1,52 @@
|
||||
package org.enso.interpreter.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Map;
|
||||
import org.enso.polyglot.RuntimeOptions;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Language;
|
||||
import org.graalvm.polyglot.Source;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ArrayTest {
|
||||
private Context ctx;
|
||||
|
||||
@Before
|
||||
public void prepareCtx() {
|
||||
this.ctx = Context.newBuilder()
|
||||
.allowExperimentalOptions(true)
|
||||
.allowIO(true)
|
||||
.allowAllAccess(true)
|
||||
.logHandler(new ByteArrayOutputStream())
|
||||
.option(
|
||||
RuntimeOptions.LANGUAGE_HOME_OVERRIDE,
|
||||
Paths.get("../../distribution/component").toFile().getAbsolutePath()
|
||||
).build();
|
||||
final Map<String, Language> langs = ctx.getEngine().getLanguages();
|
||||
assertNotNull("Enso found: " + langs, langs.get("enso"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dontExposeNullsOutOfArray() throws Exception {
|
||||
final URI facUri = new URI("memory://choose.enso");
|
||||
final Source facSrc = Source.newBuilder("enso", """
|
||||
from Standard.Base import all
|
||||
|
||||
null =
|
||||
a = Array.new 1
|
||||
b = a.at 0
|
||||
b
|
||||
""", "nulls.enso")
|
||||
.uri(facUri)
|
||||
.buildLiteral();
|
||||
|
||||
var module = ctx.eval(facSrc);
|
||||
var res = module.invokeMember("eval_expression", "null");
|
||||
assertTrue("i null", res.isNull());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user