Exemplo n.º 1
0
class EqualityComparer(Node):
    count = 0
    
    def __init__(self, db, KEY_TYPE, eq_args, hash_args):
        self.db = db
        self.cts = CTS(db)
        self.KEY_TYPE = KEY_TYPE
        self.key_type = self.cts.lltype_to_cts(KEY_TYPE)
        self.eq_args = eq_args
        self.hash_args = hash_args
        self.name = 'EqualityComparer_%d' % EqualityComparer.count
        EqualityComparer.count += 1

    def get_ctor(self):
        return 'instance void %s::.ctor()' % self.name

    def render(self, ilasm):
        self.ilasm = ilasm
        IEqualityComparer = IEQUALITY_COMPARER % self.key_type
        ilasm.begin_class(self.name, interfaces=[IEqualityComparer])
        self._ctor()
        self._method('Equals', [(self.key_type, 'x'), (self.key_type, 'y')],
                     'bool', self.eq_args)
        self._method('GetHashCode', [(self.key_type, 'x')], 'int32', self.hash_args)
        ilasm.end_class()

    def _ctor(self):
        self.ilasm.begin_function('.ctor', [], 'void', False, 'specialname', 'rtspecialname', 'instance')
        self.ilasm.opcode('ldarg.0')
        self.ilasm.call('instance void [mscorlib]System.Object::.ctor()')
        self.ilasm.opcode('ret')
        self.ilasm.end_function()
        
    def _method(self, name, arglist, return_type, fn_args):
        self.ilasm.begin_function(name, arglist, return_type, False,
                                  'final', 'virtual', 'hidebysig', 'newslot',
                                  'instance', 'default')

        if type(fn_args) == types.FunctionType:
            assert len(fn_args.self_arg) <= 1
            if len(fn_args.self_arg) == 1:
                assert fn_args.graph.getargs()[0].concretetype is ootype.Void
            self._call_function(fn_args.graph, len(arglist))
        else:
            fn, obj, method_name = fn_args
            # fn is a Constant(StaticMethod)
            if method_name.value is None:
                self._call_function(fn.value.graph, len(arglist))
            else:
                assert False, 'XXX'

        self.ilasm.end_function()

    def _call_function(self, graph, n_args):
        self.db.pending_function(graph)
        for arg in range(1, n_args+1):
            self.ilasm.opcode('ldarg', arg)
        signature = self.cts.graph_to_signature(graph)
        self.ilasm.call(signature)
        self.ilasm.opcode('ret')
Exemplo n.º 2
0
 def __init__(self, db, KEY_TYPE, eq_args, hash_args):
     self.db = db
     self.cts = CTS(db)
     self.KEY_TYPE = KEY_TYPE
     self.key_type = self.cts.lltype_to_cts(KEY_TYPE)
     self.eq_args = eq_args
     self.hash_args = hash_args
     self.name = 'EqualityComparer_%d' % EqualityComparer.count
     EqualityComparer.count += 1
Exemplo n.º 3
0
 def __init__(self, db, KEY_TYPE, eq_args, hash_args):
     self.db = db
     self.cts = CTS(db)
     self.KEY_TYPE = KEY_TYPE
     self.key_type = self.cts.lltype_to_cts(KEY_TYPE)
     self.eq_args = eq_args
     self.hash_args = hash_args
     self.name = 'EqualityComparer_%d' % EqualityComparer.count
     EqualityComparer.count += 1
