@Specialization(guards = "isIntegerFixnumRange(range)")
    public Object getIndex(DynamicObject matchData, DynamicObject range, NotProvided len) {
      final Object[] values = getValues(matchData);
      final int normalizedIndex =
          ArrayNodes.normalizeIndex(values.length, Layouts.INTEGER_FIXNUM_RANGE.getBegin(range));
      final int end =
          ArrayNodes.normalizeIndex(values.length, Layouts.INTEGER_FIXNUM_RANGE.getEnd(range));
      final int exclusiveEnd =
          ArrayNodes.clampExclusiveIndex(
              values.length, Layouts.INTEGER_FIXNUM_RANGE.getExcludedEnd(range) ? end : end + 1);
      final int length = exclusiveEnd - normalizedIndex;

      final Object[] store = Arrays.copyOfRange(values, normalizedIndex, normalizedIndex + length);
      return createArray(store, length);
    }
    @Specialization
    public DynamicObject toA(DynamicObject matchData) {
      CompilerDirectives.transferToInterpreter();

      return ArrayNodes.fromObjects(
          getContext().getCoreLibrary().getArrayClass(), getValues(matchData));
    }
Beispiel #3
0
 @TruffleBoundary
 private Object[] unsplat(Object[] argumentsObjects) {
   // TOOD(CS): what is the error behaviour here?
   assert argumentsObjects.length == 1;
   assert RubyGuards.isRubyArray(argumentsObjects[0]);
   return ArrayNodes.slowToArray(((RubyBasicObject) argumentsObjects[0]));
 }
 @Specialization
 public Object getIndex(DynamicObject matchData, int index, int length) {
   CompilerDirectives.transferToInterpreter();
   // TODO BJF 15-May-2015 Need to handle negative indexes and lengths and out of bounds
   final Object[] values = getValues(matchData);
   final int normalizedIndex = ArrayNodes.normalizeIndex(values.length, index);
   final Object[] store = Arrays.copyOfRange(values, normalizedIndex, normalizedIndex + length);
   return createArray(store, length);
 }
    @Specialization
    public Object getIndex(DynamicObject matchData, int index, NotProvided length) {
      CompilerDirectives.transferToInterpreter();

      final Object[] values = getValues(matchData);
      final int normalizedIndex = ArrayNodes.normalizeIndex(values.length, index);

      if ((normalizedIndex < 0) || (normalizedIndex >= values.length)) {
        return nil();
      } else {
        return values[normalizedIndex];
      }
    }
Beispiel #6
0
  public boolean require(String feature, Node currentNode) throws IOException {
    final RubyConstant dataConstantBefore =
        ModuleOperations.lookupConstant(
            context, LexicalScope.NONE, context.getCoreLibrary().getObjectClass(), "DATA");

    if (feature.startsWith("./")) {
      final String cwd = context.getRuntime().getCurrentDirectory();
      feature = cwd + "/" + feature.substring(2);
    } else if (feature.startsWith("../")) {
      final String cwd = context.getRuntime().getCurrentDirectory();
      feature = cwd.substring(0, cwd.lastIndexOf('/')) + "/" + feature.substring(3);
    }

    try {
      if (isAbsolutePath(feature)) {
        // Try as a full path

        if (requireInPath(null, feature, currentNode)) {
          return true;
        }
      } else {
        // Try each load path in turn

        for (Object pathObject : ArrayNodes.slowToArray(context.getCoreLibrary().getLoadPath())) {
          String loadPath = pathObject.toString();
          if (!isAbsolutePath(loadPath)) {
            loadPath = expandPath(context, loadPath);
          }

          if (requireInPath(loadPath, feature, currentNode)) {
            return true;
          }
        }
      }

      throw new RaiseException(context.getCoreLibrary().loadErrorCannotLoad(feature, currentNode));
    } finally {
      if (dataConstantBefore == null) {
        context.getCoreLibrary().getObjectClass().removeConstant(currentNode, "DATA");
      } else {
        context
            .getCoreLibrary()
            .getObjectClass()
            .setConstant(currentNode, "DATA", dataConstantBefore.getValue());
      }
    }
  }
