@Override
  public Label interpret(InterpreterContext interp) {
    RubyModule clazz = (RubyModule) getArg().retrieve(interp);
    String name = method.getName();
    ThreadContext context = interp.getContext();

    Visibility visibility = context.getCurrentVisibility();
    if (name == "initialize"
        || name == "initialize_copy"
        || visibility == Visibility.MODULE_FUNCTION) {
      visibility = Visibility.PRIVATE;
    }

    DynamicMethod newMethod = new InterpretedIRMethod(method, visibility, clazz);
    clazz.addMethod(name, newMethod);

    if (visibility == Visibility.MODULE_FUNCTION) {
      clazz
          .getSingletonClass()
          .addMethod(
              name, new WrapperMethod(clazz.getSingletonClass(), newMethod, Visibility.PUBLIC));
      clazz.callMethod(context, "singleton_method_added", interp.getRuntime().fastNewSymbol(name));
    }

    // 'class << state.self' and 'class << obj' uses defn as opposed to defs
    if (clazz.isSingleton()) {
      ((MetaClass) clazz)
          .getAttached()
          .callMethod(context, "singleton_method_added", interp.getRuntime().fastNewSymbol(name));
    } else {
      clazz.callMethod(context, "method_added", interp.getRuntime().fastNewSymbol(name));
    }
    return null;
  }
Пример #2
0
  @Override
  public Object retrieve(InterpreterContext interp) {
    RubyRegexp reg =
        RubyRegexp.newRegexp(
            interp.getRuntime(), ((RubyString) regexp.retrieve(interp)).getByteList(), options);

    reg.setLiteral();

    return reg;
  }
Пример #3
0
  public IRubyObject commonCallPath(
      ThreadContext context,
      IRubyObject[] args,
      IRubyObject self,
      RubyModule klass,
      boolean isArray,
      Binding binding,
      Type type,
      Block block) {
    // SSS FIXME: Is this correct?
    // isArray is not used??
    if (klass == null) {
      self = prepareSelf(binding);
    }

    // SSS FIXME: Can it happen that (type != block.type)?
    // if (type != block.type) System.out.println("incoming block type is different from
    // block.type");

    RubyModule currentModule = closure.getStaticScope().getModule();
    context.getCurrentScope().getStaticScope().setModule(currentModule);

    InterpreterContext interp =
        new NaiveInterpreterContext(
            context,
            currentModule,
            self,
            null,
            closure.getLocalVariablesCount(),
            closure.getTemporaryVariableSize(),
            args,
            block,
            type);
    interp.setDynamicScope(binding.getDynamicScope());

    return Interpreter.interpret(context, self, closure.getCFG(), interp);
  }