Exemplo n.º 4
0
class Delegate(Node):
    def __init__(self, db, TYPE, name):
        self.cts = CTS(db)
        self.TYPE = TYPE
        self.name = name

    def __eq__(self, other):
        return self.TYPE == other.TYPE

    def __ne__(self, other):
        return not self == other

    def __hash__(self):
        return hash(self.TYPE)

    def get_name(self):
        return self.name

    def dependencies(self):
        # record we know about result and argument types
        self.cts.lltype_to_cts(self.TYPE.RESULT)
        for ARG in self.TYPE.ARGS:
            self.cts.lltype_to_cts(ARG)

    def render(self, ilasm):
        TYPE = self.TYPE
        ilasm.begin_class(self.name,
                          '[mscorlib]System.MulticastDelegate',
                          sealed=True)
        ilasm.begin_function('.ctor', [('object', "'object'"),
                                       ('native int', "'method'")],
                             'void',
                             False,
                             'hidebysig',
                             'specialname',
                             'rtspecialname',
                             'instance',
                             'default',
                             runtime=True)
        ilasm.end_function()

        resulttype = self.cts.lltype_to_cts(TYPE.RESULT)
        arglist = [(self.cts.lltype_to_cts(ARG), '') for ARG in TYPE.ARGS
                   if ARG is not ootype.Void]
        ilasm.begin_function('Invoke',
                             arglist,
                             resulttype,
                             False,
                             'virtual',
                             'hidebysig',
                             'instance',
                             'default',
                             runtime=True)
        ilasm.end_function()
        ilasm.end_class()
Exemplo n.º 5
0
class Delegate(Node):
    def __init__(self, db, TYPE, name):
        self.cts = CTS(db)        
        self.TYPE = TYPE
        self.name = name

    def __eq__(self, other):
        return self.TYPE == other.TYPE

    def __ne__(self, other):
        return not self == other

    def __hash__(self):
        return hash(self.TYPE)

    def get_name(self):
        return self.name

    def dependencies(self):
        # record we know about result and argument types
        self.cts.lltype_to_cts(self.TYPE.RESULT)
        for ARG in self.TYPE.ARGS:
            self.cts.lltype_to_cts(ARG)


    def render(self, ilasm):
        TYPE = self.TYPE
        ilasm.begin_class(self.name, '[mscorlib]System.MulticastDelegate', sealed=True)
        ilasm.begin_function('.ctor',
                             [('object', "'object'"), ('native int', "'method'")],
                             'void',
                             False,
                             'hidebysig', 'specialname', 'rtspecialname', 'instance', 'default',
                             runtime=True)
        ilasm.end_function()

        resulttype = self.cts.lltype_to_cts(TYPE.RESULT)
        arglist = [(self.cts.lltype_to_cts(ARG), '') for ARG in TYPE.ARGS if ARG is not ootype.Void]
        ilasm.begin_function('Invoke', arglist, resulttype, False,
                             'virtual', 'hidebysig', 'instance', 'default',
                             runtime=True)
        ilasm.end_function()
        ilasm.end_class()
Exemplo n.º 6
0
 def set_db(self, db):
     self.db = db
     self.cts = CTS(db)
Exemplo n.º 7
0
 def __init__(self, db, record, name):
     self.db = db
     self.cts = CTS(db)
     self.record = record
     self.name = name
