From 79298efe4e30261ff76b3f989fc2d0002a47c9d6 Mon Sep 17 00:00:00 2001 From: Shri Borde Date: Mon, 23 Mar 2009 22:40:07 -0700 Subject: [PATCH] Marshal.WriteObject was writing serialization data which includes instance variables, but the end of MarshalWriter.WriteAnObject was writing instance data as well. Removed writing of serialization data TimeOps.load had a bug causing local time to be loaded as utc time. Added building of IronPython to irtests.bat since it is needed for the language interop tests --- .../ironruby-tags/core/marshal/dump_tags.txt | 1 - .../mspec/rubyspec/core/marshal/dump_spec.rb | 8 +-- .../core/marshal/fixtures/marshal_data.rb | 59 +++++++++++++------ .../mspec/rubyspec/core/marshal/load_spec.rb | 19 ++++-- .../mspec/rubyspec/core/time/_load_spec.rb | 11 +++- .../Builtins/Marshal.cs | 40 +++++-------- .../Builtins/TimeOps.cs | 2 +- .../Main/Languages/Ruby/Scripts/irtests.bat | 7 +++ 8 files changed, 86 insertions(+), 61 deletions(-) delete mode 100644 Merlin/External/Languages/IronRuby/mspec/ironruby-tags/core/marshal/dump_tags.txt diff --git a/Merlin/External/Languages/IronRuby/mspec/ironruby-tags/core/marshal/dump_tags.txt b/Merlin/External/Languages/IronRuby/mspec/ironruby-tags/core/marshal/dump_tags.txt deleted file mode 100644 index 6935b2be11..0000000000 --- a/Merlin/External/Languages/IronRuby/mspec/ironruby-tags/core/marshal/dump_tags.txt +++ /dev/null @@ -1 +0,0 @@ -fails:Marshal.dump dumps a Module nested diff --git a/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/dump_spec.rb b/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/dump_spec.rb index 03821bf46a..3d1e1348d0 100644 --- a/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/dump_spec.rb +++ b/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/dump_spec.rb @@ -77,12 +77,6 @@ def _dump(depth); 10; end Marshal.dump(obj).should == "#{mv+nv}o:\x0BObject\x06:\x09@str[\x09:\x07so;\x07\"\x07hi@\x07" end - it "dumps an extended_user_regexp having ivar" do - r = UserRegexp.new('').extend(Meths) - r.instance_variable_set(:@noise, 'much') - Marshal.dump(r).should == "#{mv+nv}Ie:\x0AMethsC:\x0FUserRegexp/\x00\x00\x06:\x0B@noise\"\x09much" - end - it "raises a TypeError with hash having default proc" do lambda { Marshal.dump(Hash.new {}) }.should raise_error(TypeError) end @@ -90,7 +84,7 @@ def _dump(depth); 10; end it "dumps an extended_user_hash_default" do h = UserHash.new(:Meths).extend(Meths) h['three'] = 3 - Marshal.dump(h).should == "#{mv+nv}e:\x0AMethsC:\x0DUserHash}\x06\"\x0Athreei\x08;\x00" + Marshal.dump(h).should == "#{mv+nv}Ie:\x0AMethsC:\x0DUserHash}\x06\"\x0Athreei\x08;\x00\006:\a@ai\006" end it "dumps an extended_user_hash with a parameter to initialize" do diff --git a/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/fixtures/marshal_data.rb b/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/fixtures/marshal_data.rb index d0a9e0b981..473f1fa4a0 100644 --- a/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/fixtures/marshal_data.rb +++ b/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/fixtures/marshal_data.rb @@ -1,11 +1,12 @@ -class UserDefined - +class UserOuter class Nested def ==(other) other.kind_of? self.class end end +end +class UserSimple attr_reader :a, :b def initialize @@ -13,6 +14,15 @@ def initialize @b = @a end + def ==(other) + self.class === other and + @a == other.a and + @b == other.b + end + +end + +class UserDefined < UserSimple def _dump(depth) Marshal.dump [@a, @b] end @@ -26,13 +36,6 @@ def self._load(data) obj end - - def ==(other) - self.class === other and - @a == other.a and - @b == other.b - end - end class UserDefinedWithIvar @@ -101,10 +104,21 @@ def ==(other) end end +module AnAttribute + attr :a + + def initialize(*args) + @a = 1 + super + end +end + class UserArray < Array + include AnAttribute end class UserHash < Hash + include AnAttribute end class UserHashInitParams < Hash @@ -117,9 +131,11 @@ class UserObject end class UserRegexp < Regexp + include AnAttribute end class UserString < String + include AnAttribute end module Meths @@ -161,10 +177,10 @@ module MarshalSpec "\004\b\"\002,\001#{'big' * 100}"], "String extended" => [''.extend(Meths), # TODO: check for module on load "\004\be:\nMeths\"\000"], - "String subclass" => [UserString.new, - "\004\bC:\017UserString\"\000"], + "String subclass" => [UserString.new("hello"), + "\004\bIC:\017UserString\"\nhello\006:\a@ai\006"], "String subclass extended" => [UserString.new.extend(Meths), - "\004\be:\nMethsC:\017UserString\"\000"], + "\004\bIe:\nMethsC:\017UserString\"\000\006:\a@ai\006"], "Symbol small" => [:big, "\004\b:\010big"], "Symbol big" => [('big' * 100).to_sym, @@ -199,8 +215,11 @@ module MarshalSpec "\004\bc\vString"], "Module Marshal" => [Marshal, "\004\bm\fMarshal"], - "Module nested" => [UserDefined::Nested.new, - "\004\bo:\030UserDefined::Nested\000"], + "User type" => [UserSimple.new, + "\004\bo:\017UserSimple\a:\a@b\"\nstuff:\a@a@\006", + { :a => "stuff", :b => "stuff" }], + "Module nested" => [UserOuter::Nested.new, + "\004\bo:\026UserOuter::Nested\000"], "_dump object" => [UserDefinedWithIvar.new, "\004\bu:\030UserDefinedWithIvar5\004\b[\bI\"\nstuff\006:\t@foo:\030UserDefinedWithIvar\"\tmore@\a"], "_dump object extended" => [UserDefined.new.extend(Meths), @@ -210,7 +229,9 @@ module MarshalSpec "Regexp" => [/\A.\Z/, "\004\b/\n\\A.\\Z\000"], "Regexp subclass /i" => [UserRegexp.new('', Regexp::IGNORECASE), - "\004\bC:\017UserRegexp/\000\001"], + "\004\bIC:\017UserRegexp/\000\001\006:\a@ai\006"], + "Regexp subclass extended" => [UserRegexp.new('').extend(Meths), + "\004\bIe:\nMethsC:\017UserRegexp/\000\000\006:\a@ai\006"], "Float 0.0" => [0.0, "\004\bf\0060"], "Float -0.0" => [-0.0, @@ -223,12 +244,12 @@ module MarshalSpec "\004\bf\0061"], "Hash" => [Hash.new, "\004\b{\000"], - "Hash subclass" => [UserHash.new, - "\004\bC:\rUserHash{\000"], + "Hash subclass" => [UserHash.new.merge({:hi => "hi"}), + "\004\bIC:\rUserHash{\006:\ahi\"\ahi\006:\a@ai\006"], "Array" => [Array.new, "\004\b[\000"], - "Array subclass" => [UserArray.new, - "\004\bC:\016UserArray[\000"], + "Array subclass" => [UserArray.new([100, 200]), + "\004\bIC:\016UserArray[\aiii\001\310\006:\a@ai\006"], "Struct" => [Struct::Pyramid.new, "\004\bS:\024Struct::Pyramid\000"], } diff --git a/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/load_spec.rb b/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/load_spec.rb index 1c227684ca..2b1495f8c8 100644 --- a/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/load_spec.rb +++ b/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/marshal/load_spec.rb @@ -89,7 +89,7 @@ new_obj.instance_variable_get(:@noise).should == 'much' new_obj_metaclass_ancestors = class << new_obj; ancestors; end new_obj_metaclass_ancestors.first(3).should == - [Meths, UserRegexp, Regexp] + [Meths, UserRegexp, AnAttribute] end it "loads a Float NaN" do @@ -206,17 +206,26 @@ lambda { Marshal.load marshal_data }.should raise_error(TypeError) end + it "raises ArgumentError on loading from an empty string" do + lambda { Marshal.load("") }.should raise_error(ArgumentError) + end + it "raises EOFError on loading an empty file" do temp_file = tmp("marshal.rubinius.tmp.#{Process.pid}") file = File.new(temp_file, "w+") begin - # TODO: This should be in an ensure block, but because of a bug in - # Rubinius that can't be done yet. - File.unlink(temp_file) - lambda { Marshal.load(file) }.should raise_error(EOFError) + + compliant_on :rubinius do + # TODO: This should be in an ensure block, but because of a bug in + # Rubinius that can't be done yet. + File.unlink(temp_file) + end ensure file.close + not_compliant_on :rubinius do + File.unlink(temp_file) + end end end diff --git a/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/time/_load_spec.rb b/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/time/_load_spec.rb index 8ac43de6f6..4e86b9e0b3 100644 --- a/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/time/_load_spec.rb +++ b/Merlin/External/Languages/IronRuby/mspec/rubyspec/core/time/_load_spec.rb @@ -2,10 +2,13 @@ require File.dirname(__FILE__) + '/fixtures/methods' describe "Time#_load" do + before :each do + @t = Time.local(2000, 1, 15, 20, 1, 1) + end + ruby_bug("http://redmine.ruby-lang.org/issues/show/627", "1.8.7") do it "loads a time object in the new format" do - t = Time.local(2000, 1, 15, 20, 1, 1) - t = t.gmtime + t = @t.gmtime high = 1 << 31 | (t.gmt? ? 1 : 0) << 30 | @@ -32,4 +35,8 @@ Time._load([high, low].pack("LL")).should == t end + + it "loads local time" do + Time._load("\004\002\031\200\000\000\020\004").should == @t + end end diff --git a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Marshal.cs b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Marshal.cs index 1a780d35b6..e8aadda086 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Marshal.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Marshal.cs @@ -278,37 +278,23 @@ class SubclassData { } } + private void WriteRange(Range/*!*/ range) { + _writer.Write((byte)'o'); + WriteSymbol("Range"); + WriteInt32(3); + WriteSymbol("begin"); + WriteAnObject(range.Begin); + WriteSymbol("end"); + WriteAnObject(range.End); + WriteSymbol("excl"); + WriteAnObject(range.ExcludeEnd); + } + private void WriteObject(object/*!*/ obj) { _writer.Write((byte)'o'); RubyClass theClass = _context.GetClassOf(obj); TestForAnonymous(theClass); WriteSymbol(theClass.Name); - -#if !SILVERLIGHT - ISerializable serializableObj = (obj as ISerializable); - if (serializableObj != null) { - SerializationInfo info = new SerializationInfo(theClass.GetUnderlyingSystemType(), new FormatterConverter()); - serializableObj.GetObjectData(info, _streamingContext); - int count = info.MemberCount; - try { - // We need this attribute for CLR serialization but it's not compatible with MRI serialization - // Unfortunately, there's no way to test for a value without either iterating over all values - // or throwing an exception if it's not present - if (info.GetValue("#class", typeof(RubyClass)) != null) { - count--; - } - } catch (Exception) { - } - WriteInt32(count); - foreach (SerializationEntry entry in info) { - if (!entry.Name.Equals("#class")) { - WriteSymbol(entry.Name); - WriteAnObject(entry.Value); - } - } - return; - } -#endif } private void WriteUsingDump(object/*!*/ obj) { @@ -443,6 +429,8 @@ class SubclassData { WriteModule((RubyModule)obj); } else if (obj is RubyStruct) { WriteStruct((RubyStruct)obj); + } else if (obj is Range) { + WriteRange((Range)obj); } else { if (writeInstanceData) { // Overwrite the "I"; we always have instance data diff --git a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/TimeOps.cs b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/TimeOps.cs index 10e9903201..e3081bc51c 100644 --- a/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/TimeOps.cs +++ b/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/TimeOps.cs @@ -274,7 +274,7 @@ public static class TimeOps { try { DateTime result = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc); result = result.AddTicks(usec * 10L); - if (isUtc) { + if (!isUtc) { result = result.ToLocalTime(); } return result; diff --git a/Merlin/Main/Languages/Ruby/Scripts/irtests.bat b/Merlin/Main/Languages/Ruby/Scripts/irtests.bat index 666192d73b..680465f015 100644 --- a/Merlin/Main/Languages/Ruby/Scripts/irtests.bat +++ b/Merlin/Main/Languages/Ruby/Scripts/irtests.bat @@ -1,5 +1,11 @@ @setlocal +msbuild.exe %MERLIN_ROOT%\Languages\Ruby\Ruby.sln /p:Configuration="Debug" +if not %ERRORLEVEL%==0 goto END +REM IronPython needs to be in sync for the language interop tests +msbuild.exe %MERLIN_ROOT%\Languages\IronPython\IronPython.sln /p:Configuration="Debug" +if not %ERRORLEVEL%==0 goto END + start "Smoke Tests" %MERLIN_ROOT%\Languages\Ruby\Tests\Scripts\irtest.bat start "Legacy Tests" %MERLIN_ROOT%\Languages\Ruby\Tests\run.bat @@ -17,3 +23,4 @@ start "Command Line RubySpec tests" mspec ci -fd -V :cli %MERLIN_ROOT%\Bin\Debug\ipy.exe %MERLIN_ROOT%\Scripts\Python\GenerateSystemCoreCsproj.py ) +:END