Alright, I know I'm not *supposed* to send in patch's for the runtime, but
this is a bug in the Silverlight build. Classes implemented in Ruby cannot
be created using RubyUtils.CreateObject, as I mentioned in my previous
email. As a result, Marshal.load will fail when trying to deserialize
classes implemented in Ruby, because the _underlyingSystemType will
be RubyObject, which implements ISerializable. In the debugger, if I force
the aforementioned CreateObject method to call the
CreateObject(RubyClass/*!*/ theClass) overload, it works just fine.
We probably need to change this:
if (typeof(ISerializable).IsAssignableFrom(baseType)) {
to this:
if (typeof(ISerializable).IsAssignableFrom(baseType) && !(baseType is
RubyObject)) {
Should I make this change to my fork? Or would one of you core dev's make
the appropriate change for us (Tomas :p)?
P.S.
Would there be any interest in being able to mspec the Silverlight build? I
would bet that would make catching these little bugs much easier. I could
throw something together if it would help - something like a command line
app called slmspec.
Thanks,
-Charles
On Sun, Jul 25, 2010 at 4:25 AM, Charles Strahan <
[email protected]> wrote:
> I've run into a problem when using Marshal.load in Silverlight - the
> following exception is thrown:
>
> NotSupportedException: Class IronRuby.Builtins.RubyObject does not have a
> valid deserializing constructor
>
>
> I tracked the code down to RubyUtils.CreateObject(RubyClass/*!*/ theclass,
> IEnumerable<KeyValuePair<string, object>>/*!*/ attributes). I see that
> CreateObject will always throw in Silverlight when the type is assignable
> from ISerializable:
>
> //------------------------------
> public static object/*!*/ CreateObject(RubyClass/*!*/ theclass,
> IEnumerable<KeyValuePair<string, object>>/*!*/ attributes) {
> Assert.NotNull(theclass, attributes);
>
> Type baseType = theclass.GetUnderlyingSystemType();
> object obj;
> if (typeof(ISerializable).IsAssignableFrom(baseType)) {
> #if !SILVERLIGHT // serialization
> BindingFlags bindingFlags = BindingFlags.NonPublic |
> BindingFlags.Public | BindingFlags.Instance;
> ConstructorInfo ci = baseType.GetConstructor(bindingFlags,
> null, _serializableTypeSignature, null);
> if (ci == null) {
> #endif
> string message = String.Format("Class {0} does not have a
> valid deserializing constructor", baseType.FullName);
> throw new NotSupportedException(message);
> #if !SILVERLIGHT // serialization
> }
> SerializationInfo info = new SerializationInfo(baseType,
> new FormatterConverter());
> info.AddValue(SerializationInfoClassKey, theclass);
> foreach (var pair in attributes) {
> info.AddValue(pair.Key, pair.Value);
> }
> obj = ci.Invoke(new object[2] { info, new
> StreamingContext(StreamingContextStates.Other, theclass) });
> #endif
> } else {
> obj = CreateObject(theclass);
> foreach (var pair in attributes) {
> theclass.Context.SetInstanceVariable(obj, pair.Key,
> pair.Value);
> }
> }
> return obj;
> }
> //------------------------------
>
>
> Is this a bug, perhaps? I'd love to step through the code and find for
> myself, but I can't seem to build IronRuby using the Silverlight3 and
> Silverlight4 build configurations (I get a ton of errors - any help getting
> it to build would rock!).
>
> -Charles
>
_______________________________________________
Ironruby-core mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core