public synchronized void attach(String file, int line, final DynamicObject block) { assert RubyGuards.isRubyProc(block); final Instrument instrument = Instrument.create( new StandardInstrumentListener() { @Override public void enter(Probe probe, Node node, VirtualFrame frame) { final DynamicObject binding = BindingNodes.createRubyBinding( context.getCoreLibrary().getBindingClass(), RubyArguments.getSelf(frame.getArguments()), frame.materialize()); ProcNodes.rootCall(block, binding); } @Override public void returnVoid(Probe probe, Node node, VirtualFrame virtualFrame) {} @Override public void returnValue( Probe probe, Node node, VirtualFrame virtualFrame, Object o) {} @Override public void returnExceptional( Probe probe, Node node, VirtualFrame virtualFrame, Exception e) {} }, String.format("Truffle::Primitive.attach@%s:%d", file, line)); final Source source = context.getSourceManager().forFileBestFuzzily(file); final LineLocation lineLocation = source.createLineLocation(line); List<Instrument> instruments = attachments.get(lineLocation); if (instruments == null) { instruments = new ArrayList<>(); attachments.put(lineLocation, instruments); } instruments.add(instrument); for (Probe probe : lineToProbesMap.findProbes(lineLocation)) { if (probe.isTaggedAs(StandardSyntaxTag.STATEMENT)) { probe.attach(instrument); return; } } throw new RuntimeException("couldn't find a statement!"); }
public synchronized void detach(String file, int line) { final Source source = context.getSourceManager().forFileBestFuzzily(file); final LineLocation lineLocation = source.createLineLocation(line); final List<Instrument> instruments = attachments.remove(lineLocation); if (instruments != null) { for (Instrument instrument : instruments) { instrument.dispose(); } } }