Beispiel #7
0
  private boolean requireFile(String feature, String path, Node currentNode) throws IOException {
    // We expect '/' in various classpath URLs, so normalize Windows file paths to use '/'
    path = path.replace('\\', '/');
    final RubyBasicObject loadedFeatures = context.getCoreLibrary().getLoadedFeatures();

    if (path.startsWith("uri:classloader:/")) {
      // TODO CS 13-Feb-15 this uri:classloader:/ and core:/ thing is a hack - simplify it

      for (Object loaded : Arrays.asList(ArrayNodes.slowToArray(loadedFeatures))) {
        if (loaded.toString().equals(path)) {
          return true;
        }
      }

      String coreFileName = path.substring("uri:classloader:/".length());

      coreFileName = FileSystems.getDefault().getPath(coreFileName).normalize().toString();

      if (context
              .getRuntime()
              .getLoadService()
              .getClassPathResource(context.getRuntime().getJRubyClassLoader(), coreFileName)
          == null) {
        return false;
      }

      if (SHOW_RESOLUTION) {
        System.err.printf("resolved %s -> %s%n", feature, coreFileName);
      }

      context.getCoreLibrary().loadRubyCore(coreFileName, "uri:classloader:/");
      ArrayNodes.slowPush(
          loadedFeatures,
          StringNodes.createString(context.getCoreLibrary().getStringClass(), path));

      return true;
    } else if (path.startsWith("core:/")) {
      for (Object loaded : Arrays.asList(ArrayNodes.slowToArray(loadedFeatures))) {
        if (loaded.toString().equals(path)) {
          return true;
        }
      }

      final String coreFileName = path.substring("core:/".length());

      if (context
              .getRuntime()
              .getLoadService()
              .getClassPathResource(context.getRuntime().getJRubyClassLoader(), coreFileName)
          == null) {
        return false;
      }

      if (SHOW_RESOLUTION) {
        System.err.printf("resolved %s -> %s%n", feature, coreFileName);
      }

      context.getCoreLibrary().loadRubyCore(coreFileName, "core:/");
      ArrayNodes.slowPush(
          loadedFeatures,
          StringNodes.createString(context.getCoreLibrary().getStringClass(), path));

      return true;
    } else {
      final File file = new File(path);

      assert file.isAbsolute();

      if (!file.isAbsolute() || !file.isFile()) {
        return false;
      }

      final String expandedPath = expandPath(context, path);

      for (Object loaded : Arrays.asList(ArrayNodes.slowToArray(loadedFeatures))) {
        if (loaded.toString().equals(expandedPath)) {
          return true;
        }
      }

      if (SHOW_RESOLUTION) {
        System.err.printf("resolved %s -> %s%n", feature, expandedPath);
      }

      // TODO (nirvdrum 15-Jan-15): If we fail to load, we should remove the path from the loaded
      // features because subsequent requires of the same statement may succeed.
      final RubyBasicObject pathString =
          StringNodes.createString(context.getCoreLibrary().getStringClass(), expandedPath);
      ArrayNodes.slowPush(loadedFeatures, pathString);
      try {
        context.loadFile(path, currentNode);
      } catch (RaiseException e) {
        final ArrayMirror mirror =
            ArrayMirror.reflect((Object[]) ArrayNodes.getStore(loadedFeatures));
        final int length = ArrayNodes.getSize(loadedFeatures);
        for (int i = length - 1; i >= 0; i--) {
          if (mirror.get(i) == pathString) {
            for (int j = length - 1; j > i; j--) {
              mirror.set(i - 1, mirror.get(i));
            }
            ArrayNodes.setSize(loadedFeatures, length - 1);
            break;
          }
        }
        throw e;
      }
    }

    return true;
  }