public CachedSingletonDispatchNode(
      RubyContext context,
      Object cachedName,
      DispatchNode next,
      DynamicObject expectedReceiver,
      DynamicObject expectedClass,
      InternalMethod method,
      DispatchAction dispatchAction) {
    super(context, cachedName, next, dispatchAction);

    this.expectedReceiver = expectedReceiver;
    this.unmodifiedAssumption = Layouts.MODULE.getFields(expectedClass).getUnmodifiedAssumption();
    this.next = next;
    this.method = method;
    this.callNode = Truffle.getRuntime().createDirectCallNode(method.getCallTarget());
    applySplittingInliningStrategy(callNode, method);
  }
  @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[] {}));
  }