Permalink
Browse files

incomplete Marshal.dump

an evil ivar_as_index is added to Object to hold
the names of modules that extend the object
  • Loading branch information...
1 parent 0a352c2 commit 1baa9468e0d89777fdb6f23e78e8ab510a19d534 Jeremy Roach committed Jan 9, 2008
@@ -167,4 +167,8 @@ def freeze
def frozen?
Ruby.primitive :object_frozen_p
end
+
+ def add_module_name(mod_name)
+ Ruby.primitive :add_module_name
+ end
end
View
@@ -5,5 +5,157 @@ module Marshal
MAJOR_VERSION = 4
MINOR_VERSION = 8
-end
+ TYPE_NIL = '0'
+ TYPE_TRUE = 'T'
+ TYPE_FALSE = 'F'
+ TYPE_FIXNUM = 'i'
+
+ TYPE_EXTENDED = 'e'
+ TYPE_UCLASS = 'C'
+ TYPE_OBJECT = 'o'
+ TYPE_DATA = 'd' # no specs
+ TYPE_USERDEF = 'u'
+ TYPE_USRMARSHAL = 'U' # no specs
+ TYPE_FLOAT = 'f'
+ TYPE_BIGNUM = 'l'
+ TYPE_STRING = '"'
+ TYPE_REGEXP = '/'
+ TYPE_ARRAY = '['
+ TYPE_HASH = '{'
+ TYPE_HASH_DEF = '}'
+ TYPE_STRUCT = 'S'
+ TYPE_MODULE_OLD = 'M' # no specs
+ TYPE_CLASS = 'c'
+ TYPE_MODULE = 'm'
+
+ TYPE_SYMBOL = ':'
+ TYPE_SYMLINK = ';'
+
+ TYPE_IVAR = 'I'
+ TYPE_LINK = '@'
+
+ def self.dump(obj, depth = -1, io = nil)
+ str = [MAJOR_VERSION, MINOR_VERSION].pack('CC')
+ str << serialize(obj, depth)
+ str
+ end
+
+ def self.serialize(obj, depth)
+ get_class_names(obj).each do |class_name|
+ case class_name
+ when 'NilClass'
+ return serialize_nil(obj)
+ when 'TrueClass'
+ return serialize_true(obj)
+ when 'FalseClass'
+ return serialize_false(obj)
+ when 'Class'
+ return serialize_class(obj)
+ when 'Module'
+ return serialize_module(obj)
+ when 'Symbol'
+ return serialize_symbol(obj)
+ when 'String'
+ return serialize_string(obj)
+ when / Integer | Fixnum | Bignum /x
+ if obj >= -2**30 and obj <= (2**30 - 1)
+ return serialize_fixnum(obj)
+ end
+ end
+ end
+ ''
+ end
+
+ def self.serialize_integer(n)
+ if n == 0
+ s = to_byte(n)
+ elsif n > 0 and n < 123
+ s = to_byte(n + 5)
+ elsif n < 0 and n > -124
+ s = to_byte(256 + (n - 5))
+ elsif n < 0
+ s = "\x00"
+ else
+ s = "\x00"
+ cnt = 0
+ while n != 0
+ s << to_byte(n & 0xFF)
+ n >>= 8
+ cnt += 1
+ end
+ s[0] = to_byte(cnt)
+ end
+ s
+ end
+
+ def self.serialize_nil(obj)
+ TYPE_NIL
+ end
+
+ def self.serialize_true(obj)
+ TYPE_TRUE
+ end
+
+ def self.serialize_false(obj)
+ TYPE_FALSE
+ end
+ def self.serialize_symbol(obj)
+ str = obj.to_s
+ TYPE_SYMBOL + serialize_integer(str.length) + str
+ end
+
+ def self.serialize_class(obj)
+ TYPE_CLASS + serialize_integer(obj.name.length) + obj.name
+ end
+
+ def self.serialize_module(obj)
+ TYPE_MODULE + serialize_integer(obj.name.length) + obj.name
+ end
+
+ def self.serialize_extended_object(obj)
+ str = ''
+ if obj.module_names.kind_of?(Array)
+ obj.module_names.each do |mod_name|
+ str << TYPE_EXTENDED + serialize_symbol(mod_name)
+ end
+ end
+ str
+ end
+
+ def self.serialize_user_class(obj, cls)
+ if obj.class != cls
+ TYPE_UCLASS + serialize_symbol(obj.class.name)
+ else
+ ''
+ end
+ end
+
+ def self.serialize_string(obj)
+ serialize_extended_object(obj) +
+ serialize_user_class(obj, String) +
+ TYPE_STRING + serialize_integer(obj.length) + obj
+ end
+
+ def self.serialize_fixnum(obj)
+ TYPE_FIXNUM + serialize_integer(obj)
+ end
+
+ def self.get_class_names(obj)
+ cls = obj.class
+ sup = get_superclass(cls)
+ [cls.to_s, sup.to_s]
+ end
+
+ def self.get_superclass(cls)
+ sup = cls.superclass
+ while sup and sup.superclass and sup.superclass != Object
+ sup = sup.superclass
+ end
+ sup
+ end
+
+ def self.to_byte(n)
+ [n].pack('C')
+ end
+end
View
@@ -8,8 +8,9 @@ class Object
RUBY_ENGINE = Rubinius::RUBY_ENGINE
RBX_VERSION = Rubinius::RBX_VERSION
- ivar_as_index :__ivars__ => 0
+ ivar_as_index :__ivars__ => 0, :module_names => 1
def __ivars__; @__ivars__ ; end
+ def module_names; @module_names; end
def initialize
end
@@ -249,6 +250,7 @@ def protected_methods(all=true)
def extend(*modules)
modules.reverse_each do |mod|
mod.extend_object(self)
+ add_module_name(mod.name)
end
self
end
@@ -7,7 +7,7 @@ module Bootstrap
:MetaClass=>{:@__ivars__=>0, :@methods=>1, :@method_cache=>2, :@name=>3, :@constants=>4, :@parent=>5, :@superclass=>6, :@instance_fields=>7, :@has_ivars=>8, :@needs_cleanup=>9, :@object_type=>10, :@attached_instance=>11},
:Class=>{:@__ivars__=>0, :@methods=>1, :@method_cache=>2, :@name=>3, :@constants=>4, :@parent=>5, :@superclass=>6, :@instance_fields=>7, :@has_ivars=>8, :@needs_cleanup=>9, :@object_type=>10},
:BlockContext=>{},
- :Object=>{:@__ivars__=>0},
+ :Object=>{:@__ivars__=>0, :@module_names => 1},
:Float=>{:@__ivars__=>0},
:Array=>{:@total=>0, :@tuple=>1, :@start => 2, :@shared => 3},
:String=>{:@bytes=>0, :@characters=>1, :@encoding=>2, :@data=>3, :@hash => 4, :@shared => 5},
@@ -180,7 +180,8 @@ class Compiler
:bignum_from_float,
:task_stack_size,
:task_get_stack_value,
- :fastctx_reload_method
+ :fastctx_reload_method,
+ :add_module_name
]
FirstRuntimePrimitive = 1024
View
@@ -2898,6 +2898,22 @@ def object_send
CODE
end
+ def add_module_name
+ <<-CODE
+ self = stack_pop();
+ t1 = stack_pop();
+ if(!RISA(self, class) && !RISA(self, module)) {
+ t2 = object_get_module_names(self);
+ if(!RISA(t2, array)) {
+ t2 = array_new(state, 1);
+ object_set_module_names(self, t2);
+ }
+ array_append(state, t2, t1);
+ }
+ stack_push(self);
+ CODE
+ end
+
end
prim = ShotgunPrimitives.new
@@ -2,42 +2,27 @@ Marshal.dump when given a recursion limit raises an ArgumentError when the recur
Marshal.dump when given an IO-Object writes the serialized data to the IO-Object
Marshal.dump when given an IO-Object returns the IO-Object
Marshal.dump when given an IO-Object raises an Error when the IO-Object does not respond to #write
-Marshal.dump returns a string-serialized version of the given argument
Marshal.dump raises an Error when trying to dump an anonymous class/module
-Marshal.dump with nil returns a string-serialized version of the given argument
-Marshal.dump with true returns a string-serialized version of the given argument
-Marshal.dump with false returns a string-serialized version of the given argument
-Marshal.dump with empty string returns a string-serialized version of the given argument
-Marshal.dump with string of length 100 returns a string-serialized version of the given argument
-Marshal.dump with string of length 200 returns a string-serialized version of the given argument
-Marshal.dump with string of length 300 returns a string-serialized version of the given argument
-Marshal.dump with empty extended_string returns a string-serialized version of the given argument
-Marshal.dump with empty user_string returns a string-serialized version of the given argument
-Marshal.dump with empty extended_user_string returns a string-serialized version of the given argument
-Marshal.dump with symbol of length 1 returns a string-serialized version of the given argument
-Marshal.dump with symbol of length 300 returns a string-serialized version of the given argument
-Marshal.dump with fixnum 0 returns a string-serialized version of the given argument
-Marshal.dump with fixnum 5 returns a string-serialized version of the given argument
-Marshal.dump with fixnum 2**16 returns a string-serialized version of the given argument
-Marshal.dump with fixnum 2**24 returns a string-serialized version of the given argument
-Marshal.dump with fixnum (2**30 - 1) returns a string-serialized version of the given argument
+Marshal.dump with fixnum -2**8 returns a string-serialized version of the given argument
+Marshal.dump with fixnum -16711680 returns a string-serialized version of the given argument
Marshal.dump with fixnum -2**16 returns a string-serialized version of the given argument
+Marshal.dump with fixnum -(2**16 - 1) returns a string-serialized version of the given argument
+Marshal.dump with fixnum -(2**16 - 2) returns a string-serialized version of the given argument
+Marshal.dump with fixnum -43690 returns a string-serialized version of the given argument
Marshal.dump with fixnum -2**30 returns a string-serialized version of the given argument
Marshal.dump with bignum 2**30 returns a string-serialized version of the given argument
-Marshal.dump with bignum -2**31 returns a string-serialized version of the given argument
+Marshal.dump with bignum -(2**31 -1) returns a string-serialized version of the given argument
Marshal.dump with bignum -2**63 returns a string-serialized version of the given argument
Marshal.dump with bignum 2**64 returns a string-serialized version of the given argument
Marshal.dump with bignum -2**64 returns a string-serialized version of the given argument
-Marshal.dump with class returns a string-serialized version of the given argument
-Marshal.dump with module returns a string-serialized version of the given argument
Marshal.dump with any object having _dump method returns a string-serialized version of the given argument
Marshal.dump with any extended_object having _dump method returns a string-serialized version of the given argument
Marshal.dump with object returns a string-serialized version of the given argument
Marshal.dump with object having ivar returns a string-serialized version of the given argument
Marshal.dump with regexp returns a string-serialized version of the given argument
Marshal.dump with extended_regexp returns a string-serialized version of the given argument
Marshal.dump with user_regexp having option Regexp::IGNORECASE returns a string-serialized version of the given argument
-Marshal.dump with extended_user_regexp returns a string-serialized version of the given argument
+Marshal.dump with extended_user_regexp having ivar returns a string-serialized version of the given argument
Marshal.dump with float 0.0 returns a string-serialized version of the given argument
Marshal.dump with float NaN returns a string-serialized version of the given argument
Marshal.dump with float -Infinity returns a string-serialized version of the given argument
@@ -50,7 +35,7 @@ Marshal.dump with extended_user_hash_default returns a string-serialized version
Marshal.dump with array returns a string-serialized version of the given argument
Marshal.dump with array containing the same symbols returns a string-serialized version of the given argument
Marshal.dump with array containing refs to the same object returns a string-serialized version of the given argument
-Marshal.dump with extended_array returns a string-serialized version of the given argument
+Marshal.dump with extended_array having ivar returns a string-serialized version of the given argument
Marshal.dump with user_array returns a string-serialized version of the given argument
Marshal.dump with extended_user_array returns a string-serialized version of the given argument
Marshal.dump with struct returns a string-serialized version of the given argument
Oops, something went wrong.

0 comments on commit 1baa946

Please sign in to comment.