com.oracle.truffle.tck.TruffleTCK Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of truffle-tck Show documentation
Show all versions of truffle-tck Show documentation
A collection of tests that can certify language implementation to be compliant
with most recent requirements of the Truffle infrastructure and tooling.
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.truffle.tck;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.DoubleBinaryOperator;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.debug.Debugger;
import com.oracle.truffle.api.debug.DebuggerSession;
import com.oracle.truffle.api.debug.SuspendedCallback;
import com.oracle.truffle.api.debug.SuspendedEvent;
import com.oracle.truffle.api.impl.Accessor;
import com.oracle.truffle.api.instrumentation.SourceSectionFilter;
import com.oracle.truffle.api.instrumentation.TruffleInstrument;
import com.oracle.truffle.api.interop.KeyInfo;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.java.*;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.vm.*;
import com.oracle.truffle.tck.Schema.Type;
import com.oracle.truffle.tck.impl.LongBinaryOperation;
import com.oracle.truffle.tck.impl.ObjectBinaryOperation;
import com.oracle.truffle.tck.impl.TckInstrument;
import com.oracle.truffle.tck.impl.TestObject;
/**
* @since 0.8 or earlier
* @deprecated Use the new
* TCK instead.
*/
@SuppressWarnings({"deprecation", "unchecked", "rawtypes"})
@java.lang.Deprecated
public abstract class TruffleTCK {
private static volatile PolyglotEngine previousVMReference;
private static final Random RANDOM = new Random();
private PolyglotEngine tckVM;
private Object prev;
/** @since 0.8 or earlier */
protected TruffleTCK() {
}
/**
* @since 0.12
*/
@AfterClass
public static void disposePreviousVM() {
if (previousVMReference != null) {
previousVMReference.dispose();
previousVMReference = null;
}
}
/**
* @since 0.30
*/
@Before
public final void enterTCK() throws Exception {
PolyglotEngine vm = vm();
this.prev = TruffleTCKAccessor.engineAccess().legacyTckEnter(vm);
}
/**
* @since 0.30
*/
@After
public final void afterTCK() throws Exception {
TruffleTCKAccessor.engineAccess().legacyTckLeave(vm(), this.prev);
}
/**
* @since 0.8 or earlier
*/
protected PolyglotEngine prepareVM() throws Exception {
return prepareVM(PolyglotEngine.newBuilder());
}
/**
* @since 0.12
*/
protected PolyglotEngine prepareVM(@SuppressWarnings("unused") PolyglotEngine.Builder preparedBuilder) throws Exception {
throw new UnsupportedOperationException();
}
/**
* @since 0.8 or earlier
*/
protected abstract String mimeType();
/**
* @since 0.8 or earlier
*/
protected abstract String fourtyTwo();
/**
* @since 0.8 or earlier
*/
protected abstract String returnsNull();
/**
* @since 0.8 or earlier
*/
protected String plusInt() {
throw new UnsupportedOperationException("Override plus(Class,Class) method!");
}
/**
* @since 0.8 or earlier
*/
@SuppressWarnings("unused")
protected String plus(Class> type1, Class> type2) {
return plusInt();
}
/**
* @since 0.8 or earlier
*/
protected abstract String applyNumbers();
/**
* @since 0.8 or earlier
*/
protected String identity() {
throw new UnsupportedOperationException("identity() method not implemented");
}
/**
* @since 0.8 or earlier
*/
protected String complexAdd() {
throw new UnsupportedOperationException("complexAdd() method not implemented");
}
/**
* @since 0.8 or earlier
*/
protected String complexAddWithMethod() {
throw new UnsupportedOperationException("complexAddWithMethod() method not implemented");
}
/**
* @since 0.8 or earlier
*/
protected String complexSumReal() {
throw new UnsupportedOperationException("complexSumReal() method not implemented");
}
/**
* @since 0.8 or earlier
*/
protected String complexCopy() {
throw new UnsupportedOperationException("complexCopy() method not implemented");
}
/**
* @since 0.8 or earlier
*/
protected String globalObject() {
throw new UnsupportedOperationException("globalObject() method not implemented");
}
/**
* @since 0.8 or earlier
*/
protected String evaluateSource() {
throw new UnsupportedOperationException("evaluateSource() method not implemented");
}
/**
* @since 0.8 or earlier
*/
@SuppressWarnings("unused")
protected String multiplyCode(String firstName, String secondName) {
throw new UnsupportedOperationException("multiply(String,String) method not implemeted!");
}
/**
*
* @since 0.14
*/
protected String addToArray() {
throw new UnsupportedOperationException("implement addToArray() method");
}
/**
* @since 0.16
*/
protected String objectWithValueProperty() {
throw new UnsupportedOperationException("implement objectWithValueProperty() method");
}
/**
*
* @since 0.16
*/
protected String objectWithValueAndAddProperty() {
throw new UnsupportedOperationException("implement objectWithValueAndAddProperty() method");
}
/**
*
* @since 0.16
*/
protected String objectWithElement() {
throw new UnsupportedOperationException("implement objectWithElement() method");
}
/**
* @since 0.26
*/
protected String objectWithKeyInfoAttributes() {
throw new UnsupportedOperationException("implement objectWithKeyInfoAttributes() method");
}
/**
*
* @since 0.16
*/
protected String functionAddNumbers() {
throw new UnsupportedOperationException("implement functionAddNumbers() method");
}
/**
*
* @since 0.16
*/
protected String readValueFromForeign() {
throw new UnsupportedOperationException("implement readValueFromForeign() method");
}
/**
*
* @since 0.16
*/
protected String readElementFromForeign() {
throw new UnsupportedOperationException("implement readElementFromForeign() method");
}
/**
*
* @since 0.16
*/
protected String writeValueToForeign() {
throw new UnsupportedOperationException("implement readValueFromForeign() method");
}
/**
*
* @since 0.16
*/
protected String writeElementToForeign() {
throw new UnsupportedOperationException("implement writeElementToForeign() method");
}
/**
*
* @since 0.16
*/
protected String getSizeOfForeign() {
throw new UnsupportedOperationException("implement getSizeOfForeign() method");
}
/**
*
* @since 0.16
*/
protected String hasSizeOfForeign() {
throw new UnsupportedOperationException("implement getHasSizeOfForeign() method");
}
/**
*
* @since 0.16
*/
protected String isNullForeign() {
throw new UnsupportedOperationException("implement getIsNullForeign() method");
}
/**
*
* @since 0.16
*/
protected String isExecutableOfForeign() {
throw new UnsupportedOperationException("implement getIsExecutableForeign() method");
}
/**
*
* @since 0.16
*/
protected String callFunction() {
throw new UnsupportedOperationException("implement callFunction() method");
}
/**
*
* @since 0.16
*/
protected String callMethod() {
throw new UnsupportedOperationException("implement callMethod() method");
}
/**
*
* @since 0.8 or earlier
*/
protected abstract String countInvocations();
/**
*
* @since 0.8 or earlier
*/
protected abstract String invalidCode();
/**
*
* @since 0.8 or earlier
*/
protected String compoundObject() {
throw new UnsupportedOperationException("compoundObject() method not implemented");
}
/**
*
* @since 0.8 or earlier
*/
protected String valuesObject() {
throw new UnsupportedOperationException("valuesObject() method not implemented");
}
/**
*
* @since 0.15
*/
protected String countUpWhile() {
throw new UnsupportedOperationException("countUpWhile() method not implemented");
}
/**
*
* @since 0.8 or earlier
*/
protected void assertDouble(String msg, double expectedValue, double actualValue) {
assertEquals(msg, expectedValue, actualValue, 0.1);
}
/**
*
* @since 0.22
*/
protected String[] metaObjects() {
throw new UnsupportedOperationException("metaObjects() method not implemented");
}
/**
*
* @since 0.22
*/
protected String valueWithSource() {
throw new UnsupportedOperationException("valueWithSource() method not implemented");
}
private PolyglotEngine vm() throws Exception {
if (previousVMReference != null) {
return previousVMReference;
}
previousVMReference = prepareVM();
return previousVMReference;
}
//
// The tests
//
/** @since 0.8 or earlier */
@Test
public void testFortyTwo() throws Exception {
PolyglotEngine.Value fourtyTwo = findGlobalSymbol(fourtyTwo());
Object res = fourtyTwo.execute().get();
assert res instanceof Number : "should yield a number, but was: " + res;
Number n = (Number) res;
assert 42 == n.intValue() : "The value is 42 = " + n.intValue();
}
/** @since 0.8 or earlier */
@Test
public void testFortyTwoWithCompoundObject() throws Exception {
CompoundObject obj = findCompoundSymbol();
if (obj == null) {
return;
}
Number res = obj.fourtyTwo();
assertEquals("Should be 42", 42, res.intValue());
}
/** @since 0.8 or earlier */
@Test
public void testNull() throws Exception {
PolyglotEngine.Value retNull = findGlobalSymbol(returnsNull());
Object res = retNull.execute().get();
assertNull("Should yield real Java null", res);
}
/** @since 0.8 or earlier */
@Test
public void testNullCanBeCastToAnything() throws Exception {
PolyglotEngine.Value retNull = findGlobalSymbol(returnsNull());
Object res = retNull.execute().as(CompoundObject.class);
assertNull("Should yield real Java null", res);
}
/** @since 0.8 or earlier */
@Test
public void testNullInCompoundObject() throws Exception {
CompoundObject obj = findCompoundSymbol();
if (obj == null) {
return;
}
Object res = obj.returnsNull();
assertNull("Should yield real Java null", res);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithInts() throws Exception {
int a = RANDOM.nextInt(100);
int b = RANDOM.nextInt(100);
doPlusWithInts(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithOneNegativeInt() throws Exception {
int a = -RANDOM.nextInt(100);
int b = RANDOM.nextInt(100);
doPlusWithInts(a, b);
}
private void doPlusWithInts(int a, int b) throws Exception {
PolyglotEngine.Value plus = findGlobalSymbol(plus(int.class, int.class));
Number n = plus.execute(a, b).as(Number.class);
assert a + b == n.intValue() : "(" + a + " + " + b + ") = " + n.intValue();
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithBytes() throws Exception {
int a = RANDOM.nextInt(50);
int b = RANDOM.nextInt(50);
doPlusWithBytes(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithOneNegativeByte() throws Exception {
int a = -RANDOM.nextInt(50);
int b = RANDOM.nextInt(50);
doPlusWithBytes(a, b);
}
private void doPlusWithBytes(int a, int b) throws Exception {
PolyglotEngine.Value plus = findGlobalSymbol(plus(byte.class, byte.class));
Number n = plus.execute((byte) a, (byte) b).as(Number.class);
assert a + b == n.intValue() : "(" + a + " + " + b + ") = " + n.intValue();
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithShort() throws Exception {
int a = RANDOM.nextInt(100);
int b = RANDOM.nextInt(100);
doPlusWithShorts(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithOneNegativeShort() throws Exception {
int a = RANDOM.nextInt(100);
int b = -RANDOM.nextInt(100);
doPlusWithShorts(a, b);
}
private void doPlusWithShorts(int a, int b) throws Exception {
PolyglotEngine.Value plus = findGlobalSymbol(plus(short.class, short.class));
Number n = plus.execute((short) a, (short) b).as(Number.class);
assert a + b == n.intValue() : "(" + a + " + " + b + ") = " + n.intValue();
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithLong() throws Exception {
long a = RANDOM.nextInt(100);
long b = RANDOM.nextInt(100);
doPlusWithLong(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithLongMaxIntMinInt() throws Exception {
doPlusWithLong(Integer.MAX_VALUE, Integer.MIN_VALUE);
}
private void doPlusWithLong(long a, long b) throws Exception {
PolyglotEngine.Value plus = findGlobalSymbol(plus(long.class, long.class));
Number n = plus.execute(a, b).as(Number.class);
assert a + b == n.longValue() : "(" + a + " + " + b + ") = " + n.longValue();
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDoubleFloatSameAsInt() throws Exception {
int x = RANDOM.nextInt(100);
int y = RANDOM.nextInt(100);
float a = x;
float b = y;
double u = a;
double v = b;
PolyglotEngine.Value floatPlus = findGlobalSymbol(plus(float.class, float.class));
PolyglotEngine.Value doublePlus = findGlobalSymbol(plus(double.class, double.class));
PolyglotEngine.Value intPlus = findGlobalSymbol(plus(int.class, int.class));
Number floatResult = floatPlus.execute(a, b).as(Number.class);
Number doubleResult = doublePlus.execute(u, v).as(Number.class);
Number intResult = intPlus.execute(x, y).as(Number.class);
assertEquals("Correct value computed via int: (" + a + " + " + b + ")", x + y, intResult.intValue());
assertEquals("Correct value computed via float: (" + a + " + " + b + ")", intResult.intValue(), floatResult.intValue());
assertEquals("Correct value computed via double: (" + a + " + " + b + ")", intResult.intValue(), doubleResult.intValue());
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithFloat() throws Exception {
float a = RANDOM.nextFloat() * 100.0f;
float b = RANDOM.nextFloat() * 100.0f;
doPlusWithFloat(a, b);
}
private void doPlusWithFloat(float a, float b) throws Exception {
PolyglotEngine.Value plus = findGlobalSymbol(plus(float.class, float.class));
Number n = plus.execute(a, b).as(Number.class);
assertDouble("Correct value computed: (" + a + " + " + b + ")", a + b, n.floatValue());
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDouble() throws Exception {
double a = RANDOM.nextDouble() * 100.0;
double b = RANDOM.nextDouble() * 100.0;
doPlusWithDouble(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDoubleRound() throws Exception {
double a = RANDOM.nextInt(1000);
double b = RANDOM.nextInt(1000);
doPlusWithDouble(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDoubleMaxInt() throws Exception {
double a = Integer.MAX_VALUE;
double b = 1;
doPlusWithDouble(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDoubleMaxMinInt() throws Exception {
double a = Integer.MAX_VALUE;
double b = Integer.MIN_VALUE;
doPlusWithDouble(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDoubleMinIntMinusOne() throws Exception {
double a = -1;
double b = Integer.MIN_VALUE;
doPlusWithDouble(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDoubleMaxIntPlusOne() throws Exception {
double a = 1;
double b = Integer.MAX_VALUE;
doPlusWithDouble(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDoubleNaNPlusNegInf() throws Exception {
double a = Double.NaN;
double b = Double.NEGATIVE_INFINITY;
doPlusWithDouble(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDoubleNaNPlusPosInf() throws Exception {
double a = Double.NaN;
double b = Double.POSITIVE_INFINITY;
doPlusWithDouble(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDoubleMaxIntPlusPosInf() throws Exception {
double a = Integer.MAX_VALUE;
double b = Double.POSITIVE_INFINITY;
doPlusWithDouble(a, b);
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithDoubleMaxIntPlusNegInf() throws Exception {
double a = Integer.MAX_VALUE;
double b = Double.NEGATIVE_INFINITY;
doPlusWithDouble(a, b);
}
private void doPlusWithDouble(double a, double b) throws Exception {
PolyglotEngine.Value plus = findGlobalSymbol(plus(double.class, double.class));
Number n = plus.execute(a, b).as(Number.class);
assertDouble("Correct value computed: (" + a + " + " + b + ")", a + b, n.doubleValue());
}
/** @since 0.8 or earlier */
@Test
public void testPlusWithIntsOnCompoundObject() throws Exception {
int a = RANDOM.nextInt(100);
int b = RANDOM.nextInt(100);
CompoundObject obj = findCompoundSymbol();
if (obj == null) {
return;
}
Number n = obj.plus(a, b);
assert a + b == n.intValue() : "(" + a + " + " + b + ") = " + n.intValue();
}
/** @since 0.8 or earlier */
@Test(expected = Exception.class)
public void testInvalidTestMethod() throws Exception {
String mime = mimeType();
String code = invalidCode();
// @formatter:off
Source invalidCode = Source.newBuilder(code).
name("Invalid code").
mimeType(mime).
build();
// @formatter:on
Object ret = vm().eval(invalidCode).get();
fail("Should yield IOException, but returned " + ret);
}
/** @since 0.8 or earlier */
@Test
public void testMaxOrMinValue() throws Exception {
PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
TruffleObject fn = JavaInterop.asTruffleFunction(LongBinaryOperation.class, new MaxMinObject(true));
Object res = apply.execute(fn).get();
assert res instanceof Number : "result should be a number: " + res;
Number n = (Number) res;
assert 42 == n.intValue() : "32 > 18 and plus 10";
}
/** @since 0.8 or earlier */
@Test
public void testMaxOrMinValue2() throws Exception {
PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
TruffleObject fn = JavaInterop.asTruffleFunction(LongBinaryOperation.class, new MaxMinObject(false));
final PolyglotEngine.Value result = apply.execute(fn);
try {
Boolean res = result.as(Boolean.class);
fail("Cannot be converted to Boolean: " + res);
} catch (ClassCastException ex) {
// correct
}
Number n = result.as(Number.class);
assert 28 == n.intValue() : "18 < 32 and plus 10";
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveReturnTypeByte() throws Exception {
PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
byte value = (byte) RANDOM.nextInt(100);
TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value));
Number n = apply.execute(fn).as(Number.class);
assertEquals("The same value returned (" + value + " + 10): ", value + 10, n.byteValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveReturnTypeShort() throws Exception {
PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
short value = (short) RANDOM.nextInt(100);
TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value));
Number n = apply.execute(fn).as(Number.class);
assertEquals("The same value returned (" + value + " + 10): ", value + 10, n.shortValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveReturnTypeInt() throws Exception {
PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
int value = RANDOM.nextInt(100);
TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value));
Number n = apply.execute(fn).as(Number.class);
assertEquals("The same value returned (" + value + " + 10): ", value + 10, n.intValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveReturnTypeLong() throws Exception {
PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
long value = RANDOM.nextInt(1000);
TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value));
Number n = apply.execute(fn).as(Number.class);
assertEquals("The same value returned (" + value + " + 10): ", value + 10, n.longValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveReturnTypeFloat() throws Exception {
PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
float value = RANDOM.nextInt(1000) + RANDOM.nextFloat();
TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value));
Number n = apply.execute(fn).as(Number.class);
assertDouble("The same value returned (" + value + " + 10): ", value + 10, n.floatValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveReturnTypeDouble() throws Exception {
PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
double value = RANDOM.nextInt(1000) + RANDOM.nextDouble();
TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value));
Number n = apply.execute(fn).as(Number.class);
assertDouble("The same value returned (" + value + " + 10): ", value + 10, n.doubleValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityByte() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
byte value = (byte) RANDOM.nextInt(100);
Number n = (Number) apply.execute(value).get();
assertEquals("The same value returned", value, n.byteValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityBoxedByte() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
byte value = (byte) RANDOM.nextInt(100);
BoxedValue boxed = new BoxedValue(value);
Number n = (Number) apply.execute(boxed).get();
assertEquals("The same value returned", value, n.byteValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityShort() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
short value = (short) RANDOM.nextInt(100);
Number n = (Number) apply.execute(value).get();
assertEquals("The same value returned", value, n.shortValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityBoxedShort() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
short value = (short) RANDOM.nextInt(100);
BoxedValue boxed = new BoxedValue(value);
Number n = (Number) apply.execute(boxed).get();
assertEquals("The same value returned", value, n.shortValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityInt() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
int value = RANDOM.nextInt(100);
Number n = (Number) apply.execute(value).get();
assertEquals("The same value returned", value, n.intValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityBoxedInt() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
int value = RANDOM.nextInt(100);
BoxedValue boxed = new BoxedValue(value);
Number n = (Number) apply.execute(boxed).get();
assertEquals("The same value returned", value, n.intValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityLong() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
long value = RANDOM.nextInt(1000);
Number n = (Number) apply.execute(value).get();
assertEquals("The same value returned", value, n.longValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityBoxedLong() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
long value = RANDOM.nextInt(1000);
BoxedValue boxed = new BoxedValue(value);
Number n = (Number) apply.execute(boxed).get();
assertEquals("The same value returned", value, n.longValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityFloat() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
float value = RANDOM.nextInt(1000) + RANDOM.nextFloat();
Number n = (Number) apply.execute(value).get();
assertDouble("The same value returned", value, n.floatValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityBoxedFloat() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
float value = RANDOM.nextInt(1000) + RANDOM.nextFloat();
BoxedValue boxed = new BoxedValue(value);
Number n = (Number) apply.execute(boxed).get();
assertDouble("The same value returned", value, n.floatValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityDouble() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
double value = RANDOM.nextInt(1000) + RANDOM.nextDouble();
Number n = (Number) apply.execute(value).get();
assertDouble("The same value returned", value, n.doubleValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityBoxedDouble() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
double value = RANDOM.nextInt(1000) + RANDOM.nextDouble();
BoxedValue boxed = new BoxedValue(value);
Number n = (Number) apply.execute(boxed).get();
assertDouble("The same value returned", value, n.doubleValue());
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityString() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
String value = "Value" + RANDOM.nextInt(1000) + RANDOM.nextDouble();
String ret = (String) apply.execute(value).get();
assertEquals("The same value returned", value, ret);
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveidentityBoxedString() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
String value = "Value" + RANDOM.nextInt(1000) + RANDOM.nextDouble();
BoxedValue boxed = new BoxedValue(value);
String ret = (String) apply.execute(boxed).get();
assertEquals("The same value returned", value, ret);
}
/** @since 0.8 or earlier */
@Test
public void testPrimitiveIdentityForeignObject() throws Exception {
String id = identity();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
Object fn = new Object();
Object ret = apply.execute(fn).get();
assertSameTruffleObject("The same value returned", fn, ret);
}
/** @since 0.8 or earlier */
@Test
public void testCoExistanceOfMultipleLanguageInstances() throws Exception {
final String countMethod = countInvocations();
PolyglotEngine.Builder builder = PolyglotEngine.newBuilder().executor(Executors.newSingleThreadExecutor());
PolyglotEngine vm2 = prepareVM(builder);
try {
PolyglotEngine.Value count2 = vm2.findGlobalSymbol(countMethod);
PolyglotEngine.Value count1 = findGlobalSymbol(countMethod);
PolyglotEngine vm1 = tckVM;
assertNotSame("Two virtual machines allocated", vm1, vm2);
int prev1 = 0;
int prev2 = 0;
StringBuilder log = new StringBuilder();
for (int i = 0; i < 10; i++) {
int quantum = RANDOM.nextInt(10);
log.append("quantum" + i + " is " + quantum + "\n");
for (int j = 0; j < quantum; j++) {
Object res = count1.execute().get();
assert res instanceof Number : "expecting number: " + res + "\n" + log;
++prev1;
assert ((Number) res).intValue() == prev1 : "expecting " + prev1 + " but was " + res + "\n" + log;
}
for (int j = 0; j < quantum; j++) {
Object res = count2.execute().get();
assert res instanceof Number : "expecting number: " + res + "\n" + log;
++prev2;
assert ((Number) res).intValue() == prev2 : "expecting " + prev2 + " but was " + res + "\n" + log;
}
assert prev1 == prev2 : "At round " + i + " the same number of invocations " + prev1 + " vs. " + prev2 + "\n" + log;
}
} finally {
vm2.dispose();
}
}
/** @since 0.8 or earlier */
@Test
public void testGlobalObjectIsAccessible() throws Exception {
String globalObjectFunction = globalObject();
if (globalObjectFunction == null) {
return;
}
PolyglotEngine.Language language = vm().getLanguages().get(mimeType());
assertNotNull("Language for " + mimeType() + " found", language);
PolyglotEngine.Value function = vm().findGlobalSymbol(globalObjectFunction);
Object global = function.execute().get();
assertEquals("Global from the language same with Java obtained one", language.getGlobalObject().get(), global);
assertIsObjectOfLanguage(global);
}
/** @since 0.8 or earlier */
@Test
public void testEvaluateSource() throws Exception {
PolyglotEngine.Language language = vm().getLanguages().get(mimeType());
assertNotNull("Language for " + mimeType() + " found", language);
PolyglotEngine.Value function = vm().findGlobalSymbol(evaluateSource());
assertNotNull(evaluateSource() + " found", function);
double expect = Math.floor(RANDOM.nextDouble() * 100000.0) / 10.0;
Object parsed = function.execute("application/x-tck", "" + expect).get();
assertTrue("Expecting numeric result, was:" + expect, parsed instanceof Number);
double value = ((Number) parsed).doubleValue();
assertDouble("Gets the double", expect, value);
}
/** @since 0.8 or earlier */
@Test
public void multiplyTwoVariables() throws Exception {
final String firstVar = "var" + (char) ('A' + RANDOM.nextInt(24));
final String secondVar = "var" + (char) ('0' + RANDOM.nextInt(10));
String mulCode = multiplyCode(firstVar, secondVar);
// @formatter:off
Source source = Source.newBuilder("TCK42:" + mimeType() + ":" + mulCode).
name("evaluate " + firstVar + " * " + secondVar).
mimeType("application/x-tck").
build();
// @formatter:on
final PolyglotEngine.Value evalSource = vm().eval(source);
final PolyglotEngine.Value invokeMul = evalSource.execute(firstVar, secondVar);
Object result = invokeMul.get();
assertTrue("Expecting numeric result, was:" + result + " for " + firstVar + " and " + secondVar, result instanceof Number);
assertEquals("Right value for " + firstVar + " and " + secondVar, 42, ((Number) result).intValue());
}
/** @since 0.8 or earlier */
@Test
public void testAddComplexNumbers() throws Exception {
String id = complexAdd();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
ComplexNumber a = new ComplexNumber(32, 10);
ComplexNumber b = new ComplexNumber(10, 32);
apply.execute(a, b);
assertEquals(42.0, a.get(ComplexNumber.REAL_IDENTIFIER), 0.1);
assertEquals(42.0, a.get(ComplexNumber.IMAGINARY_IDENTIFIER), 0.1);
}
/** @since 0.8 or earlier */
@Test
public void testAddComplexNumbersWithMethod() throws Exception {
String id = complexAddWithMethod();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
ComplexNumber a = new ComplexNumber(32, 10);
ComplexNumber b = new ComplexNumber(10, 32);
apply.execute(a, b);
assertDouble("The same value returned", 42.0, a.get(ComplexNumber.REAL_IDENTIFIER));
assertDouble("The same value returned", 42.0, a.get(ComplexNumber.IMAGINARY_IDENTIFIER));
}
/** @since 0.13 */
@Test
public void testPropertiesInteropMessage() throws Exception {
PolyglotEngine.Value values = findGlobalSymbol(valuesObject());
PolyglotEngine.Value valueObj = values.execute();
assertIsObjectOfLanguage(valueObj.get());
Map, ?> res = valueObj.as(Map.class);
Map expected = new HashMap<>();
expected.put("intValue", 0);
expected.put("byteValue", 0);
expected.put("doubleValue", 0.0);
for (Map.Entry extends Object, ? extends Object> entry : res.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
Object expValue = expected.remove(key);
if (expValue != null) {
assertEquals("For key " + key, ((Number) expValue).doubleValue(), ((Number) value).doubleValue(), 0.01);
}
}
assertTrue("All expected properties found: " + expected, expected.isEmpty());
}
/** @since 0.8 or earlier */
@Test
public void testSumRealOfComplexNumbersA() throws Exception {
String id = complexSumReal();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
ComplexNumbersA numbers = new ComplexNumbersA(new double[]{2, -1, 30, -1, 10, -1});
Number n = (Number) apply.execute(numbers).get();
assertDouble("The same value returned", 42.0, n.doubleValue());
}
/** @since 0.8 or earlier */
@Test
public void testSumRealOfComplexNumbersB() throws Exception {
String id = complexSumReal();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
ComplexNumbersB numbers = new ComplexNumbersB(new double[]{2, 30, 10}, new double[]{-1, -1, -1});
Number n = (Number) apply.execute(numbers).get();
assertDouble("The same value returned", 42.0, n.doubleValue());
}
/** @since 0.8 or earlier */
@Test
public void testSumRealOfComplexNumbersAsStructuredDataRowBased() throws Exception {
String id = complexSumReal();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
Schema schema = new Schema(3, true, Arrays.asList(ComplexNumber.REAL_IDENTIFIER, ComplexNumber.IMAGINARY_IDENTIFIER), Arrays.asList(Type.DOUBLE, Type.DOUBLE));
byte[] buffer = new byte[(6 * Double.SIZE / Byte.SIZE)];
putDoubles(buffer, new double[]{2, -1, 30, -1, 10, -1});
StructuredData numbers = new StructuredData(buffer, schema);
Number n = (Number) apply.execute(numbers).get();
assertDouble("The same value returned", 42.0, n.doubleValue());
}
/** @since 0.8 or earlier */
@Test
public void testSumRealOfComplexNumbersAsStructuredDataColumnBased() throws Exception {
String id = complexSumReal();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
Schema schema = new Schema(3, false, Arrays.asList(ComplexNumber.REAL_IDENTIFIER, ComplexNumber.IMAGINARY_IDENTIFIER), Arrays.asList(Type.DOUBLE, Type.DOUBLE));
byte[] buffer = new byte[6 * Double.SIZE / Byte.SIZE];
putDoubles(buffer, new double[]{2, 30, 10, -1, -1, -1});
StructuredData numbers = new StructuredData(buffer, schema);
Number n = (Number) apply.execute(numbers).get();
assertDouble("The same value returned", 42.0, n.doubleValue());
}
/** @since 0.8 or earlier */
@Test
public void testCopyComplexNumbersA() throws Exception {
String id = complexCopy();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
ComplexNumbersA a = new ComplexNumbersA(new double[]{-1, -1, -1, -1, -1, -1});
ComplexNumbersA b = new ComplexNumbersA(new double[]{41, 42, 43, 44, 45, 46});
apply.execute(a, b);
Assert.assertArrayEquals(new double[]{41, 42, 43, 44, 45, 46}, a.getData(), 0.1);
}
/** @since 0.8 or earlier */
@Test
public void testCopyComplexNumbersB() throws Exception {
String id = complexCopy();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
ComplexNumbersB a = new ComplexNumbersB(new double[]{-1, -1, -1}, new double[]{-1, -1, -1});
ComplexNumbersB b = new ComplexNumbersB(new double[]{41, 43, 45}, new double[]{42, 44, 46});
apply.execute(a, b);
Assert.assertArrayEquals(new double[]{41, 42, 43, 44, 45, 46}, a.getData(), 0.1);
}
/** @since 0.8 or earlier */
@Test
public void testCopyStructuredComplexToComplexNumbersA() throws Exception {
String id = complexCopy();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
ComplexNumbersA a = new ComplexNumbersA(new double[]{-1, -1, -1, -1, -1, -1});
Schema schema = new Schema(3, true, Arrays.asList(ComplexNumber.REAL_IDENTIFIER, ComplexNumber.IMAGINARY_IDENTIFIER), Arrays.asList(Type.DOUBLE, Type.DOUBLE));
byte[] buffer = new byte[6 * Double.SIZE / Byte.SIZE];
putDoubles(buffer, new double[]{41, 42, 43, 44, 45, 46});
StructuredData b = new StructuredData(buffer, schema);
apply.execute(a, b);
Assert.assertArrayEquals(new double[]{41, 42, 43, 44, 45, 46}, a.getData(), 0.1);
}
/** @since 0.8 or earlier */
@Test
public void readWriteByteValue() throws Exception {
String id = valuesObject();
ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class);
assertEquals("Zero", 0, values.byteValue());
final byte value = (byte) RANDOM.nextInt(128);
values.byteValue(value);
assertEquals("Correct value", value, values.byteValue());
}
/** @since 0.8 or earlier */
@Test
public void readWriteShortValue() throws Exception {
String id = valuesObject();
ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class);
assertEquals("Zero", 0, values.shortValue());
final short value = (short) RANDOM.nextInt(32768);
values.shortValue(value);
assertEquals("Correct value", value, values.shortValue());
}
/** @since 0.8 or earlier */
@Test
public void readWriteIntValue() throws Exception {
String id = valuesObject();
ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class);
assertEquals("Zero", 0, values.intValue());
final int value = RANDOM.nextInt();
values.intValue(value);
assertEquals("Correct value", value, values.intValue());
}
/** @since 0.8 or earlier */
@Test
public void readWriteFloatValue() throws Exception {
String id = valuesObject();
ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class);
assertDouble("Zero", 0, values.floatValue());
final float value = RANDOM.nextFloat() * 1000.0f;
values.floatValue(value);
assertDouble("Correct value", value, values.floatValue());
}
/** @since 0.8 or earlier */
@Test
public void readWriteDoubleValue() throws Exception {
String id = valuesObject();
ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class);
assertDouble("Zero", 0, values.doubleValue());
final double value = RANDOM.nextDouble() * 1000.0;
values.doubleValue(value);
assertDouble("Correct value", value, values.doubleValue());
}
/** @since 0.8 or earlier */
@Test
public void readWriteCharValue() throws Exception {
String id = valuesObject();
ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class);
assertEquals("Zero", '0', values.charValue());
String letters = "P\u0159\u00EDli\u0161 \u017Elu\u0165ou\u010Dk\u00FD k\u016F\u0148 \u00FAp\u011Bl \u010F\u00E1belsk\u00E9 \u00F3dy";
final char value = letters.charAt(RANDOM.nextInt(letters.length()));
values.charValue(value);
assertEquals("Correct value", value, values.charValue());
}
/** @since 0.8 or earlier */
@Test
public void readWriteBooleanValue() throws Exception {
String id = valuesObject();
ValuesObject values = findGlobalSymbol(id).execute().as(ValuesObject.class);
assertEquals("False", false, values.booleanValue());
values.booleanValue(true);
assertEquals("Correct value", true, values.booleanValue());
values.booleanValue(false);
assertEquals("Correct value2", false, values.booleanValue());
}
/**
* Test for array access. Creates a {@link TruffleObject} around a Java array, fills it with
* integers and asks the language to add one to each of the array elements.
*
* @since 0.14
*/
@Test
public void addOneToAnArrayElement() throws Exception {
String id = addToArray();
if (id == null) {
return;
}
PolyglotEngine.Value add = findGlobalSymbol(id);
Number[] arr = new Number[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
TruffleObject truffleArr = JavaInterop.asTruffleObject(arr);
int index = RANDOM.nextInt(arr.length - 1);
add.execute(truffleArr, index, 1);
final Number valueAtIndex = arr[index];
final Number valueAfterIndex = arr[index + 1];
assertNotNull("Non-null value expected at index " + index, valueAtIndex);
assertNotNull("Non-null value expected at index " + (index + 1), valueAfterIndex);
assertEquals("Expecting same value at both indexes", valueAtIndex.intValue(), valueAfterIndex.intValue());
}
/**
* Tests whether execution can be suspended in debugger.
*
* @since 0.15
*/
@Test
public void timeOutTest() throws Exception {
assumeFalse("Crashes on AArch64 in C2 (GR-8733)", System.getProperty("os.arch").equalsIgnoreCase("aarch64"));
final ExecWithTimeOut timeOutExecution = new ExecWithTimeOut();
ScheduledExecutorService executor = new MockExecutorService();
timeOutExecution.engine = prepareVM(PolyglotEngine.newBuilder());
PolyglotEngine.Value counting = timeOutExecution.engine.findGlobalSymbol(countUpWhile());
int index = RANDOM.nextInt(50) + 50;
CountAndKill obj = new CountAndKill(index, executor);
timeOutExecution.executeWithTimeOut(executor, counting, obj);
assertEquals("Executed " + index + " times, and counted down to zero", 0, obj.countDown);
assertTrue("Last number bigger than requested", index <= obj.lastParameter);
assertTrue("All tasks processed", executor.isShutdown());
}
/** @since 0.15 */
@Test
public void testRootNodeName() throws Exception {
final int[] haltCount = new int[1];
final String name = applyNumbers();
final String[] actualName = new String[1];
final PolyglotEngine engine = prepareVM(PolyglotEngine.newBuilder());
final PolyglotEngine.Value apply = engine.findGlobalSymbol(name);
final int value = RANDOM.nextInt(100);
final TruffleObject fn = JavaInterop.asTruffleFunction(ObjectBinaryOperation.class, new ConstantFunction(value));
try (DebuggerSession session = Debugger.find(engine).startSession(new SuspendedCallback() {
public void onSuspend(SuspendedEvent ev) {
actualName[0] = ev.getTopStackFrame().getName();
haltCount[0] = haltCount[0] + 1;
}
})) {
session.suspendNextExecution();
apply.execute(fn).as(Number.class);
}
assertEquals(1, haltCount[0]);
assertEquals(name, actualName[0]);
}
/** @since 0.16 */
@Test
public void testReadFromObjectWithValueProperty() throws Exception {
String id = objectWithValueProperty();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
TruffleObject truffleObject = (TruffleObject) apply.execute().get();
assertIsObjectOfLanguage(truffleObject);
ObjectWithValueInterface object = JavaInterop.asJavaObject(ObjectWithValueInterface.class, truffleObject);
Assert.assertEquals(42.0, object.value(), 0.1);
}
/** @since 0.16 */
@Test
public void testReadFromObjectWithElement() throws Exception {
String id = objectWithElement();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
TruffleObject truffleObject = (TruffleObject) apply.execute().get();
assertIsObjectOfLanguage(truffleObject);
List> object = JavaInterop.asJavaObject(List.class, truffleObject);
Assert.assertEquals(42.0, ((Number) object.get(2)).doubleValue(), 0.1);
}
/** @since 0.16 */
@Test
public void testWriteToObjectWithValueProperty() throws Exception {
String id = objectWithValueProperty();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
TruffleObject truffleObject = (TruffleObject) apply.execute().get();
assertIsObjectOfLanguage(truffleObject);
ObjectWithValueInterface object = JavaInterop.asJavaObject(ObjectWithValueInterface.class, truffleObject);
Assert.assertEquals(42.0, object.value(), 0.1);
object.value(13.0);
Assert.assertEquals(13.0, object.value(), 0.1);
}
/** @since 0.16 */
@Test
public void testWriteToObjectWithElement() throws Exception {
String id = objectWithElement();
if (id == null) {
return;
}
PolyglotEngine.Value apply = findGlobalSymbol(id);
TruffleObject truffleObject = (TruffleObject) apply.execute().get();
assertIsObjectOfLanguage(truffleObject);
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy