private IRubyObject uclassUnmarshall() throws IOException { RubySymbol className = (RubySymbol) unmarshalObject(false); RubyClass type = (RubyClass) runtime.getClassFromPath(className.asJavaString()); // singleton, raise error if (type.isSingleton()) throw runtime.newTypeError("singleton can't be loaded"); // All "C" marshalled objects descend from core classes, which are all at least RubyObject RubyObject result = (RubyObject) unmarshalObject(); // if result is a module or type doesn't extend result's class... if (result.getMetaClass() == runtime.getModule() || !type.isKindOfModule(result.getMetaClass())) { // if allocators do not match, error // Note: MRI is a bit different here, and tests TYPE(type.allocate()) != TYPE(result) if (type.getAllocator() != result.getMetaClass().getRealClass().getAllocator()) { throw runtime.newArgumentError("dump format error (user class)"); } } result.setMetaClass(type); return result; }
private IRubyObject defaultObjectUnmarshal() throws IOException { RubySymbol className = (RubySymbol) unmarshalObject(false); RubyClass type = null; try { type = getClassFromPath(runtime, className.toString()); } catch (RaiseException e) { if (runtime.getModule("NameError").isInstance(e.getException())) { throw runtime.newArgumentError("undefined class/module " + className.asJavaString()); } throw e; } assert type != null : "type shouldn't be null."; IRubyObject result = (IRubyObject) type.unmarshal(this); return result; }
private IRubyObject unmarshalObjectDirectly(int type, MarshalState state, boolean callProc) throws IOException { IRubyObject rubyObj = null; switch (type) { case 'I': MarshalState childState = new MarshalState(true); rubyObj = unmarshalObject(childState); if (childState.isIvarWaiting()) { defaultVariablesUnmarshal(rubyObj); } return rubyObj; case '0': rubyObj = runtime.getNil(); break; case 'T': rubyObj = runtime.getTrue(); break; case 'F': rubyObj = runtime.getFalse(); break; case '"': rubyObj = RubyString.unmarshalFrom(this); break; case 'i': rubyObj = RubyFixnum.unmarshalFrom(this); break; case 'f': rubyObj = RubyFloat.unmarshalFrom(this); break; case '/': rubyObj = RubyRegexp.unmarshalFrom(this); break; case ':': rubyObj = RubySymbol.unmarshalFrom(this); break; case '[': rubyObj = RubyArray.unmarshalFrom(this); break; case '{': rubyObj = RubyHash.unmarshalFrom(this, false); break; case '}': // "hashdef" object, a hash with a default rubyObj = RubyHash.unmarshalFrom(this, true); break; case 'c': rubyObj = RubyClass.unmarshalFrom(this); break; case 'm': rubyObj = RubyModule.unmarshalFrom(this); break; case 'e': RubySymbol moduleName = (RubySymbol) unmarshalObject(); RubyModule tp = null; try { tp = runtime.getClassFromPath(moduleName.asJavaString()); } catch (RaiseException e) { if (runtime.getModule("NameError").isInstance(e.getException())) { throw runtime.newArgumentError("undefined class/module " + moduleName.asJavaString()); } throw e; } rubyObj = unmarshalObject(); tp.extend_object(rubyObj); tp.callMethod(runtime.getCurrentContext(), "extended", rubyObj); break; case 'l': rubyObj = RubyBignum.unmarshalFrom(this); break; case 'S': rubyObj = RubyStruct.unmarshalFrom(this); break; case 'o': rubyObj = defaultObjectUnmarshal(); break; case 'u': rubyObj = userUnmarshal(state); break; case 'U': rubyObj = userNewUnmarshal(); break; case 'C': rubyObj = uclassUnmarshall(); break; default: throw getRuntime().newArgumentError("dump format error(" + (char) type + ")"); } if (callProc) { return doCallProcForObj(rubyObj); } return rubyObj; }