[pypy-svn] r50790 - in pypy/dist/pypy/translator/cli: . test
antocuni at codespeak.net
antocuni at codespeak.net
Sat Jan 19 23:13:56 CET 2008
Author: antocuni
Date: Sat Jan 19 23:13:56 2008
New Revision: 50790
Modified:
pypy/dist/pypy/translator/cli/dotnet.py
pypy/dist/pypy/translator/cli/metavm.py
pypy/dist/pypy/translator/cli/opcodes.py
pypy/dist/pypy/translator/cli/test/test_dotnet.py
Log:
a hack to be able to construct delegates of type EventHandler from RPython
Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py (original)
+++ pypy/dist/pypy/translator/cli/dotnet.py Sat Jan 19 23:13:56 2008
@@ -519,3 +519,21 @@
def specialize_call(self, hop):
v_type, = hop.inputargs(*hop.args_r)
return hop.genop('cli_typeof', [v_type], hop.r_result.lowleveltype)
+
+
+def eventhandler(obj):
+ return CLR.System.EventHandler(obj)
+
+class Entry(ExtRegistryEntry):
+ _about_ = eventhandler
+
+ def compute_result_annotation(self, s_value):
+ from pypy.translator.cli.query import load_class_maybe
+ cliType = load_class_maybe('System.EventHandler')
+ return SomeOOInstance(cliType._INSTANCE)
+
+ def specialize_call(self, hop):
+ v_obj, = hop.inputargs(*hop.args_r)
+ methodname = hop.args_r[0].methodname
+ c_methodname = hop.inputconst(ootype.Void, methodname)
+ return hop.genop('cli_eventhandler', [v_obj, c_methodname], hop.r_result.lowleveltype)
Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py (original)
+++ pypy/dist/pypy/translator/cli/metavm.py Sat Jan 19 23:13:56 2008
@@ -9,6 +9,13 @@
STRING_HELPER_CLASS = '[pypylib]pypy.runtime.String'
+def functype_to_cts(cts, FUNC):
+ ret_type = cts.lltype_to_cts(FUNC.RESULT)
+ arg_types = [cts.lltype_to_cts(arg).typename()
+ for arg in FUNC.ARGS
+ if arg is not ootype.Void]
+ return ret_type, arg_types
+
class _Call(_OOCall):
def render(self, generator, op):
@@ -22,10 +29,7 @@
for func_arg in args[1:]: # push parameters
self._load_arg_or_null(generator, func_arg)
cts = generator.cts
- ret_type = cts.lltype_to_cts(funcdesc._TYPE.RESULT)
- arg_types = [cts.lltype_to_cts(arg).typename()
- for arg in funcdesc._TYPE.ARGS
- if arg is not ootype.Void]
+ ret_type, arg_types = functype_to_cts(cts, funcdesc._TYPE)
arg_list = ', '.join(arg_types)
signature = '%s %s::%s(%s)' % (ret_type, funcdesc._cls._name, funcdesc._name, arg_list)
generator.call_signature(signature)
@@ -59,10 +63,7 @@
# special case for string: don't use methods, but plain functions
METH = this.concretetype._METHODS[method_name]
cts = generator.cts
- ret_type = cts.lltype_to_cts(METH.RESULT)
- arg_types = [cts.lltype_to_cts(arg).typename()
- for arg in METH.ARGS
- if arg is not ootype.Void]
+ ret_type, arg_types = functype_to_cts(cts, METH)
arg_types.insert(0, cts.lltype_to_cts(ootype.String).typename())
arg_list = ', '.join(arg_types)
signature = '%s %s::%s(%s)' % (ret_type, STRING_HELPER_CLASS, method_name, arg_list)
@@ -197,6 +198,25 @@
generator.ilasm.opcode('ldtoken', fullname)
generator.ilasm.call('class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)')
+class _EventHandler(MicroInstruction):
+ def render(self, generator, op):
+ cts = generator.cts
+ v_obj, c_methname = op.args
+ assert c_methname.concretetype is ootype.Void
+ TYPE = v_obj.concretetype
+ classname = TYPE._name
+ methname = 'o' + c_methname.value # XXX: do proper mangling
+ _, meth = TYPE._lookup(methname)
+ METH = ootype.typeOf(meth)
+ ret_type, arg_types = functype_to_cts(cts, METH)
+ arg_list = ', '.join(arg_types)
+ generator.load(v_obj)
+ desc = '%s class %s::%s(%s)' % (ret_type, classname, methname, arg_list)
+ generator.ilasm.opcode('ldftn instance', desc)
+ generator.ilasm.opcode('newobj', 'instance void class [mscorlib]System.EventHandler::.ctor(object, native int)')
+
+
+
OOTYPE_TO_MNEMONIC = {
ootype.Signed: 'i4',
ootype.SignedLongLong: 'i8',
@@ -222,4 +242,5 @@
GetArrayElem = _GetArrayElem()
SetArrayElem = _SetArrayElem()
TypeOf = _TypeOf()
+EventHandler = _EventHandler()
CastPrimitive = _CastPrimitive()
Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py (original)
+++ pypy/dist/pypy/translator/cli/opcodes.py Sat Jan 19 23:13:56 2008
@@ -1,7 +1,7 @@
from pypy.translator.cli.metavm import Call, CallMethod, \
IndirectCall, GetField, SetField, DownCast, NewCustomDict,\
MapException, Box, Unbox, NewArray, GetArrayElem, SetArrayElem,\
- TypeOf, CastPrimitive
+ TypeOf, CastPrimitive, EventHandler
from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\
New, RuntimeNew, CastTo, PushPrimitive, OOString, OOUnicode
from pypy.translator.cli.cts import WEAKREF
@@ -43,6 +43,7 @@
'cli_setelem': [SetArrayElem],
'cli_typeof': [TypeOf],
'cli_arraylength': 'ldlen',
+ 'cli_eventhandler': [EventHandler],
'oois': 'ceq',
'oononnull': [PushAllArgs, 'ldnull', 'ceq']+Not,
'instanceof': [CastTo, 'ldnull', 'cgt.un'],
Modified: pypy/dist/pypy/translator/cli/test/test_dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_dotnet.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_dotnet.py Sat Jan 19 23:13:56 2008
@@ -7,7 +7,7 @@
from pypy.translator.cli.test.runtest import CliTest
from pypy.translator.cli.dotnet import SomeCliClass, SomeCliStaticMethod,\
NativeInstance, CLR, box, unbox, OverloadingResolver, NativeException,\
- native_exc, new_array, init_array, typeof
+ native_exc, new_array, init_array, typeof, eventhandler
System = CLR.System
Math = CLR.System.Math
@@ -417,6 +417,23 @@
res = self.interpret(fn, [], backendopt=False)
assert res is True
+ def test_delegate(self):
+ class Foo:
+ def __init__(self):
+ self.x = 0
+ def m(self, sender, args):
+ self.x = 42
+
+ def fn(flag):
+ f = Foo()
+ if flag:
+ f.m(None, None)
+ delegate = eventhandler(f.m)
+ delegate.Invoke(None, None)
+ return f.x
+ res = self.interpret(fn, [False])
+ assert res == 42
+
class TestPythonnet(TestDotnetRtyping):
# don't interpreter functions but execute them directly through pythonnet
def interpret(self, f, args, backendopt='ignored'):
More information about the Pypy-commit
mailing list