Exemplo n.º 8
0
class Record(Node):
    def __init__(self, db, record, name):
        self.db = db
        self.cts = CTS(db)
        self.record = record
        self.name = name

    def __hash__(self):
        return hash(self.record)

    def __eq__(self, other):
        return self.record == other.record

    def __ne__(self, other):
        return not self == other

    def get_name(self):
        return self.name

    def get_base_class(self):
        return '[mscorlib]System.Object'

    def render(self, ilasm):
        self.ilasm = ilasm
        ilasm.begin_class(self.name, self.get_base_class())
        for f_name, (FIELD_TYPE, f_default) in self.record._fields.iteritems():
            f_name = self.cts.escape_name(f_name)
            cts_type = self.cts.lltype_to_cts(FIELD_TYPE)
            if cts_type != CTS.types.void:
                ilasm.field(f_name, cts_type)
        self._ctor()
        self._toString()
        self._equals()
        self._getHashCode()
        ilasm.end_class()

    def _ctor(self):
        self.ilasm.begin_function('.ctor', [], 'void', False, 'specialname',
                                  'rtspecialname', 'instance')
        self.ilasm.opcode('ldarg.0')
        self.ilasm.call('instance void %s::.ctor()' % self.get_base_class())
        self.ilasm.opcode('ret')
        self.ilasm.end_function()

    def _toString(self):
        # only for testing purposes, and only if the Record represents a tuple
        from pypy.translator.cli.test.runtest import format_object

        for f_name in self.record._fields:
            if not f_name.startswith('item'):
                return  # it's not a tuple

        self.ilasm.begin_function('ToString', [], 'string', False, 'virtual',
                                  'instance', 'default')
        self.ilasm.opcode('ldstr', '"("')
        for i in xrange(len(self.record._fields)):
            f_name = 'item%d' % i
            FIELD_TYPE, f_default = self.record._fields[f_name]
            if FIELD_TYPE is ootype.Void:
                continue
            self.ilasm.opcode('ldarg.0')
            f_type = self.cts.lltype_to_cts(FIELD_TYPE)
            self.ilasm.get_field((f_type, self.name, f_name))
            format_object(FIELD_TYPE, self.cts, self.ilasm)
            self.ilasm.call('string string::Concat(string, string)')
            self.ilasm.opcode('ldstr ", "')
            self.ilasm.call('string string::Concat(string, string)')
        self.ilasm.opcode('ldstr ")"')
        self.ilasm.call('string string::Concat(string, string)')
        self.ilasm.opcode('ret')
        self.ilasm.end_function()

    def _equals(self):
        # field by field comparison
        record_type = self.cts.lltype_to_cts(self.record)
        self.ilasm.begin_function('Equals', [('object', 'obj')], 'bool', False,
                                  'virtual', 'instance', 'default')
        self.ilasm.locals([(record_type, 'self')])
        self.ilasm.opcode('ldarg.1')
        self.ilasm.opcode('castclass', record_type.classname())
        self.ilasm.opcode('stloc.0')

        equal = 'bool [pypylib]pypy.runtime.Utils::Equal<%s>(!!0, !!0)'
        self.ilasm.opcode('ldc.i4', '1')
        for f_name, (FIELD_TYPE, default) in self.record._fields.iteritems():
            if FIELD_TYPE is ootype.Void:
                continue
            f_type = self.cts.lltype_to_cts(FIELD_TYPE)
            f_name = self.cts.escape_name(f_name)
            self.ilasm.opcode('ldarg.0')
            self.ilasm.get_field((f_type, record_type.classname(), f_name))
            self.ilasm.opcode('ldloc.0')
            self.ilasm.get_field((f_type, record_type.classname(), f_name))
            self.ilasm.call(equal % f_type)
            self.ilasm.opcode('and')

        self.ilasm.opcode('ret')
        self.ilasm.end_function()

    def _getHashCode(self):
        record_type = self.cts.lltype_to_cts(self.record)
        self.ilasm.begin_function('GetHashCode', [], 'int32', False, 'virtual',
                                  'instance', 'default')
        gethash = 'int32 [pypylib]pypy.runtime.Utils::GetHashCode<%s>(!!0)'

        self.ilasm.opcode('ldc.i4.0')  # initial hash
        if self.record._fields:
            for f_name, (FIELD_TYPE,
                         default) in self.record._fields.iteritems():
                if FIELD_TYPE is ootype.Void:
                    continue
                else:
                    # compute the hash for this field
                    f_name = self.cts.escape_name(f_name)
                    f_type = self.cts.lltype_to_cts(FIELD_TYPE)
                    self.ilasm.opcode('ldarg.0')
                    self.ilasm.get_field(
                        (f_type, record_type.classname(), f_name))
                    self.ilasm.call(gethash % f_type)

                    # xor with the previous value
                    self.ilasm.opcode('xor')

        self.ilasm.opcode('ret')
        self.ilasm.end_function()