Пример #4
0
  @Override
  public Label interpret(InterpreterContext interp) {
    String name;
    Object receiver;
    Ruby rt = interp.getRuntime();
    Object rVal = null;

    switch (this.implMethod) {
        // SSS FIXME: Note that compiler/impl/BaseBodyCompiler is using op_match2 for match() and
        // and op_match for match2,
        // and we are replicating it here ... Is this a bug there?
      case MATCH:
        receiver = getReceiver().retrieve(interp);
        rVal = ((RubyRegexp) receiver).op_match2(interp.getContext());
        break;
      case MATCH2:
        receiver = getReceiver().retrieve(interp);
        rVal =
            ((RubyRegexp) receiver)
                .op_match(interp.getContext(), (IRubyObject) getCallArgs()[0].retrieve(interp));
        break;
      case MATCH3:
        { // ENEBO: Only for rubystring?
          receiver = getReceiver().retrieve(interp);
          IRubyObject value = (IRubyObject) getCallArgs()[0].retrieve(interp);

          if (value instanceof RubyString) {
            rVal = ((RubyRegexp) receiver).op_match(interp.getContext(), value);
          } else {
            rVal = value.callMethod(interp.getContext(), "=~", (IRubyObject) receiver);
          }
          break;
        }
      case SET_WITHIN_DEFINED:
        interp.getContext().setWithinDefined(((BooleanLiteral) getCallArgs()[0]).isTrue());
        break;
      case RTH_GET_DEFINED_CONSTANT_OR_BOUND_METHOD:
        {
          IRubyObject v = (IRubyObject) getCallArgs()[0].retrieve(interp);
          name = ((StringLiteral) getCallArgs()[1])._str_value;
          ByteList definedType = RuntimeHelpers.getDefinedConstantOrBoundMethod(v, name);
          rVal =
              (definedType == null ? Nil.NIL : (new StringLiteral(definedType))).retrieve(interp);
          break;
        }
      case BLOCK_GIVEN:
        rVal = rt.newBoolean(interp.getBlock().isGiven());
        break;
      case RT_IS_GLOBAL_DEFINED:
        // name = getCallArgs()[0].retrieve(interp).toString();
        name = ((StringLiteral) getCallArgs()[0])._str_value;
        rVal = rt.newBoolean(rt.getGlobalVariables().isDefined(name));
        break;
      case RT_GET_OBJECT:
        rVal = rt.getObject();
        break;
      case RT_GET_BACKREF:
        // SSS: FIXME: Or use this directly? "context.getCurrentScope().getBackRef(rt)" What is the
        // diff??
        rVal = RuntimeHelpers.getBackref(rt, interp.getContext());
        break;
      case SELF_METACLASS:
        rVal = ((IRubyObject) getReceiver().retrieve(interp)).getMetaClass();
        break;
      case CHECK_ARITY:
        {
          Operand[] args = getCallArgs();
          int required = ((Fixnum) args[0]).value.intValue();
          int opt = ((Fixnum) args[1]).value.intValue();
          int rest = ((Fixnum) args[2]).value.intValue();
          int numArgs = interp.getParameterCount();
          if ((numArgs < required) || ((rest == -1) && (numArgs > (required + opt)))) {
            Arity.raiseArgumentError(interp.getRuntime(), numArgs, required, required + opt);
          }
          break;
        }
      case RAISE_ARGUMENT_ERROR:
        {
          Operand[] args = getCallArgs();
          int required = ((Fixnum) args[0]).value.intValue();
          int opt = ((Fixnum) args[1]).value.intValue();
          int rest = ((Fixnum) args[2]).value.intValue();
          int numArgs = ((Fixnum) args[3]).value.intValue();
          Arity.raiseArgumentError(interp.getRuntime(), numArgs, required, required + opt);
          break;
        }
      case SELF_HAS_INSTANCE_VARIABLE:
        {
          receiver = getReceiver().retrieve(interp);
          // name = getCallArgs()[0].retrieve(interp).toString();
          name = ((StringLiteral) getCallArgs()[0])._str_value;
          rVal =
              rt.newBoolean(
                  ((IRubyObject) receiver).getInstanceVariables().hasInstanceVariable(name));
          break;
        }
      case SELF_IS_METHOD_BOUND:
        {
          receiver = getReceiver().retrieve(interp);
          boolean bound =
              ((IRubyObject) receiver)
                  .getMetaClass()
                  .isMethodBound(((StringLiteral) getCallArgs()[0])._str_value, false);
          rVal = rt.newBoolean(bound);
          break;
        }
      case TC_SAVE_ERR_INFO:
        rVal = interp.getContext().getErrorInfo();
        break;
      case TC_RESTORE_ERR_INFO:
        interp.getContext().setErrorInfo((IRubyObject) getCallArgs()[0].retrieve(interp));
        break;
      case TC_GET_CONSTANT_DEFINED:
        // name = getCallArgs()[0].retrieve(interp).toString();
        name = ((StringLiteral) getCallArgs()[0])._str_value;
        rVal = rt.newBoolean(interp.getContext().getConstantDefined(name));
        break;
      case TC_GET_CURRENT_MODULE:
        rVal = interp.getContext().getCurrentScope().getStaticScope().getModule();
        break;
      case BACKREF_IS_RUBY_MATCH_DATA:
        // bRef = getBackref()
        // flag = bRef instanceof RubyMatchData
        try {
          // SSS: FIXME: Or use this directly? "context.getCurrentScope().getBackRef(rt)" What is
          // the diff??
          IRubyObject bRef = RuntimeHelpers.getBackref(rt, interp.getContext());
          rVal =
              rt.newBoolean(
                  Class.forName("RubyMatchData").isInstance(bRef)); // SSS FIXME: Is this correct?
        } catch (ClassNotFoundException e) {
          // Should never get here!
          throw new RuntimeException(e);
        }
        break;
      case METHOD_PUBLIC_ACCESSIBLE:
        {
          /* ------------------------------------------------------------
           * mc = r.metaClass
           * v  = mc.getVisibility(methodName)
           * v.isPrivate? || (v.isProtected? && receiver/self? instanceof mc.getRealClass)
           * ------------------------------------------------------------ */
          IRubyObject r = (IRubyObject) getReceiver().retrieve(interp);
          RubyClass mc = r.getMetaClass();
          String arg = ((StringLiteral) getCallArgs()[0])._str_value;
          Visibility v = mc.searchMethod(arg).getVisibility();
          rVal =
              rt.newBoolean(
                  (v != null)
                      && !v.isPrivate()
                      && !(v.isProtected() && mc.getRealClass().isInstance(r)));
          break;
        }
      case CLASS_VAR_DEFINED:
        {
          // cm.classVarDefined(name) || (cm.isSingleton && !(cm.attached instanceof RubyModule) &&
          // cm.attached.classVarDefined(name))
          boolean flag;
          RubyModule cm = (RubyModule) getReceiver().retrieve(interp);
          name = ((StringLiteral) getCallArgs()[0])._str_value;
          flag = cm.isClassVarDefined(name);
          if (!flag) {
            if (cm.isSingleton()) {
              IRubyObject ao = ((MetaClass) cm).getAttached();
              if (ao instanceof RubyModule) flag = ((RubyModule) ao).isClassVarDefined(name);
            }
          }
          rVal = rt.newBoolean(flag);
          break;
        }
      case FRAME_SUPER_METHOD_BOUND:
        {
          receiver = getReceiver().retrieve(interp);
          boolean flag = false;
          ThreadContext tc = interp.getContext();
          String fn = tc.getFrameName();
          if (fn != null) {
            RubyModule fc = tc.getFrameKlazz();
            if (fc != null) {
              flag =
                  RuntimeHelpers.findImplementerIfNecessary(
                          ((IRubyObject) receiver).getMetaClass(), fc)
                      .getSuperClass()
                      .isMethodBound(fn, false);
            }
          }
          rVal = rt.newBoolean(flag);
          break;
        }
    }

    // Store the result
    if (rVal != null) getResult().store(interp, rVal);

    return null;
  }
Пример #5
0
 @Override
 public Label interpret(InterpreterContext interp) {
   interp.getContext().setLine(lineNumber);
   return null;
 }