[pypy-svn] r50916 - in pypy/dist/pypy/translator/cli: . src test
antocuni at codespeak.net
antocuni at codespeak.net
Wed Jan 23 15:08:06 CET 2008
Author: antocuni
Date: Wed Jan 23 15:08:05 2008
New Revision: 50916
Modified:
pypy/dist/pypy/translator/cli/cts.py
pypy/dist/pypy/translator/cli/dotnet.py
pypy/dist/pypy/translator/cli/ilgenerator.py
pypy/dist/pypy/translator/cli/metavm.py
pypy/dist/pypy/translator/cli/opcodes.py
pypy/dist/pypy/translator/cli/query.py
pypy/dist/pypy/translator/cli/src/query.cs
pypy/dist/pypy/translator/cli/test/test_dotnet.py
pypy/dist/pypy/translator/cli/test/test_query.py
Log:
- add support for reading static fields of .NET classes
- add support to value types
Modified: pypy/dist/pypy/translator/cli/cts.py
==============================================================================
--- pypy/dist/pypy/translator/cli/cts.py (original)
+++ pypy/dist/pypy/translator/cli/cts.py Wed Jan 23 15:08:05 2008
@@ -41,13 +41,14 @@
class CliReferenceType(CliType):
+ prefix = 'class '
+
def typename(self):
- return 'class ' + self.classname()
+ return self.prefix + self.classname()
def classname(self):
raise NotImplementedError
-
class CliClassType(CliReferenceType):
def __init__(self, assembly, name):
self.assembly = assembly
@@ -59,6 +60,9 @@
else:
return self.name
+class CliValueType(CliClassType):
+ prefix = 'valuetype '
+
class CliGenericType(CliReferenceType):
def __init__(self, assembly, name, numparam):
@@ -229,12 +233,16 @@
elif isinstance(t, lltype.Ptr) and isinstance(t.TO, lltype.OpaqueType):
return types.object
elif isinstance(t, ootype.Instance):
+ if getattr(t, '_is_value_type', False):
+ cls = CliValueType
+ else:
+ cls = CliClassType
NATIVE_INSTANCE = t._hints.get('NATIVE_INSTANCE', None)
if NATIVE_INSTANCE:
- return CliClassType(None, NATIVE_INSTANCE._name)
+ return cls(None, NATIVE_INSTANCE._name)
else:
name = self.db.pending_class(t)
- return CliClassType(None, name)
+ return cls(None, name)
elif isinstance(t, ootype.Record):
name = self.db.pending_record(t)
return CliClassType(None, name)
Modified: pypy/dist/pypy/translator/cli/dotnet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/dotnet.py (original)
+++ pypy/dist/pypy/translator/cli/dotnet.py Wed Jan 23 15:08:05 2008
@@ -21,7 +21,15 @@
def getattr(self, s_attr):
assert self.is_constant()
assert s_attr.is_constant()
- return SomeCliStaticMethod(self.const, s_attr.const)
+ cliclass = self.const
+ attrname = s_attr.const
+ if attrname in cliclass._static_fields:
+ TYPE = cliclass._static_fields[attrname]
+ return OverloadingResolver.lltype_to_annotation(TYPE)
+ elif attrname in cliclass._static_methods:
+ return SomeCliStaticMethod(cliclass, attrname)
+ else:
+ return s_ImpossibleValue
def simple_call(self, *s_args):
assert self.is_constant()
@@ -75,7 +83,15 @@
self.cli_class = cli_class
def rtype_getattr(self, hop):
- return hop.inputconst(ootype.Void, self.cli_class)
+ attrname = hop.args_v[1].value
+ if attrname in self.cli_class._static_methods:
+ return hop.inputconst(ootype.Void, self.cli_class)
+ else:
+ assert attrname in self.cli_class._static_fields
+ TYPE = self.cli_class._static_fields[attrname]
+ c_class = hop.inputarg(hop.args_r[0], arg=0)
+ c_name = hop.inputconst(ootype.Void, hop.args_v[1].value)
+ return hop.genop("cli_getstaticfield", [c_class, c_name], resulttype=hop.r_result.lowleveltype)
def rtype_simple_call(self, hop):
# TODO: resolve constructor overloading
@@ -199,16 +215,18 @@
fullname = '%s%s.%s' % (assembly, namespace, name)
self._namespace = namespace
self._classname = name
+ self._is_value_type = False
ootype.Instance.__init__(self, fullname, superclass, fields, methods, _is_root, _hints)
## RPython interface definition
class CliClass(object):
- def __init__(self, INSTANCE, static_methods):
+ def __init__(self, INSTANCE, static_methods, static_fields):
self._name = INSTANCE._name
self._INSTANCE = INSTANCE
self._static_methods = {}
+ self._static_fields = {}
self._add_methods(static_methods)
def __repr__(self):
@@ -222,6 +240,9 @@
for name, meth in methods.iteritems():
meth._set_attrs(self, name)
+ def _add_static_fields(self, fields):
+ self._static_fields.update(fields)
+
def _lookup(self, meth_name, ARGS):
meth = self._static_methods[meth_name]
return meth._get_desc(ARGS)
@@ -239,7 +260,7 @@
self._PythonNet_class = obj
def __getattr__(self, attr):
- if attr in self._static_methods:
+ if attr in self._static_methods or attr in self._static_fields:
self._load_class()
return getattr(self._PythonNet_class, attr)
else:
Modified: pypy/dist/pypy/translator/cli/ilgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/ilgenerator.py (original)
+++ pypy/dist/pypy/translator/cli/ilgenerator.py Wed Jan 23 15:08:05 2008
@@ -203,17 +203,21 @@
def load_self(self):
self.opcode('ldarg.0')
- def load_arg(self,v):
+ def load_arg(self, v):
self.opcode('ldarg', repr(v.name))
- def load_local(self,v):
- self.opcode('ldloc', repr(v.name))
+ def load_local(self, v):
+ TYPE = v.concretetype
+ if getattr(TYPE, '_is_value_type', False):
+ self.opcode('ldloca', repr(v.name))
+ else:
+ self.opcode('ldloc', repr(v.name))
def switch(self, targets):
cmd = 'switch(%s)' % ', '.join(targets)
self.opcode(cmd)
- def load_const(self,type_,v):
+ def load_const(self,type_, v):
if type_ is Void:
pass
elif type_ is Bool:
Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py (original)
+++ pypy/dist/pypy/translator/cli/metavm.py Wed Jan 23 15:08:05 2008
@@ -215,6 +215,14 @@
generator.ilasm.opcode('ldftn instance', desc)
generator.ilasm.opcode('newobj', 'instance void class [mscorlib]System.EventHandler::.ctor(object, native int)')
+class _GetStaticField(MicroInstruction):
+ def render(self, generator, op):
+ cli_class = op.args[0].value
+ fldname = op.args[1].value
+ TYPE = op.result.concretetype
+ cts_type = generator.cts.lltype_to_cts(TYPE)
+ desc = '%s::%s' % (cli_class._name, fldname)
+ generator.ilasm.load_static_field(cts_type, desc)
OOTYPE_TO_MNEMONIC = {
@@ -243,4 +251,5 @@
SetArrayElem = _SetArrayElem()
TypeOf = _TypeOf()
EventHandler = _EventHandler()
+GetStaticField = _GetStaticField()
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 Wed Jan 23 15:08:05 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, EventHandler
+ TypeOf, CastPrimitive, EventHandler, GetStaticField
from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\
New, RuntimeNew, CastTo, PushPrimitive, OOString, OOUnicode
from pypy.translator.cli.cts import WEAKREF
@@ -44,6 +44,7 @@
'cli_typeof': [TypeOf],
'cli_arraylength': 'ldlen',
'cli_eventhandler': [EventHandler],
+ 'cli_getstaticfield': [GetStaticField],
'oois': 'ceq',
'oononnull': [PushAllArgs, 'ldnull', 'ceq']+Not,
'instanceof': [CastTo, 'ldnull', 'cgt.un'],
Modified: pypy/dist/pypy/translator/cli/query.py
==============================================================================
--- pypy/dist/pypy/translator/cli/query.py (original)
+++ pypy/dist/pypy/translator/cli/query.py Wed Jan 23 15:08:05 2008
@@ -86,8 +86,6 @@
desc.BaseType = 'System.Object'
desc.IsArray = True
desc.ElementType = 'System.Object' # not really true, but we need something
- desc.StaticMethods = []
- desc.Methods = []
elif name.endswith('[]'): # it's an array
itemname = name[:-2]
itemdesc = get_class_desc(itemname)
@@ -97,7 +95,6 @@
desc.BaseType = 'System.Array'
desc.ElementType = itemdesc.FullName
desc.IsArray = True
- desc.StaticMethods = []
desc.Methods = [
('Get', ['ootype.Signed', ], itemdesc.FullName),
('Set', ['ootype.Signed', itemdesc.FullName], 'ootype.Void')
@@ -110,6 +107,13 @@
class ClassDesc(object):
+
+ # default values
+ StaticFields = []
+ StaticMethods = []
+ Methods = []
+ IsValueType = False
+
_cliclass = None
def __eq__(self, other):
@@ -131,7 +135,8 @@
# construct OOTYPE and CliClass
# no superclass for now, will add it later
TYPE = NativeInstance('[mscorlib]', namespace, name, None, {}, {})
- Class = CliClass(TYPE, {})
+ TYPE._is_value_type = self.IsValueType
+ Class = CliClass(TYPE, {}, {})
self._cliclass = Class
# we need to check also for System.Array to prevent a circular recursion
if self.FullName in ('System.Object', 'System.Array'):
@@ -144,11 +149,13 @@
if self.IsArray:
TYPE._ELEMENT = get_ootype(self.ElementType)
- # add both static and instance methods
+ # add both static and instance methods, and static fields
static_meths = self.group_methods(self.StaticMethods, _overloaded_static_meth,
_static_meth, ootype.StaticMethod)
meths = self.group_methods(self.Methods, ootype.overload, ootype.meth, ootype.Meth)
+ fields = dict([(name, get_ootype(t)) for name, t in self.StaticFields])
Class._add_methods(static_meths)
+ Class._add_static_fields(fields)
TYPE._add_methods(meths)
return Class
Modified: pypy/dist/pypy/translator/cli/src/query.cs
==============================================================================
--- pypy/dist/pypy/translator/cli/src/query.cs (original)
+++ pypy/dist/pypy/translator/cli/src/query.cs Wed Jan 23 15:08:05 2008
@@ -60,8 +60,10 @@
outfile.WriteLine("desc.FullName = '{0}'", t.FullName);
outfile.WriteLine("desc.BaseType = '{0}'", GetBaseType(t));
outfile.WriteLine("desc.IsArray = {0}", t.IsArray);
+ outfile.WriteLine("desc.IsValueType = {0}", t.IsValueType);
PrintMethods("desc.StaticMethods", t.GetMethods(BindingFlags.Static|BindingFlags.Public|BindingFlags.DeclaredOnly));
PrintMethods("desc.Methods", t.GetMethods(BindingFlags.Instance|BindingFlags.Public|BindingFlags.DeclaredOnly));
+ PrintFields("desc.StaticFields", t.GetFields(BindingFlags.Static|BindingFlags.Public|BindingFlags.DeclaredOnly));
}
private static string GetBaseType(Type t)
@@ -118,6 +120,15 @@
outfile.WriteLine(" ]");
}
+ private static void PrintFields(string varname, FieldInfo[] fields)
+ {
+ outfile.WriteLine("{0} = [", varname);
+ // FieldName, RESULT
+ foreach(FieldInfo fld in fields)
+ outfile.WriteLine(" ('{0}', '{1}'),", fld.Name, GetOOType(fld.FieldType));
+ outfile.WriteLine(" ]");
+ }
+
private static bool IgnoreMethod(MethodInfo meth)
{
if (!meth.IsPublic)
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 Wed Jan 23 15:08:05 2008
@@ -432,6 +432,14 @@
res = self.interpret(fn, [False])
assert res == 42
+ def test_static_fields(self):
+ OpCodes = System.Reflection.Emit.OpCodes
+ def fn():
+ op = OpCodes.Add
+ return op.get_Name()
+ res = self.interpret(fn, [])
+ assert self.ll_to_string(res) == 'add'
+
class TestPythonnet(TestDotnetRtyping):
# don't interpreter functions but execute them directly through pythonnet
def interpret(self, f, args, backendopt='ignored'):
Modified: pypy/dist/pypy/translator/cli/test/test_query.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_query.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_query.py Wed Jan 23 15:08:05 2008
@@ -23,6 +23,10 @@
assert System._name == 'System'
assert hasattr(CLR, 'System')
+def test_static_fields():
+ desc = query.get_class_desc('System.Reflection.Emit.OpCodes')
+ assert ('Add', 'System.Reflection.Emit.OpCode') in desc.StaticFields
+
def test_System_Object():
Object = CLR.System.Object
assert Object._name == '[mscorlib]System.Object'
More information about the Pypy-commit
mailing list