Exemplo n.º 9
0
class EqualityComparer(Node):
    count = 0

    def __init__(self, db, KEY_TYPE, eq_args, hash_args):
        self.db = db
        self.cts = CTS(db)
        self.KEY_TYPE = KEY_TYPE
        self.key_type = self.cts.lltype_to_cts(KEY_TYPE)
        self.eq_args = eq_args
        self.hash_args = hash_args
        self.name = 'EqualityComparer_%d' % EqualityComparer.count
        EqualityComparer.count += 1

    def get_ctor(self):
        return 'instance void %s::.ctor()' % self.name

    def render(self, ilasm):
        self.ilasm = ilasm
        IEqualityComparer = IEQUALITY_COMPARER % self.key_type
        ilasm.begin_class(self.name, interfaces=[IEqualityComparer])
        self._ctor()
        self._method('Equals', [(self.key_type, 'x'), (self.key_type, 'y')],
                     'bool', self.eq_args)
        self._method('GetHashCode', [(self.key_type, 'x')], 'int32',
                     self.hash_args)
        ilasm.end_class()

    def _ctor(self):
        self.ilasm.begin_function('.ctor', [], 'void', False, 'specialname',
                                  'rtspecialname', 'instance')
        self.ilasm.opcode('ldarg.0')
        self.ilasm.call('instance void [mscorlib]System.Object::.ctor()')
        self.ilasm.opcode('ret')
        self.ilasm.end_function()

    def _method(self, name, arglist, return_type, fn_args):
        self.ilasm.begin_function(name, arglist, return_type, False, 'final',
                                  'virtual', 'hidebysig', 'newslot',
                                  'instance', 'default')

        if type(fn_args) == types.FunctionType:
            assert len(fn_args.self_arg) <= 1
            if len(fn_args.self_arg) == 1:
                assert fn_args.graph.getargs()[0].concretetype is ootype.Void
            self._call_function(fn_args.graph, len(arglist))
        else:
            fn, obj, method_name = fn_args
            # fn is a Constant(StaticMethod)
            if method_name.value is None:
                self._call_function(fn.value.graph, len(arglist))
            else:
                assert False, 'XXX'

        self.ilasm.end_function()

    def _call_function(self, graph, n_args):
        self.db.pending_function(graph)
        for arg in range(1, n_args + 1):
            self.ilasm.opcode('ldarg', arg)
        signature = self.cts.graph_to_signature(graph)
        self.ilasm.call(signature)
        self.ilasm.opcode('ret')
Exemplo n.º 10
0
 def __init__(self, db, TYPE, name):
     self.cts = CTS(db)
     self.TYPE = TYPE
     self.name = name
Exemplo n.º 11
0
 def __init__(self, db, TYPE, name):
     self.cts = CTS(db)        
     self.TYPE = TYPE
     self.name = name
Exemplo n.º 12
0
 def __init__(self, db, record, name):
     self.db = db
     self.cts = CTS(db)
     self.record = record
     self.name = name
