break;
case YARVInstructions.SETINSTANCEVARIABLE:
self.getInstanceVariables().fastSetInstanceVariable(bytecodes[ip].s_op0, pop());
break;
case YARVInstructions.GETCLASSVARIABLE: {
RubyModule rubyClass = context.getRubyClass();
String name = bytecodes[ip].s_op0;
if (rubyClass == null) {
push(self.getMetaClass().fastGetClassVar(name));
} else if (!rubyClass.isSingleton()) {
push(rubyClass.fastGetClassVar(name));
} else {
RubyModule module = (RubyModule)(((MetaClass)rubyClass).getAttached());
if (module != null) {
push(module.fastGetClassVar(name));
} else {
push(runtime.getNil());
}
}
break;
}
case YARVInstructions.SETCLASSVARIABLE: {
RubyModule rubyClass = context.getCurrentScope().getStaticScope().getModule();
if (rubyClass == null) {
rubyClass = self.getMetaClass();
} else if (rubyClass.isSingleton()) {
rubyClass = (RubyModule)(((MetaClass)rubyClass).getAttached());
}
rubyClass.fastSetClassVar(bytecodes[ip].s_op0, pop());
break;
}
case YARVInstructions.GETCONSTANT:
push(context.getConstant(bytecodes[ip].s_op0));
break;
case YARVInstructions.SETCONSTANT:
context.setConstantInCurrent(bytecodes[ip].s_op0, pop());
runtime.incGlobalState();
break;
case YARVInstructions.PUTNIL:
push(context.getRuntime().getNil());
break;
case YARVInstructions.PUTSELF:
push(self);
break;
case YARVInstructions.PUTOBJECT:
//System.out.println("PUTOBJECT: " + bytecodes[ip].o_op0);
push(bytecodes[ip].o_op0);
break;
case YARVInstructions.PUTSTRING:
push(context.getRuntime().newString(bytecodes[ip].s_op0));
break;
case YARVInstructions.CONCATSTRINGS: {
StringBuilder concatter = new StringBuilder();
for (int i = 0; i < bytecodes[ip].l_op0; i++) {
concatter.append(pop().toString());
}
push(runtime.newString(concatter.toString()));
break;
}
case YARVInstructions.TOSTRING:
IRubyObject top = peek();
if (!(top instanceof RubyString)) {
set(top.callMethod(context, "to_s"));
}
break;
case YARVInstructions.NEWARRAY:
push(runtime.newArrayNoCopy(popArray(new IRubyObject[(int) bytecodes[ip].l_op0])));
break;
case YARVInstructions.DUPARRAY:
push(bytecodes[ip].o_op0.dup());
break;
case YARVInstructions.NEWHASH:
int hsize = (int)bytecodes[ip].l_op0;
RubyHash h = RubyHash.newHash(runtime);
IRubyObject v,k;
for(int i = hsize; i>0; i -= 2) {
v = pop();
k = pop();
h.op_aset(context, k, v);
}
push(h);
break;
case YARVInstructions.PUTNOT:
push(peek().isTrue() ? runtime.getFalse() : runtime.getTrue());
break;
case YARVInstructions.POP:
pop();
break;
case YARVInstructions.DUP:
push(peek());
break;
case YARVInstructions.DUPN:
dupn((int) bytecodes[ip].l_op0);
break;
case YARVInstructions.SWAP:
swap();
break;
case YARVInstructions.TOPN:
topn((int) bytecodes[ip].l_op0);
break;
case YARVInstructions.SETN:
setn((int) bytecodes[ip].l_op0, peek());
break;
case YARVInstructions.EMPTSTACK:
stackTop = stackStart;
break;
case YARVInstructions.DEFINEMETHOD:
RubyModule containingClass = context.getRubyClass();
if (containingClass == null) {
throw runtime.newTypeError("No class to add method.");
}
String mname = bytecodes[ip].iseq_op.name;
if (containingClass == runtime.getObject() && mname == "initialize") {
runtime.getWarnings().warn(ID.REDEFINING_DANGEROUS, "redefining Object#initialize may cause infinite loop", "Object#initialize");
}
Visibility visibility = context.getCurrentVisibility();
if (mname == "initialize" || visibility == Visibility.MODULE_FUNCTION) {
visibility = Visibility.PRIVATE;
}
if (containingClass.isSingleton()) {
IRubyObject attachedObject = ((MetaClass) containingClass).getAttached();
if (attachedObject instanceof RubyFixnum || attachedObject instanceof RubySymbol) {
throw runtime.newTypeError("can't define singleton method \"" +
mname + "\" for " + attachedObject.getType());
}
}
StaticScope sco = new LocalStaticScope(null);
sco.setVariables(bytecodes[ip].iseq_op.locals);
YARVMethod newMethod = new YARVMethod(containingClass, bytecodes[ip].iseq_op, sco, visibility);
containingClass.addMethod(mname, newMethod);
if (context.getCurrentVisibility() == Visibility.MODULE_FUNCTION) {
RubyModule singleton = containingClass.getSingletonClass();
singleton.addMethod(mname, new WrapperMethod(singleton, newMethod, Visibility.PUBLIC));
containingClass.callMethod(context, "singleton_method_added", runtime.fastNewSymbol(mname));
}
// 'class << state.self' and 'class << obj' uses defn as opposed to defs
if (containingClass.isSingleton()) {