@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; }
@Override public Object retrieve(InterpreterContext interp) { RubyRegexp reg = RubyRegexp.newRegexp( interp.getRuntime(), ((RubyString) regexp.retrieve(interp)).getByteList(), options); reg.setLiteral(); return reg; }
@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; }