@Override
  public Object executeDispatch(
      VirtualFrame frame,
      Object receiverObject,
      Object methodName,
      Object blockObject,
      Object argumentsObjects) {
    if (!guardName(methodName) || !(receiverObject instanceof RubySymbol)) {
      return next.executeDispatch(frame, receiverObject, methodName, blockObject, argumentsObjects);
    }

    // Check the class has not been modified

    try {
      unmodifiedAssumption.check();
    } catch (InvalidAssumptionException e) {
      return resetAndDispatch(
          frame,
          receiverObject,
          methodName,
          (RubyProc) blockObject,
          argumentsObjects,
          "class modified");
    }

    switch (getDispatchAction()) {
      case CALL_METHOD:
        {
          if (isIndirect()) {
            return indirectCallNode.call(
                frame,
                method.getCallTarget(),
                RubyArguments.pack(
                    method,
                    method.getDeclarationFrame(),
                    receiverObject,
                    (RubyProc) blockObject,
                    (Object[]) argumentsObjects));
          } else {
            return callNode.call(
                frame,
                RubyArguments.pack(
                    method,
                    method.getDeclarationFrame(),
                    receiverObject,
                    (RubyProc) blockObject,
                    (Object[]) argumentsObjects));
          }
        }

      case RESPOND_TO_METHOD:
        return true;

      case READ_CONSTANT:
        return value;

      default:
        throw new UnsupportedOperationException();
    }
  }
 @Override
 protected Object executeDispatch(VirtualFrame frame, LlvmFunction function, Object[] arguments) {
   /*
    * Llvm has a quite simple call lookup: just ask the function for the current call target,
    * and call it.
    */
   return callNode.call(frame, function.getCallTarget(), arguments);
 }
Esempio n. 3
0
 @Specialization(contains = "doDirect")
 protected Object doIndirect(
     VirtualFrame frame,
     LLVMFunction function,
     Object[] arguments, //
     @Cached("create()") IndirectCallNode callNode) {
   return callNode.call(frame, context.getFunction(function), arguments);
 }
 @Override
 public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects) {
   final RubyMethod method = block.getMethod();
   return callNode.call(
       frame,
       method.getCallTarget(),
       RubyArguments.pack(
           method.getDeclarationFrame(),
           block.getSelfCapturedInScope(),
           block.getBlockCapturedInScope(),
           argumentsObjects));
 }
Esempio n. 5
0
  @Override
  public Object execute(VirtualFrame frame) {
    CompilerDirectives.transferToInterpreter();

    // TODO(CS): cast
    final DynamicObject module = (DynamicObject) definingModule.execute(frame);

    lexicalScope.setLiveModule(module);
    Layouts.MODULE.getFields(lexicalScope.getParent().getLiveModule()).addLexicalDependent(module);

    final InternalMethod definition =
        definitionMethod.executeMethod(frame).withDeclaringModule(module);
    return callModuleDefinitionNode.call(
        frame,
        definition.getCallTarget(),
        RubyArguments.pack(
            definition, null, null, module, null, DeclarationContext.MODULE, new Object[] {}));
  }
Esempio n. 6
0
  @Override
  public Object execute(VirtualFrame frame) {
    final DynamicObject module = (DynamicObject) definingModule.execute(frame);
    final InternalMethod definition =
        prepareLexicalScope(module, definitionMethod.executeMethod(frame));

    return callModuleDefinitionNode.call(
        frame,
        definition.getCallTarget(),
        RubyArguments.pack(
            null,
            null,
            definition,
            DeclarationContext.MODULE,
            null,
            module,
            null,
            new Object[] {}));
  }
Esempio n. 7
0
  @Override
  public Object dispatch(
      VirtualFrame frame,
      RubyBasicObject receiverObject,
      RubyProc blockObject,
      Object[] argumentsObjects) {
    MethodCacheEntry entry = lookupInCache(receiverObject.getLookupNode());

    if (entry == null) {
      CompilerDirectives.transferToInterpreterAndInvalidate();

      final RubyBasicObject boxedCallingSelf =
          getContext().getCoreLibrary().box(RubyArguments.getSelf(frame.getArguments()));

      try {
        entry = new MethodCacheEntry(lookup(boxedCallingSelf, receiverObject, name), false);
      } catch (UseMethodMissingException e) {
        try {
          entry =
              new MethodCacheEntry(
                  lookup(boxedCallingSelf, receiverObject, "method_missing"), true);
        } catch (UseMethodMissingException e2) {
          throw new RaiseException(
              getContext()
                  .getCoreLibrary()
                  .runtimeError(receiverObject.toString() + " didn't have a #method_missing"));
        }
      }

      if (entry.isMethodMissing()) {
        hasAnyMethodsMissing = true;
      }

      cache.put(receiverObject.getLookupNode(), entry);

      if (cache.size() > RubyContext.GENERAL_DISPATCH_SIZE_WARNING_THRESHOLD) {
        getContext()
            .getRuntime()
            .getWarnings()
            .warn(
                IRubyWarnings.ID.TRUFFLE,
                getEncapsulatingSourceSection().getSource().getName(),
                getEncapsulatingSourceSection().getStartLine(),
                "general call node cache has " + cache.size() + " entries");
      }
    }

    final Object[] argumentsToUse;

    if (hasAnyMethodsMissing && entry.isMethodMissing()) {
      final Object[] modifiedArgumentsObjects = new Object[1 + argumentsObjects.length];
      modifiedArgumentsObjects[0] = getContext().newSymbol(name);
      System.arraycopy(argumentsObjects, 0, modifiedArgumentsObjects, 1, argumentsObjects.length);
      argumentsToUse = modifiedArgumentsObjects;
    } else {
      argumentsToUse = argumentsObjects;
    }

    return callNode.call(
        frame,
        entry.getMethod().getCallTarget(),
        RubyArguments.pack(
            entry.getMethod().getDeclarationFrame(), receiverObject, blockObject, argumentsToUse));
  }
 @Override
 public Object executeWith(VirtualFrame frame, TruffleObject truffleObject, Object[] arguments) {
   final CallTarget ct = findCallTarget(truffleObject);
   return indirectCallNode.call(
       frame, ct, accessArguments.executeCreate(truffleObject, arguments));
 }