InteroplatedRegexpNode.java

  1. /*
  2.  * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. This
  3.  * code is released under a tri EPL/GPL/LGPL license. You can use it,
  4.  * redistribute it and/or modify it under the terms of the:
  5.  *
  6.  * Eclipse Public License version 1.0
  7.  * GNU General Public License version 2
  8.  * GNU Lesser General Public License version 2.1
  9.  */
  10. package org.jruby.truffle.nodes.core;

  11. import com.oracle.truffle.api.frame.VirtualFrame;
  12. import com.oracle.truffle.api.source.SourceSection;
  13. import org.jruby.truffle.nodes.RubyNode;
  14. import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
  15. import org.jruby.truffle.runtime.RubyContext;
  16. import org.jruby.truffle.runtime.core.RubyEncoding;
  17. import org.jruby.truffle.runtime.core.RubyRegexp;
  18. import org.jruby.truffle.runtime.core.RubyString;
  19. import org.jruby.truffle.translator.BodyTranslator;
  20. import org.jruby.util.RegexpOptions;

  21. public class InteroplatedRegexpNode extends RubyNode {

  22.     @Children protected final RubyNode[] children;
  23.     private final RegexpOptions options;
  24.     @Child protected DispatchHeadNode toS;

  25.     public InteroplatedRegexpNode(RubyContext context, SourceSection sourceSection, RubyNode[] children, RegexpOptions options) {
  26.         super(context, sourceSection);
  27.         this.children = children;
  28.         this.options = options;
  29.         toS = new DispatchHeadNode(context);
  30.     }

  31.     @Override
  32.     public RubyRegexp executeRubyRegexp(VirtualFrame frame) {
  33.         notDesignedForCompilation();

  34.         final org.jruby.RubyString[] strings = new org.jruby.RubyString[children.length];

  35.         for (int n = 0; n < children.length; n++) {
  36.             final Object child = children[n].execute(frame);
  37.             strings[n] = org.jruby.RubyString.newString(getContext().getRuntime(), ((RubyString) toS.call(frame, child, "to_s", null)).getBytes());
  38.         }

  39.         final org.jruby.RubyString preprocessed = org.jruby.RubyRegexp.preprocessDRegexp(getContext().getRuntime(), strings, options);

  40.         final RubyRegexp regexp = new RubyRegexp(this, getContext().getCoreLibrary().getRegexpClass(), preprocessed.getByteList(), options.toOptions());

  41.         if (options.isEncodingNone()) {
  42.             // This isn't quite right - we shouldn't be looking up by name, we need a real reference to this constants

  43.             if (!BodyTranslator.all7Bit(preprocessed.getByteList().bytes())) {
  44.                 regexp.forceEncoding((RubyEncoding) getContext().getCoreLibrary().getEncodingClass().getConstants().get("ASCII_8BIT").getValue());
  45.             } else {
  46.                 regexp.forceEncoding((RubyEncoding) getContext().getCoreLibrary().getEncodingClass().getConstants().get("US_ASCII").getValue());
  47.             }
  48.         }

  49.         return regexp;
  50.     }

  51.     @Override
  52.     public Object execute(VirtualFrame frame) {
  53.         return executeRubyRegexp(frame);
  54.     }
  55. }