Skip to content

Commit

Permalink
Use EnsoMultiValue.NewNode to allocate new instances of EnsoMultiValue
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Dec 20, 2024
1 parent d44d30e commit 7b6d364
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,19 @@ private static void registerValue(
var rawValue = ContextUtils.unwrapValue(ctx(), polyValue);
var rawType = ContextUtils.unwrapValue(ctx(), t);
if (rawType instanceof Type type) {
var singleMultiValue = EnsoMultiValue.create(new Type[] {type}, 1, new Object[] {rawValue});
var singleMultiValue =
EnsoMultiValue.NewNode.getUncached()
.newValue(new Type[] {type}, 1, new Object[] {rawValue});
var n = t.getMetaSimpleName();
data.add(new Object[] {singleMultiValue, n, 0});
var rawInt = (Type) ContextUtils.unwrapValue(ctx(), g.typeInteger());
var secondMultiValue =
EnsoMultiValue.create(new Type[] {rawInt, type}, 2, new Object[] {5L, rawValue});
EnsoMultiValue.NewNode.getUncached()
.newValue(new Type[] {rawInt, type}, 2, new Object[] {5L, rawValue});
data.add(new Object[] {secondMultiValue, n, 1});
var firstMultiValue =
EnsoMultiValue.create(new Type[] {type, rawInt}, 2, new Object[] {rawValue, 6L});
EnsoMultiValue.NewNode.getUncached()
.newValue(new Type[] {type, rawInt}, 2, new Object[] {rawValue, 6L});
data.add(new Object[] {firstMultiValue, n, 0});
} else {
if (!t.isHostObject()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ public void multiValueWithHiddenType() {
new Type[] {
ensoCtx.getBuiltins().number().getInteger(), ensoCtx.getBuiltins().text()
};
var multi = EnsoMultiValue.create(types, 1, new Object[] {42L, "Meaning"});
var multi =
EnsoMultiValue.NewNode.getUncached()
.newValue(types, 1, new Object[] {42L, "Meaning"});
var arr = (Object[]) testTypesCall.call(multi, true);
var allTypes = (Type[]) arr[1];
assertEquals("Two types", 2, allTypes.length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ public void avoidDoubleWrappingOfEnsoMultiValue() {
() -> {
var builtins = ContextUtils.leakContext(ctx).getBuiltins();
var m1 =
EnsoMultiValue.create(
new Type[] {builtins.text(), builtins.number().getInteger()},
2,
new Object[] {"Hi", 42});
EnsoMultiValue.NewNode.getUncached()
.newValue(
new Type[] {builtins.text(), builtins.number().getInteger()},
2,
new Object[] {"Hi", 42});
assertEquals("Text & Integer", m1.toDisplayString(true));

var res = convert.call(m1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ private static void registerValue(
if (rawT1 instanceof Type typ1 && rawT2 instanceof Type typ2) {
var r1 = ContextUtils.unwrapValue(ctx, v1);
var r2 = ContextUtils.unwrapValue(ctx, v2);
var both = EnsoMultiValue.create(new Type[] {typ1, typ2}, 2, new Object[] {r1, r2});
var both =
EnsoMultiValue.NewNode.getUncached()
.newValue(new Type[] {typ1, typ2}, 2, new Object[] {r1, r2});
data.add(new Object[] {both});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ public void testEqualityIntegerAndMultiValue() {
var intType = builtins.number().getInteger();
var textText = builtins.text();
var fourExtraText =
EnsoMultiValue.create(
new Type[] {intType, textText}, 1, new Object[] {4L, Text.create("Hi")});
EnsoMultiValue.NewNode.getUncached()
.newValue(
new Type[] {intType, textText}, 1, new Object[] {4L, Text.create("Hi")});

assertTrue("4 == 4t", equalityCheck(4L, fourExtraText));
assertFalse("5 != 4t", equalityCheck(5L, fourExtraText));
Expand Down Expand Up @@ -85,7 +86,7 @@ public void testEqualityTextAndExtraIntegerMultiValue() {
// x = _ : (Text & Integer) : Text
// e.g. multi value with Text and Integer, casted to Text only
//
var multiV = EnsoMultiValue.create(bothTypes, 1, text, integer);
var multiV = EnsoMultiValue.NewNode.getUncached().newValue(bothTypes, 1, text, integer);

assertTrue("'Hi' == multiV", equalityCheck(text, multiV));
assertFalse("'Ahoj' != multiV", equalityCheck(ahoj, multiV));
Expand All @@ -112,7 +113,8 @@ public void testEqualityIntegerAndMultiValueWithBoth() {
var textText = builtins.text();
var hi = Text.create("Hi");
var fourExtraText =
EnsoMultiValue.create(new Type[] {textText, intType}, 2, new Object[] {hi, 4L});
EnsoMultiValue.NewNode.getUncached()
.newValue(new Type[] {textText, intType}, 2, new Object[] {hi, 4L});

assertTrue("4 == 4t", equalityCheck(4L, fourExtraText));
assertFalse("5 != 4t", equalityCheck(5L, fourExtraText));
Expand All @@ -134,8 +136,9 @@ public void testEqualityIntegerAndMultiValueWithIntText() {
var intType = builtins.number().getInteger();
var textText = builtins.text();
var fourExtraText =
EnsoMultiValue.create(
new Type[] {intType, textText}, 2, new Object[] {4L, Text.create("Hi")});
EnsoMultiValue.NewNode.getUncached()
.newValue(
new Type[] {intType, textText}, 2, new Object[] {4L, Text.create("Hi")});

assertTrue("4 == 4t", equalityCheck(4L, fourExtraText));
assertFalse("5 != 4t", equalityCheck(5L, fourExtraText));
Expand All @@ -155,14 +158,17 @@ public void twoMultiValues() {
var intType = builtins.number().getInteger();
var textText = builtins.text();
var fourExtraText =
EnsoMultiValue.create(
new Type[] {intType, textText}, 1, new Object[] {4L, Text.create("Hi")});
EnsoMultiValue.NewNode.getUncached()
.newValue(
new Type[] {intType, textText}, 1, new Object[] {4L, Text.create("Hi")});
var fourExtraText2 =
EnsoMultiValue.create(
new Type[] {intType, textText}, 1, new Object[] {4L, Text.create("Hi")});
EnsoMultiValue.NewNode.getUncached()
.newValue(
new Type[] {intType, textText}, 1, new Object[] {4L, Text.create("Hi")});
var fiveExtraText =
EnsoMultiValue.create(
new Type[] {intType, textText}, 1, new Object[] {5L, Text.create("Hi")});
EnsoMultiValue.NewNode.getUncached()
.newValue(
new Type[] {intType, textText}, 1, new Object[] {5L, Text.create("Hi")});

assertFalse("!= for sure #1", equalityCheck(fiveExtraText, fourExtraText));
assertFalse("!= for sure #2", equalityCheck(fourExtraText, fiveExtraText));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Object executeCheckOrConversion(VirtualFrame frame, Object value, ExpressionNode
values[at] = result;
at++;
}
return EnsoMultiValue.create(valueTypes, valueTypes.length, values);
return EnsoMultiValue.NewNode.getUncached().newValue(valueTypes, valueTypes.length, values);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,51 @@ private EnsoMultiValue(MultiType dispatch, MultiType extra, Object[] values) {
this.values = values;
}

/**
* Creates new instance of EnsoMultiValue from provided information.
*
* @param types all the types this value can be {@link CastToNode cast to}
* @param dispatchTypes the (subset of) types that the value is cast to currently - bigger than
* {@code 0} and at most {@code type.length}
* @param values value of each of the provided {@code types}
* @return non-{@code null} multi value instance
*/
@NeverDefault
public static EnsoMultiValue create(
@NeverDefault Type[] types, @NeverDefault int dispatchTypes, @NeverDefault Object... values) {
assert dispatchTypes > 0;
assert dispatchTypes <= types.length;
assert types.length == values.length;
assert !Stream.of(values).anyMatch(v -> v instanceof EnsoMultiValue)
: "Avoid double wrapping " + Arrays.toString(values);
var dt = MultiType.create(types, 0, dispatchTypes);
var et = MultiType.create(types, dispatchTypes, types.length);
return new EnsoMultiValue(dt, et, values);
/** Creates new instance of EnsoMultiValue from provided information. */
@GenerateUncached
public abstract static class NewNode extends Node {
private static final String INLINE_CACHE_LIMIT = "5";

@NeverDefault
public static NewNode create() {
return EnsoMultiValueFactory.NewNodeGen.create();
}

@NeverDefault
public static NewNode getUncached() {
return EnsoMultiValueFactory.NewNodeGen.getUncached();
}

/**
* Creates new multi value from provided information.
*
* @param types all the types this value can be {@link CastToNode cast to}
* @param dispatchTypes the (subset of) types that the value is cast to currently - bigger than
* {@code 0} and at most {@code type.length}
* @param values value of each of the provided {@code types}
* @return non-{@code null} multi value instance
*/
@NeverDefault
public EnsoMultiValue newValue(
@NeverDefault Type[] types,
@NeverDefault int dispatchTypes,
@NeverDefault Object... values) {
assert dispatchTypes > 0;
assert dispatchTypes <= types.length;
assert types.length == values.length;
assert !Stream.of(values).anyMatch(v -> v instanceof EnsoMultiValue)
: "Avoid double wrapping " + Arrays.toString(values);
var dt = executeTypes(types, 0, dispatchTypes);
var et = executeTypes(types, dispatchTypes, types.length);
return new EnsoMultiValue(dt, et, values);
}

abstract MultiType executeTypes(Type[] types, int from, int to);

@Specialization
final MultiType createMultiType(Type[] types, int from, int to) {
return MultiType.create(types, from, to);
}
}

@ExportMessage
Expand Down Expand Up @@ -460,7 +485,7 @@ public final Object findTypeOrNull(
copyValues[0] = copyValues[i];
copyTypes[i] = mv.dispatch.types[0];
copyValues[i] = mv.values[0];
return EnsoMultiValue.create(copyTypes, 1, copyValues);
return EnsoMultiValue.NewNode.getUncached().newValue(copyTypes, 1, copyValues);
} else {
return mv.values[i];
}
Expand Down

0 comments on commit 7b6d364

Please sign in to comment.