Exemplo n.º 13
0
class Record(Node):
    def __init__(self, db, record, name):
        self.db = db
        self.cts = CTS(db)
        self.record = record
        self.name = name

    def __hash__(self):
        return hash(self.record)

    def __eq__(self, other):
        return self.record == other.record

    def __ne__(self, other):
        return not self == other

    def get_name(self):
        return self.name

    def get_base_class(self):
        return '[mscorlib]System.Object'        

    def render(self, ilasm):
        self.ilasm = ilasm
        ilasm.begin_class(self.name, self.get_base_class())
        for f_name, (FIELD_TYPE, f_default) in self.record._fields.iteritems():
            f_name = self.cts.escape_name(f_name)
            cts_type = self.cts.lltype_to_cts(FIELD_TYPE)
            if cts_type != CTS.types.void:
                ilasm.field(f_name, cts_type)
        self._ctor()
        self._toString()
        self._equals()
        self._getHashCode()
        ilasm.end_class()

    def _ctor(self):
        self.ilasm.begin_function('.ctor', [], 'void', False, 'specialname', 'rtspecialname', 'instance')
        self.ilasm.opcode('ldarg.0')
        self.ilasm.call('instance void %s::.ctor()' % self.get_base_class())
        self.ilasm.opcode('ret')
        self.ilasm.end_function()
        
    def _toString(self):
        # only for testing purposes, and only if the Record represents a tuple
        from pypy.translator.cli.test.runtest import format_object

        for f_name in self.record._fields:
            if not f_name.startswith('item'):
                return # it's not a tuple

        self.ilasm.begin_function('ToString', [], 'string', False, 'virtual', 'instance', 'default')
        self.ilasm.opcode('ldstr', '"("')
        for i in xrange(len(self.record._fields)):
            f_name = 'item%d' % i
            FIELD_TYPE, f_default = self.record._fields[f_name]
            if FIELD_TYPE is ootype.Void:
                continue
            self.ilasm.opcode('ldarg.0')
            f_type = self.cts.lltype_to_cts(FIELD_TYPE)
            self.ilasm.get_field((f_type, self.name, f_name))
            format_object(FIELD_TYPE, self.cts, self.ilasm)
            self.ilasm.call('string string::Concat(string, string)')
            self.ilasm.opcode('ldstr ", "')
            self.ilasm.call('string string::Concat(string, string)')
        self.ilasm.opcode('ldstr ")"')
        self.ilasm.call('string string::Concat(string, string)')            
        self.ilasm.opcode('ret')
        self.ilasm.end_function()

    def _equals(self):
        # field by field comparison
        record_type = self.cts.lltype_to_cts(self.record)
        self.ilasm.begin_function('Equals', [('object', 'obj')], 'bool',
                                  False, 'virtual', 'instance', 'default')
        self.ilasm.locals([(record_type, 'self')])
        self.ilasm.opcode('ldarg.1')
        self.ilasm.opcode('castclass', record_type.classname())
        self.ilasm.opcode('stloc.0')

        equal = 'bool [pypylib]pypy.runtime.Utils::Equal<%s>(!!0, !!0)'
        self.ilasm.opcode('ldc.i4', '1')
        for f_name, (FIELD_TYPE, default) in self.record._fields.iteritems():
            if FIELD_TYPE is ootype.Void:
                continue
            f_type = self.cts.lltype_to_cts(FIELD_TYPE)
            f_name = self.cts.escape_name(f_name)
            self.ilasm.opcode('ldarg.0')
            self.ilasm.get_field((f_type, record_type.classname(), f_name))
            self.ilasm.opcode('ldloc.0')
            self.ilasm.get_field((f_type, record_type.classname(), f_name))
            self.ilasm.call(equal % f_type)
            self.ilasm.opcode('and')

        self.ilasm.opcode('ret')
        self.ilasm.end_function()

    def _getHashCode(self):
        record_type = self.cts.lltype_to_cts(self.record)
        self.ilasm.begin_function('GetHashCode', [], 'int32', False, 'virtual', 'instance', 'default')
        gethash = 'int32 [pypylib]pypy.runtime.Utils::GetHashCode<%s>(!!0)'

        self.ilasm.opcode('ldc.i4.0') # initial hash
        if self.record._fields:
            for f_name, (FIELD_TYPE, default) in self.record._fields.iteritems():
                if FIELD_TYPE is ootype.Void:
                    continue
                else:
                    # compute the hash for this field
                    f_name = self.cts.escape_name(f_name)
                    f_type = self.cts.lltype_to_cts(FIELD_TYPE)
                    self.ilasm.opcode('ldarg.0')
                    self.ilasm.get_field((f_type, record_type.classname(), f_name))
                    self.ilasm.call(gethash % f_type)

                    # xor with the previous value
                    self.ilasm.opcode('xor')
                    
        self.ilasm.opcode('ret')
        self.ilasm.end_function()