com.oracle.truffle.api.instrumentation.test.VariablesScopeTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of truffle-instrument-test Show documentation
Show all versions of truffle-instrument-test Show documentation
Instrumentation tests including InstrumentationTestLanguage.
The newest version!
/*
* Copyright (c) 2017, 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.api.instrumentation.test;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.Scope;
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrumentation.EventContext;
import com.oracle.truffle.api.instrumentation.ExecutionEventListener;
import com.oracle.truffle.api.instrumentation.Instrumentable;
import com.oracle.truffle.api.instrumentation.ProvidedTags;
import com.oracle.truffle.api.instrumentation.SourceSectionFilter;
import com.oracle.truffle.api.instrumentation.StandardTags;
import com.oracle.truffle.api.instrumentation.TruffleInstrument;
import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.java.JavaInterop;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
/**
* Test of {@link Scope}.
*/
public class VariablesScopeTest extends AbstractInstrumentationTest {
@Test
public void testDefaultScope() throws Throwable {
assureEnabled(engine.getInstruments().get("testVariablesScopeInstrument"));
TestScopeInstrument.INSTANCE.setTester(new DefaultScopeTester());
run("ROOT(DEFINE(\ntestFunction,ROOT(\nVARIABLE(a, 10),\nVARIABLE(b, 20),\nSTATEMENT)),\nCALL(testFunction))");
TestScopeInstrument.INSTANCE.checkForFailure();
}
@TruffleInstrument.Registration(id = "testVariablesScopeInstrument", services = Object.class)
public static class TestScopeInstrument extends TruffleInstrument {
static TestScopeInstrument INSTANCE;
private Tester tester;
private boolean scopeTested;
private Throwable failure;
@Override
protected void onCreate(TruffleInstrument.Env env) {
INSTANCE = this;
env.getInstrumenter().attachListener(SourceSectionFilter.ANY, new ExecutionEventListener() {
@Override
public void onEnter(EventContext context, VirtualFrame frame) {
scopeTested = true;
try {
tester.doTestScope(env, context.getInstrumentedNode(), frame);
} catch (Throwable t) {
failure = t;
}
}
@Override
public void onReturnValue(EventContext context, VirtualFrame frame, Object result) {
}
@Override
public void onReturnExceptional(EventContext context, VirtualFrame frame, Throwable exception) {
}
});
}
void setTester(Tester tester) {
scopeTested = false;
this.tester = tester;
}
void checkForFailure() throws Throwable {
tester = null;
assertTrue("Scope instrument not triggered", scopeTested);
if (failure != null) {
throw failure;
}
}
interface Tester {
void doTestScope(TruffleInstrument.Env env, Node node, VirtualFrame frame) throws Exception;
}
}
private static class DefaultScopeTester implements TestScopeInstrument.Tester {
@SuppressWarnings("rawtypes")
public void doTestScope(TruffleInstrument.Env env, Node node, VirtualFrame frame) throws Exception {
Iterable lscopes = env.findLocalScopes(node, null); // lexical
Iterable dscopes = env.findLocalScopes(node, frame); // dynamic
assertNotNull(lscopes);
assertNotNull(dscopes);
Iterator iterator = lscopes.iterator();
assertTrue(iterator.hasNext());
Scope lscope = iterator.next();
assertFalse(iterator.hasNext());
iterator = dscopes.iterator();
assertTrue(iterator.hasNext());
Scope dscope = iterator.next();
assertFalse(iterator.hasNext());
int line = node.getSourceSection().getStartLine();
if (line == 1 || line == 6) {
assertEquals("Line = " + line + ", function name: ", "", lscope.getName());
} else {
assertEquals("Line = " + line + ", function name: ", "testFunction", lscope.getName());
// Lexical access:
TruffleObject vars = (TruffleObject) lscope.getVariables();
Map varsMap = JavaInterop.asJavaObject(Map.class, vars);
final int numVars = Math.max(line - 3, 0);
assertEquals("Line = " + line + ", num vars:", numVars, varsMap.size());
if (numVars >= 1) {
assertTrue("Var a: ", varsMap.containsKey("a"));
try {
varsMap.get("a");
fail();
} catch (Exception ex) {
// variable value can not be read in the static access
}
}
if (numVars >= 2) {
assertTrue("Var b: ", varsMap.containsKey("b"));
try {
varsMap.get("b");
fail();
} catch (Exception ex) {
// variable value can not be read in the static access
}
}
// Dynamic access:
vars = (TruffleObject) dscope.getVariables();
varsMap = JavaInterop.asJavaObject(Map.class, vars);
assertEquals("Line = " + line + ", num vars:", numVars, varsMap.size());
if (numVars >= 1) {
assertTrue("Var a: ", varsMap.containsKey("a"));
assertEquals("Var a: ", 10, varsMap.get("a"));
}
if (numVars >= 2) {
assertTrue("Var b: ", varsMap.containsKey("b"));
assertEquals("Var b: ", 20, varsMap.get("b"));
}
}
if (line == 6) {
doTestTopScope(env);
}
}
private static void doTestTopScope(TruffleInstrument.Env env) throws UnsupportedMessageException, UnknownIdentifierException {
Iterable topScopes = env.findTopScopes(InstrumentationTestLanguage.ID);
Iterator iterator = topScopes.iterator();
assertTrue(iterator.hasNext());
Scope scope = iterator.next();
assertEquals("global", scope.getName());
assertNull(scope.getNode());
assertNull(scope.getArguments());
TruffleObject variables = (TruffleObject) scope.getVariables();
TruffleObject keys = ForeignAccess.sendKeys(Message.KEYS.createNode(), variables);
assertNotNull(keys);
Number size = (Number) ForeignAccess.sendGetSize(Message.GET_SIZE.createNode(), keys);
assertEquals(1, size.intValue());
String functionName = (String) ForeignAccess.sendRead(Message.READ.createNode(), keys, 0);
assertEquals("testFunction", functionName);
TruffleObject function = (TruffleObject) ForeignAccess.sendRead(Message.READ.createNode(), variables, functionName);
assertTrue(ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), function));
}
}
@Test
public void testSPIScopeCalls() throws Throwable {
org.graalvm.polyglot.Source source = org.graalvm.polyglot.Source.create("test-custom-variables-scope-language", "test");
assureEnabled(engine.getInstruments().get("testVariablesScopeInstrument"));
TestScopeInstrument.INSTANCE.setTester(new CustomScopeTester());
context.eval(source);
TestScopeInstrument.INSTANCE.checkForFailure();
}
@TruffleLanguage.Registration(name = "", version = "", id = "test-custom-variables-scope-language", mimeType = "x-testCustomVariablesScope")
@ProvidedTags({StandardTags.StatementTag.class})
public static class CustomScopeLanguage extends TruffleLanguage © 2015 - 2025 Weber Informatics LLC | Privacy Policy