|
40 | 40 | */
|
41 | 41 | package com.oracle.truffle.api.instrumentation.test;
|
42 | 42 |
|
43 |
| -import com.oracle.truffle.api.CompilerDirectives; |
44 |
| -import com.oracle.truffle.api.frame.VirtualFrame; |
45 | 43 | import java.io.IOException;
|
46 | 44 | import java.util.ArrayList;
|
47 | 45 | import java.util.List;
|
48 | 46 |
|
| 47 | +import com.oracle.truffle.api.CallTarget; |
| 48 | +import com.oracle.truffle.api.CompilerDirectives; |
| 49 | +import com.oracle.truffle.api.TruffleLanguage; |
| 50 | +import com.oracle.truffle.api.frame.VirtualFrame; |
49 | 51 | import com.oracle.truffle.api.instrumentation.EventBinding;
|
50 | 52 | import com.oracle.truffle.api.instrumentation.EventContext;
|
51 | 53 | import com.oracle.truffle.api.instrumentation.ExecutionEventNode;
|
52 | 54 | import com.oracle.truffle.api.instrumentation.ExecutionEventNodeFactory;
|
| 55 | +import com.oracle.truffle.api.instrumentation.GenerateWrapper; |
| 56 | +import com.oracle.truffle.api.instrumentation.InstrumentableNode; |
53 | 57 | import com.oracle.truffle.api.instrumentation.LoadSourceSectionEvent;
|
54 | 58 | import com.oracle.truffle.api.instrumentation.LoadSourceSectionListener;
|
55 | 59 | import com.oracle.truffle.api.instrumentation.NearestSectionFilter;
|
| 60 | +import com.oracle.truffle.api.instrumentation.ProbeNode; |
56 | 61 | import com.oracle.truffle.api.instrumentation.SourceSectionFilter;
|
| 62 | +import com.oracle.truffle.api.instrumentation.StandardTags; |
57 | 63 | import com.oracle.truffle.api.instrumentation.StandardTags.ExpressionTag;
|
58 | 64 | import com.oracle.truffle.api.instrumentation.StandardTags.StatementTag;
|
| 65 | +import com.oracle.truffle.api.instrumentation.Tag; |
| 66 | +import com.oracle.truffle.api.nodes.Node; |
| 67 | +import com.oracle.truffle.api.nodes.RootNode; |
| 68 | +import com.oracle.truffle.api.test.polyglot.ProxyLanguage; |
59 | 69 |
|
60 | 70 | import static org.junit.Assert.assertEquals;
|
61 | 71 | import static org.junit.Assert.assertNotEquals;
|
62 | 72 | import org.junit.Test;
|
63 | 73 |
|
| 74 | +import org.graalvm.polyglot.Context; |
| 75 | +import org.graalvm.polyglot.Source; |
64 | 76 | import org.graalvm.polyglot.SourceSection;
|
65 | 77 | import org.graalvm.polyglot.Value;
|
66 | 78 |
|
@@ -218,6 +230,75 @@ private void entered() {
|
218 | 230 | assertEquals(executedEvents.toString(), 0, executedEvents.size());
|
219 | 231 | }
|
220 | 232 |
|
| 233 | + @Test |
| 234 | + public void testUnavailableSection() { |
| 235 | + setupEnv(Context.create(), new ProxyLanguage() { |
| 236 | + |
| 237 | + @Override |
| 238 | + protected CallTarget parse(TruffleLanguage.ParsingRequest request) throws Exception { |
| 239 | + com.oracle.truffle.api.source.Source source = request.getSource(); |
| 240 | + return new RootNode(languageInstance) { |
| 241 | + @Node.Child private NearestStatementTestNode child = new NearestStatementTestNode(source.createSection(1), StandardTags.RootTag.class); |
| 242 | + |
| 243 | + @Override |
| 244 | + public Object execute(VirtualFrame frame) { |
| 245 | + return child.execute(frame); |
| 246 | + } |
| 247 | + |
| 248 | + @Override |
| 249 | + public com.oracle.truffle.api.source.SourceSection getSourceSection() { |
| 250 | + return source.createUnavailableSection(); |
| 251 | + } |
| 252 | + }.getCallTarget(); |
| 253 | + } |
| 254 | + }); |
| 255 | + Source source = Source.create(ProxyLanguage.ID, "a"); |
| 256 | + context.eval(source); |
| 257 | + checkLoadEvents(NearestSectionFilter.newBuilder(1, 0).build(), SourceSectionFilter.ANY, createSection(source, -1, -1)); |
| 258 | + SourceSection textSection = createSection(source, 0, 1); |
| 259 | + checkLoadEvents(NearestSectionFilter.newBuilder(1, 0).tagIs(ExpressionTag.class).build(), SourceSectionFilter.ANY, textSection); |
| 260 | + checkLoadEvents(NearestSectionFilter.newBuilder(1, 1).tagIs(ExpressionTag.class).build(), SourceSectionFilter.ANY, textSection); |
| 261 | + checkLoadEvents(NearestSectionFilter.newBuilder(2, 0).tagIs(ExpressionTag.class).build(), SourceSectionFilter.ANY, textSection); |
| 262 | + } |
| 263 | + |
| 264 | + @GenerateWrapper |
| 265 | + static class NearestStatementTestNode extends Node implements InstrumentableNode { |
| 266 | + |
| 267 | + private final com.oracle.truffle.api.source.SourceSection sourceSection; |
| 268 | + private final Class<?> tag; |
| 269 | + @Node.Child private NearestStatementTestNode child; |
| 270 | + |
| 271 | + NearestStatementTestNode(com.oracle.truffle.api.source.SourceSection sourceSection, Class<?> tag) { |
| 272 | + this.sourceSection = StandardTags.RootTag.class.equals(tag) ? sourceSection.getSource().createUnavailableSection() : sourceSection; |
| 273 | + this.tag = tag; |
| 274 | + this.child = StandardTags.RootTag.class.equals(tag) ? new NearestStatementTestNode(sourceSection, StandardTags.ExpressionTag.class) : null; |
| 275 | + } |
| 276 | + |
| 277 | + @Override |
| 278 | + public boolean isInstrumentable() { |
| 279 | + return true; |
| 280 | + } |
| 281 | + |
| 282 | + @Override |
| 283 | + public InstrumentableNode.WrapperNode createWrapper(ProbeNode probe) { |
| 284 | + return new NearestStatementTestNodeWrapper(sourceSection, tag, this, probe); |
| 285 | + } |
| 286 | + |
| 287 | + public Object execute(@SuppressWarnings("unused") VirtualFrame frame) { |
| 288 | + return child != null ? child.execute(frame) : true; |
| 289 | + } |
| 290 | + |
| 291 | + @Override |
| 292 | + public boolean hasTag(Class<? extends Tag> t) { |
| 293 | + return this.tag.equals(t); |
| 294 | + } |
| 295 | + |
| 296 | + @Override |
| 297 | + public com.oracle.truffle.api.source.SourceSection getSourceSection() { |
| 298 | + return sourceSection; |
| 299 | + } |
| 300 | + } |
| 301 | + |
221 | 302 | private void checkLoadEvents(NearestSectionFilter nearestFilter, SourceSectionFilter baseFilter, SourceSection... expectedSections) {
|
222 | 303 | final List<LoadSourceSectionEvent> visitedEvents = new ArrayList<>(expectedSections.length);
|
223 | 304 | LoadSourceSectionListener listener = new LoadSourceSectionListener() {
|
|
0 commit comments