예제 #1
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]));
 }
예제 #2
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());
      }
    }
  }
예제 #3
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;
  }