From arigo at codespeak.net Thu Jun 1 20:41:17 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 1 Jun 2006 20:41:17 +0200 (CEST) Subject: [pypy-svn] r28060 - pypy/extradoc/talk/dls2006 Message-ID: <20060601184117.A6EFD10070@code0.codespeak.net> Author: arigo Date: Thu Jun 1 20:41:16 2006 New Revision: 28060 Modified: pypy/extradoc/talk/dls2006/paper.tex Log: Minor tweaks on the paper. Modified: pypy/extradoc/talk/dls2006/paper.tex ============================================================================== --- pypy/extradoc/talk/dls2006/paper.tex (original) +++ pypy/extradoc/talk/dls2006/paper.tex Thu Jun 1 20:41:16 2006 @@ -156,11 +156,12 @@ \begin{enumerate} \item We take as input RPython function objects,\footnote{The input to our translation chain are indeed loaded runtime function objects, - not source code or ASTs. This enables a form of staged + not source code nor ASTs. This enables a form of staged programming in which we can use unrestricted Python for meta-programming purposes at load time: the whole of - the source program -- as Python program -- produces the RPython - program input to the tool-chain as the object graph loaded in + the source program -- as a Python program -- produces the RPython + program which is sent to the tool-chain in the form of its object + graph loaded in memory. This includes both the relevant functions and prebuilt data.} and convert them to control flow graphs -- a structure amenable to analysis. These flow graphs contain polymorphic @@ -215,7 +216,7 @@ We have two alternatives, each implemented as a transformation step. The first one inserts naive reference counting throughout the whole -program's graphs, which without further optimizations gives exceedingly +program's graphs, which without further optimizations gives a somewhat bad performance (it should be noted that the CPython interpreter is also based on reference counting, and experience suggests that it was not a bad choice in this particular case). @@ -223,9 +224,10 @@ The other, and better, alternative is an exact GC, coupled with a transformation, the \textit{GC transformer}. It inputs C-level-typed graphs and replaces all \texttt{malloc} operations with calls to a garbage -collector's allocation routine. It can inspect all the graphs to discover the -\texttt{struct} types in use by the program, and assign a unique type id to -each of them. These type ids are collected in internal tables that +collector's allocation routine. +The transformation inspects all the graphs to discover the +\texttt{struct} types in use by the program, and assigns a unique type id to +each of them. These type ids are then collected in internal tables that describe the layout of the structures, e.g.\ their sizes and the location of the pointer fields. @@ -236,7 +238,7 @@ Another example is the exception transformer, which transforms graphs that still contain implicit exception handling into a form suitable for C (currently based on a global flag to signal the presence of an -exception, set and checked around selected function calls). +exception, which is set and checked around selected function calls). Finally, currently under development is a variant of the very first transformation step, for use when targeting higher-level, @@ -250,7 +252,7 @@ C-level flow graphs, where the object-oriented features of RPython (classes and instances) become manipulations of C structs with explicit virtual table pointers. By contrast, for OO environments the -transformation step is called the \textit{OOTyper}: it targets a simple +transformation step is called the \textit{OOTyper:} it targets a simple object-oriented type system, and preserves the classes and instances of the original RPython program. The LLTyper and OOTyper still have much code in common, to convert the more Python-specific features like @@ -281,8 +283,8 @@ front-end, using this time the transformation's target (lower-level) type system during the type inference. In other words, we can write plain Python code that manipulates objects that conform to the -lower-level type system, and have these functions automatically -transformed into appropriately typed graphs. +lower-level type system, and turn these functions into graph that are +directly typed in this lower-level type system. For example, \texttt{ll\textunderscore{}append()} in figure \ref{fig_llappend} is a Python function @@ -320,7 +322,7 @@ the restriction of having to use pointer-like and address-like objects, Python remains more expressive than, say, C to write a GC (the work on the Jikes RVM's GC \cite{JikesGC} was the inspiration to try to -express GCs in Python, see section \ref{relatedwork}). +express GCs in Python; see section \ref{relatedwork}). In the sequel, we will call \textit{system code} functions written in Python that are meant to be analysed by the front-end. For the @@ -336,7 +338,7 @@ operations at RPython level is, comparatively speaking, quite large: all list and dictionary operations, instance and class attribute accesses, many string processing methods, a good subset of all Python -built-in functions... Compared to other approaches +built-in functions... Compared with other approaches (e.g.\ Squeak \cite{Squeak}), we do not try to minimize the number of primitives -- at least not at the source level. It is fine to have many primitives at any high enough @@ -375,7 +377,7 @@ % \begin{enumerate} \item The types, which we use to tag the variables of the graphs at - the given level (types are actually annotated, self-recursive + the given level (types are actually annotated self-recursive formal terms, and would have been implemented simply as such if Python supported them directly). @@ -389,7 +391,7 @@ The emulating instances provide a concrete implementation of these operations that works in normal Python; the types involved in the operations are also known to the type inference engine when it -analyses system code like the helpers of figure \ref{fig_llappend}. +analyses system code like the helper of figure \ref{fig_llappend}. Now, clearly, the purpose of types like a ``C-like struct'' or a ``C-like array'' is to be translated to a real \texttt{struct} or array declaration by @@ -412,10 +414,10 @@ The third reason is fundamental: we use these emulating objects to \textit{represent} pre-built objects at that level. For example, the GC -transformer instantiates the objects emulating C arrays for the internal -type id tables, and it fills them with the correct values. These array -objects are then either used directly when testing the GC, or translated -by the C back-end into static pre-initialized arrays. +transformer instantiates an object emulating a C array for the internal +type id table, and fills it with the correct values. This array +object is then either used directly when testing the GC, or translated +by the C back-end into a static pre-initialized array. @@ -457,11 +459,11 @@ Remember that building the control flow graphs is not done, as one might first expect, by following a function at the syntactic level. Instead, -the whole program is imported in a normal Python interpreter; the full -Python language is used at this point as a kind of preprocessor with +the whole program is imported in a normal Python interpreter -- the full +Python language is used as a kind of preprocessor with meta-programming capabilities. Once the program is imported, the object data in memory consists of Python function objects in bytecode format, -and any other kind of objects created at import-time, like class +as well as any other kind of objects created at import-time, like class objects, prebuilt instances of those, prebuilt tables, and so on. Note that these objects have typically no text representation any more; for example, cyclic data structures may have been built at this point. The @@ -483,22 +485,21 @@ \label{fig_screenshot} \end{figure} -The actual transformation from function objects -- i.e.\ bytecode -- to -flow graph is performed by the Flow Object Space, a short but generic -plug-in component for the Python interpreter of PyPy. The architecture -of our Python interpreter is shown in figure \ref{interpobjspace}. - \begin{figure} \centering - \label{interpobjspace} \begin{tabular}{|c|c|} \hline \multicolumn{2}{|c|}{\vphantom{\Large X}forest of bytecode objects from the application} \\ \hline \multicolumn{2}{|c|}{\vphantom{\Large X}Python bytecode interpreter} \\ \hline \vphantom{\Large X} Standard Object Space & Flow Object Space \\ \hline \end{tabular} \caption{the interpreter and object spaces.} + \label{fig_interpobjspace} \end{figure} +The actual transformation from function objects -- i.e.\ bytecode -- to +flow graph is performed by the Flow Object Space, a short but generic +plug-in component for the Python interpreter of PyPy. The architecture +of our Python interpreter is shown in figure \ref{fig_interpobjspace}. Note that the left column, i.e.\ the bytecode interpreter and the Standard Object Space, form the full Python interpreter of PyPy. It is an RPython program, and the whole purpose of the translation process is @@ -522,7 +523,7 @@ \begin{figure*} \centering -\includegraphics[scale=0.75]{image/flowlattice.pdf} +\includegraphics[scale=0.667]{image/flowlattice.pdf} \caption{the lattice order of the flow object space.} \label{flowlattice} \end{figure*} @@ -580,7 +581,9 @@ form, an extension of Static Single Assignment\cite{SSA}: each variable is only used in exactly one basic block. All variables that are not dead at the end of a basic block are explicitly carried over to the next -block and renamed. +block and renamed, as can be seen in figure \ref{fig_interpobjspace}: +each link carries a list of variables matching the formal input +arguments of its target block. While the Flow Object Space is quite a short piece of code -- its core functionality takes only 300 lines -- the detail of the interactions @@ -649,8 +652,9 @@ close a loop, the previously assigned types can be found to be too restrictive. In this case, we generalise them to allow for a larger set of possible run-time values, and schedule the block where they appear -for reflowing. The more general type can generalise the types of the -results of the variables in the block, which in turn can generalise the +for reflowing. +The newly generalised types can in turn generalise the types of other +result variables in the block, which in turn can generalise the types that flow into the following blocks, and so on. This process continues until a fixed point is reached. @@ -698,10 +702,18 @@ \item $NullableStr$, $NullableInst(class)$ -- a string or \texttt{None}; resp. an instance or \texttt{None}. \end{itemize} -% + Figures \ref{latticeoverall} and \ref{latticedetail} show how these -types are ordered to form a lattice. We mostly use its structure of -join-semilattice only. +types are ordered to form a lattice -- we generally use its structure of +join-semilattice only, but we will see in section \ref{precision} +a use case for the \textit{meet}. +Not shown on the figures are the list terms, which are simply +unordered with each other, and the Pbcs, which form a +classical finite set-of-subsets lattice. In addition, we have left +out a number of other annotations that are irrelevant for the basic +description of the annotator and straightforward to handle: +$Dictionary$, $Tuple$, $Float$, $UnicodePoint$, $Iterator$, etc. The +complete list is described in \cite{T}. \begin{figure} \centering @@ -712,15 +724,8 @@ \label{latticedetail} \end{figure} -All list terms for all variables are unordered. The Pbcs form a -classical finite set-of-subsets lattice. In addition, we have left -out a number of other annotations that are irrelevant for the basic -description of the annotator and straightforward to handle: -$Dictionary$, $Tuple$, $Float$, $UnicodePoint$, $Iterator$, etc. The -complete list is described in \cite{T}. - The type system moreover comes with a family of rules, which for every -operation and every sensible combination of input types describes the +operation and every meaningful combination of input types describes the type of its result variable. Let $V$ be the set of Variables that appear in the user program's flow graphs. Let $b$ be a map from $V$ to $A$; it is a ``binding'' that gives to each variable a type. The @@ -761,14 +766,17 @@ It is outside the scope of the present paper to describe the type inference engine and the rules more formally. The difficult points -involve mutable containers -- e.g.\ initially empty list that are -filled somewhere else -- and the discovery of instance attributes -- +involve mutable containers, e.g.\ initially empty list that are +filled somewhere else; the discovery of instance attributes -- in Python, classes do not declare upfront a fixed set of attributes -for their instances, let alone their types. Both these examples -require sophisticated reflowing techniques that invalidate existing +for their instances, let alone their types; and the discovery of +base class interfaces -- across a class hierarchy, some methods with +the same name may be called polymorphically by the program, while +others may be unrelated methods used internally by the subclasses. +These examples require reflowing techniques that invalidate existing types in already-annotated basic blocks, to account for the influence of more general types coming indirectly from a possibly distant part -of the program. The reader is referred to technical report \cite{D} +of the program. The reader is referred to \cite{D} for more information. @@ -804,11 +812,11 @@ handful of times, providing a close-to-linear practical complexity. We give formal termination and correctness proofs in \cite{D}, as well as -worst-case bounds and some experimental evidence of their practical -irrelevance. +worst-case bounds and common-case estimates. \subsection{Precision} +\label{precision} Of course, this would be pointless if the annotation did not give precise enough information for our needs. We must describe a detail of @@ -862,12 +870,12 @@ Inside the function graph, we propagate the \textit{join} of the types of the actual parameters of the call sites. We \textit{do} support specialization, however: we can generate several independently-annotated -copies of the flow graphs of certain functions. When annotating RPython +copies of the flow graph of certain functions. When annotating RPython programs, such specialization does not happen automatically: we rely on hints provided by the programmer in the source code, in the form of flags attached to function objects. As we had this trade-off in mind -when we wrote the Python interpreter of PyPy, we only had to add a dozen -or so hints in the end. +when we wrote the Python interpreter of PyPy, we only had to add about +a dozen hints in the end. This does not mean that automatic specialization policies are difficult to implement. Indeed, the simpler lower-level type systems rely quite @@ -876,20 +884,21 @@ case, because the types at this level are limited and mostly unordered, specializing all functions on their input argument's types works well. -At the level of RPython, on the other hand, the range of specializations -that make sense is much wider. We have used anything between -specialization by the type of an argument, to specialization by an -expected-to-be-constant argument value, to memoized functions that the +At the level of RPython, the range of specializations +that make sense is actually much wider. Although we only specialize a +very small subset of the functions, we use criteria as diverse as +specialization by the type of an argument, specialization by an +expected-to-be-constant argument value, memoized functions that the type inference engine will actually call during annotation and replace -by look-up tables, to complete overriding of the annotator's behavior in +by look-up tables, and even complete overriding of the annotator's behavior in extreme cases. In this sense, the need for manual specialization turned into an advantage, in term of simplicity and flexibility of implementing and using new specialization schemes. -This conclusion can be generalized. We experimented with a simple +This conclusion can be generalised. We experimented with a simple approach to type inference that works well in practice, and that can -very flexibly accomodate changes in the type system and even completely -different type systems. We think that the reasons for this success are +very flexibly accomodate small and big changes in the type system. +We think that the reasons for this success are to be found on the one hand in the (reasonable) restrictions we put on ourselves when designing the RPython language and writing the Python interpreter of PyPy in RPython, and on the other hand in an ad-hoc type From arigo at codespeak.net Thu Jun 1 21:06:22 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 1 Jun 2006 21:06:22 +0200 (CEST) Subject: [pypy-svn] r28061 - pypy/extradoc/talk/dls2006 Message-ID: <20060601190622.86A1510069@code0.codespeak.net> Author: arigo Date: Thu Jun 1 21:06:21 2006 New Revision: 28061 Modified: pypy/extradoc/talk/dls2006/paper.bib pypy/extradoc/talk/dls2006/paper.tex Log: Final tweaks. Modified: pypy/extradoc/talk/dls2006/paper.bib ============================================================================== --- pypy/extradoc/talk/dls2006/paper.bib (original) +++ pypy/extradoc/talk/dls2006/paper.bib Thu Jun 1 21:06:21 2006 @@ -19,7 +19,7 @@ location = {Albuquerque, Mexico}, doi = {http://doi.acm.org/10.1145/582153.582176}, publisher = {ACM Press}, - address = {New York, NY, USA}, + address = {\balancecolumns New York, NY, USA}, } @article{Miln, @@ -56,7 +56,6 @@ % Squeak/ PreScheme @inproceedings{Squeak, author = {Dan Ingalls and Ted Kaehler and John Maloney and Scott Wallace and -\balancecolumns Alan Kay}, title = {Back to the future: the story of Squeak, a practical Smalltalk written in itself}, booktitle = {OOPSLA '97: Proceedings of the 12th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications}, @@ -253,3 +252,12 @@ year = 2006, month = "March", } + + at InProceedings{LLVM:CGO04, + author = {Chris Lattner and Vikram Adve}, + title = "{LLVM: A Compilation Framework for Lifelong Program Analysis \& Transformation}", + booktitle = "{Proceedings of the 2004 International Symposium on Code Generation and Optimization (CGO'04)}", + address = {Palo Alto, California}, + month = {Mar}, + year = {2004} + } Modified: pypy/extradoc/talk/dls2006/paper.tex ============================================================================== --- pypy/extradoc/talk/dls2006/paper.tex (original) +++ pypy/extradoc/talk/dls2006/paper.tex Thu Jun 1 21:06:21 2006 @@ -922,7 +922,8 @@ Our tool-chain is capable of translating the Python interpreter of PyPy, written in RPython, currently producing either ANSI C code as -described before, or LLVM\footnote{The LLVM project is the realization +described before, or LLVM\footnote{ +The LLVM \cite{LLVM:CGO04} project is the realization of a portable assembler infrastructure, offering both a virtual machine with JIT capabilities and static compilation. Currently we are using the latter with its good high-level optimizations for PyPy.} @@ -933,8 +934,8 @@ translated interpreters are benchmarked using pystone (a Dhrystone 2.0 \cite{dhry20} derivative traditionally used by the Python community, although it is a rather poor benchmark) and the classical Richards -benchmark (ported to Python) and compared against CPython 2.4.3 \cite{cpy243} -results and are summarized in table \ref{perfsumm}. +benchmark (ported to Python) and compared against CPython 2.4.3 \cite{cpy243}. +Results are summarized in table \ref{perfsumm}. \begin{table*} % the layout of this table isn't wonderful, but it's probably OK. @@ -964,21 +965,21 @@ follows: {\bf pypy-c:} - The simplest variant; translated to C code with no explicit memory + the simplest variant; translated to C code with no explicit memory management, and linked with the Boehm conservative GC. {\bf pypy-c-thread:} - The same, with OS thread support enabled (thread support is kept + the same, with OS thread support enabled (thread support is kept separate for measurement purposes because it has an impact on the GC performance). {\bf pypy-c-stackless:} - The same as pypy-c, plus the ``stackless transformation'' step which + the same as pypy-c, plus the ``stackless transformation'' step which modifies the flow graph of all functions to allow them to save and restore their local state, as a way to enable coroutines. {\bf pypy-c-gcframework:} - In this variant, the ``gc transformation'' step inserts explicit + in this variant, the ``gc transformation'' step inserts explicit memory management and a simple mark-and-sweep GC implementation. The resulting program is not linked with Boehm. Note that it is not possible to find all roots from the C stack in portable C; instead, @@ -986,7 +987,7 @@ to an alternate stack around each subcall. {\bf pypy-c-stackless-gcframework:} - This variant combines the ``gc transformation'' step with the + this variant combines the ``gc transformation'' step with the ``stackless transformation'' step. The overhead introduced by the stackless feature is theoretically balanced with the removal of the overhead of pushing and popping roots explicitly on an alternate @@ -998,13 +999,13 @@ 6MB for the basic pypy-c. Making it smaller is work in progress.) {\bf pypy-llvm-c:} - The same as pypy-c, but using the LLVM back-end instead of the C + the same as pypy-c, but using the LLVM back-end instead of the C back-end. The LLVM assembler-compiler gives the best results when - as we do here -- it optimizes its input and generates again C code, which is fed to GCC. {\bf pypy-llvm-c-prof:} - The same as pypy-llvm-c, but using GCC's profile-driven + the same as pypy-llvm-c, but using GCC's profile-driven optimizations. The speed difference with CPython 2.4.3 can be explained at two levels. @@ -1013,12 +1014,15 @@ seeks flexibility and high abstraction levels. The other, probably dominant, factor is that various indices show that our approach places a very high load on the GC and on the memory caches of the machine. The -Boehm GC is known to be less efficient than more customized approach; +Boehm GC is known to be less efficient than a more customized approach; kernel-level profiling shows that pypy-c typically spends 30\% of its time in the Boehm library. Our current, naively simple mark-and-sweep -GC is manages to be a bit worse. The interaction with processor caches is also -hard to predict and account for; in general, we tend to produce -relatively large amounts of code and prebuilt data. +GC manages to be a bit worse. The interaction with processor caches is +also hard to predict and account for; in general, we tend to produce +quite large amounts of code and prebuilt data. The overall performance +is still reasonable: some variants are within the same order of +magnitude as CPython, while others trade a slow-down for functionalities +not available in CPython. \subsection{Translation times} @@ -1076,10 +1080,12 @@ As described in section \ref{experimentalresults}, the performance of -the compiled Python interpreters is still not up to competing with the +the compiled Python interpreters is not yet up to competing with the well-established CPython. We are always working to improve matters, -considering new optimizations and better GCs. Also, the OOTyper and -back-ends for CLI/.NET and Smalltalk/Squeak are currently in progress. +considering new optimizations and better GCs. + +Current work also includes the OOTyper and back-ends for CLI/.NET and +Smalltalk/Squeak, all in-progress. \subsection{JIT Specializer} @@ -1092,7 +1098,7 @@ To achieve high performance for dynamic languages such as Python, the proven approach is to use dynamic compilation techniques, i.e.\ to write -JITs. With direct techniques, this is however a major endeavour, and +JITs. With direct techniques, this is a major endeavour, and increases the effort involved in further evolution of the language. In the context of the PyPy project, we are now exploring -- as we planned @@ -1195,8 +1201,8 @@ progress, but given that many of the initial components are shared with the existing stack of transformations leading to C, we are confident that this work will soon give results. Moreover, we believe that these -results will show reasonable efficiency, because the back-ends for VMs -like Squeak and .NET can take advantage of high-level input (as opposed +results will show reasonable efficiency, because our back-ends for VMs +like Squeak and .NET can take advantage of a high-level input (as opposed to trying to translate, say, C-like code to Smalltalk). A desirable property of our approach is to allow a given language and VM From ale at codespeak.net Fri Jun 2 10:31:53 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 2 Jun 2006 10:31:53 +0200 (CEST) Subject: [pypy-svn] r28069 - pypy/extradoc/talk/LaTe_Lunch2006 Message-ID: <20060602083153.09F3310060@code0.codespeak.net> Author: ale Date: Fri Jun 2 10:31:52 2006 New Revision: 28069 Added: pypy/extradoc/talk/LaTe_Lunch2006/ pypy/extradoc/talk/LaTe_Lunch2006/Ontology.odp (contents, props changed) pypy/extradoc/talk/LaTe_Lunch2006/Ontology.pdf (contents, props changed) Log: A talk I gave at DFKI about OWL, not much about PyPy Added: pypy/extradoc/talk/LaTe_Lunch2006/Ontology.odp ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/LaTe_Lunch2006/Ontology.pdf ============================================================================== Binary file. No diff available. From ale at codespeak.net Fri Jun 2 10:33:46 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 2 Jun 2006 10:33:46 +0200 (CEST) Subject: [pypy-svn] r28070 - pypy/dist/pypy/doc Message-ID: <20060602083346.F368A1006D@code0.codespeak.net> Author: ale Date: Fri Jun 2 10:33:45 2006 New Revision: 28070 Added: pypy/dist/pypy/doc/pyontology.txt Log: Random ramblings on OWL posing as the begining of documentationfor pyontology Added: pypy/dist/pypy/doc/pyontology.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/pyontology.txt Fri Jun 2 10:33:45 2006 @@ -0,0 +1,115 @@ +================================ +Documentation of pyontology.py +================================ + +.. contents:: +.. sectnum:: + +Introduction +============= + + +The fundamental concepts of OWL (Web Ontology Language) are: + +Classes +------- + +Classes are defined in the following ways: + + 1. a class identifier (a URI reference) (ie. (?, owl:type, owl:Classes) triples) + 2. an exhaustive enumeration of individuals that together form the instances of a class + 3. a property restriction + 4. the intersection of two or more class descriptions (intersectionOf predicate) + 5. the union of two or more class descriptions (unionOf predicate) + 6. the complement of a class description (complementOf predicate) + +Properties +---------- + +Properties can be of the types owl:ObjectProperty, owl:DatatypeProperty, owl:FunctionalProperty, +owl: InverseFunctionalProperty, owl:SymmetricProperty. + +Properties can have restrictions on them, either value restrictions, cardinality restrictions or global +restrictions in the form of domain and range restrictions. + + +Individuals +----------- + +Individuals are instances of classes. Individuals are created either with a owl:type predicate with object being userdefined class, by a owl:type, owl:Thing triple or by a triple with a userdefined property as predicate. Individuals has to be able to been compared. The comparison can return true, false or unknown. Individuals are equal if it has the same names, or there has been a owl:sameAs triple relating the two Individuals. Two Individuals compare unequal (return false) if there has been a owl:differentFrom (or a Alldifferent) triple. + + +Implementation +=============== + +The Ontology is read from a file (either in RDF-XML or N3 format) into a RDFLIB Graph. The triples of the +Graph are considered individually by calling the methods on the Ontology class. + +Since the ordering of triples is random the final processing has to be postponed until all triples have been +considered. + +When all triples have been processed the semantics of the Ontology will be contained in the objects in self.variables. In order to complete the conversion from the OWL ontology to a constraint problem the finish method of the objects needs to be called. + +The result of considering all the triples is a constraint problem. A constraint problem cosists of variables domains an constraints. The variables of the OWL constraint problem are the names of the userdefined classses and userdefined properties. Each variable has a domain which hold the individuals. The constraints makes relations between variables. By setting the domain of each variables, which have an empty domain (meaningthat it have no explicit individuals) to the domain of everything (owl:Thing or owl:Property for properties) the constraints can narrow the domain to the subset that satisfies the constraints imposed on this class. + +The domains of properties contain tuples of individual and value, so the triple (Peter, hasParent, Mary) will put the tuple (Peter, Mary) into the domain of the property hasParent. + +Some special variables and domains are created to enable to infer facts on Ontologies that have no individuals. + +Restrictions +------------ + +Restrictions are anonymous classes that define restrictions on properties. The individuals that satisfies The restriction are the Individuals that shall be in the domain of this anonymous class. + +Cardinality restrictions +------------------------ + +Cardinality restrictions have two implications. The can be used to assert the restrictions on individuals, +to check that an individual of class fulfills the restriction, and to check the schema of a class is consistent. +That is to check for example that a certain class is not defined to have a maxCardinality lower than a +minCardinality for a certain property. + +maxCardinality +-------------- + +The result of a maxCardinality restriction is all the individuals that have at most the number of values for the property as stated in the object of the triple. + +This is achieved by adding a constraint that will use the "getValuesPrKey" method of the property domain and remove the individuals that do not satisfy the constraint from the domain of the restriction. The constraint is implementedby the class CardinalityConstraint, which takes a property class, a restriction name, a val and a comparison string (can be '<','>' or '='). + +To check for the consistency in absence of individuals, a special variable is created with the domain of range(val + 1). This is the domain of possible values for the cardinality. + +As the name of the property might not be known when the triple containing the cardinality restriction is being processed the actual addition of the domains and constraint is being deferred to the finish method of the restriction class. + +hasValue +-------- + +The hasvalue restriction defines the set of individuals which have the value for the property concerned. + +subClassOf +---------- + +The subClassOf triple states that the set of individuals of the subject class shall be a subset of the setof individuals of the object class. + +When a triple with predicate "subClassOf" is considered, we add the object to the bases attribute of the subjecct class. When the finish method is called the domains and constraints of the subject class will be augmented with those of the object class. + +equivalentClass +---------------- + +The equivalentClass states that the subject class and object class contain the same elements. + +If the two classes has a different number of elements it must mean that all elements must be the same. + + +The Ontology class +------------------- + +ClassDomain.finish() ++++++++++++++++++++++ + 1. Evaluate the uninitialised constraints of the class. + sadsda + + 2. Loop through the bases list and for each class: + call finish() + instantiate the constraints found in the baseclasses + remove BNodes from the domain store + From mwh at codespeak.net Fri Jun 2 11:31:56 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Jun 2006 11:31:56 +0200 (CEST) Subject: [pypy-svn] r28080 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060602093156.8448B1006B@code0.codespeak.net> Author: mwh Date: Fri Jun 2 11:31:49 2006 New Revision: 28080 Added: pypy/extradoc/sprintinfo/ddorf2006/day0-issue-status.txt Log: the result of charging through all the open 0.9 issues on the first morning of the sprint. Added: pypy/extradoc/sprintinfo/ddorf2006/day0-issue-status.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/ddorf2006/day0-issue-status.txt Fri Jun 2 11:31:49 2006 @@ -0,0 +1,137 @@ +Planning/status for the first morning +========================================= + +Holger is AWOL, Christian is doing paperwork, Armin and Nik aren't here yet... + +Looking at the 0.9 issues, critical first: + +* 111 test reports / platform sorted : + + Holger! + +* 194 Advance rctypes approach to become usable + + Basically done (ask Armin) + +* 197 implement __del__ support for framework gcs + + Needs more testing (particularly with the stacklessgc), but we think this + works. + +* 198 implement tasklet pickling + + No problem at all! hahahaha + + - finish needed object type pickling/unpickling + - finish and integrate explict resume points support + - use the latter to implement restarting after unpickling + (likely hack! hack! hack! until it works) + + Tasklet cloning has become completely different, that kind of works now + (needs more testing). + +* 30 dist -> trunk, dist becomes newest release + + Not something to do at a sprint. + +* 81 weakrefs + + This is about 90% done, only the other 90% to go :) + Many of the CPython tests are hopeless, we need + modified-2.4.1/test/test_weakref.py. Exposing gc.collect() would help. + +Now the bugs: + +* 137 Control-C runtime support + + No progress here. Hopefully not that hard. + +* 181 time module is incomplete + + Will be done by the SoC ctypes project we hope :) + +* 182 compiler crash on windows + + We need a windows user for this? + +* 183 windows build needs superuser + + This too. + +* 184 compiled pypy-c is host dependent + + How much of this do we want to do for 0.9? + +* 195 Make website doc generation more reliable + + Holger! + +* 21 _file.py needs more tests + + Yes, it does. + +* 22 app-level docstrings missing everywhere + + Should be an easy sprint task. + +* 3 fix real bugs exposed by test_descr + + We can do this now we have weakrefs, but it's a bonus point type task. + +* 95 create a glossary for common PyPy terms + + Should be done, at last. + +Features: + +* 101 Tool for discovering REV that broke translation + + We're surviving without it ok, eric's nightly benchmarks help. + +* 103 finish posix module + + SoC! + +* 145 implement -m command line option + + Probably not critical for 0.9. + +* 199 finish app-level stackless support + + This should be rated 'critical'! Not sure what the status is. + +* 200 moving gcs + + Another GC bonus point. Probably not going to happen for 0.9. + +* 34 running translator goals per revision + + See comments on issue101. + +* 41 roadmap till PyPy 1.x + + Well, yes. We need to have this by the end of the sprint, I guess. + +* 44 have a doc chapter for CPython-dev'ers + + This is part of getting the ext-compiler to be usable in some sense. + There should be an "0.9 documentation" issue. + +* 74 come up with nice pictures/diagrams + + It's not so much coming up with these things as actually linking to them + from the docs that remains to be done. + +Wish: + +* 133 remove unused files + + Part of preparing for the release. + +* 4 code integrity in documentation + + No closer to fixing the hard problems at the moment? + +* 6 Allow users to specify 'allwaysnosy' + + This is a codespeak issue, mainly. From mwh at codespeak.net Fri Jun 2 12:11:27 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Jun 2006 12:11:27 +0200 (CEST) Subject: [pypy-svn] r28082 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060602101127.0807610060@code0.codespeak.net> Author: mwh Date: Fri Jun 2 12:11:27 2006 New Revision: 28082 Added: pypy/extradoc/sprintinfo/ddorf2006/planning.txt - copied, changed from r28080, pypy/extradoc/sprintinfo/ddorf2006/day0-issue-status.txt Log: planning.txt for the morning From antocuni at codespeak.net Fri Jun 2 14:03:21 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 2 Jun 2006 14:03:21 +0200 (CEST) Subject: [pypy-svn] r28090 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem Message-ID: <20060602120321.0AF811006F@code0.codespeak.net> Author: antocuni Date: Fri Jun 2 14:03:20 2006 New Revision: 28090 Modified: pypy/dist/pypy/rpython/lltypesystem/rdict.py pypy/dist/pypy/rpython/ootypesystem/rdict.py pypy/dist/pypy/rpython/rdict.py Log: (antocuni, nikh) Don't use externalvsinternal repr distinction in ootypesystem because it's not needed. Modified: pypy/dist/pypy/rpython/lltypesystem/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rdict.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rdict.py Fri Jun 2 14:03:20 2006 @@ -60,6 +60,9 @@ self._custom_eq_hash_repr = custom_eq_hash # setup() needs to be called to finish this initialization + def _externalvsinternal(self, rtyper, item_repr): + return rmodel.externalvsinternal(self.rtyper, item_repr) + def _setup_repr(self): if 'key_repr' not in self.__dict__: key_repr = self._key_repr_computer() Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rdict.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rdict.py Fri Jun 2 14:03:20 2006 @@ -44,6 +44,9 @@ self._custom_eq_hash_repr = custom_eq_hash # setup() needs to be called to finish this initialization + def _externalvsinternal(self, rtyper, item_repr): + return item_repr, item_repr + def _setup_repr(self): if 'key_repr' not in self.__dict__: key_repr = self._key_repr_computer() Modified: pypy/dist/pypy/rpython/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/rdict.py (original) +++ pypy/dist/pypy/rpython/rdict.py Fri Jun 2 14:03:20 2006 @@ -49,7 +49,7 @@ if self.custom_eq_hash: return item_repr, item_repr else: - return rmodel.externalvsinternal(self.rtyper, item_repr) + return self._externalvsinternal(self.rtyper, item_repr) def pickkeyrepr(self, key_repr): external, internal = self.pickrepr(key_repr) From ale at codespeak.net Fri Jun 2 14:18:32 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 2 Jun 2006 14:18:32 +0200 (CEST) Subject: [pypy-svn] r28092 - pypy/dist/pypy/objspace/std Message-ID: <20060602121832.62DC91006F@code0.codespeak.net> Author: ale Date: Fri Jun 2 14:18:31 2006 New Revision: 28092 Modified: pypy/dist/pypy/objspace/std/complexobject.py Log: The str of complex made test_compare fail Modified: pypy/dist/pypy/objspace/std/complexobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/complexobject.py (original) +++ pypy/dist/pypy/objspace/std/complexobject.py Fri Jun 2 14:18:31 2006 @@ -271,10 +271,10 @@ def str__Complex(f): if not f.real: - return repr(possint(f.imag))+'j' + return str(possint(f.imag))+'j' imag = f.imag sign = ((imag >= 0) and '+') or '' - return "'("+repr(possint(f.real)) + sign + repr(possint(f.imag))+"j)'" + return '('+str(possint(f.real)) + sign + str(possint(f.imag))+'j)' """, filename=__file__) From ale at codespeak.net Fri Jun 2 14:33:14 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 2 Jun 2006 14:33:14 +0200 (CEST) Subject: [pypy-svn] r28094 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20060602123314.D0FEB10073@code0.codespeak.net> Author: ale Date: Fri Jun 2 14:33:13 2006 New Revision: 28094 Modified: pypy/dist/pypy/objspace/std/test/test_unicodeobject.py pypy/dist/pypy/objspace/std/unicodeobject.py Log: actually do hashes of empty unicode strings Modified: pypy/dist/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_unicodeobject.py Fri Jun 2 14:33:13 2006 @@ -20,6 +20,9 @@ check(u'a' + 'b', u'ab') check('a' + u'b', u'ab') + def test_hash(self): + assert hash(u'') == 0 + def test_join(self): def check(a, b): assert a == b Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Fri Jun 2 14:33:13 2006 @@ -197,6 +197,8 @@ def hash__Unicode(space, w_uni): if w_uni.w_hash is None: chars = w_uni._value + if len(chars) == 0: + return space.wrap(0) x = ord(chars[0]) << 7 for c in chars: x = intmask((1000003 * x) ^ ord(c)) From ale at codespeak.net Fri Jun 2 14:43:55 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 2 Jun 2006 14:43:55 +0200 (CEST) Subject: [pypy-svn] r28095 - pypy/dist/lib-python Message-ID: <20060602124355.A620510074@code0.codespeak.net> Author: ale Date: Fri Jun 2 14:43:55 2006 New Revision: 28095 Modified: pypy/dist/lib-python/conftest.py Log: test_genexps need _weakref Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Jun 2 14:43:55 2006 @@ -510,7 +510,7 @@ RegrTest('test_gdbm.py', enabled=False, dumbtest=1), RegrTest('test_generators.py', enabled=True, core=True), #rev 10840: 30 of 152 tests fail - RegrTest('test_genexps.py', enabled=True, core=True), + RegrTest('test_genexps.py', enabled=True, core=True, usemodules='_weakref'), RegrTest('test_getargs.py', enabled=False, dumbtest=1), RegrTest('test_getargs2.py', enabled=False), #rev 10840: ImportError: _testcapi From mwh at codespeak.net Fri Jun 2 15:05:29 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Jun 2006 15:05:29 +0200 (CEST) Subject: [pypy-svn] r28096 - in pypy/dist/pypy: rpython rpython/lltypesystem translator/stackless/test Message-ID: <20060602130529.65DC210073@code0.codespeak.net> Author: mwh Date: Fri Jun 2 15:05:28 2006 New Revision: 28096 Added: pypy/dist/pypy/translator/stackless/test/test_resume_point.py - copied, changed from r28094, pypy/branch/explicit_resume_pt_experiment/translator/stackless/test/test_resume_point.py Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/lltypesystem/lloperation.py pypy/dist/pypy/rpython/rstack.py Log: (pedronis, mwh) begin reimplementing the stuff from samuele's explicit_resume_pt_experiment branch in a less experimental way :) only annotation/rtyping stuff so far, no actual implementation Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Fri Jun 2 15:05:28 2006 @@ -428,6 +428,9 @@ def op_hint(self, x, hints): return x + def op_resume_point(self, *args): + pass + def op_decode_arg(self, fname, i, name, vargs, vkwds): raise NotImplementedError("decode_arg") Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Fri Jun 2 15:05:28 2006 @@ -343,6 +343,10 @@ 'yield_current_frame_to_caller': LLOp(canraise=(StackException,)), # can always unwind, not just if stackless gc + 'resume_point': LLOp(), + 'resume_state_create': LLOp(canraise=(MemoryError,), canunwindgc=True), + 'resume_state_invoke': LLOp(canraise=(Exception, StackException)), + # __________ misc operations __________ 'keepalive': LLOp(), Modified: pypy/dist/pypy/rpython/rstack.py ============================================================================== --- pypy/dist/pypy/rpython/rstack.py (original) +++ pypy/dist/pypy/rpython/rstack.py Fri Jun 2 15:05:28 2006 @@ -32,3 +32,102 @@ class frame_stack_top(object): def switch(self): raise NotImplementedError("only works in translated versions") + + +from pypy.rpython.extregistry import ExtRegistryEntry + +def resume_point(label, *args, **kwds): + pass + +class ResumePointFnEntry(ExtRegistryEntry): + _about_ = resume_point + + def compute_result_annotation(self, s_label, *args_s, **kwds_s): + from pypy.annotation import model as annmodel + return annmodel.s_None + + def specialize_call(self, hop, **kwds_i): + from pypy.rpython.lltypesystem import lltype + + assert hop.args_s[0].is_constant() + c_label = hop.inputconst(lltype.Void, hop.args_s[0].const) + args_v = hop.args_v[1:] + if 'i_returns' in kwds_i: + assert len(kwds_i) == 1 + returns_index = kwds_i['i_returns'] + v_return = args_v.pop(returns_index-1) + else: + assert not kwds_i + v_return = hop.inputconst(lltype.Void, None) + + hop.exception_is_here() + return hop.genop('resume_point', [c_label, v_return] + args_v, + hop.r_result) + +class ResumeState(object): + pass + +def resume_state_create(prevstate, label, *args): + raise RuntimeError("cannot resume states in non-translated versions") + +class ResumeStateCreateFnEntry(ExtRegistryEntry): + _about_ = resume_state_create + + def compute_result_annotation(self, s_prevstate, s_label, *args_s): + from pypy.annotation import model as annmodel + return annmodel.SomeExternalObject(ResumeState) + + def specialize_call(self, hop): + from pypy.rpython.lltypesystem import lltype + from pypy.rpython.rmodel import SimplePointerRepr + from pypy.translator.stackless.frame import STATE_HEADER + + assert hop.args_s[1].is_constant() + c_label = hop.inputconst(lltype.Void, hop.args_s[1].const) + + r = SimplePointerRepr(lltype.Ptr(STATE_HEADER)) + state_v = hop.inputarg(r, arg=0) + + args_v = hop.args_v[2:] + + hop.exception_is_here() + return hop.genop('resume_state_create', [c_label] + args_v, + hop.r_result) + +class ResumeStateEntry(ExtRegistryEntry): + _type_ = ResumeState + + def get_repr(self, rtyper, s_state): + from pypy.rpython.rmodel import SimplePointerRepr + from pypy.translator.stackless.frame import STATE_HEADER + from pypy.rpython.lltypesystem import lltype + return SimplePointerRepr(lltype.Ptr(STATE_HEADER)) + +def resume_state_invoke(type, state, **kwds): + raise NotImplementedError("only works in translated versions") + +class ResumeStateInvokeFnEntry(ExtRegistryEntry): + _about_ = resume_state_invoke + + def compute_result_annotation(self, s_type, s_state, **kwds): + from pypy.annotation.bookkeeper import getbookkeeper + assert s_type.is_constant() + return getbookkeeper().valueoftype(s_type.const) + + def specialize_call(self, hop, **kwds_i): + from pypy.rpython.lltypesystem import lltype + v_state = hop.args_v[0] + + if 'i_returns' in kwds_i: + assert len(kwds_i) == 1 + returns_index = kwds_i['i_returns'] + v_return = args_v.pop(returns_index-1) + else: + assert not kwds_i + v_return = hop.inputconst(lltype.Void, None) + + hop.exception_is_here() + return hop.genop('resume_state_invoke', [v_state, v_return], + hop.r_result) + + From ale at codespeak.net Fri Jun 2 15:10:53 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 2 Jun 2006 15:10:53 +0200 (CEST) Subject: [pypy-svn] r28097 - pypy/dist/lib-python Message-ID: <20060602131053.D494710073@code0.codespeak.net> Author: ale Date: Fri Jun 2 15:10:53 2006 New Revision: 28097 Modified: pypy/dist/lib-python/conftest.py Log: test_imp needs thread Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Jun 2 15:10:53 2006 @@ -540,7 +540,7 @@ RegrTest('test_imageop.py', enabled=False, dumbtest=1), RegrTest('test_imaplib.py', enabled=True, dumbtest=1), RegrTest('test_imgfile.py', enabled=False, dumbtest=1), - RegrTest('test_imp.py', enabled=True, core=True), + RegrTest('test_imp.py', enabled=True, core=True, usemodules='thread'), RegrTest('test_import.py', enabled=True, dumbtest=1, core=True), RegrTest('test_importhooks.py', enabled=True, core=True), RegrTest('test_inspect.py', enabled=True, dumbtest=1), From mwh at codespeak.net Fri Jun 2 15:47:28 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Jun 2006 15:47:28 +0200 (CEST) Subject: [pypy-svn] r28103 - in pypy/dist/pypy/translator/stackless: . test Message-ID: <20060602134728.0A51910036@code0.codespeak.net> Author: mwh Date: Fri Jun 2 15:47:26 2006 New Revision: 28103 Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/transform.py Log: (pedronis, mwh) a little code, and another test passes. Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Fri Jun 2 15:47:26 2006 @@ -68,7 +68,6 @@ def example(): f(one(),one()+one()) return 0 - py.test.skip("in-progress") e = py.test.raises(Exception, transform_stackless_function, example) assert e.value.args == ('not covered needed value at resume_point',) Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Fri Jun 2 15:47:26 2006 @@ -100,6 +100,10 @@ def operation_is_true(self, op): if op.opname == 'yield_current_frame_to_caller': return True + elif op.opname == 'resume_point': + return True + elif op.opname == 'resume_point_invoke': + return True return self.stackless_gc and LL_OPERATIONS[op.opname].canunwindgc def analyze_external_call(self, op): @@ -108,7 +112,18 @@ return callable in [ll_stack.ll_stack_unwind, ll_stack.ll_stack_capture, ll_stackless.ll_stackless_stack_frames_depth, ll_stackless.ll_stackless_switch] - + +def vars_to_save(block): + lastresult = block.operations[-1].result + args = [] + for l in block.exits: + for arg in l.args: + if isinstance(arg, model.Variable) \ + and arg is not lastresult \ + and arg not in args \ + and arg not in [l.last_exception, l.last_exc_value]: + args.append(arg) + return args class StacklessTransformer(object): @@ -228,6 +243,9 @@ self.c_gc_nocollect = model.Constant("gc_nocollect", lltype.Void) self.is_finished = False + + self.explicit_resume_points = {} + # register the prebuilt restartinfos for restartinfo in frame.RestartInfo.prebuilt: self.register_restart_info(restartinfo) @@ -405,9 +423,54 @@ if op.opname == 'yield_current_frame_to_caller': op = replace_with_call(self.yield_current_frame_to_caller_ptr) stackless_op = True - + if (op.opname in ('direct_call', 'indirect_call') or self.analyzer.operation_is_true(op)): + if op.opname == 'resume_point': + # in some circumstances we might be able to reuse + # an already inserted resume point + if i == len(block.operations) - 1: + link = block.exits[0] + else: + link = support.split_block_with_keepalive(block, i+1) + parms = op.args[1:] + if not isinstance(parms[0], model.Variable): + assert parms[0].value is None + parms[0] = None + args = vars_to_save(block) + for a in args: + if a not in parms: + raise Exception, "not covered needed value at resume_point" + if parms[0] is not None: # returns= case + res = parms[0] + args = [arg for arg in args if arg is not res] + else: + args = args + res = op.result + + (frame_type, + fieldnames) = self.frametyper.frame_type_for_vars(args) + + self.resume_points.append( + ResumePoint(res, args, tuple(block.exits), + frame_type, fieldnames)) + + field2parm = {} + for arg, fieldname in zip(args, fieldnames): + p = parms.index(arg) + field2parm[fieldname] = p-1 # ignore parm[0] + + label = op.args[0].value + self.explicit_resume_points[label] = { + 'restart': len(self.masterarray1) + len(self.resume_points)-1, + 'frame_type': frame_type, + 'restype': res.concretetype, + 'field2parm': field2parm, + } + block = link.target + i = 0 + continue + # trap calls to stackless-related suggested primitives if op.opname == 'direct_call': func = getattr(op.args[0].value._obj, '_callable', None) @@ -467,14 +530,7 @@ # function be called right at the end of the resuming # block, and that it is called even if the return # value is not again used. - args = [] - for l in block.exits: - for arg in l.args: - if isinstance(arg, model.Variable) \ - and arg is not op.result \ - and arg not in args \ - and arg not in [l.last_exception, l.last_exc_value]: - args.append(arg) + args = vars_to_save(block) save_block, frame_state_type, fieldnames = \ self.generate_save_block(args, var_unwind_exception) From ale at codespeak.net Fri Jun 2 16:26:27 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 2 Jun 2006 16:26:27 +0200 (CEST) Subject: [pypy-svn] r28104 - pypy/dist/lib-python/modified-2.4.1 Message-ID: <20060602142627.3A0A81006B@code0.codespeak.net> Author: ale Date: Fri Jun 2 16:26:25 2006 New Revision: 28104 Added: pypy/dist/lib-python/modified-2.4.1/stringprep.py - copied, changed from r28095, pypy/dist/lib-python/2.4.1/stringprep.py Log: We are actually using version 4.1.0 From antocuni at codespeak.net Fri Jun 2 16:30:27 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 2 Jun 2006 16:30:27 +0200 (CEST) Subject: [pypy-svn] r28105 - in pypy/dist/pypy/rpython: ootypesystem test Message-ID: <20060602143027.28B501006B@code0.codespeak.net> Author: antocuni Date: Fri Jun 2 16:30:26 2006 New Revision: 28105 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rlist.py pypy/dist/pypy/rpython/test/test_rlist.py Log: (antocuni, nikh) - Marked some tests as lltypesystem-specific - Removed two skip from tests that now are passing - Fixed a bug about list of void Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Fri Jun 2 16:30:26 2006 @@ -743,7 +743,8 @@ checked_args = [] for a, ARG in zip(args, self._TYPE.ARGS): try: - a = enforce(ARG, a) + if ARG is not Void: + a = enforce(ARG, a) except TypeError: raise TypeError,"calling %r with wrong argument types: %r" % (self._TYPE, args) checked_args.append(a) @@ -973,7 +974,7 @@ def ll_setitem_fast(self, index, item): # NOT_RPYTHON - assert typeOf(item) == self._TYPE._ITEMTYPE + assert self._TYPE._ITEMTYPE is Void or typeOf(item) == self._TYPE._ITEMTYPE assert typeOf(index) == Signed assert index >= 0 self._list[index] = item Modified: pypy/dist/pypy/rpython/ootypesystem/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rlist.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rlist.py Fri Jun 2 16:30:26 2006 @@ -27,9 +27,6 @@ # setup() needs to be called to finish this initialization def _externalvsinternal(self, rtyper, item_repr): - # EXPERIMENTAL: distinct internal and external repr are not - # needed in high level backends - #return externalvsinternal(rtyper, item_repr) return item_repr, item_repr def _setup_repr(self): @@ -101,7 +98,7 @@ c_resize = inputconst(ootype.Void, "_ll_resize") c_length = inputconst(ootype.Signed, len(items_v)) llops.genop("oosend", [c_resize, v_result, c_length], resulttype=ootype.Void) - + c_setitem = inputconst(ootype.Void, "ll_setitem_fast") for i, v_item in enumerate(items_v): ci = inputconst(Signed, i) Modified: pypy/dist/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rlist.py (original) +++ pypy/dist/pypy/rpython/test/test_rlist.py Fri Jun 2 16:30:26 2006 @@ -1017,7 +1017,6 @@ assert res == 17 def test_voidlist_fixed(self): - self._skip_oo('_freeze_') fr = Freezing() def f(): return len([fr, fr]) @@ -1025,7 +1024,6 @@ assert res == 2 def test_voidlist_nonfixed(self): - self._skip_oo('_freeze_') class Freezing: def _freeze_(self): return True @@ -1039,8 +1037,49 @@ res = self.interpret(f, []) assert res == 2 + def test_access_in_try(self): + def f(sq): + try: + return sq[2] + except ZeroDivisionError: + return 42 + return -1 + def g(n): + l = [1] * n + return f(l) + res = self.interpret(g, [3]) + assert res == 1 + + def test_access_in_try_set(self): + def f(sq): + try: + sq[2] = 77 + except ZeroDivisionError: + return 42 + return -1 + def g(n): + l = [1] * n + f(l) + return l[2] + res = self.interpret(g, [3]) + assert res == 77 + + +class TestLLtype(BaseTestRlist, LLRtypeMixin): + rlist = ll_rlist + + def test_memoryerror(self): + def fn(i): + lst = [0] * i + lst[i-1] = 5 + return lst[0] + res = self.interpret(fn, [1]) + assert res == 5 + res = self.interpret(fn, [2]) + assert res == 0 + self.interpret_raises(MemoryError, fn, [sys.maxint]) + def test_type_erase_fixed_size(self): - self._skip_oo('type erasing') class A(object): pass class B(object): @@ -1065,7 +1104,6 @@ assert r_A_list.lowleveltype == r_B_list.lowleveltype def test_type_erase_var_size(self): - self._skip_oo('type erasing') class A(object): pass class B(object): @@ -1092,48 +1130,6 @@ assert isinstance(r_B_list, self.rlist.ListRepr) assert r_A_list.lowleveltype == r_B_list.lowleveltype - - def test_access_in_try(self): - def f(sq): - try: - return sq[2] - except ZeroDivisionError: - return 42 - return -1 - def g(n): - l = [1] * n - return f(l) - res = self.interpret(g, [3]) - assert res == 1 - - def test_access_in_try_set(self): - def f(sq): - try: - sq[2] = 77 - except ZeroDivisionError: - return 42 - return -1 - def g(n): - l = [1] * n - f(l) - return l[2] - res = self.interpret(g, [3]) - assert res == 77 - - -class TestLLtype(BaseTestRlist, LLRtypeMixin): - rlist = ll_rlist - - def test_memoryerror(self): - def fn(i): - lst = [0] * i - lst[i-1] = 5 - return lst[0] - res = self.interpret(fn, [1]) - assert res == 5 - res = self.interpret(fn, [2]) - assert res == 0 - self.interpret_raises(MemoryError, fn, [sys.maxint]) class TestOOtype(BaseTestRlist, OORtypeMixin): From antocuni at codespeak.net Fri Jun 2 16:45:00 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 2 Jun 2006 16:45:00 +0200 (CEST) Subject: [pypy-svn] r28108 - pypy/dist/pypy/rpython/test Message-ID: <20060602144500.A52071006B@code0.codespeak.net> Author: antocuni Date: Fri Jun 2 16:44:59 2006 New Revision: 28108 Modified: pypy/dist/pypy/rpython/test/test_rlist.py Log: (antocuni, nikh) Yet another lltypesystem-specific test. Modified: pypy/dist/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rlist.py (original) +++ pypy/dist/pypy/rpython/test/test_rlist.py Fri Jun 2 16:44:59 2006 @@ -932,27 +932,6 @@ res = self.interpret(fn, [-2]) assert res == -1 - def test_no_unneeded_refs(self): - self._skip_oo('assert') - def fndel(p, q): - lis = ["5", "3", "99"] - assert q >= 0 - assert p >= 0 - del lis[p:q] - return lis - def fnpop(n): - lis = ["5", "3", "99"] - while n: - lis.pop() - n -=1 - return lis - for i in range(2, 3+1): - lis = self.interpret(fndel, [0, i]) - assert list_is_clear(lis, 3-i) - for i in range(3): - lis = self.interpret(fnpop, [i]) - assert list_is_clear(lis, 3-i) - def test_list_basic_ops(self): def list_basic_ops(i=int, j=int): l = [1,2,3] @@ -1130,6 +1109,26 @@ assert isinstance(r_B_list, self.rlist.ListRepr) assert r_A_list.lowleveltype == r_B_list.lowleveltype + + def test_no_unneeded_refs(self): + def fndel(p, q): + lis = ["5", "3", "99"] + assert q >= 0 + assert p >= 0 + del lis[p:q] + return lis + def fnpop(n): + lis = ["5", "3", "99"] + while n: + lis.pop() + n -=1 + return lis + for i in range(2, 3+1): + lis = self.interpret(fndel, [0, i]) + assert list_is_clear(lis, 3-i) + for i in range(3): + lis = self.interpret(fnpop, [i]) + assert list_is_clear(lis, 3-i) class TestOOtype(BaseTestRlist, OORtypeMixin): From antocuni at codespeak.net Fri Jun 2 16:48:52 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 2 Jun 2006 16:48:52 +0200 (CEST) Subject: [pypy-svn] r28110 - in pypy/dist/pypy/rpython: ootypesystem test Message-ID: <20060602144852.62B371006B@code0.codespeak.net> Author: antocuni Date: Fri Jun 2 16:48:50 2006 New Revision: 28110 Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py pypy/dist/pypy/rpython/test/test_rdict.py pypy/dist/pypy/rpython/test/test_rstr.py Log: (antocuni, nikh) Fixed a bug that prevented assertion to work. Don't longer skip some tests that make use of 'assert'. Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Fri Jun 2 16:48:50 2006 @@ -59,9 +59,15 @@ for desc in self.s_pbc.descriptions: if desc.find_source_for('__init__') is not None: unbound = desc.s_get_value(desc.getuniqueclassdef(), '__init__') - unbound, = unbound.descriptions - bound = unbound.bind_self(desc.getuniqueclassdef()) - inits.append(bound) + if isinstance(unbound, annmodel.SomePBC): + unbound, = unbound.descriptions + bound = unbound.bind_self(desc.getuniqueclassdef()) + inits.append(bound) + else: + assert isinstance(unbound, annmodel.SomeBuiltin) + # do nothing, because builtin __init__s (for + # example from exceptions such as Exception and + # AssertionError) do nothing. if inits: s_init = annmodel.SomePBC(inits) Modified: pypy/dist/pypy/rpython/test/test_rdict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rdict.py (original) +++ pypy/dist/pypy/rpython/test/test_rdict.py Fri Jun 2 16:48:50 2006 @@ -124,7 +124,6 @@ assert res == 42 def test_dict_itermethods(self): - self._skip_oo('assert') def func(): d = {} d['hello'] = 6 Modified: pypy/dist/pypy/rpython/test/test_rstr.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rstr.py (original) +++ pypy/dist/pypy/rpython/test/test_rstr.py Fri Jun 2 16:48:50 2006 @@ -239,7 +239,6 @@ assert res == fn(i, j) def test_find_with_start(self): - self._skip_oo('assert') def fn(i): assert i >= 0 return 'ababcabc'.find('abc', i) @@ -248,7 +247,6 @@ assert res == fn(i) def test_find_with_start_end(self): - self._skip_oo('assert') def fn(i, j): assert i >= 0 assert j >= 0 From ale at codespeak.net Fri Jun 2 16:50:24 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 2 Jun 2006 16:50:24 +0200 (CEST) Subject: [pypy-svn] r28112 - pypy/dist/lib-python Message-ID: <20060602145024.A9B491006B@code0.codespeak.net> Author: ale Date: Fri Jun 2 16:50:23 2006 New Revision: 28112 Modified: pypy/dist/lib-python/conftest.py Log: test_generators need _weakref and thread Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Jun 2 16:50:23 2006 @@ -508,7 +508,7 @@ RegrTest('test_future3.py', enabled=True, core=True), RegrTest('test_gc.py', enabled=True, dumbtest=1, usemodules='_weakref'), RegrTest('test_gdbm.py', enabled=False, dumbtest=1), - RegrTest('test_generators.py', enabled=True, core=True), + RegrTest('test_generators.py', enabled=True, core=True, usemodules='thread _weakref'), #rev 10840: 30 of 152 tests fail RegrTest('test_genexps.py', enabled=True, core=True, usemodules='_weakref'), RegrTest('test_getargs.py', enabled=False, dumbtest=1), From antocuni at codespeak.net Fri Jun 2 17:05:56 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 2 Jun 2006 17:05:56 +0200 (CEST) Subject: [pypy-svn] r28113 - pypy/dist/pypy/rpython/test Message-ID: <20060602150556.B792F1006B@code0.codespeak.net> Author: antocuni Date: Fri Jun 2 17:05:55 2006 New Revision: 28113 Modified: pypy/dist/pypy/rpython/test/test_rpbc.py pypy/dist/pypy/rpython/test/tool.py Log: (antocuni, nikh) - Refactored test_rpbc.py to take advantages of tool.py. - Don't skip some tests that now pass. Modified: pypy/dist/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rpbc.py (original) +++ pypy/dist/pypy/rpython/test/test_rpbc.py Fri Jun 2 17:05:55 2006 @@ -1,7 +1,8 @@ from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.test.test_llinterp import interpret - +from pypy.rpython.ootypesystem import ootype +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin class MyBase: def m(self, x): @@ -31,14 +32,14 @@ return self.x + y -class BaseTestRPBC: +class BaseTestRPBC(BaseRtypingTest): def test_easy_call(self): def f(x): return x+1 def g(y): return f(y+2) - res = interpret(g, [5], type_system=self.ts) + res = self.interpret(g, [5]) assert res == 8 def test_multiple_call(self): @@ -52,9 +53,9 @@ else: f = f2 return f(y+3) - res = interpret(g, [-1], type_system=self.ts) + res = self.interpret(g, [-1]) assert res == 3 - res = interpret(g, [1], type_system=self.ts) + res = self.interpret(g, [1]) assert res == 6 @@ -63,7 +64,7 @@ obj = MyBase() obj.z = a return obj.m(b) - res = interpret(f, [4, 5], type_system=self.ts) + res = self.interpret(f, [4, 5]) assert res == 9 def test_virtual_method_call(self): @@ -74,9 +75,9 @@ obj = MySubclass() obj.z = a return obj.m(b) - res = interpret(f, [1, 2.3], type_system=self.ts) + res = self.interpret(f, [1, 2.3]) assert res == 3.3 - res = interpret(f, [-1, 2.3], type_system=self.ts) + res = self.interpret(f, [-1, 2.3]) assert res == -3.3 def test_stranger_subclass_1(self): @@ -84,7 +85,7 @@ obj = MyStrangerSubclass() obj.z = 100 return obj.m(6, 7) - res = interpret(f1, [], type_system=self.ts) + res = self.interpret(f1, []) assert res == 42 def test_stranger_subclass_2(self): @@ -92,7 +93,7 @@ obj = MyStrangerSubclass() obj.z = 100 return obj.m(6, 7) + MyBase.m(obj, 58) - res = interpret(f2, [], type_system=self.ts) + res = self.interpret(f2, []) assert res == 200 @@ -100,32 +101,32 @@ def f(a): instance = MyBaseWithInit(a) return instance.a1 - assert interpret(f, [5], type_system=self.ts) == 5 + assert self.interpret(f, [5]) == 5 def test_class_init_2(self): def f(a, b): instance = MySubclassWithInit(a, b) return instance.a1 * instance.b1 - assert interpret(f, [6, 7], type_system=self.ts) == 42 + assert self.interpret(f, [6, 7]) == 42 def test_class_calling_init(self): def f(): instance = MySubclassWithInit(1, 2) instance.__init__(3, 4) return instance.a1 * instance.b1 - assert interpret(f, [], type_system=self.ts) == 12 + assert self.interpret(f, []) == 12 def test_class_init_w_kwds(self): def f(a): instance = MyBaseWithInit(a=a) return instance.a1 - assert interpret(f, [5], type_system=self.ts) == 5 + assert self.interpret(f, [5]) == 5 def test_class_init_2_w_kwds(self): def f(a, b): instance = MySubclassWithInit(a, b=b) return instance.a1 * instance.b1 - assert interpret(f, [6, 7], type_system=self.ts) == 42 + assert self.interpret(f, [6, 7]) == 42 def test_freezing(self): @@ -143,9 +144,9 @@ else: fr = None return g(fr) - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 5 - res = interpret(f, [-1], type_system=self.ts) + res = self.interpret(f, [-1]) assert res == 6 def test_call_frozen_pbc_simple(self): @@ -153,7 +154,7 @@ fr1.x = 5 def f(n): return fr1.mymethod(n) - res = interpret(f, [6], type_system=self.ts) + res = self.interpret(f, [6]) assert res == 11 def test_call_frozen_pbc_simple_w_kwds(self): @@ -161,7 +162,7 @@ fr1.x = 5 def f(n): return fr1.mymethod(y=n) - res = interpret(f, [6], type_system=self.ts) + res = self.interpret(f, [6]) assert res == 11 def test_call_frozen_pbc_multiple(self): @@ -175,9 +176,9 @@ else: fr = fr2 return fr.mymethod(n) - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 6 - res = interpret(f, [-1], type_system=self.ts) + res = self.interpret(f, [-1]) assert res == 5 def test_call_frozen_pbc_multiple_w_kwds(self): @@ -191,9 +192,9 @@ else: fr = fr2 return fr.mymethod(y=n) - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 6 - res = interpret(f, [-1], type_system=self.ts) + res = self.interpret(f, [-1]) assert res == 5 def test_is_among_frozen(self): @@ -209,9 +210,9 @@ else: fr = givefr2() return fr is fr1 - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res is False - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res is True def test_unbound_method(self): @@ -219,7 +220,7 @@ inst = MySubclass() inst.z = 40 return MyBase.m(inst, 2) - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert res == 42 def test_call_defaults(self): @@ -231,11 +232,11 @@ return g(1, 10) def f3(): return g(1, 10, 100) - res = interpret(f1, [], type_system=self.ts) + res = self.interpret(f1, []) assert res == 1+2+3 - res = interpret(f2, [], type_system=self.ts) + res = self.interpret(f2, []) assert res == 1+10+3 - res = interpret(f3, [], type_system=self.ts) + res = self.interpret(f3, []) assert res == 1+10+100 def test_call_memoized_function(self): @@ -257,9 +258,9 @@ fr = fr2 return getorbuild(fr) - res = interpret(f1, [0], type_system=self.ts) + res = self.interpret(f1, [0]) assert res == 7 - res = interpret(f1, [1], type_system=self.ts) + res = self.interpret(f1, [1]) assert res == 3 def test_call_memoized_function_with_bools(self): @@ -286,7 +287,7 @@ return getorbuild(fr, i % 2 == 0, i % 3 == 0) for n in [0, 1, 2, -3, 6]: - res = interpret(f1, [n], type_system=self.ts) + res = self.interpret(f1, [n]) assert res == f1(n) def test_call_memoized_cache(self): @@ -328,9 +329,9 @@ newfr = cache1.getorbuild(fr) return cache2.getorbuild(newfr) - res = interpret(f1, [0], type_system=self.ts) + res = self.interpret(f1, [0]) assert res == 3 - res = interpret(f1, [1], type_system=self.ts) + res = self.interpret(f1, [1]) assert res == 7 def test_call_memo_with_single_value(self): @@ -342,7 +343,7 @@ def f1(): A() # make sure we have a ClassDef return memofn(A) - res = interpret(f1, [], type_system=self.ts) + res = self.interpret(f1, []) assert res == 1 def test_call_memo_with_class(self): @@ -359,9 +360,9 @@ cls = FooBar FooBar() # make sure we have ClassDefs return memofn(cls) - res = interpret(f1, [1], type_system=self.ts) + res = self.interpret(f1, [1]) assert res == 1 - res = interpret(f1, [2], type_system=self.ts) + res = self.interpret(f1, [2]) assert res == 6 def test_rpbc_bound_method_static_call(self): @@ -372,7 +373,7 @@ m = r.meth def fn(): return m() - res = interpret(fn, [], type_system=self.ts) + res = self.interpret(fn, []) assert res == 0 def test_rpbc_bound_method_static_call_w_kwds(self): @@ -383,7 +384,7 @@ m = r.meth def fn(): return m(x=3) - res = interpret(fn, [], type_system=self.ts) + res = self.interpret(fn, []) assert res == 3 @@ -394,7 +395,7 @@ r = R() def fn(): return r.meth() - res = interpret(fn, [], type_system=self.ts) + res = self.interpret(fn, []) assert res == 0 def test_None_is_false(self): @@ -404,9 +405,9 @@ else: v = fn return bool(v) - res = interpret(fn, [1], type_system=self.ts) + res = self.interpret(fn, [1]) assert res is True - res = interpret(fn, [0], type_system=self.ts) + res = self.interpret(fn, [0]) assert res is False def test_classpbc_getattr(self): @@ -420,9 +421,9 @@ else: v = B return v.myvalue - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 123 - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 456 def test_function_or_None(self): @@ -437,11 +438,11 @@ else: return 12 - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 12 - res = interpret(f, [6], type_system=self.ts) + res = self.interpret(f, [6]) assert res == 12 - res = interpret(f, [7], type_system=self.ts) + res = self.interpret(f, [7]) assert res == 42 def test_classdef_getattr(self): @@ -456,9 +457,9 @@ else: v = B return v.myvalue - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 123 - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 456 def test_call_classes(self): @@ -470,9 +471,9 @@ else: cls = A return cls() - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert self.class_name(res) == 'A' - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert self.class_name(res) == 'B' def test_call_classes_with_init2(self): @@ -489,17 +490,15 @@ else: cls = A return cls(z) - res = interpret(f, [0, 5], type_system=self.ts) + res = self.interpret(f, [0, 5]) assert self.class_name(res) == 'A' assert self.read_attr(res, "z") == 5 - res = interpret(f, [1, -7645], type_system=self.ts) + res = self.interpret(f, [1, -7645]) assert self.class_name(res) == 'B' assert self.read_attr(res, "z") == -7645 assert self.read_attr(res, "extra") == 42 def test_conv_from_None(self): - if self.ts == "ootype": - py.test.skip("disabled while ootype string support is incomplete") class A(object): pass def none(): return None @@ -509,19 +508,19 @@ return none() else: return "ab" - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert not res - res = interpret(f, [0], type_system=self.ts) - assert ''.join(res.chars) == "ab" + res = self.interpret(f, [0]) + assert self.ll_to_string(res) == "ab" def g(i): if i == 1: return none() else: return A() - res = interpret(g, [1], type_system=self.ts) + res = self.interpret(g, [1]) assert not res - res = interpret(g, [0], type_system=self.ts) + res = self.interpret(g, [0]) assert self.class_name(res) == 'A' @@ -543,9 +542,9 @@ cls = b() return cls() - res = interpret(g, [0], type_system=self.ts) + res = self.interpret(g, [0]) assert self.class_name(res) == 'B' - res = interpret(g, [1], type_system=self.ts) + res = self.interpret(g, [1]) assert self.class_name(res) == 'A' def bc(j): @@ -561,11 +560,11 @@ cls = bc(j) return cls() - res = interpret(g, [0, 0], type_system=self.ts) + res = self.interpret(g, [0, 0]) assert self.class_name(res) == 'C' - res = interpret(g, [0, 1], type_system=self.ts) + res = self.interpret(g, [0, 1]) assert self.class_name(res) == 'B' - res = interpret(g, [1, 0], type_system=self.ts) + res = self.interpret(g, [1, 0]) assert self.class_name(res) == 'A' def test_call_starargs(self): @@ -582,15 +581,15 @@ return g(7, 17, 27) else: return g(10, 198, 1129, 13984) - res = interpret(f, [-1], type_system=self.ts) + res = self.interpret(f, [-1]) assert res == -100 - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 4 - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 6 - res = interpret(f, [2], type_system=self.ts) + res = self.interpret(f, [2]) assert res == 9 - res = interpret(f, [3], type_system=self.ts) + res = self.interpret(f, [3]) assert res == 13 def test_call_keywords(self): @@ -622,7 +621,7 @@ return g(b=7,c=11,a=13) for i in range(11): - res = interpret(f, [i], type_system=self.ts) + res = self.interpret(f, [i]) assert res == f(i) def test_call_star_and_keywords(self): @@ -657,7 +656,7 @@ for i in range(9): for x in range(1): - res = interpret(f, [i, x], type_system=self.ts) + res = self.interpret(f, [i, x]) assert res == f(i, x) def test_call_star_and_keywords_starargs(self): @@ -716,7 +715,7 @@ for i in range(21): for x in range(1): - res = interpret(f, [i, x], type_system=self.ts) + res = self.interpret(f, [i, x]) assert res == f(i, x) def test_conv_from_funcpbcset_to_larger(self): @@ -740,9 +739,9 @@ f = b() return f() - res = interpret(g, [0], type_system=self.ts) + res = self.interpret(g, [0]) assert res == 11 - res = interpret(g, [1], type_system=self.ts) + res = self.interpret(g, [1]) assert res == 7 def bc(j): @@ -758,11 +757,11 @@ cls = bc(j) return cls() - res = interpret(g, [0, 0], type_system=self.ts) + res = self.interpret(g, [0, 0]) assert res == 13 - res = interpret(g, [0, 1], type_system=self.ts) + res = self.interpret(g, [0, 1]) assert res == 11 - res = interpret(g, [1, 0], type_system=self.ts) + res = self.interpret(g, [1, 0]) assert res == 7 def test_call_special_starargs_method(self): @@ -776,7 +775,7 @@ s = Star(i) return s.meth(i, j) - res = interpret(f, [3, 0], type_system=self.ts) + res = self.interpret(f, [3, 0]) assert res == 5 def test_call_star_method(self): @@ -790,7 +789,7 @@ n = N(i) return n.meth(*(i, j)) - res = interpret(f, [3, 7], type_system=self.ts) + res = self.interpret(f, [3, 7]) assert res == 13 def test_call_star_special_starargs_method(self): @@ -804,7 +803,7 @@ n = N(i) return n.meth(*(i, j)) - res = interpret(f, [3, 0], type_system=self.ts) + res = self.interpret(f, [3, 0]) assert res == 5 def test_various_patterns_but_one_signature_method(self): @@ -827,9 +826,9 @@ r2 = x.meth(3, 2) r3 = x.meth(7, b=11) return r1+r2+r3 - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 1+3+2+7+11 - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 3*2+11*7 @@ -865,7 +864,7 @@ return c.method(x + 1) except E: return None - res = interpret(call, [0], type_system=self.ts) + res = self.interpret(call, [0]) def test_multiple_pbc_with_void_attr(self): class A: @@ -885,9 +884,9 @@ else: a = a2 return g(a) - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 42 - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 42 def test_function_or_none(self): @@ -905,11 +904,11 @@ if func: return func(y) return -1 - res = interpret(f, [1, 100], type_system=self.ts) + res = self.interpret(f, [1, 100]) assert res == 142 - res = interpret(f, [2, 100], type_system=self.ts) + res = self.interpret(f, [2, 100]) assert res == 184 - res = interpret(f, [3, 100], type_system=self.ts) + res = self.interpret(f, [3, 100]) assert res == -1 def test_pbc_getattr_conversion(self): @@ -934,7 +933,7 @@ y = pick23(i) return x.value, y.value for i in [0, 5, 10]: - res = interpret(f, [i], type_system=self.ts) + res = self.interpret(f, [i]) assert type(res.item0) is int # precise assert type(res.item1) is float assert res.item0 == f(i)[0] @@ -963,15 +962,13 @@ y = pick23(i) return x.value, y.value for i in [0, 5, 10]: - res = interpret(f, [i], type_system=self.ts) + res = self.interpret(f, [i]) assert type(res.item0) is int # precise assert type(res.item1) is float assert res.item0 == f(i)[0] assert res.item1 == f(i)[1] def test_pbc_imprecise_attrfamily(self): - if self.ts == "ootype": - py.test.skip("disabled while ootype string support is incomplete") fr1 = Freezing(); fr1.x = 5; fr1.y = [8] fr2 = Freezing(); fr2.x = 6; fr2.y = ["string"] def head(fr): @@ -982,12 +979,10 @@ else: fr = fr2 return head(fr1) + fr.x - res = interpret(f, [2], type_system=self.ts) + res = self.interpret(f, [2]) assert res == 8 + 6 def test_multiple_specialized_functions(self): - if self.ts == "ootype": - py.test.skip("disabled while ootype string support is incomplete") def myadder(x, y): # int,int->int or str,str->str return x+y def myfirst(x, y): # int,int->int or str,str->str @@ -1008,12 +1003,10 @@ n = g(40, 2) return len(s) * n for i in range(3): - res = interpret(f, [i], type_system=self.ts) + res = self.interpret(f, [i]) assert res == f(i) def test_specialized_method_of_frozen(self): - if self.ts == "ootype": - py.test.skip("disabled while ootype string support is incomplete") class space: def _freeze_(self): return True @@ -1035,14 +1028,12 @@ w1 = sp.wrap('hello') w2 = sp.wrap(42) return w1 + w2 - res = interpret(f, [1], type_system=self.ts) - assert ''.join(res.chars) == 'tag1:hellotag1:< 42 >' - res = interpret(f, [0], type_system=self.ts) - assert ''.join(res.chars) == 'tag2:hellotag2:< 42 >' + res = self.interpret(f, [1]) + assert self.ll_to_string(res) == 'tag1:hellotag1:< 42 >' + res = self.interpret(f, [0]) + assert self.ll_to_string(res) == 'tag2:hellotag2:< 42 >' def test_specialized_method(self): - if self.ts == "ootype": - py.test.skip("disabled while ootype string support is incomplete") class A: def __init__(self, tag): self.tag = tag @@ -1062,10 +1053,10 @@ w1 = sp.wrap('hello') w2 = sp.wrap(42) return w1 + w2 - res = interpret(f, [1], type_system=self.ts) - assert ''.join(res.chars) == 'tag1:hellotag1:< 42 >' - res = interpret(f, [0], type_system=self.ts) - assert ''.join(res.chars) == 'tag2:hellotag2:< 42 >' + res = self.interpret(f, [1]) + assert self.ll_to_string(res) == 'tag1:hellotag1:< 42 >' + res = self.interpret(f, [0]) + assert self.ll_to_string(res) == 'tag2:hellotag2:< 42 >' def test_precise_method_call_1(self): class A(object): @@ -1087,7 +1078,7 @@ result2 = C().meth() return result1 * result2 for i in [0, 1]: - res = interpret(f, [i, 1234], type_system=self.ts) + res = self.interpret(f, [i, 1234]) assert res == f(i, 1234) def test_precise_method_call_2(self): @@ -1115,7 +1106,7 @@ result2 = x.meth() return result1 * result2 for i in [0, 1]: - res = interpret(f, [i, 1234], type_system=self.ts) + res = self.interpret(f, [i, 1234]) assert res == f(i, 1234) def test_disjoint_pbcs(self): @@ -1144,7 +1135,7 @@ return (h(fr1) + 10*h(fr2) + 100*a + 1000*b + 10000*h2(fr1) + 100000*h2(fr2)) - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert res == 13211 def test_disjoint_pbcs_2(self): @@ -1171,7 +1162,7 @@ h(None) return total + 10*h(fr) - res = interpret(f, [3], type_system=self.ts) + res = self.interpret(f, [3]) assert res == 42 def test_convert_multiple_to_single(self): @@ -1186,7 +1177,7 @@ def f(): return A().meth(fr1) * B().meth(fr2) - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert res == 65*66 def test_convert_multiple_to_single_method_of_frozen_pbc(self): @@ -1201,7 +1192,7 @@ def f(): return A().meth(fr1.mymethod) * B().meth(fr2.mymethod) - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert res == 165 * 1066 def test_convert_none_to_frozen_pbc(self): @@ -1217,7 +1208,7 @@ else: fr = fr1 return g(fr) - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 65 def test_multiple_attribute_access_patterns(self): @@ -1257,9 +1248,9 @@ return f2 def f(n): return choose(n) is f1 - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == True - res = interpret(f, [2], type_system=self.ts) + res = self.interpret(f, [2]) assert res == False @@ -1531,33 +1522,11 @@ res = interp.eval_graph(ll_h_graph, [None, c_f, c_a]) assert typeOf(res) == A_repr.lowleveltype -class TestLltype(BaseTestRPBC): - - ts = "lltype" - - def class_name(self, value): - return "".join(value.super.typeptr.name)[:-1] - - def read_attr(self, value, attr_name): - value = value._obj - while value is not None: - attr = getattr(value, "inst_" + attr_name, None) - if attr is None: - value = value._parentstructure() - else: - return attr - raise AttributeError() - -from pypy.rpython.ootypesystem import ootype - -class TestOotype(BaseTestRPBC): +class TestLLtype(BaseTestRPBC, LLRtypeMixin): + pass - ts = "ootype" +class TestOOtype(BaseTestRPBC, OORtypeMixin): + pass - def class_name(self, value): - return ootype.dynamicType(value)._name.split(".")[-1] - def read_attr(self, value, attr): - value = ootype.oodowncast(ootype.dynamicType(value), value) - return getattr(value, "o" + attr) Modified: pypy/dist/pypy/rpython/test/tool.py ============================================================================== --- pypy/dist/pypy/rpython/test/tool.py (original) +++ pypy/dist/pypy/rpython/test/tool.py Fri Jun 2 17:05:55 2006 @@ -26,6 +26,16 @@ def class_name(self, value): return "".join(value.super.typeptr.name)[:-1] + def read_attr(self, value, attr_name): + value = value._obj + while value is not None: + attr = getattr(value, "inst_" + attr_name, None) + if attr is None: + value = value._parentstructure() + else: + return attr + raise AttributeError() + class OORtypeMixin(object): type_system = 'ootype' @@ -38,3 +48,7 @@ def class_name(self, value): return ootype.dynamicType(value)._name.split(".")[-1] + + def read_attr(self, value, attr): + value = ootype.oodowncast(ootype.dynamicType(value), value) + return getattr(value, "o" + attr) From antocuni at codespeak.net Fri Jun 2 17:08:07 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 2 Jun 2006 17:08:07 +0200 (CEST) Subject: [pypy-svn] r28114 - pypy/dist/pypy/annotation Message-ID: <20060602150807.A011010071@code0.codespeak.net> Author: antocuni Date: Fri Jun 2 17:08:06 2006 New Revision: 28114 Modified: pypy/dist/pypy/annotation/unaryop.py Log: (antocuni, nikh) Remove a dead line that caused some tests failing. Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Fri Jun 2 17:08:06 2006 @@ -642,7 +642,6 @@ class __extend__(SomeOOBoundMeth): def simple_call(m, *args_s): - llargs = [annotation_to_lltype(arg_s)._example() for arg_s in args_s] inst = m.ootype._example() RESULT = ootype.typeOf(m.ootype._lookup(m.name)[1]).RESULT return lltype_to_annotation(RESULT) From ac at codespeak.net Fri Jun 2 18:03:16 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 2 Jun 2006 18:03:16 +0200 (CEST) Subject: [pypy-svn] r28116 - in pypy/dist/pypy: interpreter lib module/gc rpython rpython/test Message-ID: <20060602160316.C347B1006B@code0.codespeak.net> Author: ac Date: Fri Jun 2 18:03:16 2006 New Revision: 28116 Added: pypy/dist/pypy/module/gc/ (props changed) pypy/dist/pypy/module/gc/__init__.py (contents, props changed) pypy/dist/pypy/module/gc/app_gc.py (contents, props changed) pypy/dist/pypy/module/gc/interp_gc.py (contents, props changed) pypy/dist/pypy/rpython/test/test_rgc.py (contents, props changed) Removed: pypy/dist/pypy/lib/gc.py Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/rpython/rgc.py Log: Implement gc.collect. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Fri Jun 2 18:03:16 2006 @@ -211,7 +211,7 @@ if name not in modules: modules.append(name) - modules.extend(['unicodedata', '_codecs', + modules.extend(['unicodedata', '_codecs', 'gc', 'array', 'marshal', 'errno', 'math', '_sre']) modules.append('_pickle_support') Added: pypy/dist/pypy/module/gc/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/gc/__init__.py Fri Jun 2 18:03:16 2006 @@ -0,0 +1,11 @@ +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + appleveldefs = { + 'enable': 'app_gc.enable', + 'disable': 'app_gc.disable', + 'isenabled': 'app_gc.isenabled', + } + interpleveldefs = { + 'collect': 'interp_gc.collect', + } Added: pypy/dist/pypy/module/gc/app_gc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/gc/app_gc.py Fri Jun 2 18:03:16 2006 @@ -0,0 +1,9 @@ + +def isenabled(): + pass + +def enable(): + pass + +def disable(): + pass Added: pypy/dist/pypy/module/gc/interp_gc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/gc/interp_gc.py Fri Jun 2 18:03:16 2006 @@ -0,0 +1,9 @@ +from pypy.interpreter.gateway import ObjSpace +from pypy.rpython import rgc # Force registration of gc.collect +import gc + +def collect(space): + gc.collect() + +collect.unwrap_spec = [ObjSpace] + Modified: pypy/dist/pypy/rpython/rgc.py ============================================================================== --- pypy/dist/pypy/rpython/rgc.py (original) +++ pypy/dist/pypy/rpython/rgc.py Fri Jun 2 18:03:16 2006 @@ -1,5 +1,4 @@ from pypy.rpython.extregistry import ExtRegistryEntry - # ____________________________________________________________ # Framework GC features @@ -92,3 +91,18 @@ v_gcobject = hop.genop('cast_opaque_ptr', [v_gcobjectptr], resulttype = r_tuple.items_r[0]) return rtuple.newtuple(hop.llops, r_tuple, [v_gcobject, v_pool]) + +# Support for collection. +import gc + +class CollectEntry(ExtRegistryEntry): + _about_ = gc.collect + + def compute_result_annotation(self): + from pypy.annotation import model as annmodel + return annmodel.SomeImpossibleValue() + + def specialize_call(self, hop): + return hop.genop('gc__collect', [], resulttype=hop.r_result) + + Added: pypy/dist/pypy/rpython/test/test_rgc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/test/test_rgc.py Fri Jun 2 18:03:16 2006 @@ -0,0 +1,13 @@ +from pypy.rpython.test.test_llinterp import gengraph +from pypy.rpython import rgc # Force registration of gc.collect +import gc + +def test_collect(): + def f(): + gc.collect() + + t, typer, graph = gengraph(f, []) + ops = list(graph.iterblockops()) + assert len(ops) == 1 + op = ops[0][1] + assert op.opname == 'gc__collect' From nik at codespeak.net Fri Jun 2 18:50:10 2006 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 2 Jun 2006 18:50:10 +0200 (CEST) Subject: [pypy-svn] r28117 - in pypy/dist/pypy/rpython: . lltypesystem/module module ootypesystem ootypesystem/module test Message-ID: <20060602165010.713781006B@code0.codespeak.net> Author: nik Date: Fri Jun 2 18:50:08 2006 New Revision: 28117 Added: pypy/dist/pypy/rpython/lltypesystem/module/ pypy/dist/pypy/rpython/lltypesystem/module/__init__.py (contents, props changed) pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py (contents, props changed) pypy/dist/pypy/rpython/ootypesystem/module/ pypy/dist/pypy/rpython/ootypesystem/module/__init__.py (contents, props changed) pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py (contents, props changed) Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/ll_os.py pypy/dist/pypy/rpython/ootypesystem/ooregistry.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/test/test_rbuiltin.py Log: (antocuni, nik) overall goal: make external functions work with the ootypesystem. this was achieved by making it possible to split the ll_* modules in rpython.module into separate versions for the two type systems. have separate versions of ll_os with ll_os_getcwd. tests for that. Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Fri Jun 2 18:50:08 2006 @@ -10,21 +10,30 @@ class ExtFuncInfo: def __init__(self, func, annotation, ll_function_path, ll_annotable, backend_functiontemplate): self.func = func + self.ll_function_path = ll_function_path self.annotation = annotation - modulename, tail = ll_function_path.split('/') - if '.' not in modulename: - modulename = 'pypy.rpython.module.%s' % modulename - self.ll_module = ImportMe(modulename) - lastmodulename = modulename[modulename.rfind('.')+1:] - self.ll_function_name = '%s_%s' % (lastmodulename, tail) self.ll_annotable = ll_annotable self.backend_functiontemplate = backend_functiontemplate - def get_ll_function(self): + def get_ll_function(self, type_system): """Get the ll_*() function implementing the given high-level 'func'.""" - mod = self.ll_module.load() - return getattr(mod, self.ll_function_name) - ll_function = property(get_ll_function) + modulename, tail = self.ll_function_path.split('/') + if '.' not in modulename: + modulename = 'pypy.rpython.module.%s' % modulename + mod = self.import_module(modulename) + lastmodulename = modulename[modulename.rfind('.')+1:] + ll_function_name = '%s_%s' % (lastmodulename, tail) + try: + ll_function = getattr(mod, ll_function_name) + except AttributeError: + mod = self.import_module("pypy.rpython.%s.module.%s" + % (type_system.name, lastmodulename)) + ll_function = getattr(mod, ll_function_name) + return ll_function + + def import_module(self, module_name): + ll_module = ImportMe(module_name) + return ll_module.load() class ExtTypeInfo: Added: pypy/dist/pypy/rpython/lltypesystem/module/__init__.py ============================================================================== Added: pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py Fri Jun 2 18:50:08 2006 @@ -0,0 +1,7 @@ +import os +from pypy.rpython.module.support import to_rstr + +def ll_os_getcwd(): + return to_rstr(os.getcwd()) +ll_os_getcwd.suggested_primitive = True + Modified: pypy/dist/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/module/ll_os.py Fri Jun 2 18:50:08 2006 @@ -55,10 +55,6 @@ ll_os_close.suggested_primitive = True -def ll_os_getcwd(): - return to_rstr(os.getcwd()) -ll_os_getcwd.suggested_primitive = True - def ll_os_dup(fd): return os.dup(fd) Added: pypy/dist/pypy/rpython/ootypesystem/module/__init__.py ============================================================================== Added: pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py Fri Jun 2 18:50:08 2006 @@ -0,0 +1,7 @@ +import os +from pypy.rpython.ootypesystem.ootype import oostring + +def ll_os_getcwd(): + return oostring(os.getcwd(), -1) +ll_os_getcwd.suggested_primitive = True + Modified: pypy/dist/pypy/rpython/ootypesystem/ooregistry.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ooregistry.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ooregistry.py Fri Jun 2 18:50:08 2006 @@ -9,7 +9,8 @@ assert isinstance(obj_s, (annmodel.SomeInteger, annmodel.SomeChar, annmodel.SomeFloat, - annmodel.SomeOOInstance)) + annmodel.SomeOOInstance, + annmodel.SomeString)) assert isinstance(base_s, annmodel.SomeInteger) return annmodel.SomeOOInstance(ootype.String) @@ -18,7 +19,8 @@ annmodel.SomeChar, annmodel.SomeString, annmodel.SomeFloat, - annmodel.SomeOOInstance)) + annmodel.SomeOOInstance, + annmodel.SomeString)) assert isinstance(hop.args_s[1], annmodel.SomeInteger) return hop.genop('oostring', hop.args_v, resulttype = ootype.String) Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Fri Jun 2 18:50:08 2006 @@ -457,13 +457,13 @@ def make_rtype_extfunc(extfuncinfo): if extfuncinfo.ll_annotable: def rtype_extfunc(hop): - ll_function = extfuncinfo.ll_function + ll_function = extfuncinfo.get_ll_function(hop.rtyper.type_system) vars = hop.inputargs(*hop.args_r) hop.exception_is_here() return hop.gendirectcall(ll_function, *vars) else: def rtype_extfunc(hop): - ll_function = extfuncinfo.ll_function + ll_function = extfuncinfo.get_ll_function(hop.rtyper.type_system) resulttype = hop.r_result vars = hop.inputargs(*hop.args_r) hop.exception_is_here() Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Fri Jun 2 18:50:08 2006 @@ -7,6 +7,7 @@ from pypy.rpython.rarithmetic import r_uint, intmask from pypy.annotation.builtin import * from pypy.rpython.module.support import to_rstr +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin import py def test_rbuiltin_list(): @@ -75,13 +76,6 @@ if op.opname == 'direct_call': yield op -def test_os_getcwd(): - import os - def fn(): - return os.getcwd() - res = interpret(fn, []) - assert ''.join(res.chars) == fn() - def test_os_dup(): import os def fn(fd): @@ -335,3 +329,21 @@ return lltype.cast_primitive(lltype.UniChar, v) res = interpret(llf, [ord('x')], policy=LowLevelAnnotatorPolicy()) assert res == u'x' + + +class BaseTestExtfunc(BaseRtypingTest): + + def test_os_getcwd(self): + import os + def fn(): + return os.getcwd() + res = self.interpret(fn, []) + assert self.ll_to_string(res) == fn() + + +class TestOOtype(BaseTestExtfunc, OORtypeMixin): + pass + +class TestLLtype(BaseTestExtfunc, LLRtypeMixin): + pass + From ale at codespeak.net Fri Jun 2 19:20:38 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 2 Jun 2006 19:20:38 +0200 (CEST) Subject: [pypy-svn] r28120 - pypy/dist/pypy/objspace/std Message-ID: <20060602172038.667001006B@code0.codespeak.net> Author: ale Date: Fri Jun 2 19:20:37 2006 New Revision: 28120 Modified: pypy/dist/pypy/objspace/std/complexobject.py Log: Add __int__ and __float__ to ComplexObject Modified: pypy/dist/pypy/objspace/std/complexobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/complexobject.py (original) +++ pypy/dist/pypy/objspace/std/complexobject.py Fri Jun 2 19:20:37 2006 @@ -249,6 +249,11 @@ def coerce__Complex_Complex(space, w_complex1, w_complex2): return space.newtuple([w_complex1, w_complex2]) +def float__Complex(space, w_complex): + raise OperationError(space.w_TypeError, space.wrap("can't convert complex to int; use int(abs(z))")) + +int__Complex = float__Complex + def complex_conjugate__Complex(space, w_self): #w_real = space.call_function(space.w_float,space.wrap(w_self.realval)) #w_imag = space.call_function(space.w_float,space.wrap(-w_self.imagval)) From nik at codespeak.net Fri Jun 2 19:25:17 2006 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 2 Jun 2006 19:25:17 +0200 (CEST) Subject: [pypy-svn] r28121 - in pypy/dist/pypy/rpython: lltypesystem/module module ootypesystem/module test Message-ID: <20060602172517.842261006B@code0.codespeak.net> Author: nik Date: Fri Jun 2 19:25:16 2006 New Revision: 28121 Modified: pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py pypy/dist/pypy/rpython/module/ll_os.py pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py pypy/dist/pypy/rpython/test/test_rbuiltin.py Log: (antocuni, nik) move os.write and os.open to typesystem-specific ll_os modules. add and pass test for this. Modified: pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py Fri Jun 2 19:25:16 2006 @@ -1,5 +1,13 @@ import os -from pypy.rpython.module.support import to_rstr +from pypy.rpython.module.support import from_rstr, to_rstr + +def ll_os_open(fname, flag, mode): + return os.open(from_rstr(fname), flag, mode) +ll_os_open.suggested_primitive = True + +def ll_os_write(fd, astring): + return os.write(fd, from_rstr(astring)) +ll_os_write.suggested_primitive = True def ll_os_getcwd(): return to_rstr(os.getcwd()) Modified: pypy/dist/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/module/ll_os.py Fri Jun 2 19:25:16 2006 @@ -21,11 +21,6 @@ from pypy.rpython import ros from pypy.rpython.rarithmetic import r_longlong -def ll_os_open(fname, flag, mode): - return os.open(from_rstr(fname), flag, mode) -ll_os_open.suggested_primitive = True - - def ll_read_into(fd, buffer): data = os.read(fd, len(buffer.chars)) _ll_strfill(buffer, data, len(data)) @@ -45,10 +40,6 @@ return buffer -def ll_os_write(fd, astring): - return os.write(fd, from_rstr(astring)) -ll_os_write.suggested_primitive = True - def ll_os_close(fd): os.close(fd) Modified: pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py Fri Jun 2 19:25:16 2006 @@ -1,7 +1,15 @@ import os -from pypy.rpython.ootypesystem.ootype import oostring +from pypy.rpython.ootypesystem.module.support import from_rstr, to_rstr + +def ll_os_open(fname, flag, mode): + return os.open(from_rstr(fname), flag, mode) +ll_os_open.suggested_primitive = True + +def ll_os_write(fd, astring): + return os.write(fd, from_rstr(astring)) +ll_os_write.suggested_primitive = True def ll_os_getcwd(): - return oostring(os.getcwd(), -1) + return to_rstr(os.getcwd()) ll_os_getcwd.suggested_primitive = True Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Fri Jun 2 19:25:16 2006 @@ -103,7 +103,7 @@ res = interpret(f, []) os.close(res) count = 0 - from pypy.rpython.module import ll_os + from pypy.rpython.lltypesystem.module import ll_os for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, wr_open): cfptr = dir_call.args[0] assert cfptr.value._obj._callable == ll_os.ll_os_open @@ -340,6 +340,19 @@ res = self.interpret(fn, []) assert self.ll_to_string(res) == fn() + def test_os_write(self): + tmpdir = str(udir.udir.join("os_write_test")) + import os + def wr_open(fname): + fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777) + os.write(fd, "hello world") + return fd + def f(): + return wr_open(tmpdir) + res = self.interpret(f, []) + os.close(res) + hello = open(tmpdir).read() + assert hello == "hello world" class TestOOtype(BaseTestExtfunc, OORtypeMixin): pass From cfbolz at codespeak.net Sat Jun 3 00:00:49 2006 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Jun 2006 00:00:49 +0200 (CEST) Subject: [pypy-svn] r28124 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20060602220049.DBC181006B@code0.codespeak.net> Author: cfbolz Date: Sat Jun 3 00:00:47 2006 New Revision: 28124 Modified: pypy/dist/pypy/objspace/std/complexobject.py pypy/dist/pypy/objspace/std/test/test_complexobject.py Log: slightly more precise error message + test Modified: pypy/dist/pypy/objspace/std/complexobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/complexobject.py (original) +++ pypy/dist/pypy/objspace/std/complexobject.py Sat Jun 3 00:00:47 2006 @@ -250,9 +250,10 @@ return space.newtuple([w_complex1, w_complex2]) def float__Complex(space, w_complex): - raise OperationError(space.w_TypeError, space.wrap("can't convert complex to int; use int(abs(z))")) + raise OperationError(space.w_TypeError, space.wrap("can't convert complex to float; use abs(z)")) -int__Complex = float__Complex +def int__Complex(space, w_complex): + raise OperationError(space.w_TypeError, space.wrap("can't convert complex to int; use int(abs(z))")) def complex_conjugate__Complex(space, w_self): #w_real = space.call_function(space.w_float,space.wrap(w_self.realval)) Modified: pypy/dist/pypy/objspace/std/test/test_complexobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_complexobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_complexobject.py Sat Jun 3 00:00:47 2006 @@ -329,3 +329,7 @@ os.remove(pth) except (OSError, IOError): pass + + def test_convert(self): + raises(TypeError, int, 1+1j) + raises(TypeError, float, 1+1j) From ericvrp at codespeak.net Sat Jun 3 08:41:47 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 3 Jun 2006 08:41:47 +0200 (CEST) Subject: [pypy-svn] r28125 - in pypy/dist/pypy: interpreter interpreter/test module/_pickle_support Message-ID: <20060603064147.39E371006B@code0.codespeak.net> Author: ericvrp Date: Sat Jun 3 08:41:41 2006 New Revision: 28125 Modified: pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/test/test_pickle.py pypy/dist/pypy/module/_pickle_support/maker.py Log: More support for frame pickling. I'm checking this in so people at the sprint may have a change to look at it. It has not been crossreferenced against pricklepit.c of stackless.com. The biggest issue currently is the pickling of f_locals which still causes some errors. Quite a few XXX's in the code&test give an indication of what I'm trying to do. Frame pickling is incomplete plus it's unknown if it will translate. To enable frame pickling do: - interpreter/test/test_pickle.py : remove skip from test_pickle_frame - interpreter/typedef.py : remove comments from PyFrame.typedef - interpreter/pyframe.py : outcomment line with 'frame pickling is work in progress' - module/_pickle_support/__init__.py : remove comment from 'frame_new' line This is rather conservative, hopefully it helps. Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Sat Jun 3 08:41:41 2006 @@ -68,16 +68,44 @@ self.instr_prev = -1; def descr__reduce__(self, space): + ''' + >>>> dir(frame) + ['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'f_back', 'f_builtins', 'f_code', 'f_exc_traceback', 'f_exc_type', 'f_exc_value', 'f_globals', 'f_lasti', 'f_lineno', 'f_locals', 'f_restricted', 'f_trace'] + ''' raise Exception('frame pickling is work in progress') from pypy.interpreter.mixedmodule import MixedModule w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('frame_new') w = space.wrap - tup = [ + + #XXX how to call PyFrame.fget_f_lineno(..) from here? just make it a staticmethod? + #f_lineno = PyFrame.fget_f_lineno(space, self) #TypeError: unbound method fget_f_lineno() must be called with PyFrame instance as first argument (got StdObjSpace instance instead) + if self.w_f_trace is None: + f_lineno = self.get_last_lineno() + else: + f_lineno = self.f_lineno + + tup = [ + w(self.f_back), + w(self.builtin), w(self.pycode), + w(self.last_exception), #f_exc_traceback, f_exc_type, f_exc_value self.w_globals, + w(self.last_instr), + w(self.next_instr), #not in PyFrame.typedef! + w(f_lineno), #why not w(self.f_lineno)? something with self.w_f_trace? + + #space.newtuple(self.fastlocals_w), #XXX (application-level) PicklingError: Can't pickle : it's not found as __builtin__.AppTestInterpObjectPickling + #self.getdictscope(), #XXX (application-level) PicklingError: Can't pickle : it's not found as __builtin__.AppTestInterpObjectPickling + space.w_None, #XXX placeholder + + #f_restricted requires no additional data! + self.w_f_trace, ] + + #XXX what to do with valuestack and blockstack here? + return space.newtuple([new_inst, space.newtuple(tup)]) def hide(self): Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Sat Jun 3 08:41:41 2006 @@ -94,14 +94,22 @@ assert frame.__doc__ == result.__doc__ assert type(frame.f_back) is type(result.f_back) assert frame.f_builtins is result.f_builtins - assert frame.f_code is result.f_code + assert frame.f_code == result.f_code assert frame.f_exc_traceback is result.f_exc_traceback assert frame.f_exc_type is result.f_exc_type assert frame.f_exc_value is result.f_exc_value - assert frame.f_globals is result.f_globals + + #print 'frame f_globals =', frame.f_globals #frame f_globals = {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } + #print 'result.f_globals=', result.f_globals #result.f_globals= {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } + #assert frame.f_globals == result.f_globals #XXX test_pickle_frame function not same identity (see pickle func tests, we don't compare by identity there!)? + assert frame.f_lasti == result.f_lasti assert frame.f_lineno == result.f_lineno - assert list(frame.f_locals) == list(result.f_locals) + + #print 'frame.f_locals=', frame.f_locals #['exc_info', 'tb', 'exc_type', 'exc'] + #print 'result.f_locals=', result.f_locals #[] + #assert list(frame.f_locals) == list(result.f_locals) + assert frame.f_restricted is result.f_restricted assert frame.f_trace is result.f_trace Modified: pypy/dist/pypy/module/_pickle_support/maker.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/maker.py (original) +++ pypy/dist/pypy/module/_pickle_support/maker.py Sat Jun 3 08:41:41 2006 @@ -50,6 +50,26 @@ index = space.int_w(w_index) - space.int_w(w_len) return W_ReverseSeqIterObject(space, w_seq, index) -def frame_new(space, w_pycode, w_globals): - new_frame = PyFrame(space, w_pycode, w_globals, None) +def frame_new(space, __args__): + args_w, kwds_w = __args__.unpack() #stolen from std/fake.py + args = [space.unwrap(w_arg) for w_arg in args_w] + f_back, builtin, pycode, last_exception, globals, last_instr, next_instr,\ + f_lineno, fastlocals, f_trace = args + w = space.wrap + + new_frame = PyFrame(space, pycode, w(globals), None) + new_frame.f_back = f_back + new_frame.builtin = builtin + new_frame.last_exception = last_exception + new_frame.last_instr = last_instr + new_frame.next_instr = next_instr + new_frame.f_lineno = f_lineno + #new_frame.fastlocals_w = w(fastlocals) + + if space.is_w(f_trace, space.w_None): + new_frame.w_f_trace = None + else: + new_frame.w_f_trace = w(f_trace) + return space.wrap(new_frame) +frame_new.unwrap_spec = [ObjSpace, Arguments] From nik at codespeak.net Sat Jun 3 10:11:55 2006 From: nik at codespeak.net (nik at codespeak.net) Date: Sat, 3 Jun 2006 10:11:55 +0200 (CEST) Subject: [pypy-svn] r28128 - pypy/dist/pypy/rpython/ootypesystem/module Message-ID: <20060603081155.25A391006B@code0.codespeak.net> Author: nik Date: Sat Jun 3 10:11:55 2006 New Revision: 28128 Added: pypy/dist/pypy/rpython/ootypesystem/module/support.py (contents, props changed) Log: argh! forgot to check in this file yesterday. most failures in the nightly test run were due to this ... Added: pypy/dist/pypy/rpython/ootypesystem/module/support.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/ootypesystem/module/support.py Sat Jun 3 10:11:55 2006 @@ -0,0 +1,10 @@ +from pypy.rpython.ootypesystem.ootype import oostring + +def from_rstr(rs): + if not rs: # null pointer + return None + else: + return "".join([rs.ll_stritem_nonneg(i) for i in range(rs.ll_strlen())]) + +def to_rstr(s): + return oostring(s, -1) From antocuni at codespeak.net Sat Jun 3 10:28:14 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Jun 2006 10:28:14 +0200 (CEST) Subject: [pypy-svn] r28130 - in pypy/dist/pypy/rpython: ootypesystem test Message-ID: <20060603082814.E39E610070@code0.codespeak.net> Author: antocuni Date: Sat Jun 3 10:28:12 2006 New Revision: 28130 Modified: pypy/dist/pypy/rpython/ootypesystem/rstr.py pypy/dist/pypy/rpython/test/test_rfloat.py Log: (antocuni, nik) Added a test and fixed a bug about string formatting with floats. Modified: pypy/dist/pypy/rpython/ootypesystem/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rstr.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rstr.py Sat Jun 3 10:28:12 2006 @@ -206,6 +206,7 @@ return hop.genop('oosend', [c_build, v_buf], resulttype=ootype.String) do_stringformat = classmethod(do_stringformat) + def add_helpers(): dic = {} for name, meth in ootype.String._GENERIC_METHODS.iteritems(): @@ -223,7 +224,7 @@ add_helpers() del add_helpers - +do_stringformat = LLHelpers.do_stringformat string_repr = StringRepr() char_repr = CharRepr() unichar_repr = UniCharRepr() Modified: pypy/dist/pypy/rpython/test/test_rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rfloat.py (original) +++ pypy/dist/pypy/rpython/test/test_rfloat.py Sat Jun 3 10:28:12 2006 @@ -58,6 +58,13 @@ res = self.interpret(fn, [1.5]) assert float(self.ll_to_string(res)) == 1.5 + def test_string_mod_float(self): + def fn(f): + return '%f' % f + + res = self.interpret(fn, [1.5]) + assert float(self.ll_to_string(res)) == 1.5 + class TestLLtype(BaseTestRfloat, LLRtypeMixin): pass From nik at codespeak.net Sat Jun 3 10:36:38 2006 From: nik at codespeak.net (nik at codespeak.net) Date: Sat, 3 Jun 2006 10:36:38 +0200 (CEST) Subject: [pypy-svn] r28132 - in pypy/dist/pypy: rpython/lltypesystem/module translator/c Message-ID: <20060603083638.7786410070@code0.codespeak.net> Author: nik Date: Sat Jun 3 10:36:37 2006 New Revision: 28132 Modified: pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py pypy/dist/pypy/translator/c/extfunc.py Log: in genc's extfunc use the ll helpers from lltypesystem ll_os. this fixes some more tests ... Modified: pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py Sat Jun 3 10:36:37 2006 @@ -1,5 +1,6 @@ import os from pypy.rpython.module.support import from_rstr, to_rstr +from pypy.rpython.module.ll_os import * def ll_os_open(fname, flag, mode): return os.open(from_rstr(fname), flag, mode) Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Sat Jun 3 10:36:37 2006 @@ -5,8 +5,9 @@ from pypy.rpython.lltypesystem.rstr import STR from pypy.rpython.lltypesystem import rstr from pypy.rpython.lltypesystem import rlist -from pypy.rpython.module import ll_os, ll_time, ll_math, ll_strtod +from pypy.rpython.module import ll_time, ll_math, ll_strtod from pypy.rpython.module import ll_stackless, ll_stack +from pypy.rpython.lltypesystem.module import ll_os from pypy.module.thread.rpython import ll_thread # table of functions hand-written in src/ll_*.h From hpk at codespeak.net Sat Jun 3 11:48:24 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Jun 2006 11:48:24 +0200 (CEST) Subject: [pypy-svn] r28140 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060603094824.C6C5710070@code0.codespeak.net> Author: hpk Date: Sat Jun 3 11:47:41 2006 New Revision: 28140 Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt Log: update planning session for today Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/ddorf2006/planning.txt (original) +++ pypy/extradoc/sprintinfo/ddorf2006/planning.txt Sat Jun 3 11:47:41 2006 @@ -1,37 +1,49 @@ -Planning for the first morning +Sprint Planning DDorf ========================================= -Christian is doing paperwork, Armin isn't here yet. - -Today's assignments are in **bold**. +Armin isn't here yet. +Before the sprint, there were two somewhat-similar, somewhat-conflicting +goals: finish off wp7 functionality (stackless stuff, and more...) and +getting the 0.9 release out of the door. We decided that the priority of this sprint, or at least the next two days should be on wp7 and particularly +stackless relates features. Some things that don't really have issues yet: * the ext compiler + * Document using ext-compiler getting-started * documentation * running the compliance tests and getting results on the web again - **Holger and Anders** + (DONE) compliance is at 86% **Holger and Anders** * ootypesystem stuff - **Nik and Antonio seem to be on this already :)** (lucky non-EU constrained - people :) + **Nik and Antonio are working on ootype completion ** + ** Maciek will join later ** Looking at the 0.9 issues, critical first: * 194 Advance rctypes approach to become usable - Basically done (ask Armin) + Basically done (ask Armin). + open sub-issue: what about releasing the GIL? * 197 implement __del__ support for framework gcs Needs more testing (particularly with the stacklessgc), but we think this works. - **This we can do now (mwh + cfbolz in parallel with something else)** + **Arre, cfbolz to do more testing** + +* ??? expose coroutine cloning to app level. + + * settle on APIs on RPython level + * experiment a bit with exposing it to applevel + * document for 0.9 release + + Shouldn't be too hard, needs to be done though. * 198 implement tasklet pickling @@ -55,12 +67,20 @@ **cfbolz + arre** +* 199 finish app-level stackless support + + This should be rated 'critical'! Not sure what the status is. + + Greenlets could be done quickly. + Now the bugs: * 137 Control-C runtime support No progress here. Hopefully not that hard. + (holger, later) + * 181 time module is incomplete Will be done by the SoC ctypes project we hope :) @@ -111,10 +131,6 @@ Probably not critical for 0.9. -* 199 finish app-level stackless support - - This should be rated 'critical'! Not sure what the status is. - * 200 moving gcs Another GC bonus point. Probably not going to happen for 0.9. From ac at codespeak.net Sat Jun 3 11:52:10 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sat, 3 Jun 2006 11:52:10 +0200 (CEST) Subject: [pypy-svn] r28141 - in pypy/dist/pypy/rpython: . test Message-ID: <20060603095210.A5DD41006B@code0.codespeak.net> Author: ac Date: Sat Jun 3 11:52:09 2006 New Revision: 28141 Modified: pypy/dist/pypy/rpython/rgc.py pypy/dist/pypy/rpython/test/test_rgc.py Log: (cfbolz, arre) Fix annotation typo. Modified: pypy/dist/pypy/rpython/rgc.py ============================================================================== --- pypy/dist/pypy/rpython/rgc.py (original) +++ pypy/dist/pypy/rpython/rgc.py Sat Jun 3 11:52:09 2006 @@ -100,7 +100,7 @@ def compute_result_annotation(self): from pypy.annotation import model as annmodel - return annmodel.SomeImpossibleValue() + return annmodel.s_None def specialize_call(self, hop): return hop.genop('gc__collect', [], resulttype=hop.r_result) Modified: pypy/dist/pypy/rpython/test/test_rgc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rgc.py (original) +++ pypy/dist/pypy/rpython/test/test_rgc.py Sat Jun 3 11:52:09 2006 @@ -1,13 +1,19 @@ -from pypy.rpython.test.test_llinterp import gengraph +from pypy.rpython.test.test_llinterp import gengraph, interpret from pypy.rpython import rgc # Force registration of gc.collect import gc def test_collect(): def f(): - gc.collect() + return gc.collect() t, typer, graph = gengraph(f, []) ops = list(graph.iterblockops()) assert len(ops) == 1 op = ops[0][1] assert op.opname == 'gc__collect' + + + res = interpret(f, []) + + assert res is None + From fijal at codespeak.net Sat Jun 3 12:27:34 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Jun 2006 12:27:34 +0200 (CEST) Subject: [pypy-svn] r28143 - in pypy/dist/pypy/translator/js2: . test Message-ID: <20060603102734.559BC10070@code0.codespeak.net> Author: fijal Date: Sat Jun 3 12:27:32 2006 New Revision: 28143 Modified: pypy/dist/pypy/translator/js2/asmgen.py pypy/dist/pypy/translator/js2/function.py pypy/dist/pypy/translator/js2/test/test_snippet.py Log: Reverted to using magic for(;;) as goto replacement. Works pretty slow. Modified: pypy/dist/pypy/translator/js2/asmgen.py ============================================================================== --- pypy/dist/pypy/translator/js2/asmgen.py (original) +++ pypy/dist/pypy/translator/js2/asmgen.py Sat Jun 3 12:27:32 2006 @@ -122,6 +122,10 @@ self.codegenerator.write("while ( %s == %s )"%(arg_name, str(exitcase).lower())) self.codegenerator.openblock() + def branch_while_true(self): + self.codegenerator.write("while (true)") + self.codegenerator.openblock() + def branch_else(self): self.codegenerator.closeblock() self.codegenerator.write("else") @@ -228,6 +232,24 @@ def end_try(self): self.codegenerator.closeblock() + def begin_for(self): + self.codegenerator.writeline("var block = 0;") + self.codegenerator.write("for(;;)") + self.codegenerator.openblock() + self.codegenerator.write("switch(block)") + self.codegenerator.openblock() + + def write_case(self, num): + self.codegenerator.writeline("case %d:"%num) + + def jump_block(self, num): + self.codegenerator.writeline("block = %d;"%num) + self.codegenerator.writeline("break;") + + def end_for(self): + self.codegenerator.closeblock() + self.codegenerator.closeblock() + def inherits(self, subclass_name, parent_name): self.codegenerator.writeline("%s.inherits(%s);"%(subclass_name, parent_name)) Modified: pypy/dist/pypy/translator/js2/function.py ============================================================================== --- pypy/dist/pypy/translator/js2/function.py (original) +++ pypy/dist/pypy/translator/js2/function.py Sat Jun 3 12:27:32 2006 @@ -39,10 +39,14 @@ def visit_Link(self, link, switches): if link.target in switches: + #if self.loops.has_key(link.target): + # # double loop + # pass + block_switch = self.block_seeing_order[link.target] if len(self.block_seeing_order[link.target]) == 1: - self.loops[link.target] = self.block_seeing_order[link.target][0].exitcase + self.loops[(block_switch[0].exitcase,link.target)] = block_switch[0].exitcase else: - self.loops[link.target] = self.block_seeing_order[link.target][1].exitcase + self.loops[(block_switch[1].exitcase,link.target)] = block_switch[1].exitcase if not link.target in self.seen: self.parents[link.target] = self.parents[link.prevblock] @@ -75,14 +79,16 @@ return cmp(self.order, other.order) def _is_return_block(self, block): - return (not block.exits) and len(block.inputargs) == 1 - + return self.graph.returnblock is block + def _is_raise_block(self, block): - return (not block.exits) and len(block.inputargs) == 2 - - def render_block(self, block, stop_block = None): - if block is stop_block: + return self.graph.exceptblock is block + + def loop_render_block(self, block, stop_blocks = []): + # FIXME: This code is awfull, some refactoring please + if block in stop_blocks: return + log("Rendering block %r"%block) handle_exc = (block.exitswitch == flowmodel.c_last_exception) if handle_exc: @@ -102,35 +108,98 @@ assert(len(block.exits) == 1) link = block.exits[0] self._setup_link(link) - self.render_block(link.target, stop_block) + self.render_block(link.target, stop_blocks) elif block.exitswitch is flowmodel.c_last_exception: # we've got exception block raise NotImplementedError("Exception handling not implemented") else: - if self.loops.has_key(block): + if self.loops.has_key((True,block)) and self.loops.has_key((False,block)): + # double loop + #self.ilasm.branch_while + self.ilasm.branch_while_true() + self.ilasm.branch_if(block.exitswitch, self.loops[(True,block)]) + self._setup_link(block.exits[True]) + self.render_block(block.exits[True].target, stop_blocks+[block]) + self.ilasm.branch_else() + self._setup_link(block.exits[False]) + self.render_block(block.exits[False].target, stop_blocks+[block]) + self.ilasm.close_branch() + for op in block.operations: + self._render_op(op) + self.ilasm.close_branch() + elif self.loops.has_key((True, block)) or self.loops.has_key((False, block)): # we've got loop - self.ilasm.branch_while(block.exitswitch, self.loops[block]) - exit_case = block.exits[self.loops[block]] + try: + loop_case = self.loops[(True, block)] + except KeyError: + loop_case = self.loops[(False, block)] + self.ilasm.branch_while(block.exitswitch, loop_case) + exit_case = block.exits[loop_case] self._setup_link(exit_case) - self.render_block(exit_case.target, block) + self.render_block(exit_case.target, stop_blocks+[block]) for op in block.operations: self._render_op(op) self.ilasm.close_branch() - exit_case = block.exits[not self.loops[block]] + exit_case = block.exits[not loop_case] self._setup_link(exit_case) #log ( ) - self.render_block(exit_case.target,block) + self.render_block(exit_case.target, stop_blocks+[block]) #raise NotImplementedError ( "loop" ) else: # just a simple if assert(len(block.exits) == 2) self.ilasm.branch_if(block.exitswitch, True) self._setup_link(block.exits[True]) - self.render_block(block.exits[True].target, stop_block) + self.render_block(block.exits[True].target, stop_blocks) + self.ilasm.branch_else() + self._setup_link(block.exits[False]) + self.render_block(block.exits[False].target, stop_blocks) + self.ilasm.close_branch() + + def render_block_operations(self, block): + for op in block.operations: + self._render_op(op) + + def render_block(self, startblock): + """ Block rendering routine using for variable trick + """ + self.ilasm.begin_for() + + block_map = {} + blocknum = 0 + + graph = self.graph + + for block in graph.iterblocks(): + block_map[block] = blocknum + blocknum += 1 + + for block in graph.iterblocks(): + self.ilasm.write_case(block_map[block]) + self.render_block_operations(block) + if self._is_return_block(block): + return_var = block.inputargs[0] + #if return_var.concretetype is not Void: + self.load(return_var) + self.ilasm.ret() + elif block.exitswitch is None: + self._setup_link(block.exits[0]) + self.ilasm.jump_block(block_map[block.exits[0].target]) + elif block.exitswitch.concretetype is Bool: + self.ilasm.branch_if(block.exitswitch, True) + self._setup_link(block.exits[True]) + self.ilasm.jump_block(block_map[block.exits[True].target]) self.ilasm.branch_else() self._setup_link(block.exits[False]) - self.render_block(block.exits[False].target, stop_block) + self.ilasm.jump_block(block_map[block.exits[False].target]) self.ilasm.close_branch() + elif block.exitswitch is flowmodel.c_last_exception: + raise NotImplementedError("Exception work in progress") + else: + raise TypeError("Unknow block.exitswitch type %r"%block.exitswitch) + + self.ilasm.end_for() + #self.render_operations( def render(self,ilasm): if self.db.graph_name(self.graph) is not None and not self.is_method: @@ -143,16 +212,17 @@ self.ilasm = ilasm - self.loops = LoopFinder(self.graph.startblock).loops + #self.loops = LoopFinder(self.graph.startblock).loops if self.is_method: self.ilasm.begin_method(self.name, self._class, args) else: self.ilasm.begin_function(self.name, args) - log("loops: %r"%self.loops) + #log("loops: %r"%self.loops) # render all variables self.ilasm.set_locals(",".join(self.locals)) + self.render_block(self.graph.startblock) self.ilasm.end_function() @@ -206,7 +276,7 @@ seen = {} for v in mix: is_var = isinstance(v, flowmodel.Variable) - if id(v) not in seen and is_var and v.name not in args and v.concretetype is not Void: + if id(v) not in seen and is_var and v.name not in args: locals.append(v.name) seen[id(v)] = True Modified: pypy/dist/pypy/translator/js2/test/test_snippet.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_snippet.py (original) +++ pypy/dist/pypy/translator/js2/test/test_snippet.py Sat Jun 3 12:27:32 2006 @@ -33,12 +33,12 @@ assert f() == 4 def test_sieve_of_eratosthenes(self): - py.test.skip("Loop error in loop detection software") + #py.test.skip("Loop error in loop detection software") f = compile_function(test.sieve_of_eratosthenes, []) assert f() == 1028 def test_nested_whiles(self): - py.test.skip("Loop error in loop detection software") + #py.test.skip("Loop error in loop detection software") f = compile_function(test.nested_whiles, [int, int]) assert test.nested_whiles(3,2) == f(3,2) @@ -51,7 +51,7 @@ assert while_func(10) == 55 def test_time_waster(self): - py.test.skip("Loop error in loop detection software") + #py.test.skip("Loop error in loop detection software") f = compile_function(test.time_waster, [int]) assert f(1) == 1 assert f(2) == 2 From ac at codespeak.net Sat Jun 3 12:30:24 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sat, 3 Jun 2006 12:30:24 +0200 (CEST) Subject: [pypy-svn] r28144 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20060603103024.592D710070@code0.codespeak.net> Author: ac Date: Sat Jun 3 12:30:23 2006 New Revision: 28144 Added: pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py - copied unchanged from r28142, pypy/dist/lib-python/2.4.1/test/test_weakref.py Log: (cfbolz, arre) Fix tests. From antocuni at codespeak.net Sat Jun 3 12:49:21 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Jun 2006 12:49:21 +0200 (CEST) Subject: [pypy-svn] r28148 - pypy/dist/pypy/rpython/test Message-ID: <20060603104921.9EF1D10070@code0.codespeak.net> Author: antocuni Date: Sat Jun 3 12:49:20 2006 New Revision: 28148 Modified: pypy/dist/pypy/rpython/test/test_rpbc.py Log: (antocuni, nik) Added a failing test. Modified: pypy/dist/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rpbc.py (original) +++ pypy/dist/pypy/rpython/test/test_rpbc.py Sat Jun 3 12:49:20 2006 @@ -25,6 +25,9 @@ MyBaseWithInit.__init__(self, a) self.b1 = b +class MySubclassWithoutInit(MyBaseWithInit): + pass + class Freezing: def _freeze_(self): return True @@ -128,6 +131,12 @@ return instance.a1 * instance.b1 assert self.interpret(f, [6, 7]) == 42 + def test_class_init_inherited(self): + self._skip_oo('inherited __init__') + def f(a): + instance = MySubclassWithoutInit(a) + return instance.a1 + assert self.interpret(f, [42]) == 42 def test_freezing(self): fr1 = Freezing() From hpk at codespeak.net Sat Jun 3 13:18:13 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Jun 2006 13:18:13 +0200 (CEST) Subject: [pypy-svn] r28152 - pypy/dist/pypy/tool/pytest Message-ID: <20060603111813.D22711006B@code0.codespeak.net> Author: hpk Date: Sat Jun 3 13:18:12 2006 New Revision: 28152 Modified: pypy/dist/pypy/tool/pytest/htmlreport.py Log: complain if no tests could be found Modified: pypy/dist/pypy/tool/pytest/htmlreport.py ============================================================================== --- pypy/dist/pypy/tool/pytest/htmlreport.py (original) +++ pypy/dist/pypy/tool/pytest/htmlreport.py Sat Jun 3 13:18:12 2006 @@ -121,6 +121,8 @@ err = len([x for x in tests if x.iserror()]) to = len([x for x in tests if x.istimeout()]) numtests = ok + err + to + assert numtests == len(tests) + assert numtests t = html.table() sum100 = numtests / 100.0 From nik at codespeak.net Sat Jun 3 13:39:34 2006 From: nik at codespeak.net (nik at codespeak.net) Date: Sat, 3 Jun 2006 13:39:34 +0200 (CEST) Subject: [pypy-svn] r28154 - pypy/dist/pypy/rpython/test Message-ID: <20060603113934.D72991006B@code0.codespeak.net> Author: nik Date: Sat Jun 3 13:39:33 2006 New Revision: 28154 Modified: pypy/dist/pypy/rpython/test/test_rpbc.py Log: (fijal, nik) a test failing for ootypesystem, discovered by maciek. Modified: pypy/dist/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rpbc.py (original) +++ pypy/dist/pypy/rpython/test/test_rpbc.py Sat Jun 3 13:39:33 2006 @@ -454,6 +454,21 @@ res = self.interpret(f, [7]) assert res == 42 + def test_simple_function_pointer(self): + py.test.skip("a problem with ootypesystem") + def f1(x): + return x + 1 + def f2(x): + return x + 2 + + l = [f1, f2] + + def pointersimple(i): + return l[i](i) + + res = self.interpret(pointersimple, [1]) + assert res == 3 + def test_classdef_getattr(self): class A: myvalue = 123 From mwh at codespeak.net Sat Jun 3 13:47:15 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Jun 2006 13:47:15 +0200 (CEST) Subject: [pypy-svn] r28155 - in pypy/dist/pypy: rpython translator/stackless translator/stackless/test Message-ID: <20060603114715.AF7DB1006B@code0.codespeak.net> Author: mwh Date: Sat Jun 3 13:47:02 2006 New Revision: 28155 Modified: pypy/dist/pypy/rpython/rstack.py pypy/dist/pypy/translator/stackless/code.py pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/transform.py Log: (pedronis, mwh) Reenable the first resume_point test. Most/all of the code from the branch is now on the trunk, but a little saner. Some refactorings were necessary for sanity + a couple bugfixes. Modified: pypy/dist/pypy/rpython/rstack.py ============================================================================== --- pypy/dist/pypy/rpython/rstack.py (original) +++ pypy/dist/pypy/rpython/rstack.py Sat Jun 3 13:47:02 2006 @@ -86,12 +86,12 @@ c_label = hop.inputconst(lltype.Void, hop.args_s[1].const) r = SimplePointerRepr(lltype.Ptr(STATE_HEADER)) - state_v = hop.inputarg(r, arg=0) + v_state = hop.inputarg(r, arg=0) args_v = hop.args_v[2:] hop.exception_is_here() - return hop.genop('resume_state_create', [c_label] + args_v, + return hop.genop('resume_state_create', [v_state, c_label] + args_v, hop.r_result) class ResumeStateEntry(ExtRegistryEntry): @@ -116,7 +116,7 @@ def specialize_call(self, hop, **kwds_i): from pypy.rpython.lltypesystem import lltype - v_state = hop.args_v[0] + v_state = hop.args_v[1] if 'i_returns' in kwds_i: assert len(kwds_i) == 1 Modified: pypy/dist/pypy/translator/stackless/code.py ============================================================================== --- pypy/dist/pypy/translator/stackless/code.py (original) +++ pypy/dist/pypy/translator/stackless/code.py Sat Jun 3 13:47:02 2006 @@ -181,6 +181,38 @@ INDEX_CAPTURE = frame.RestartInfo.add_prebuilt(ll_stack_capture, [EMPTY_STATE]) +RESUME_AFTER_STATE = frame.make_state_header_type('resume_after_state', + ('c', lltype.Ptr(STATE_HEADER)),) + +def resume_after_void(state, retvalue): + if global_state.restart_substate == -1: + # normal entry point for a call to state.switch() + # first unwind the stack + u = UnwindException() + s = lltype.malloc(RESUME_AFTER_STATE) + s.header.f_restart = INDEX_RESUME_AFTER_VOID + s.c = state + add_frame_state(u, s.header) + raise u + elif global_state.restart_substate == 0: + # STATE 0: we didn't do anything so far, but the stack is unwound + global_state.restart_substate = -1 + # grab the frame corresponding to ourself + # the 'targetstate' local is garbage here, it must be read back from + # 's.c' where we saved it by the normal entry point above + mystate = global_state.top + s = lltype.cast_pointer(lltype.Ptr(RESUME_AFTER_STATE), mystate) + targetstate = s.c + targetstate.f_back = mystate.f_back + global_state.top = targetstate + raise UnwindException() + else: + return 0 + +resume_after_void.stackless_explicit = True +INDEX_RESUME_AFTER_VOID = frame.RestartInfo.add_prebuilt(resume_after_void, + [RESUME_AFTER_STATE, + EMPTY_STATE]) # ____________________________________________________________ class StacklessData: Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sat Jun 3 13:47:02 2006 @@ -25,9 +25,9 @@ state = rstack.resume_state_create(None, "rp0", one(), one()+one()+one()) v2 = rstack.resume_state_invoke(int, state) return v1*10 + v2 - transform_stackless_function(example) -## res = llinterp_stackless_function(example, assert_unwind=False) -## assert res == 24 +## transform_stackless_function(example) + res = llinterp_stackless_function(example, assert_unwind=False) + assert res == 24 def test_call(): def g(x,y): Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sat Jun 3 13:47:02 2006 @@ -12,6 +12,7 @@ from pypy.rpython.rbuiltin import gen_cast from pypy.rpython.rtyper import LowLevelOpList from pypy.rpython.module import ll_stackless, ll_stack +from pypy.rpython.objectmodel import ComputedIntSymbolic from pypy.translator.backendopt import graphanalyze from pypy.translator.stackless.frame import SAVED_REFERENCE, STORAGE_TYPES @@ -54,6 +55,15 @@ # abort() # return retval + x + 1 +class SymbolicRestartNumber(ComputedIntSymbolic): + def __init__(self, value=None): + ComputedIntSymbolic.__init__(self, self._getvalue) + self.value = value + + def _getvalue(self): + assert self.value is not None + return self.value + class ResumePoint: def __init__(self, var_result, args, links_to_resumption, frame_state_type, fieldnames): @@ -223,6 +233,11 @@ self.yield_current_frame_to_caller_ptr = mixlevelannotator.constfunc( code.yield_current_frame_to_caller, [], s_StatePtr) + self.resume_after_void_ptr = mixlevelannotator.constfunc( + code.resume_after_void, [annmodel.SomePtr(lltype.Ptr(STATE_HEADER)), + annmodel.s_None], + annmodel.SomeInteger()) + mixlevelannotator.finish() s_global_state = bk.immutablevalue(code.global_state) @@ -244,7 +259,8 @@ self.is_finished = False - self.explicit_resume_points = {} + #self.explicit_resume_points = {} + self.symbolic_restart_numbers = {} # register the prebuilt restartinfos for restartinfo in frame.RestartInfo.prebuilt: @@ -404,6 +420,96 @@ new_start_block.isstartblock = True graph.startblock = new_start_block + def handle_resume_point(self, block, i): + # in some circumstances we might be able to reuse + # an already inserted resume point + op = block.operations[i] + if i == len(block.operations) - 1: + link = block.exits[0] + else: + link = support.split_block_with_keepalive(block, i+1) + parms = op.args[1:] + if not isinstance(parms[0], model.Variable): + assert parms[0].value is None + parms[0] = None + args = vars_to_save(block) + for a in args: + if a not in parms: + raise Exception, "not covered needed value at resume_point" + if parms[0] is not None: # returns= case + res = parms[0] + args = [arg for arg in args if arg is not res] + else: + args = args + res = op.result + + (frame_type, + fieldnames) = self.frametyper.frame_type_for_vars(parms[1:]) + + self.resume_points.append( + ResumePoint(res, parms[1:], tuple(block.exits), + frame_type, fieldnames)) + + label = op.args[0].value + + restart_number = len(self.masterarray1) + len(self.resume_points)-1 + +## assert label not in self.explicit_resume_points +## self.explicit_resume_points[label] = { +## 'restype': res.concretetype, +## } + + if label in self.symbolic_restart_numbers: + symb = self.symbolic_restart_numbers[label] + assert symb.value is None + symb.value = restart_number + else: + symb = SymbolicRestartNumber(restart_number) + self.symbolic_restart_numbers[label] = symb + + return link.target, i + + def handle_resume_state_create(self, block, i): + op = block.operations[i] + llops = LowLevelOpList() + # XXX we do not look at op.args[0], the prevstate, at all + label = op.args[1].value + parms = op.args[2:] + FRAME, fieldnames = self.frametyper.frame_type_for_vars(parms) + c_FRAME = model.Constant(FRAME, lltype.Void) + v_state = llops.genop('malloc', [c_FRAME], + resulttype = lltype.Ptr(FRAME)) + llops.extend(self.generate_saveops(v_state, parms, fieldnames)) + v_state = llops.genop('cast_pointer', [v_state], + resulttype = lltype.Ptr(frame.STATE_HEADER)) + + if label in self.symbolic_restart_numbers: + symb = self.symbolic_restart_numbers[label] + else: + symb = SymbolicRestartNumber() + self.symbolic_restart_numbers[label] = symb + + llops.genop('setfield', [v_state, + model.Constant('f_restart', lltype.Void), + model.Constant(symb, lltype.Signed)]) + llops.append(model.SpaceOperation('same_as', [v_state], op.result)) + block.operations[i:i+1] = llops + + def handle_resume_state_invoke(self, block, i): + op = block.operations[i] + if op.result.concretetype != lltype.Signed: + raise NotImplementedError + v_returns = op.args[1] + if v_returns.concretetype == lltype.Signed: + raise NotImplementedError + elif v_returns.concretetype == lltype.Void: + args = [self.resume_after_void_ptr] + op.args + newop = model.SpaceOperation('direct_call', args, op.result) + block.operations[i] = newop + else: + raise NotImplementedError + return newop + def transform_block(self, block): i = 0 @@ -424,51 +530,18 @@ op = replace_with_call(self.yield_current_frame_to_caller_ptr) stackless_op = True + if op.opname == 'resume_state_invoke': + op = self.handle_resume_state_invoke(block, i) + stackless_op = True + + if op.opname == 'resume_state_create': + self.handle_resume_state_create(block, i) + continue # go back and look at that malloc + if (op.opname in ('direct_call', 'indirect_call') or self.analyzer.operation_is_true(op)): if op.opname == 'resume_point': - # in some circumstances we might be able to reuse - # an already inserted resume point - if i == len(block.operations) - 1: - link = block.exits[0] - else: - link = support.split_block_with_keepalive(block, i+1) - parms = op.args[1:] - if not isinstance(parms[0], model.Variable): - assert parms[0].value is None - parms[0] = None - args = vars_to_save(block) - for a in args: - if a not in parms: - raise Exception, "not covered needed value at resume_point" - if parms[0] is not None: # returns= case - res = parms[0] - args = [arg for arg in args if arg is not res] - else: - args = args - res = op.result - - (frame_type, - fieldnames) = self.frametyper.frame_type_for_vars(args) - - self.resume_points.append( - ResumePoint(res, args, tuple(block.exits), - frame_type, fieldnames)) - - field2parm = {} - for arg, fieldname in zip(args, fieldnames): - p = parms.index(arg) - field2parm[fieldname] = p-1 # ignore parm[0] - - label = op.args[0].value - self.explicit_resume_points[label] = { - 'restart': len(self.masterarray1) + len(self.resume_points)-1, - 'frame_type': frame_type, - 'restype': res.concretetype, - 'field2parm': field2parm, - } - block = link.target - i = 0 + block, i = self.handle_resume_point(block, i) continue # trap calls to stackless-related suggested primitives @@ -477,7 +550,7 @@ if func in self.suggested_primitives: op = replace_with_call(self.suggested_primitives[func]) stackless_op = True - + if not stackless_op and not self.analyzer.analyze(op): i += 1 continue From hpk at codespeak.net Sat Jun 3 14:30:35 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Jun 2006 14:30:35 +0200 (CEST) Subject: [pypy-svn] r28159 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060603123035.EFDDE1006F@code0.codespeak.net> Author: hpk Date: Sat Jun 3 14:30:34 2006 New Revision: 28159 Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt Log: small update to planning (and testing website gen) Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/ddorf2006/planning.txt (original) +++ pypy/extradoc/sprintinfo/ddorf2006/planning.txt Sat Jun 3 14:30:34 2006 @@ -165,4 +165,5 @@ * 6 Allow users to specify 'allwaysnosy' - This is a codespeak issue, mainly. + postponed to 1.0, probably involves updating the tracker schema + on a larger scale. From hpk at codespeak.net Sat Jun 3 14:36:35 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Jun 2006 14:36:35 +0200 (CEST) Subject: [pypy-svn] r28160 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060603123635.0CD4410073@code0.codespeak.net> Author: hpk Date: Sat Jun 3 14:36:34 2006 New Revision: 28160 Modified: pypy/extradoc/sprintinfo/ddorf2006/people.txt Log: update my ddorf attendance Modified: pypy/extradoc/sprintinfo/ddorf2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/ddorf2006/people.txt (original) +++ pypy/extradoc/sprintinfo/ddorf2006/people.txt Sat Jun 3 14:36:34 2006 @@ -10,7 +10,7 @@ ==================== ============== ===================== Michael Hudson ? private Armin Rigo ? private -Holger Krekel 1st-9th ? +Holger Krekel 1st-8th hotel regina Carl Friedrich Bolz nope :-) private Eric van Riet Paap 6th - 8th private Maciej Fijalkowski 3rd-9th cfbolz From hpk at codespeak.net Sat Jun 3 14:43:22 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Jun 2006 14:43:22 +0200 (CEST) Subject: [pypy-svn] r28161 - in pypy/extradoc: . eu-report irclog minute paper planning planning/malaga_exhibition_feb2006 publication pypy.org soc-2006 sprintinfo sprintinfo/ddorf2006 sprintinfo/europython-2006 sprintinfo/gothenburg-2005 sprintinfo/iceland sprintinfo/leysin-winter-2006 sprintinfo/louvain-la-neuve-2006 sprintinfo/mallorca sprintinfo/paris sprintinfo/pycon06 sprintinfo/tokyo talk talk/22c3 talk/22c3/plots talk/LaTe_Lunch2006 talk/accu2006 talk/accu2006/accu-2006.key talk/accu2006/accu-2006.key/Contents talk/accu2006/accu-2006.key/thumbs talk/agile2006 talk/chalmers talk/chalmers/image talk/dls2006 talk/dls2006/image talk/ep2006 talk/img talk/louvain-la-neuve-2006 talk/louvain-la-neuve-2006/ui talk/louvain-la-neuve-2006/ui/default talk/mallorca-talk-2006 talk/mallorca-talk-2006/ui talk/mallorca-talk-2006/ui/default talk/pycon2006 talk/pycon2006/pypy-selfcontained-2.key talk/pycon2006/pypy-selfcontained-2.key/Contents talk/pycon2006/pypy-selfcontained-2.key/thumbs talk/pycon2006/pypy-selfcontained-3.key talk/pycon2006/pypy-selfcontained-3.key/Contents talk/pycon2006/pypy-selfcontained-3.key/thumbs talk/pycon2006/pypy-selfcontained.key talk/pycon2006/pypy-selfcontained.key/Contents talk/pycon2006/pypy-selfcontained.key/thumbs talk/pypy-talk-pycon2005 talk/pypy-talk-pycon2005/bubbob talk/pypy-talk-pycon2005/bubbob/ext5 talk/pypy-talk-pycon2005/bubbob/images talk/pypy-talk-pycon2005/bubbob/pat talk/pypy_euworkshop_2005-12-08 talk/sprint-introduction.key talk/sprint-introduction.key/Contents talk/sprint-introduction.key/thumbs talk/tokyo talk/tokyo/ui talk/tokyo/ui/default talk/ui talk/ui/default Message-ID: <20060603124322.8B2EC10072@code0.codespeak.net> Author: hpk Date: Sat Jun 3 14:43:18 2006 New Revision: 28161 Removed: pypy/extradoc/to_edu_sig.txt Modified: pypy/extradoc/eu-report/ (props changed) pypy/extradoc/irclog/ (props changed) pypy/extradoc/minute/ (props changed) pypy/extradoc/paper/ (props changed) pypy/extradoc/planning/ (props changed) pypy/extradoc/planning/malaga_exhibition_feb2006/ (props changed) pypy/extradoc/publication/ (props changed) pypy/extradoc/pypy.org/ (props changed) pypy/extradoc/soc-2006/ (props changed) pypy/extradoc/sprintinfo/ (props changed) pypy/extradoc/sprintinfo/ddorf2006/ (props changed) pypy/extradoc/sprintinfo/ddorf2006/day0-issue-status.txt (props changed) pypy/extradoc/sprintinfo/ddorf2006/planning.txt (props changed) pypy/extradoc/sprintinfo/europython-2006/ (props changed) pypy/extradoc/sprintinfo/europython-2006/announce.txt (props changed) pypy/extradoc/sprintinfo/europython-2006/people.txt (props changed) pypy/extradoc/sprintinfo/gothenburg-2005/ (props changed) pypy/extradoc/sprintinfo/iceland/ (props changed) pypy/extradoc/sprintinfo/leysin-winter-2006/ (props changed) pypy/extradoc/sprintinfo/louvain-la-neuve-2006/ (props changed) pypy/extradoc/sprintinfo/mallorca/ (props changed) pypy/extradoc/sprintinfo/paris/ (props changed) pypy/extradoc/sprintinfo/pycon06/ (props changed) pypy/extradoc/sprintinfo/tokyo/ (props changed) pypy/extradoc/sprintinfo/tokyo/sprint-report.txt (contents, props changed) pypy/extradoc/talk/ (props changed) pypy/extradoc/talk/22c3/ (props changed) pypy/extradoc/talk/22c3/plots/ (props changed) pypy/extradoc/talk/LaTe_Lunch2006/ (props changed) pypy/extradoc/talk/accu2006/ (props changed) pypy/extradoc/talk/accu2006/accu-2006.key/ (props changed) pypy/extradoc/talk/accu2006/accu-2006.key/Contents/ (props changed) pypy/extradoc/talk/accu2006/accu-2006.key/thumbs/ (props changed) pypy/extradoc/talk/agile2006/ (props changed) pypy/extradoc/talk/chalmers/ (props changed) pypy/extradoc/talk/chalmers/image/ (props changed) pypy/extradoc/talk/dls2006/ (props changed) pypy/extradoc/talk/dls2006/image/ (props changed) pypy/extradoc/talk/ep2006/ (props changed) pypy/extradoc/talk/ep2006/archsession.txt (props changed) pypy/extradoc/talk/ep2006/usecases.txt (props changed) pypy/extradoc/talk/img/ (props changed) pypy/extradoc/talk/louvain-la-neuve-2006/ (props changed) pypy/extradoc/talk/louvain-la-neuve-2006/ui/ (props changed) pypy/extradoc/talk/louvain-la-neuve-2006/ui/default/ (props changed) pypy/extradoc/talk/mallorca-talk-2006/ (props changed) pypy/extradoc/talk/mallorca-talk-2006/ui/ (props changed) pypy/extradoc/talk/mallorca-talk-2006/ui/default/ (props changed) pypy/extradoc/talk/pycon2006/ (props changed) pypy/extradoc/talk/pycon2006/pypy-selfcontained-2.key/ (props changed) pypy/extradoc/talk/pycon2006/pypy-selfcontained-2.key/Contents/ (props changed) pypy/extradoc/talk/pycon2006/pypy-selfcontained-2.key/thumbs/ (props changed) pypy/extradoc/talk/pycon2006/pypy-selfcontained-3.key/ (props changed) pypy/extradoc/talk/pycon2006/pypy-selfcontained-3.key/Contents/ (props changed) pypy/extradoc/talk/pycon2006/pypy-selfcontained-3.key/thumbs/ (props changed) pypy/extradoc/talk/pycon2006/pypy-selfcontained.key/ (props changed) pypy/extradoc/talk/pycon2006/pypy-selfcontained.key/Contents/ (props changed) pypy/extradoc/talk/pycon2006/pypy-selfcontained.key/thumbs/ (props changed) pypy/extradoc/talk/pypy-talk-pycon2005/ (props changed) pypy/extradoc/talk/pypy-talk-pycon2005/bubbob/ (props changed) pypy/extradoc/talk/pypy-talk-pycon2005/bubbob/ext5/ (props changed) pypy/extradoc/talk/pypy-talk-pycon2005/bubbob/images/ (props changed) pypy/extradoc/talk/pypy-talk-pycon2005/bubbob/pat/ (props changed) pypy/extradoc/talk/pypy_euworkshop_2005-12-08/ (props changed) pypy/extradoc/talk/sprint-introduction.key/ (props changed) pypy/extradoc/talk/sprint-introduction.key/Contents/ (props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/ (props changed) pypy/extradoc/talk/tokyo/ (props changed) pypy/extradoc/talk/tokyo/ui/ (props changed) pypy/extradoc/talk/tokyo/ui/default/ (props changed) pypy/extradoc/talk/ui/ (props changed) pypy/extradoc/talk/ui/default/ (props changed) Log: FIXEOL + ignoring .html Modified: pypy/extradoc/sprintinfo/tokyo/sprint-report.txt ============================================================================== --- pypy/extradoc/sprintinfo/tokyo/sprint-report.txt (original) +++ pypy/extradoc/sprintinfo/tokyo/sprint-report.txt Sat Jun 3 14:43:18 2006 @@ -1,82 +1,82 @@ -Tokyo 2006 Sprint Report -============================= - -Parts of the PyPy team visited Tokyo and hosted a sprint between 23-29th of April, 2006. -We sprinted in the facilities of the National Institute of Advanced Science and -Technology, being invited by The Free Software Initiative of Japan. The idea was to -promote Python as a programming language and present PyPy for Japanese hackers. - -Here is the list of people participating in the sprint: - - * Anders Lehmann - * Nik Haldimann - * Samuele Pedronis - * Beatrice D?ring - * Anders Chrigstrom (Arre) - * Eric Van Riet Paap - * Valentino Volonghi - * Sanghyeon Seo - * Yutaka Niibe - * Yusei Tahara - * George Toshida - * Koichi Sasada - -The announced goals for the sprint were: - - Work on gensqueak (our Squeak backend) or possibly other backends. - - - Implementing Python 2.5 features in PyPy. - - - Progress further on an 'rctypes' module aiming at letting us use a ctypes - implementation of an extension module from the compiled pypy-c. - - - Writing ctypes implementations of modules to be used by the above - tool. - - - Experimenting and improving performance of our garbage collectors. - - - Experiment with PyPy flexibility or other aspects of the implementation. - - - Possibly experiment with writing modules translatable for use both - in PyPy and CPython. - - - Whatever participants want to do with PyPy or particular areas - of PyPy (please send suggestions to the mailing list before to allow us to plan - and give feedback) - -After an initial round of checking general interests in the group during the first day we ended -up with this list - the content of the sprint is a mix between these goald and interests -and of course all topics on these lists were not achieved although we were productive ;-): - - - gensqueak/ootypesystem - - - Implementing Python 2.5 features in PyPy. - - - Progress further on an 'rctypes' module aiming at letting us use a ctypes - implementation of an extension module from the compiled pypy-c. - - - check status - - ctypes time and socket (and select ;)) - - - rctypes support for LLVM (Eric) - - - convert JS backend to ootypesystem - - - genjs test failure fixes - - - raisingops transformation - - - PyPy debian packaging? - - - Fun with the Common Lisp backend - - - Possibly experiment with writing modules translatable for use both - in PyPy and CPython. - -Day 1-3 ------------ - -Breakday ------------ - -Day 5-7 +Tokyo 2006 Sprint Report +============================= + +Parts of the PyPy team visited Tokyo and hosted a sprint between 23-29th of April, 2006. +We sprinted in the facilities of the National Institute of Advanced Science and +Technology, being invited by The Free Software Initiative of Japan. The idea was to +promote Python as a programming language and present PyPy for Japanese hackers. + +Here is the list of people participating in the sprint: + + * Anders Lehmann + * Nik Haldimann + * Samuele Pedronis + * Beatrice D?ring + * Anders Chrigstrom (Arre) + * Eric Van Riet Paap + * Valentino Volonghi + * Sanghyeon Seo + * Yutaka Niibe + * Yusei Tahara + * George Toshida + * Koichi Sasada + +The announced goals for the sprint were: + - Work on gensqueak (our Squeak backend) or possibly other backends. + + - Implementing Python 2.5 features in PyPy. + + - Progress further on an 'rctypes' module aiming at letting us use a ctypes + implementation of an extension module from the compiled pypy-c. + + - Writing ctypes implementations of modules to be used by the above + tool. + + - Experimenting and improving performance of our garbage collectors. + + - Experiment with PyPy flexibility or other aspects of the implementation. + + - Possibly experiment with writing modules translatable for use both + in PyPy and CPython. + + - Whatever participants want to do with PyPy or particular areas + of PyPy (please send suggestions to the mailing list before to allow us to plan + and give feedback) + +After an initial round of checking general interests in the group during the first day we ended +up with this list - the content of the sprint is a mix between these goald and interests +and of course all topics on these lists were not achieved although we were productive ;-): + + - gensqueak/ootypesystem + + - Implementing Python 2.5 features in PyPy. + + - Progress further on an 'rctypes' module aiming at letting us use a ctypes + implementation of an extension module from the compiled pypy-c. + + - check status + - ctypes time and socket (and select ;)) + + - rctypes support for LLVM (Eric) + + - convert JS backend to ootypesystem + + - genjs test failure fixes + + - raisingops transformation + + - PyPy debian packaging? + + - Fun with the Common Lisp backend + + - Possibly experiment with writing modules translatable for use both + in PyPy and CPython. + +Day 1-3 +----------- + +Breakday +----------- + +Day 5-7 ---------- \ No newline at end of file From hpk at codespeak.net Sat Jun 3 15:10:04 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Jun 2006 15:10:04 +0200 (CEST) Subject: [pypy-svn] r28162 - pypy/extradoc/talk/dls2006 Message-ID: <20060603131004.6B3A710060@code0.codespeak.net> Author: hpk Date: Sat Jun 3 15:09:57 2006 New Revision: 28162 Modified: pypy/extradoc/talk/dls2006/outline.txt Log: fixing ReST Modified: pypy/extradoc/talk/dls2006/outline.txt ============================================================================== --- pypy/extradoc/talk/dls2006/outline.txt (original) +++ pypy/extradoc/talk/dls2006/outline.txt Sat Jun 3 15:09:57 2006 @@ -52,6 +52,6 @@ ========== Works, effectively increases flexibility and expressiveness, - reasonably efficient, quite confusing at times; +reasonably efficient, quite confusing at times; work in progress, some things are rough and could use more streamlined implementations and uniform approaches From hpk at codespeak.net Sat Jun 3 15:37:29 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Jun 2006 15:37:29 +0200 (CEST) Subject: [pypy-svn] r28163 - pypy/dist/pypy/doc Message-ID: <20060603133729.2975110070@code0.codespeak.net> Author: hpk Date: Sat Jun 3 15:37:23 2006 New Revision: 28163 Modified: pypy/dist/pypy/doc/extradoc.txt Log: added michael's talk Modified: pypy/dist/pypy/doc/extradoc.txt ============================================================================== --- pypy/dist/pypy/doc/extradoc.txt (original) +++ pypy/dist/pypy/doc/extradoc.txt Sat Jun 3 15:37:23 2006 @@ -5,6 +5,9 @@ Talks and Presentations ---------------------------------- +* `PyPy intro`_ talk, given at ACCU 2006 (April), also stating the status + of the project. + * oscon2003-paper_ an early paper presented at Oscon 2003 describing what the PyPy project is about and why you should care. @@ -19,6 +22,7 @@ * `py lib slides`_ from the py lib talk at PyCon 2005 (py is used as a support/testing library for PyPy). +.. _`PyPy intro`: http://codespeak.net/pypy/extradoc/talk/accu2006/accu-2006.pdf .. _oscon2003-paper: http://codespeak.net/pypy/extradoc/talk/oscon2003-paper.html .. _`Architecture introduction slides`: http://codespeak.net/pypy/extradoc/talk/amsterdam-sprint-intro.pdf .. _`EU funding for FOSS`: http://codespeak.net/pypy/extradoc/talk/2004-21C3-pypy-EU-hpk.pdf From hpk at codespeak.net Sat Jun 3 15:43:46 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Jun 2006 15:43:46 +0200 (CEST) Subject: [pypy-svn] r28164 - pypy/dist/pypy/doc Message-ID: <20060603134346.AFBAC10070@code0.codespeak.net> Author: hpk Date: Sat Jun 3 15:43:46 2006 New Revision: 28164 Modified: pypy/dist/pypy/doc/extradoc.txt Log: add pycon method talk and 22C3 pypy talk Modified: pypy/dist/pypy/doc/extradoc.txt ============================================================================== --- pypy/dist/pypy/doc/extradoc.txt (original) +++ pypy/dist/pypy/doc/extradoc.txt Sat Jun 3 15:43:46 2006 @@ -5,8 +5,15 @@ Talks and Presentations ---------------------------------- -* `PyPy intro`_ talk, given at ACCU 2006 (April), also stating the status - of the project. +* `PyPy intro`_ talk, given by Michael Hudson at ACCU 2006 (April), + also stating the status of the project. + +* `PyPy development method`_ talk, given by Bea During and + Holger Krekel at Pycon2006 + +* `PyPy - the new Python implementation on the block`_ talk, + given by Carl Friedrich Bolz and Holger Krekel at the + 22nd Chaos Communication Conference in Berlin, Dec. 2005. * oscon2003-paper_ an early paper presented at Oscon 2003 describing what the PyPy project is about and why you should care. @@ -22,6 +29,8 @@ * `py lib slides`_ from the py lib talk at PyCon 2005 (py is used as a support/testing library for PyPy). +.. _`PyPy - the new Python implementation on the block`: http://codespeak.net/pypy/extradoc/talk/22c3/hpk-tech.html +.. _`PyPy development method`: http://codespeak.net/pypy/extradoc/talk/pycon2006/method_talk.html .. _`PyPy intro`: http://codespeak.net/pypy/extradoc/talk/accu2006/accu-2006.pdf .. _oscon2003-paper: http://codespeak.net/pypy/extradoc/talk/oscon2003-paper.html .. _`Architecture introduction slides`: http://codespeak.net/pypy/extradoc/talk/amsterdam-sprint-intro.pdf From ac at codespeak.net Sat Jun 3 16:21:40 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sat, 3 Jun 2006 16:21:40 +0200 (CEST) Subject: [pypy-svn] r28167 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20060603142140.DE91C10070@code0.codespeak.net> Author: ac Date: Sat Jun 3 16:21:39 2006 New Revision: 28167 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py Log: (cfbolz, arre) Rigg some tests :-) Modified: pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py Sat Jun 3 16:21:39 2006 @@ -509,7 +509,11 @@ del c1, c2, C, D gc.collect() - def test_callback_in_cycle_resurrection(self): + def XXX_test_callback_in_cycle_resurrection(self): + # We can't guarrantee the behaviour tested with our + # current weakref implementations. + # If an object and a weakref to it gets collected at the + # same time it is unclear whether the callback is called. import gc # Do something nasty in a weakref callback: resurrect objects @@ -555,7 +559,8 @@ gc.collect() self.assertEqual(alist, []) - def test_callbacks_on_callback(self): + def XXX_test_callbacks_on_callback(self): + # See XXX_test_callback_in_cycle_resurrection above import gc # Set up weakref callbacks *on* weakref callbacks. @@ -600,8 +605,12 @@ self.check_gc_during_creation(weakref.proxy) def check_gc_during_creation(self, makeref): - thresholds = gc.get_threshold() - gc.set_threshold(1, 1, 1) + # gc.get/set_threshold does not exist in pypy + # The tests calling this function probaly don't test anything + # usefull anymore + + #thresholds = gc.get_threshold() + #gc.set_threshold(1, 1, 1) gc.collect() class A: pass @@ -622,7 +631,7 @@ weakref.ref(referenced, callback) finally: - gc.set_threshold(*thresholds) + pass #gc.set_threshold(*thresholds) class SubclassableWeakrefTestCase(unittest.TestCase): @@ -705,6 +714,7 @@ # # This exercises d.copy(), d.items(), d[], del d[], len(d). # + import gc dict, objects = self.make_weak_valued_dict() for o in objects: self.assert_(weakref.getweakrefcount(o) == 1, @@ -720,6 +730,7 @@ del items1, items2 self.assert_(len(dict) == self.COUNT) del objects[0] + gc.collect() self.assert_(len(dict) == (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o @@ -736,6 +747,7 @@ # This exercises d.copy(), d.items(), d[] = v, d[], del d[], # len(d), d.has_key(). # + import gc dict, objects = self.make_weak_keyed_dict() for o in objects: self.assert_(weakref.getweakrefcount(o) == 1, @@ -749,6 +761,7 @@ del items1, items2 self.assert_(len(dict) == self.COUNT) del objects[0] + gc.collect() self.assert_(len(dict) == (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o From mwh at codespeak.net Sat Jun 3 16:41:40 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Jun 2006 16:41:40 +0200 (CEST) Subject: [pypy-svn] r28168 - in pypy/dist/pypy: rpython translator/stackless translator/stackless/test Message-ID: <20060603144140.AB3AC10070@code0.codespeak.net> Author: mwh Date: Sat Jun 3 16:41:39 2006 New Revision: 28168 Modified: pypy/dist/pypy/rpython/rstack.py pypy/dist/pypy/translator/stackless/code.py pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) Add a test that chains resume_points. Add functionality needed to make this pass and fix the bugs that got in the way. Add some sanity checks to the code. Modified: pypy/dist/pypy/rpython/rstack.py ============================================================================== --- pypy/dist/pypy/rpython/rstack.py (original) +++ pypy/dist/pypy/rpython/rstack.py Sat Jun 3 16:41:39 2006 @@ -85,8 +85,7 @@ assert hop.args_s[1].is_constant() c_label = hop.inputconst(lltype.Void, hop.args_s[1].const) - r = SimplePointerRepr(lltype.Ptr(STATE_HEADER)) - v_state = hop.inputarg(r, arg=0) + v_state = hop.inputarg(hop.r_result, arg=0) args_v = hop.args_v[2:] Modified: pypy/dist/pypy/translator/stackless/code.py ============================================================================== --- pypy/dist/pypy/translator/stackless/code.py (original) +++ pypy/dist/pypy/translator/stackless/code.py Sat Jun 3 16:41:39 2006 @@ -203,7 +203,10 @@ mystate = global_state.top s = lltype.cast_pointer(lltype.Ptr(RESUME_AFTER_STATE), mystate) targetstate = s.c - targetstate.f_back = mystate.f_back + resume_bottom = targetstate + while resume_bottom.f_back: + resume_bottom = resume_bottom.f_back + resume_bottom.f_back = mystate.f_back global_state.top = targetstate raise UnwindException() else: Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sat Jun 3 16:41:39 2006 @@ -29,6 +29,19 @@ res = llinterp_stackless_function(example, assert_unwind=False) assert res == 24 +def test_bogus_restart_state_create(): + def f(x, y): + x = x-1 + rstack.resume_point("rp0", x, y) + return x+y + def example(): + v1 = f(one(),one()+one()) + state = rstack.resume_state_create(None, "rp0", one()) + return v1 + info = py.test.raises(AssertionError, "transform_stackless_function(example)") + assert 'rp0' in str(info.value) + + def test_call(): def g(x,y): return x*y @@ -71,3 +84,20 @@ e = py.test.raises(Exception, transform_stackless_function, example) assert e.value.args == ('not covered needed value at resume_point',) +def test_chained_states(): + def g(x, y): + x += 1 + rstack.resume_point("rp1", x, y) + return x + y + def f(x, y, z): + y += 1 + r = g(x, y) + rstack.resume_point("rp2", z, returns=r) + return r + z + def example(): + v1 = f(one(), 2*one(), 3*one()) + s2 = rstack.resume_state_create(None, "rp2", 2*one()) + s1 = rstack.resume_state_create(s2, "rp1", 4*one(), 5*one()) + return 100*v1 + rstack.resume_state_invoke(int, s1) + res = llinterp_stackless_function(example, assert_unwind=False) + assert res == 811 Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sat Jun 3 16:41:39 2006 @@ -259,7 +259,9 @@ self.is_finished = False - #self.explicit_resume_points = {} + # only for sanity checking, but still very very important + self.explicit_resume_point_data = {} + self.symbolic_restart_numbers = {} # register the prebuilt restartinfos @@ -446,19 +448,20 @@ (frame_type, fieldnames) = self.frametyper.frame_type_for_vars(parms[1:]) + label = op.args[0].value + + if label in self.explicit_resume_point_data: + other_type = self.explicit_resume_point_data[label] + assert frame_type == other_type, "inconsistent types for label %r"%(label,) + else: + self.explicit_resume_point_data[label] = frame_type + self.resume_points.append( ResumePoint(res, parms[1:], tuple(block.exits), frame_type, fieldnames)) - label = op.args[0].value - restart_number = len(self.masterarray1) + len(self.resume_points)-1 -## assert label not in self.explicit_resume_points -## self.explicit_resume_points[label] = { -## 'restype': res.concretetype, -## } - if label in self.symbolic_restart_numbers: symb = self.symbolic_restart_numbers[label] assert symb.value is None @@ -476,6 +479,13 @@ label = op.args[1].value parms = op.args[2:] FRAME, fieldnames = self.frametyper.frame_type_for_vars(parms) + + if label in self.explicit_resume_point_data: + other_type = self.explicit_resume_point_data[label] + assert FRAME == other_type, "inconsistent types for label %r"%(label,) + else: + self.explicit_resume_point_data[label] = FRAME + c_FRAME = model.Constant(FRAME, lltype.Void) v_state = llops.genop('malloc', [c_FRAME], resulttype = lltype.Ptr(FRAME)) @@ -492,6 +502,9 @@ llops.genop('setfield', [v_state, model.Constant('f_restart', lltype.Void), model.Constant(symb, lltype.Signed)]) + llops.genop('setfield', [v_state, + model.Constant('f_back', lltype.Void), + op.args[0]]) llops.append(model.SpaceOperation('same_as', [v_state], op.result)) block.operations[i:i+1] = llops From mwh at codespeak.net Sat Jun 3 16:52:50 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Jun 2006 16:52:50 +0200 (CEST) Subject: [pypy-svn] r28172 - pypy/dist/pypy/translator/stackless/test Message-ID: <20060603145250.2055A10070@code0.codespeak.net> Author: mwh Date: Sat Jun 3 16:52:49 2006 New Revision: 28172 Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py Log: (mwh, pedronis) A new test, which passes. Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sat Jun 3 16:52:49 2006 @@ -101,3 +101,25 @@ return 100*v1 + rstack.resume_state_invoke(int, s1) res = llinterp_stackless_function(example, assert_unwind=False) assert res == 811 + +def test_return_instance(): + class C: + pass + def g(x): + c = C() + c.x = x + 1 + rstack.resume_point("rp1", c) + return c + def f(x, y): + r = g(x) + rstack.resume_point("rp2", y, returns=r) + return r.x + y + def example(): + v1 = f(one(), 2*one()) + s2 = rstack.resume_state_create(None, "rp2", 2*one()) + c = C() + c.x = 4*one() + s1 = rstack.resume_state_create(s2, "rp1", c) + return v1*100 + rstack.resume_state_invoke(int, s1) + res = llinterp_stackless_function(example, assert_unwind=False) + assert res == 406 From tismer at codespeak.net Sat Jun 3 17:18:46 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 3 Jun 2006 17:18:46 +0200 (CEST) Subject: [pypy-svn] r28174 - pypy/dist/pypy/interpreter Message-ID: <20060603151846.3256110070@code0.codespeak.net> Author: tismer Date: Sat Jun 3 17:18:45 2006 New Revision: 28174 Modified: pypy/dist/pypy/interpreter/pyframe.py Log: added some YYY to the XXX about frame pickling Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Sat Jun 3 17:18:45 2006 @@ -105,6 +105,9 @@ ] #XXX what to do with valuestack and blockstack here? + #YYY well, we build the valuestack as a tuple (with a marker for NULL objects) + #YYY and we pickle the blockstack as well. + #YYY see frameobject_reduce line 722 in prickelpit.c in the stackless distro. return space.newtuple([new_inst, space.newtuple(tup)]) From antocuni at codespeak.net Sat Jun 3 17:28:12 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Jun 2006 17:28:12 +0200 (CEST) Subject: [pypy-svn] r28175 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem test Message-ID: <20060603152812.8F4E110070@code0.codespeak.net> Author: antocuni Date: Sat Jun 3 17:28:11 2006 New Revision: 28175 Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py pypy/dist/pypy/rpython/ootypesystem/rpbc.py pypy/dist/pypy/rpython/rpbc.py pypy/dist/pypy/rpython/test/test_rpbc.py Log: (antocuni, nik, arigo) Generalized the instantiation of classes: now the two typesystems shares most of the code, and as a bonus a failing test now passes. Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py Sat Jun 3 17:28:11 2006 @@ -151,56 +151,12 @@ # no __init__ here, AbstractClassesPBCRepr.__init__ is good enough - def rtype_simple_call(self, hop): - return self.redispatch_call(hop, call_args=False) + def _instantiate_runtime_class(self, hop, vtypeptr, r_instance): + from pypy.rpython.lltypesystem.rbuiltin import ll_instantiate + v_inst1 = hop.gendirectcall(ll_instantiate, vtypeptr) + return hop.genop('cast_pointer', [v_inst1], resulttype = r_instance) - def rtype_call_args(self, hop): - return self.redispatch_call(hop, call_args=True) - def redispatch_call(self, hop, call_args): - s_instance = hop.s_result - r_instance = hop.r_result - - if self.lowleveltype is Void: - # instantiating a single class - assert isinstance(s_instance, annmodel.SomeInstance) - classdef = hop.s_result.classdef - v_instance = rclass.rtype_new_instance(hop.rtyper, classdef, - hop.llops, hop) - if isinstance(v_instance, tuple): - v_instance, must_call_init = v_instance - if not must_call_init: - return v_instance - s_init = classdef.classdesc.s_read_attribute('__init__') - v_init = Constant("init-func-dummy") # this value not really used - else: - # instantiating a class from multiple possible classes - from pypy.rpython.lltypesystem.rbuiltin import ll_instantiate - vtypeptr = hop.inputarg(self, arg=0) - try: - access_set, r_class = self.get_access_set('__init__') - except MissingRTypeAttribute: - s_init = annmodel.s_ImpossibleValue - else: - s_init = access_set.s_value - v_init = r_class.getpbcfield(vtypeptr, access_set, '__init__', - hop.llops) - v_inst1 = hop.gendirectcall(ll_instantiate, vtypeptr) - v_instance = hop.genop('cast_pointer', [v_inst1], - resulttype = r_instance) - - if isinstance(s_init, annmodel.SomeImpossibleValue): - assert hop.nb_args == 1, ("arguments passed to __init__, " - "but no __init__!") - else: - hop2 = self.replace_class_with_inst_arg( - hop, v_instance, s_instance, call_args) - hop2.v_s_insertfirstarg(v_init, s_init) # add 'initfunc' - hop2.s_result = annmodel.s_None - hop2.r_result = self.rtyper.getrepr(hop2.s_result) - # now hop2 looks like simple_call(initfunc, instance, args...) - hop2.dispatch() - return v_instance # ____________________________________________________________ Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Sat Jun 3 17:28:11 2006 @@ -11,6 +11,7 @@ from pypy.annotation import model as annmodel from pypy.annotation import description from pypy.annotation.pairtype import pairtype +from pypy.objspace.flow.model import Constant, Variable import types @@ -37,54 +38,19 @@ return llop.genop('oogetfield', [v, c_rowname], resulttype=resulttype) class ClassesPBCRepr(AbstractClassesPBCRepr): - - def rtype_simple_call(self, hop): - classdef = hop.s_result.classdef - if self.lowleveltype is not ootype.Void: - # instantiating a class from multiple possible classes - v_meta = hop.inputarg(self, arg=0) - c_class_ = hop.inputconst(ootype.Void, "class_") - v_class = hop.genop('oogetfield', [v_meta, c_class_], - resulttype=ootype.Class) - resulttype = getinstancerepr(hop.rtyper, classdef).lowleveltype - v_instance = hop.genop('runtimenew', [v_class], resulttype=resulttype) - c_meta = hop.inputconst(ootype.Void, "meta") - hop.genop('oosetfield', [v_instance, c_meta, v_meta], - resulttype=ootype.Void) - else: - # instantiating a single class - v_instance = rtype_new_instance(hop.rtyper, classdef, hop.llops) - - inits = [] - for desc in self.s_pbc.descriptions: - if desc.find_source_for('__init__') is not None: - unbound = desc.s_get_value(desc.getuniqueclassdef(), '__init__') - if isinstance(unbound, annmodel.SomePBC): - unbound, = unbound.descriptions - bound = unbound.bind_self(desc.getuniqueclassdef()) - inits.append(bound) - else: - assert isinstance(unbound, annmodel.SomeBuiltin) - # do nothing, because builtin __init__s (for - # example from exceptions such as Exception and - # AssertionError) do nothing. - - if inits: - s_init = annmodel.SomePBC(inits) - s_instance = annmodel.SomeInstance(classdef) - hop2 = hop.copy() - hop2.r_s_popfirstarg() # discard the class pointer argument - hop2.v_s_insertfirstarg(v_instance, s_init) # add 'instance' - hop2.s_result = annmodel.s_None - hop2.r_result = self.rtyper.getrepr(hop2.s_result) - # now hop2 looks like simple_call(initmeth, args...) - hop2.dispatch() - else: - assert hop.nb_args == 1, ("arguments passed to __init__, " - "but no __init__!") + + def _instantiate_runtime_class(self, hop, v_meta, r_instance): + classdef = hop.s_result.classdef + c_class_ = hop.inputconst(ootype.Void, "class_") + v_class = hop.genop('oogetfield', [v_meta, c_class_], + resulttype=ootype.Class) + resulttype = getinstancerepr(hop.rtyper, classdef).lowleveltype + v_instance = hop.genop('runtimenew', [v_class], resulttype=resulttype) + c_meta = hop.inputconst(ootype.Void, "meta") + hop.genop('oosetfield', [v_instance, c_meta, v_meta], + resulttype=ootype.Void) return v_instance - rtype_call_args = rtype_simple_call def row_method_name(methodname, rowname): return "%s_%s" % (methodname, rowname) Modified: pypy/dist/pypy/rpython/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/rpbc.py (original) +++ pypy/dist/pypy/rpython/rpbc.py Sat Jun 3 17:28:11 2006 @@ -651,6 +651,55 @@ hop2.v_s_insertfirstarg(v_inst, s_inst) # add 'instance' return hop2 + def rtype_simple_call(self, hop): + return self.redispatch_call(hop, call_args=False) + + def rtype_call_args(self, hop): + return self.redispatch_call(hop, call_args=True) + + def redispatch_call(self, hop, call_args): + s_instance = hop.s_result + r_instance = hop.r_result + + if self.lowleveltype is Void: + # instantiating a single class + assert isinstance(s_instance, annmodel.SomeInstance) + classdef = hop.s_result.classdef + v_instance = rclass.rtype_new_instance(hop.rtyper, classdef, + hop.llops, hop) + if isinstance(v_instance, tuple): + v_instance, must_call_init = v_instance + if not must_call_init: + return v_instance + s_init = classdef.classdesc.s_read_attribute('__init__') + v_init = Constant("init-func-dummy") # this value not really used + else: + # instantiating a class from multiple possible classes + vtypeptr = hop.inputarg(self, arg=0) + try: + access_set, r_class = self.get_access_set('__init__') + except MissingRTypeAttribute: + s_init = annmodel.s_ImpossibleValue + else: + s_init = access_set.s_value + v_init = r_class.getpbcfield(vtypeptr, access_set, '__init__', + hop.llops) + v_instance = self._instantiate_runtime_class(hop, vtypeptr, r_instance) + + if isinstance(s_init, annmodel.SomeImpossibleValue): + assert hop.nb_args == 1, ("arguments passed to __init__, " + "but no __init__!") + else: + hop2 = self.replace_class_with_inst_arg( + hop, v_instance, s_instance, call_args) + hop2.v_s_insertfirstarg(v_init, s_init) # add 'initfunc' + hop2.s_result = annmodel.s_None + hop2.r_result = self.rtyper.getrepr(hop2.s_result) + # now hop2 looks like simple_call(initfunc, instance, args...) + hop2.dispatch() + return v_instance + + class __extend__(pairtype(AbstractClassesPBCRepr, rclass.AbstractClassRepr)): def convert_from_to((r_clspbc, r_cls), v, llops): Modified: pypy/dist/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rpbc.py (original) +++ pypy/dist/pypy/rpython/test/test_rpbc.py Sat Jun 3 17:28:11 2006 @@ -28,6 +28,9 @@ class MySubclassWithoutInit(MyBaseWithInit): pass +class MySubclassWithoutMethods(MyBase): + pass + class Freezing: def _freeze_(self): return True @@ -132,12 +135,18 @@ assert self.interpret(f, [6, 7]) == 42 def test_class_init_inherited(self): - self._skip_oo('inherited __init__') def f(a): instance = MySubclassWithoutInit(a) return instance.a1 assert self.interpret(f, [42]) == 42 + def test_class_method_inherited(self): + def f(a): + instance = MySubclassWithoutMethods() + instance.z = a + return instance.m(a) + assert self.interpret(f, [42]) == 84 + def test_freezing(self): fr1 = Freezing() fr2 = Freezing() From hpk at codespeak.net Sat Jun 3 17:45:26 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Jun 2006 17:45:26 +0200 (CEST) Subject: [pypy-svn] r28176 - in pypy/extradoc: minute soc-2006 sprintinfo talk talk/dls2006 Message-ID: <20060603154526.606541000A@code0.codespeak.net> Author: hpk Date: Sat Jun 3 17:45:24 2006 New Revision: 28176 Added: pypy/extradoc/talk/dls2006/conftest.py Modified: pypy/extradoc/minute/pypy-sync-2006-04-20.txt pypy/extradoc/minute/pypy-sync-2006-05-11.txt pypy/extradoc/soc-2006/code-templating.txt pypy/extradoc/sprintinfo/conftest.py pypy/extradoc/talk/solutions-linux-paris-2006.html Log: fix ReST issues, prevent some directory/patterns from causing trouble (dls paper, sprintinfo/*planning.txt files) Modified: pypy/extradoc/minute/pypy-sync-2006-04-20.txt ============================================================================== --- pypy/extradoc/minute/pypy-sync-2006-04-20.txt (original) +++ pypy/extradoc/minute/pypy-sync-2006-04-20.txt Sat Jun 3 17:45:24 2006 @@ -13,10 +13,8 @@ we quickly agreed to a) go for being mentors through PSF at Google's Summe of Code campaign b) determined mentors - c) to create a directory in extradoc/soc-2006 listing all info - (mentors, topics) - d) next week Michael will communicate all the info - to Neal / PSF / SoC + c) to create a directory in extradoc/soc-2006 listing all info (mentors, topics) + d) next week Michael will communicate all the info to Neal / PSF / SoC - what needs to be done until Iceland (21st May) for 0.9? @@ -38,207 +36,209 @@ IRC log ------------------------------- -Apr 20 17:28:55 stakkars: hi! -Apr 20 17:29:25 hi friends -Apr 20 17:29:59 I'll give rxe a call -Apr 20 17:30:25 hi all! -Apr 20 17:30:33 stakkars stedi67 Apr 20 17:30:37 stakkars: want to wake him up? :) -Apr 20 17:30:45 hi -Apr 20 17:30:53 T-0 according to me -Apr 20 17:30:58 yip -Apr 20 17:31:01 who is moderating? hpk ? -Apr 20 17:31:06 yes, i guess so -Apr 20 17:31:17 topics: -Apr 20 17:31:17 * activity reports -Apr 20 17:31:17 * summer of X -Apr 20 17:31:17 * work until iceland for 0.9 topics -Apr 20 17:31:17 * assigning major 0.9 topics -Apr 20 17:31:23 he's early, probably in the company, swamped with work -Apr 20 17:31:43 so let's start with activity reports (and we can see who is actually really here on the channel active :) -Apr 20 17:31:59 PREV: vacation, configuring new laptop -Apr 20 17:31:59 NEXT: Tokyo sprint -Apr 20 17:31:59 BLOCKERS: - -Apr 20 17:32:05 PREV: Vacation -Apr 20 17:32:06 LAST: Leysin Sprint, iceland organisation, some testing and playing around -Apr 20 17:32:06 NEXT: work on testing and build environment -Apr 20 17:32:06 BLOCKERS: - -Apr 20 17:32:06 LAST: slept off leysin, ACCU -Apr 20 17:32:07 NEXT: stackless transform? -Apr 20 17:32:07 BLOCKERS: insane busyness -Apr 20 17:32:09 LAST: investigating translatability of constraint stuff -Apr 20 17:32:10 NEXT: playing with choose() -Apr 20 17:32:10 BLOCKERS: working, clonable coroutines -Apr 20 17:32:13 LAST: travelling -Apr 20 17:32:13 NEXT: Tokyo sprint -Apr 20 17:32:13 BLOCKERS: - -Apr 20 17:32:16 NEXT: Sprint -Apr 20 17:32:18 BLOCKERS: - -Apr 20 17:32:23 LAST: set implementation, finding bugs -Apr 20 17:32:23 NEXT: finding and documenting more bugs... -Apr 20 17:32:23 BLOCKERS: - -Apr 20 17:32:26 LAST: completed rlist support for ootypesystem -Apr 20 17:32:27 NEXT: more works on ootypesystem (probably rdict) -Apr 20 17:32:29 BLOCKER: my still poor knowledge of pypy internals :-) -Apr 20 17:32:34 LAST: GC work, optimizations -Apr 20 17:32:35 NEXT: uni stuff, trying to implement __del__ with the framework -Apr 20 17:32:35 BLOCKERS: new environment, time constraints -Apr 20 17:32:43 LAST: {}[[]], tweaks and fixing various transformation problems, rested during easter -Apr 20 17:32:45 NEXT: tokyo sprint -Apr 20 17:32:46 BLOCKERS: - -Apr 20 17:33:03 * auc is away for 5 minutes -Apr 20 17:33:07 auc: how badly do you depend on "clonable coroutines" and in which way? -Apr 20 17:33:11 oh, never mind then -Apr 20 17:33:37 ok, let's head on then -Apr 20 17:33:43 * summer of X -Apr 20 17:34:05 from in-between discussions and opinions i gather that we are all leaning towards participating in SoC as mentors through PSF -Apr 20 17:34:11 yes -Apr 20 17:34:12 DONE: wrapping -Apr 20 17:34:12 NEXT: finalizing, prepare next PyPy work -Apr 20 17:34:12 BLOCK: complexity -Apr 20 17:34:12 is that correct or are there other opinions? -Apr 20 17:34:35 sounds good to me -Apr 20 17:34:51 ditto -Apr 20 17:34:56 +1 -Apr 20 17:35:00 +1 -Apr 20 17:35:04 fine, then let's see how we go about it -Apr 20 17:35:05 a) mentors -Apr 20 17:35:06 b) topics -Apr 20 17:35:15 hpk: just removed last years's mentorship entry from the wiki -Apr 20 17:35:21 i suggest that we open a soc-2006 directory in extradoc with such information -Apr 20 17:35:32 everyone willing to mentor should email neal norwitz -Apr 20 17:35:35 (Aurelien already committed something today to pypy/doc) -Apr 20 17:35:48 mwh: i think we should gather on our side and then someone sends all the info -Apr 20 17:36:02 should gather info -Apr 20 17:36:04 if you need "personal references" as on the python.org wiki, feel free to mention me :) -Apr 20 17:36:05 +1 -Apr 20 17:36:11 hpk: if you like -Apr 20 17:36:24 i'm already signed up as a mentor, cause i was one last year -Apr 20 17:36:44 mwh: ok, carl is as well i think -Apr 20 17:37:03 or will soon be -Apr 20 17:37:06 ok, then let's put all info into soc-2006 and send info off on the weekend -Apr 20 17:37:15 just to get a quick impression: -Apr 20 17:37:16 is there a deadline for mentoring? -Apr 20 17:37:20 who would mentor? -Apr 20 17:37:25 mwh: yes, there is one -Apr 20 17:37:32 1st may i think -Apr 20 17:37:38 cfbolz: me, you, armin for certain -Apr 20 17:37:40 (but i may confuse the various deadlines) -Apr 20 17:37:56 hpk: i thought 1 may was the deadline for being a mentoring *organization* -Apr 20 17:37:57 i would also mentor but preferably to py.test, build-tool stuff i guess -Apr 20 17:38:06 hpk: neal writes "soon" :-) -Apr 20 17:38:17 mwh: ok, might well be, whatever, let's just get this sorted and communicate to them -Apr 20 17:38:25 hpk: sure -Apr 20 17:38:28 it shouldn't be hard -Apr 20 17:38:48 anybody else? -Apr 20 17:39:07 i am sure that aurelien or so would be interested -Apr 20 17:39:10 Add me as well -Apr 20 17:39:16 I would prefer not to -Apr 20 17:39:31 eric also said that he would not like to -Apr 20 17:39:41 ok, then that's it for now -Apr 20 17:39:44 I would, of course -Apr 20 17:39:46 I would like to b a mentor but I think it would not be a good idea (indeed) -Apr 20 17:39:49 pedronis, i guess -Apr 20 17:40:03 let's just open the soc-2006 directory and put info there -Apr 20 17:40:08 hpk: are you going to be the one who checks this in? -Apr 20 17:40:17 mwh: ye -Apr 20 17:40:17 cfbolz: can you make this happen and make sure we communicate next week to them? -Apr 20 17:40:34 hpk: not before sunday, no -Apr 20 17:41:00 ok, then i start but would like you or someone else to communicate to the SoC people (Neal) -Apr 20 17:41:08 eventually -Apr 20 17:41:12 as i haven't been involved there -Apr 20 17:41:23 mwh: do you know neal? -Apr 20 17:41:34 cfbolz: i talked to him a bit at pycon -Apr 20 17:41:45 i can do the communicating -Apr 20 17:41:52 cool, thanks -Apr 20 17:41:57 i am away 29 apr -> 8 may (ish) -Apr 20 17:42:02 so i'll do it before then :) -Apr 20 17:42:06 ok, let's try to do it before then -Apr 20 17:42:07 yes -Apr 20 17:42:10 next topic -Apr 20 17:42:24 * 0.9 related work until iceland -Apr 20 17:42:44 --> rxe (n=rxe at 66.151.59.5) has joined #pypy-sync -Apr 20 17:42:47 hi richard :) -Apr 20 17:42:57 Hi everyone! :-) -Apr 20 17:42:59 :-) -Apr 20 17:43:01 hey richard -Apr 20 17:43:02 sorry it has been a long time -Apr 20 17:43:03 hey rxe -Apr 20 17:43:48 so there has been a bit of discussion on pypy-dev -Apr 20 17:44:05 what do the others think? -Apr 20 17:45:31 the truth is somewhere in the middle. there is definitively more to do than just stackless pickling -Apr 20 17:45:51 My feeling is that a 0.9 version should be almost a 1.0 version (which I consider a "this is it" version) does that make sense? -Apr 20 17:46:07 which I think we are not quiet yet -Apr 20 17:46:08 like finishing the stackless-applevel exposure -Apr 20 17:46:33 the major topics of the 0.9 release are the ext-module compiler and stackless features -Apr 20 17:46:37 well, there's also other stuff in the WP7 tasks which is explcitly listed -Apr 20 17:46:48 yes, __del__, weakref -Apr 20 17:47:09 that's just work. pickling is hard since I still don't know how -Apr 20 17:47:10 I don't think WP7 says anything about __dell__ or weakrefr -Apr 20 17:47:26 well, even just work takes time -Apr 20 17:47:31 pedronis: then not :-) -Apr 20 17:47:33 pedronis: indeed -Apr 20 17:47:53 yes but I can distribute if I know how -Apr 20 17:48:06 stakkars: what are you working planning on working on? -Apr 20 17:48:21 damn timezones mean i don't get to chat much... -Apr 20 17:49:02 well pickling first thing, although it might depend on the new transform -Apr 20 17:49:05 cfbolz: the thing regarding "middle ground": we really only have 7 months left for tons of stuff we want to do - just postponing things from a "we don't neccessarily need to do it" will backfire IMO -Apr 20 17:49:21 so we should strike a good balance -Apr 20 17:49:26 stakkars stedi67 Apr 20 17:49:33 cfbolz: the fact is that some unfinished WP7ish stuff is really WP5 leftovers -Apr 20 17:49:34 stakkars: note that the new transform is not fully integrated -Apr 20 17:49:45 stakkars: have you looked at the transforrm code? -Apr 20 17:49:45 it just mostly works but certainly requires work -Apr 20 17:50:10 that's what I'm saying, might be blocker -Apr 20 17:50:25 pedronis: what is a wp5 leftover? -Apr 20 17:50:35 cfbolz: well part of the GC stuff -Apr 20 17:50:53 stakkars: michael and me worked on stackless to support you, not to block you :) -Apr 20 17:50:58 i mean, maybe in the short term it makes sense for stakkars to work on channels and greenlets, and for me to try to polish the stackless transform -Apr 20 17:51:00 stakkars: you have 9 mm in WP7 -Apr 20 17:51:19 * auc is back (ouch) -Apr 20 17:51:28 gosh. I appreciate of course. -Apr 20 17:51:30 by "short term" i mean "for a week" -Apr 20 17:51:59 I just didn't realize that it's necessary,, before i saw pedronis message -Apr 20 17:52:21 the idea of the current topic is that we identify the issues and assign responsible persons -Apr 20 17:52:30 i am not sure we can achieve it in some minutes -Apr 20 17:52:40 but we should aim for getting that clarified latest next week -Apr 20 17:53:23 yes -Apr 20 17:53:35 because not discussing it will not help either :) -Apr 20 17:53:47 indeed :) -Apr 20 17:53:54 mwh: that makes a lot of sense -Apr 20 17:53:56 stakkars: is really your workpackage. Helping you is shifting things around. It may even become a serious issue after a point. -Apr 20 17:54:25 but is not the right forum for that discussion -Apr 20 17:54:29 yes, i agree -Apr 20 17:55:10 pedronis:I considered the grapg transform as an add-on, nice to have. as said, didn't know -Apr 20 17:55:27 stakkars: well, it will be necessary for graph pickling -Apr 20 17:55:35 stakkars: so it is not an addon -Apr 20 17:55:36 so we need a discussion next week about this specific "how to tackle 0.9 tasks" topic and to define the scope -Apr 20 17:55:46 cfbolz: necessary is a strong word, but i more or less agree -Apr 20 17:56:03 another point that isn't entirely irrelevant is that i'm enjoying working on 'stackless style' stuff -Apr 20 17:56:12 :) -Apr 20 17:56:12 * hpk too actually -Apr 20 17:56:14 anyway task pickling plus the other missing stuff is not a small task -Apr 20 17:56:19 yes -Apr 20 17:56:24 to finish in less than a month -Apr 20 17:56:50 that we are so late was not expected -Apr 20 17:56:58 ok, as we are discussing things mostly from an EU perspective i'd like to invite to a specific meeting for EU developers early next week -Apr 20 17:57:15 yes, this is not the right forum -Apr 20 17:57:21 tuesday? -Apr 20 17:57:28 big thing is to find the right time for everyone :) -Apr 20 17:57:35 tuesday would be fine -Apr 20 17:57:38 5pm seems likes the best compromise -Apr 20 17:57:44 midnight in japan, 8am in CA -Apr 20 17:57:45 (i will be in d??sseldorf) -Apr 20 17:57:58 stakkars stedi67 Apr 20 17:58:20 mwh, stakkars, cfbolz, pedronis, auc, aleale, arre, ...: fine for you? -Apr 20 17:58:23 for me, the other way goes as well (midnight +) -Apr 20 17:58:35 ok -Apr 20 17:58:37 yes -Apr 20 17:59:00 stakkars stedi67 Apr 20 17:59:05 ok -Apr 20 17:59:14 ok -Apr 20 17:59:28 ok -Apr 20 17:59:45 great, than we close this topic (and the next one, which relates to it) -Apr 20 17:59:46 ok -Apr 20 17:59:58 see you all, i will mail to pypy-dev to not forget anyone -Apr 20 18:00:31 auc: you are available for mentoring as well, right? -Apr 20 18:00:36 auc: mentoring SoC -Apr 20 18:01:12 --> Gromit_ (n=bear at does-d9b90ad6.pool.mediaWays.net) has joined #pypy-sync -Apr 20 18:01:49 hpk: i guesss so ... -Apr 20 18:02:12 but not necessarily about all of what i posted in pypy/doc +:: + + Apr 20 17:28:55 stakkars: hi! + Apr 20 17:29:25 hi friends + Apr 20 17:29:59 I'll give rxe a call + Apr 20 17:30:25 hi all! + Apr 20 17:30:33 stakkars stedi67 Apr 20 17:30:37 stakkars: want to wake him up? :) + Apr 20 17:30:45 hi + Apr 20 17:30:53 T-0 according to me + Apr 20 17:30:58 yip + Apr 20 17:31:01 who is moderating? hpk ? + Apr 20 17:31:06 yes, i guess so + Apr 20 17:31:17 topics: + Apr 20 17:31:17 * activity reports + Apr 20 17:31:17 * summer of X + Apr 20 17:31:17 * work until iceland for 0.9 topics + Apr 20 17:31:17 * assigning major 0.9 topics + Apr 20 17:31:23 he's early, probably in the company, swamped with work + Apr 20 17:31:43 so let's start with activity reports (and we can see who is actually really here on the channel active :) + Apr 20 17:31:59 PREV: vacation, configuring new laptop + Apr 20 17:31:59 NEXT: Tokyo sprint + Apr 20 17:31:59 BLOCKERS: - + Apr 20 17:32:05 PREV: Vacation + Apr 20 17:32:06 LAST: Leysin Sprint, iceland organisation, some testing and playing around + Apr 20 17:32:06 NEXT: work on testing and build environment + Apr 20 17:32:06 BLOCKERS: - + Apr 20 17:32:06 LAST: slept off leysin, ACCU + Apr 20 17:32:07 NEXT: stackless transform? + Apr 20 17:32:07 BLOCKERS: insane busyness + Apr 20 17:32:09 LAST: investigating translatability of constraint stuff + Apr 20 17:32:10 NEXT: playing with choose() + Apr 20 17:32:10 BLOCKERS: working, clonable coroutines + Apr 20 17:32:13 LAST: travelling + Apr 20 17:32:13 NEXT: Tokyo sprint + Apr 20 17:32:13 BLOCKERS: - + Apr 20 17:32:16 NEXT: Sprint + Apr 20 17:32:18 BLOCKERS: - + Apr 20 17:32:23 LAST: set implementation, finding bugs + Apr 20 17:32:23 NEXT: finding and documenting more bugs... + Apr 20 17:32:23 BLOCKERS: - + Apr 20 17:32:26 LAST: completed rlist support for ootypesystem + Apr 20 17:32:27 NEXT: more works on ootypesystem (probably rdict) + Apr 20 17:32:29 BLOCKER: my still poor knowledge of pypy internals :-) + Apr 20 17:32:34 LAST: GC work, optimizations + Apr 20 17:32:35 NEXT: uni stuff, trying to implement __del__ with the framework + Apr 20 17:32:35 BLOCKERS: new environment, time constraints + Apr 20 17:32:43 LAST: {}[[]], tweaks and fixing various transformation problems, rested during easter + Apr 20 17:32:45 NEXT: tokyo sprint + Apr 20 17:32:46 BLOCKERS: - + Apr 20 17:33:03 * auc is away for 5 minutes + Apr 20 17:33:07 auc: how badly do you depend on "clonable coroutines" and in which way? + Apr 20 17:33:11 oh, never mind then + Apr 20 17:33:37 ok, let's head on then + Apr 20 17:33:43 * summer of X + Apr 20 17:34:05 from in-between discussions and opinions i gather that we are all leaning towards participating in SoC as mentors through PSF + Apr 20 17:34:11 yes + Apr 20 17:34:12 DONE: wrapping + Apr 20 17:34:12 NEXT: finalizing, prepare next PyPy work + Apr 20 17:34:12 BLOCK: complexity + Apr 20 17:34:12 is that correct or are there other opinions? + Apr 20 17:34:35 sounds good to me + Apr 20 17:34:51 ditto + Apr 20 17:34:56 +1 + Apr 20 17:35:00 +1 + Apr 20 17:35:04 fine, then let's see how we go about it + Apr 20 17:35:05 a) mentors + Apr 20 17:35:06 b) topics + Apr 20 17:35:15 hpk: just removed last years's mentorship entry from the wiki + Apr 20 17:35:21 i suggest that we open a soc-2006 directory in extradoc with such information + Apr 20 17:35:32 everyone willing to mentor should email neal norwitz + Apr 20 17:35:35 (Aurelien already committed something today to pypy/doc) + Apr 20 17:35:48 mwh: i think we should gather on our side and then someone sends all the info + Apr 20 17:36:02 should gather info + Apr 20 17:36:04 if you need "personal references" as on the python.org wiki, feel free to mention me :) + Apr 20 17:36:05 +1 + Apr 20 17:36:11 hpk: if you like + Apr 20 17:36:24 i'm already signed up as a mentor, cause i was one last year + Apr 20 17:36:44 mwh: ok, carl is as well i think + Apr 20 17:37:03 or will soon be + Apr 20 17:37:06 ok, then let's put all info into soc-2006 and send info off on the weekend + Apr 20 17:37:15 just to get a quick impression: + Apr 20 17:37:16 is there a deadline for mentoring? + Apr 20 17:37:20 who would mentor? + Apr 20 17:37:25 mwh: yes, there is one + Apr 20 17:37:32 1st may i think + Apr 20 17:37:38 cfbolz: me, you, armin for certain + Apr 20 17:37:40 (but i may confuse the various deadlines) + Apr 20 17:37:56 hpk: i thought 1 may was the deadline for being a mentoring *organization* + Apr 20 17:37:57 i would also mentor but preferably to py.test, build-tool stuff i guess + Apr 20 17:38:06 hpk: neal writes "soon" :-) + Apr 20 17:38:17 mwh: ok, might well be, whatever, let's just get this sorted and communicate to them + Apr 20 17:38:25 hpk: sure + Apr 20 17:38:28 it shouldn't be hard + Apr 20 17:38:48 anybody else? + Apr 20 17:39:07 i am sure that aurelien or so would be interested + Apr 20 17:39:10 Add me as well + Apr 20 17:39:16 I would prefer not to + Apr 20 17:39:31 eric also said that he would not like to + Apr 20 17:39:41 ok, then that's it for now + Apr 20 17:39:44 I would, of course + Apr 20 17:39:46 I would like to b a mentor but I think it would not be a good idea (indeed) + Apr 20 17:39:49 pedronis, i guess + Apr 20 17:40:03 let's just open the soc-2006 directory and put info there + Apr 20 17:40:08 hpk: are you going to be the one who checks this in? + Apr 20 17:40:17 mwh: ye + Apr 20 17:40:17 cfbolz: can you make this happen and make sure we communicate next week to them? + Apr 20 17:40:34 hpk: not before sunday, no + Apr 20 17:41:00 ok, then i start but would like you or someone else to communicate to the SoC people (Neal) + Apr 20 17:41:08 eventually + Apr 20 17:41:12 as i haven't been involved there + Apr 20 17:41:23 mwh: do you know neal? + Apr 20 17:41:34 cfbolz: i talked to him a bit at pycon + Apr 20 17:41:45 i can do the communicating + Apr 20 17:41:52 cool, thanks + Apr 20 17:41:57 i am away 29 apr -> 8 may (ish) + Apr 20 17:42:02 so i'll do it before then :) + Apr 20 17:42:06 ok, let's try to do it before then + Apr 20 17:42:07 yes + Apr 20 17:42:10 next topic + Apr 20 17:42:24 * 0.9 related work until iceland + Apr 20 17:42:44 --> rxe (n=rxe at 66.151.59.5) has joined #pypy-sync + Apr 20 17:42:47 hi richard :) + Apr 20 17:42:57 Hi everyone! :-) + Apr 20 17:42:59 :-) + Apr 20 17:43:01 hey richard + Apr 20 17:43:02 sorry it has been a long time + Apr 20 17:43:03 hey rxe + Apr 20 17:43:48 so there has been a bit of discussion on pypy-dev + Apr 20 17:44:05 what do the others think? + Apr 20 17:45:31 the truth is somewhere in the middle. there is definitively more to do than just stackless pickling + Apr 20 17:45:51 My feeling is that a 0.9 version should be almost a 1.0 version (which I consider a "this is it" version) does that make sense? + Apr 20 17:46:07 which I think we are not quiet yet + Apr 20 17:46:08 like finishing the stackless-applevel exposure + Apr 20 17:46:33 the major topics of the 0.9 release are the ext-module compiler and stackless features + Apr 20 17:46:37 well, there's also other stuff in the WP7 tasks which is explcitly listed + Apr 20 17:46:48 yes, __del__, weakref + Apr 20 17:47:09 that's just work. pickling is hard since I still don't know how + Apr 20 17:47:10 I don't think WP7 says anything about __dell__ or weakrefr + Apr 20 17:47:26 well, even just work takes time + Apr 20 17:47:31 pedronis: then not :-) + Apr 20 17:47:33 pedronis: indeed + Apr 20 17:47:53 yes but I can distribute if I know how + Apr 20 17:48:06 stakkars: what are you working planning on working on? + Apr 20 17:48:21 damn timezones mean i don't get to chat much... + Apr 20 17:49:02 well pickling first thing, although it might depend on the new transform + Apr 20 17:49:05 cfbolz: the thing regarding "middle ground": we really only have 7 months left for tons of stuff we want to do - just postponing things from a "we don't neccessarily need to do it" will backfire IMO + Apr 20 17:49:21 so we should strike a good balance + Apr 20 17:49:26 stakkars stedi67 Apr 20 17:49:33 cfbolz: the fact is that some unfinished WP7ish stuff is really WP5 leftovers + Apr 20 17:49:34 stakkars: note that the new transform is not fully integrated + Apr 20 17:49:45 stakkars: have you looked at the transforrm code? + Apr 20 17:49:45 it just mostly works but certainly requires work + Apr 20 17:50:10 that's what I'm saying, might be blocker + Apr 20 17:50:25 pedronis: what is a wp5 leftover? + Apr 20 17:50:35 cfbolz: well part of the GC stuff + Apr 20 17:50:53 stakkars: michael and me worked on stackless to support you, not to block you :) + Apr 20 17:50:58 i mean, maybe in the short term it makes sense for stakkars to work on channels and greenlets, and for me to try to polish the stackless transform + Apr 20 17:51:00 stakkars: you have 9 mm in WP7 + Apr 20 17:51:19 * auc is back (ouch) + Apr 20 17:51:28 gosh. I appreciate of course. + Apr 20 17:51:30 by "short term" i mean "for a week" + Apr 20 17:51:59 I just didn't realize that it's necessary,, before i saw pedronis message + Apr 20 17:52:21 the idea of the current topic is that we identify the issues and assign responsible persons + Apr 20 17:52:30 i am not sure we can achieve it in some minutes + Apr 20 17:52:40 but we should aim for getting that clarified latest next week + Apr 20 17:53:23 yes + Apr 20 17:53:35 because not discussing it will not help either :) + Apr 20 17:53:47 indeed :) + Apr 20 17:53:54 mwh: that makes a lot of sense + Apr 20 17:53:56 stakkars: is really your workpackage. Helping you is shifting things around. It may even become a serious issue after a point. + Apr 20 17:54:25 but is not the right forum for that discussion + Apr 20 17:54:29 yes, i agree + Apr 20 17:55:10 pedronis:I considered the grapg transform as an add-on, nice to have. as said, didn't know + Apr 20 17:55:27 stakkars: well, it will be necessary for graph pickling + Apr 20 17:55:35 stakkars: so it is not an addon + Apr 20 17:55:36 so we need a discussion next week about this specific "how to tackle 0.9 tasks" topic and to define the scope + Apr 20 17:55:46 cfbolz: necessary is a strong word, but i more or less agree + Apr 20 17:56:03 another point that isn't entirely irrelevant is that i'm enjoying working on 'stackless style' stuff + Apr 20 17:56:12 :) + Apr 20 17:56:12 * hpk too actually + Apr 20 17:56:14 anyway task pickling plus the other missing stuff is not a small task + Apr 20 17:56:19 yes + Apr 20 17:56:24 to finish in less than a month + Apr 20 17:56:50 that we are so late was not expected + Apr 20 17:56:58 ok, as we are discussing things mostly from an EU perspective i'd like to invite to a specific meeting for EU developers early next week + Apr 20 17:57:15 yes, this is not the right forum + Apr 20 17:57:21 tuesday? + Apr 20 17:57:28 big thing is to find the right time for everyone :) + Apr 20 17:57:35 tuesday would be fine + Apr 20 17:57:38 5pm seems likes the best compromise + Apr 20 17:57:44 midnight in japan, 8am in CA + Apr 20 17:57:45 (i will be in d??sseldorf) + Apr 20 17:57:58 stakkars stedi67 Apr 20 17:58:20 mwh, stakkars, cfbolz, pedronis, auc, aleale, arre, ...: fine for you? + Apr 20 17:58:23 for me, the other way goes as well (midnight +) + Apr 20 17:58:35 ok + Apr 20 17:58:37 yes + Apr 20 17:59:00 stakkars stedi67 Apr 20 17:59:05 ok + Apr 20 17:59:14 ok + Apr 20 17:59:28 ok + Apr 20 17:59:45 great, than we close this topic (and the next one, which relates to it) + Apr 20 17:59:46 ok + Apr 20 17:59:58 see you all, i will mail to pypy-dev to not forget anyone + Apr 20 18:00:31 auc: you are available for mentoring as well, right? + Apr 20 18:00:36 auc: mentoring SoC + Apr 20 18:01:12 --> Gromit_ (n=bear at does-d9b90ad6.pool.mediaWays.net) has joined #pypy-sync + Apr 20 18:01:49 hpk: i guesss so ... + Apr 20 18:02:12 but not necessarily about all of what i posted in pypy/doc Modified: pypy/extradoc/minute/pypy-sync-2006-05-11.txt ============================================================================== --- pypy/extradoc/minute/pypy-sync-2006-05-11.txt (original) +++ pypy/extradoc/minute/pypy-sync-2006-05-11.txt Sat Jun 3 17:45:24 2006 @@ -46,8 +46,6 @@ IRC logs ------------- -**** BEGIN LOGGING AT Thu May 11 17:00:48 2006 - May 11 17:00:48 --> You are now talking on #pypy-sync May 11 17:00:48 --- Topic for #pypy-sync is PyPy - the flexible snake. This channel is used for pair programming and sync meetings. May 11 17:00:48 --- Topic for #pypy-sync set by xorAxAx at Sun Apr 16 21:44:23 Modified: pypy/extradoc/soc-2006/code-templating.txt ============================================================================== --- pypy/extradoc/soc-2006/code-templating.txt (original) +++ pypy/extradoc/soc-2006/code-templating.txt Sat Jun 3 17:45:24 2006 @@ -11,7 +11,7 @@ touching the grammar file (it means in short : making available the new operator at runtime by way of importing some module). -Examples of choice usage : +Examples of choice usage:: def soft_color(): choice: @@ -62,7 +62,7 @@ choice: or: or: ... or: - which has to be rewritten as : + which has to be rewritten as :: choice = choose(N) if choice == 1: @@ -83,7 +83,7 @@ creation-time (not even None) and can be bound only once. Currently, the newvar() builtin is used instead of it in PyPy -* :=: is a short-cut notation we might want instead of merely calling +* `:=:` is a short-cut notation we might want instead of merely calling unify, as in : unify(Term1, Term2) * fail() makes the current computation space fail: it means that the @@ -140,28 +140,29 @@ Annex ----- + A Common Lisp programmer would have a 'choice' operator like this : (choice ) - ... for instance : + for instance :: - (defun contrast (C1 C2) - (choice - ((unify C1 (soft-color)) - (unify C2 (hard-color))) - ((unify C1 (hard-color)) - (unify C2 (soft-color))))) - - He would define choice as a macro, as follows : - - (defmacro choice (&body choice-points) - (let ((choices (length choice-points)) - (choice (gensym "choice"))) - `(let ((,choice (choose ,choices))) - (cond - ,(loop for alternative in choice-points - for i from 1 upto choices - collect `((= ,i ,choice) - (progn ,alternative))))))) + (defun contrast (C1 C2) + (choice + ((unify C1 (soft-color)) + (unify C2 (hard-color))) + ((unify C1 (hard-color)) + (unify C2 (soft-color))))) + + He would define choice as a macro, as follows :: + + (defmacro choice (&body choice-points) + (let ((choices (length choice-points)) + (choice (gensym "choice"))) + `(let ((,choice (choose ,choices))) + (cond + ,(loop for alternative in choice-points + for i from 1 upto choices + collect `((= ,i ,choice) + (progn ,alternative))))))) Modified: pypy/extradoc/sprintinfo/conftest.py ============================================================================== --- pypy/extradoc/sprintinfo/conftest.py (original) +++ pypy/extradoc/sprintinfo/conftest.py Sat Jun 3 17:45:24 2006 @@ -29,3 +29,10 @@ class Directory(Directory): ReSTChecker = PyPyReSTChecker + def run(self): + l = [] + for x in super(Directory, self).run(): + if x.endswith("planning.txt"): + continue + l.append(x) + return l Added: pypy/extradoc/talk/dls2006/conftest.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/dls2006/conftest.py Sat Jun 3 17:45:24 2006 @@ -0,0 +1,11 @@ + +import py + +class Directory(py.test.collect.Directory): + def run(self): + l = [] + for x in super(Directory, self).run(): + if x in ['draft.txt']: + continue + l.append(x) + return l Modified: pypy/extradoc/talk/solutions-linux-paris-2006.html ============================================================================== --- pypy/extradoc/talk/solutions-linux-paris-2006.html (original) +++ pypy/extradoc/talk/solutions-linux-paris-2006.html Sat Jun 3 17:45:24 2006 @@ -1,327 +1,26 @@ - - - - - - -PyPy - un projet libre dot?? d'un financement europ??en - - - - - - - - - - - - - - -
-
-
- - -
-
-
-

PyPy - un projet libre dot?? d'un financement europ??en

+ + + PyPy[solutions-linux-paris-2006] + + + +
+ + PyPy
+
+
PyPy[solutions-linux-paris-2006]
+
+
+
+
modified 1 month ago by Carl Friedrich Bolz
+
+

PyPy - un projet libre dot? d'un financement europ?en

@@ -342,143 +41,146 @@ ============================ --> + - - -
-

Sujets abord??s

+
+

Sujets abord?s

    -
  • quels mod??les ??conomiques pour le logiciel libre ?
  • -
  • le logiciel libre et les projets europ??ens
  • -
  • le langage Python et l'interpr??teur PyPy
  • +
  • quels mod?les ?conomiques pour le logiciel libre ?
  • +
  • le logiciel libre et les projets europ?ens
  • +
  • le langage Python et l'interpr?teur PyPy
-
-

Plan

+
+

Plan

  • historique du projet
  • -
  • proc??dure de candidature
  • -
  • d??roulement
  • -
  • UE et agilit??
  • +
  • proc?dure de candidature
  • +
  • d?roulement
  • +
  • UE et agilit?
  • qu'est-ce que PyPy ?
-
-

Historique

+
+

Historique

    -
  • d??bute mi-2003 suite ?? EuroPython
  • +
  • d?bute mi-2003 suite ? EuroPython
  • prototype prometteur en 2004
  • -
  • d??but 2004, recherche des moyens n??cessaires ?? la poursuite du projet
  • +
  • d?but 2004, recherche des moyens n?cessaires ? la poursuite du projet
  • fin 2004, signature contrat
-
-

Candidature

+
+

Candidature

    -
  • appels ?? projet (IST - 6th Framework)
  • +
  • appels ? projet (IST - 6th Framework)
  • recherche partenaires manquants
  • -
  • r??daction collaborative de l'offre (outils et m??thodes du libre)
  • +
  • r?daction collaborative de l'offre (outils et m?thodes du libre)
  • soumission automne 2004
  • -
  • signature contrat d??c 2004
  • +
  • signature contrat d?c 2004
-
-

Caract??ristiques

+
+

Caract?ristiques

  • projet innovant
  • budget 1,3 Millions EUR
  • 2 ans (2005/2006)
  • -
  • 7 partenaires europ??ens
  • -
  • 15 ann??es.homme
  • +
  • 7 partenaires europ?ens
  • +
  • 15 ann?es.homme
  • logiciel libre
-
-

Consortium

+
+

Consortium

  • DFKI (Allemagne)
  • HHU (Allemagne)
  • Logilab (France)
  • -
  • Strakt (Su??de)
  • +
  • Strakt (Su?de)
  • Merlinux (Allemagne)
  • Tismerysoft (Allemagne)
  • -
  • Changemaker (Su??de)
  • +
  • Changemaker (Su?de)
-
-

Financement europ??en

+
+

Financement europ?en

  • financement partiel:
      -
    • 50% pour partenaires priv??s
    • +
    • 50% pour partenaires priv?s
    • 100% pour partenaires publics
  • deniers publics financent biens publics
  • -
  • d??lais de paiement
  • +
  • d?lais de paiement
-
-

Financement public pour LL

+
+

Financement public pour LL

    -
  • projets men??s par administrations
  • -
  • certaines r??ductions d'imp??ts
  • +
  • projets men?s par administrations
  • +
  • certaines r?ductions d'imp?ts
  • approche politique au niveau local
-
-

Diff??rences culturelles

+
+

Diff?rences culturelles

    -
  • gestion de projet par m??thodes agiles
  • +
  • gestion de projet par m?thodes agiles
  • UE gestion plus "classique"
  • -
  • documentation, processus de validation, d??lais, etc.
  • +
  • documentation, processus de validation, d?lais, etc.
  • sprints toutes les 6 semaines
  • reste ouvert aux contributeurs externes
-
-

Et PyPy ?

+
+

Et PyPy ?

    -
  • interpr??teur pour langage Python
  • +
  • interpr?teur pour langage Python
  • flexible
  • performant
  • modulable
-
-

Objectifs PyPy

+
+

Objectifs PyPy

  • Python en Python
  • -
  • respect de la d??finition du langage
  • -
  • performances ??quivalentes ?? CPython
  • +
  • respect de la d?finition du langage
  • +
  • performances ?quivalentes ? CPython
  • traduction vers langages cibles
  • -
  • ajout fonctionnalit??s
  • -
  • un interpr??teur d??clinable
  • +
  • ajout fonctionnalit?s
  • +
  • un interpr?teur d?clinable
-
-

Etat d??but 2006

+
+

Etat d?but 2006

  • version 0.8 est un Python 2.4 fonctionnel
  • -
  • manque gestion de la m??moire
  • +
  • manque gestion de la m?moire
  • 10 fois plus lent que l'original
  • -
  • g??n??re code C (et autres)
  • +
  • g?n?re code C (et autres)
-
-

Etapes pour fin 2006

+
+

Etapes pour fin 2006

    -
  • compilation et ??valuation partielle
  • +
  • compilation et ?valuation partielle
  • logique, aspects, distribution
  • diffusion
-
-

Pour finir

+
+

Pour finir

  • Questions
- - + +
\ No newline at end of file From hpk at codespeak.net Sat Jun 3 17:54:08 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Jun 2006 17:54:08 +0200 (CEST) Subject: [pypy-svn] r28180 - pypy/dist/pypy/tool Message-ID: <20060603155408.7132110060@code0.codespeak.net> Author: hpk Date: Sat Jun 3 17:54:07 2006 New Revision: 28180 Added: pypy/dist/pypy/tool/codespeak-gendoc.py (contents, props changed) Log: add doc generation script (has to run on codespeak with certain paths setup) Added: pypy/dist/pypy/tool/codespeak-gendoc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/codespeak-gendoc.py Sat Jun 3 17:54:07 2006 @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +# XXX needs to run on codespeak + +import py +import sys +import os + +base = py.path.local('/www/codespeak.net/htdocs') + +def runpytest(path, outfile): + lockfile = base.join(".gendoclock") + return os.system("/admin/bin/withlock %s py.test %s >>%s 2>&1" %( + lockfile, path, outfile)) + +if __name__ == '__main__': + results = [] + for fn in sys.argv[1:]: + p = base.join(fn, abs=True) + assert p.check(), p + outfile = p.join("gendoc.log") + wc = py.path.svnwc(p) + wc.update() + rev = wc.info().rev + outfile.write("gendoc for %s revision %d\n\n" %(p, rev)) + errcode = runpytest(p, outfile) + if errcode: + results.append("in revision %d of %s" %(rev, p)) + results.append(" gendoc failed with %d, see %s " %( + errcode, outfile)) + print results[-1] + + if results: + for line in results: + print >>sys.stderr, line + sys.exit(1) + + + + + + From mwh at codespeak.net Sat Jun 3 18:25:30 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Jun 2006 18:25:30 +0200 (CEST) Subject: [pypy-svn] r28184 - in pypy/dist/pypy/translator: c stackless stackless/test Message-ID: <20060603162530.0D3B610050@code0.codespeak.net> Author: mwh Date: Sat Jun 3 18:25:27 2006 New Revision: 28184 Modified: pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) Another resume_point test, resuming with an instance value. For variety, run it through genc and add the miniscule support genc needed for this. It works, but it really shouldn't :) Next on the menu: making it fail. Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Sat Jun 3 18:25:27 2006 @@ -663,6 +663,9 @@ typename = cdecl(self.db.gettype(TYPE), '') return "%(result)s = (%(typename)s)(%(val)s);" % locals() + def OP_RESUME_POINT(self, op): + return '/* resume point %s */'%(op.args[0],) + def OP_DEBUG_PRINT(self, op): # XXX from pypy.rpython.lltypesystem.rstr import STR Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sat Jun 3 18:25:27 2006 @@ -1,5 +1,5 @@ from pypy.translator.stackless.transform import StacklessTransformer -from pypy.translator.stackless.test.test_transform import llinterp_stackless_function, rtype_stackless_function, one +from pypy.translator.stackless.test.test_transform import llinterp_stackless_function, rtype_stackless_function, one, run_stackless_function from pypy import conftest import py from pypy.rpython import rstack @@ -123,3 +123,20 @@ return v1*100 + rstack.resume_state_invoke(int, s1) res = llinterp_stackless_function(example, assert_unwind=False) assert res == 406 + +def test_really_return_instance(): + class C: + pass + def g(x): + c = C() + c.x = x + 1 + rstack.resume_point("rp1", c) + return c + def example(): + v1 = g(one()).x + c = C() + c.x = 4*one() + s1 = rstack.resume_state_create(None, "rp1", c) + return v1*100 + rstack.resume_state_invoke(C, s1).x + res = run_stackless_function(example) + assert res == 204 Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sat Jun 3 18:25:27 2006 @@ -112,7 +112,7 @@ return True elif op.opname == 'resume_point': return True - elif op.opname == 'resume_point_invoke': + elif op.opname == 'resume_state_invoke': return True return self.stackless_gc and LL_OPERATIONS[op.opname].canunwindgc @@ -394,23 +394,8 @@ newblock.exitswitch = None if resume_point.var_result.concretetype != rettype: - llops = LowLevelOpList() - newvar = gen_cast(llops, - resume_point.var_result.concretetype, - retval) - convertblock = unsimplify.insert_empty_block( - None, newblock.exits[0], llops) - # begin ouch! - for index, linkvar in enumerate(convertblock.exits[0].args): - # does this var come from retval ? - try: - index1 = convertblock.inputargs.index(linkvar) - except ValueError: # e.g. linkvar is a Constant - continue - if newblock.exits[0].args[index1] is retval: - # yes - convertblock.exits[0].args[index] = newvar - # end ouch! + self.insert_return_conversion( + newblock.exits[0], resume_point.var_result.concretetype, retval) resuming_links.append( model.Link([], newblock, resume_point_index)) @@ -422,6 +407,25 @@ new_start_block.isstartblock = True graph.startblock = new_start_block + def insert_return_conversion(self, link, targettype, retvar): + llops = LowLevelOpList() + newvar = gen_cast(llops, targettype, retvar) + convertblock = unsimplify.insert_empty_block(None, link, llops) + # begin ouch! + foundit = False + for index, linkvar in enumerate(convertblock.exits[0].args): + # does this var come from retval ? + try: + index1 = convertblock.inputargs.index(linkvar) + except ValueError: # e.g. linkvar is a Constant + continue + if link.args[index1] is retvar: + foundit = True + # yes + convertblock.exits[0].args[index] = newvar + # end ouch! + assert foundit + def handle_resume_point(self, block, i): # in some circumstances we might be able to reuse # an already inserted resume point @@ -508,20 +512,30 @@ llops.append(model.SpaceOperation('same_as', [v_state], op.result)) block.operations[i:i+1] = llops - def handle_resume_state_invoke(self, block, i): - op = block.operations[i] - if op.result.concretetype != lltype.Signed: - raise NotImplementedError + def handle_resume_state_invoke(self, block): + op = block.operations[-1] + assert op.opname == 'resume_state_invoke' + rettype = storage_type(op.result.concretetype) + if op.result.concretetype != rettype: + retvar = varoftype(rettype) + else: + retvar = op.result v_returns = op.args[1] if v_returns.concretetype == lltype.Signed: raise NotImplementedError elif v_returns.concretetype == lltype.Void: args = [self.resume_after_void_ptr] + op.args - newop = model.SpaceOperation('direct_call', args, op.result) - block.operations[i] = newop + newop = model.SpaceOperation('direct_call', args, retvar) + block.operations[-1] = newop else: raise NotImplementedError - return newop + if retvar is not op.result: + noexclink = block.exits[0] + for i, a in enumerate(noexclink.args): + if a is op.result: + noexclink.args[i] = retvar + self.insert_return_conversion( + noexclink, op.result.concretetype, retvar) def transform_block(self, block): i = 0 @@ -543,10 +557,6 @@ op = replace_with_call(self.yield_current_frame_to_caller_ptr) stackless_op = True - if op.opname == 'resume_state_invoke': - op = self.handle_resume_state_invoke(block, i) - stackless_op = True - if op.opname == 'resume_state_create': self.handle_resume_state_create(block, i) continue # go back and look at that malloc @@ -556,7 +566,7 @@ if op.opname == 'resume_point': block, i = self.handle_resume_point(block, i) continue - + # trap calls to stackless-related suggested primitives if op.opname == 'direct_call': func = getattr(op.args[0].value._obj, '_callable', None) @@ -616,6 +626,11 @@ # function be called right at the end of the resuming # block, and that it is called even if the return # value is not again used. + + if op.opname == 'resume_state_invoke': + self.handle_resume_state_invoke(block) + op = block.operations[-1] + args = vars_to_save(block) save_block, frame_state_type, fieldnames = \ From ac at codespeak.net Sat Jun 3 18:59:28 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sat, 3 Jun 2006 18:59:28 +0200 (CEST) Subject: [pypy-svn] r28189 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20060603165928.3991C10053@code0.codespeak.net> Author: ac Date: Sat Jun 3 18:59:27 2006 New Revision: 28189 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py Log: (cfbolz, arre) More gc.collect(). Modified: pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py Sat Jun 3 18:59:27 2006 @@ -67,6 +67,7 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del o + gc.collect() self.assert_(ref1() is None, "expected reference to be invalidated") self.assert_(ref2() is None, @@ -98,13 +99,17 @@ ref1 = weakref.proxy(o, self.callback) ref2 = weakref.proxy(o, self.callback) del o + gc.collect() + gc.collect() + gc.collect() def check(proxy): proxy.bar self.assertRaises(weakref.ReferenceError, check, ref1) self.assertRaises(weakref.ReferenceError, check, ref2) - self.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C())) + # Works only with refcounting + # self.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C())) self.assert_(self.cbcalled == 2) def check_basic_ref(self, factory): @@ -121,6 +126,7 @@ o = factory() ref = weakref.ref(o, self.callback) del o + gc.collect() self.assert_(self.cbcalled == 1, "callback did not properly set 'cbcalled'") self.assert_(ref() is None, @@ -145,6 +151,7 @@ self.assert_(weakref.getweakrefcount(o) == 2, "wrong weak ref count for object") del proxy + gc.collect() self.assert_(weakref.getweakrefcount(o) == 1, "wrong weak ref count for object after deleting proxy") @@ -284,6 +291,7 @@ "got wrong number of weak reference objects") del ref1, ref2, proxy1, proxy2 + gc.collect() self.assert_(weakref.getweakrefcount(o) == 0, "weak reference objects not unlinked from" " referent when discarded.") @@ -297,6 +305,7 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del ref1 + gc.collect() self.assert_(weakref.getweakrefs(o) == [ref2], "list of refs does not match") @@ -304,10 +313,12 @@ ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del ref2 + gc.collect() self.assert_(weakref.getweakrefs(o) == [ref1], "list of refs does not match") del ref1 + gc.collect() self.assert_(weakref.getweakrefs(o) == [], "list of refs not cleared") @@ -728,12 +739,16 @@ self.assert_(items1 == items2, "cloning of weak-valued dictionary did not work!") del items1, items2 + gc.collect() self.assert_(len(dict) == self.COUNT) del objects[0] gc.collect() + gc.collect() + gc.collect() self.assert_(len(dict) == (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o + gc.collect() self.assert_(len(dict) == 0, "deleting the values did not clear the dictionary") # regression on SF bug #447152: @@ -759,12 +774,16 @@ self.assert_(set(items1) == set(items2), "cloning of weak-keyed dictionary did not work!") del items1, items2 + gc.collect() self.assert_(len(dict) == self.COUNT) del objects[0] gc.collect() + gc.collect() + gc.collect() self.assert_(len(dict) == (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o + gc.collect() self.assert_(len(dict) == 0, "deleting the keys did not clear the dictionary") o = Object(42) @@ -971,6 +990,7 @@ for o in objs: d[o] = o.value del o # now the only strong references to keys are in objs + gc.collect() # Find the order in which iterkeys sees the keys. objs = d.keys() # Reverse it, so that the iteration implementation of __delitem__ @@ -989,6 +1009,7 @@ for o in objs: count += 1 del d[o] + gc.collect() self.assertEqual(len(d), 0) self.assertEqual(count, 2) From mwh at codespeak.net Sat Jun 3 19:22:49 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Jun 2006 19:22:49 +0200 (CEST) Subject: [pypy-svn] r28190 - in pypy/dist/pypy/translator/stackless: . test Message-ID: <20060603172249.6EAC510060@code0.codespeak.net> Author: mwh Date: Sat Jun 3 19:22:47 2006 New Revision: 28190 Modified: pypy/dist/pypy/translator/stackless/code.py pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) make the last test work for better reasons, and convince ourselves that we only need to write len(STORAGE_TYPES) versions of resume_after_... and not len(STORAGE_TYPES)**2. see the big comment for more. Modified: pypy/dist/pypy/translator/stackless/code.py ============================================================================== --- pypy/dist/pypy/translator/stackless/code.py (original) +++ pypy/dist/pypy/translator/stackless/code.py Sat Jun 3 19:22:47 2006 @@ -209,8 +209,6 @@ resume_bottom.f_back = mystate.f_back global_state.top = targetstate raise UnwindException() - else: - return 0 resume_after_void.stackless_explicit = True INDEX_RESUME_AFTER_VOID = frame.RestartInfo.add_prebuilt(resume_after_void, Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sat Jun 3 19:22:47 2006 @@ -138,5 +138,5 @@ c.x = 4*one() s1 = rstack.resume_state_create(None, "rp1", c) return v1*100 + rstack.resume_state_invoke(C, s1).x - res = run_stackless_function(example) + res = llinterp_stackless_function(example) assert res == 204 Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sat Jun 3 19:22:47 2006 @@ -236,7 +236,7 @@ self.resume_after_void_ptr = mixlevelannotator.constfunc( code.resume_after_void, [annmodel.SomePtr(lltype.Ptr(STATE_HEADER)), annmodel.s_None], - annmodel.SomeInteger()) + annmodel.s_None) mixlevelannotator.finish() @@ -515,11 +515,21 @@ def handle_resume_state_invoke(self, block): op = block.operations[-1] assert op.opname == 'resume_state_invoke' - rettype = storage_type(op.result.concretetype) - if op.result.concretetype != rettype: - retvar = varoftype(rettype) - else: - retvar = op.result + # some commentary. + # + # we don't want to write 155 or so different versions of + # resume_after_foo that appear to the annotator to return + # different types. we take advantage of the fact that this + # function always raises UnwindException and have it (appear + # to) return Void. then to placate all the other machinery, + # we pass a constant zero-of-the-appropriate-type along the + # non-exceptional link (which we know will never be taken). + # Nota Bene: only mutate a COPY of the non-exceptional link + # because the non-exceptional link has been stored in + # self.resume_points and we don't want a constant "zero" in + # there. + retvar = varoftype(lltype.Void) + realrettype = op.result.concretetype v_returns = op.args[1] if v_returns.concretetype == lltype.Signed: raise NotImplementedError @@ -529,13 +539,11 @@ block.operations[-1] = newop else: raise NotImplementedError - if retvar is not op.result: - noexclink = block.exits[0] - for i, a in enumerate(noexclink.args): - if a is op.result: - noexclink.args[i] = retvar - self.insert_return_conversion( - noexclink, op.result.concretetype, retvar) + noexclink = block.exits[0].copy() + for i, a in enumerate(noexclink.args): + if a is op.result: + noexclink.args[i] = model.Constant(realrettype._defl(), realrettype) + block.recloseblock(*((noexclink,) + block.exits[1:])) def transform_block(self, block): i = 0 @@ -627,10 +635,6 @@ # block, and that it is called even if the return # value is not again used. - if op.opname == 'resume_state_invoke': - self.handle_resume_state_invoke(block) - op = block.operations[-1] - args = vars_to_save(block) save_block, frame_state_type, fieldnames = \ @@ -650,6 +654,9 @@ block.recloseblock(*newexits) self.translator.rtyper._convert_link(block, newlink) + if op.opname == 'resume_state_invoke': + self.handle_resume_state_invoke(block) + block = link.target i = 0 else: From antocuni at codespeak.net Sat Jun 3 19:38:31 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Jun 2006 19:38:31 +0200 (CEST) Subject: [pypy-svn] r28191 - in pypy/dist/pypy/rpython: . ootypesystem test Message-ID: <20060603173831.B5BBF10060@code0.codespeak.net> Author: antocuni Date: Sat Jun 3 19:38:30 2006 New Revision: 28191 Modified: pypy/dist/pypy/rpython/callparse.py pypy/dist/pypy/rpython/ootypesystem/rpbc.py pypy/dist/pypy/rpython/test/test_rpbc.py Log: (antocuni, nik, arigo) Fixed a cornercase for ootypesytem, where methods defined in superclass are only called in subclasses. Modified: pypy/dist/pypy/rpython/callparse.py ============================================================================== --- pypy/dist/pypy/rpython/callparse.py (original) +++ pypy/dist/pypy/rpython/callparse.py Sat Jun 3 19:38:30 2006 @@ -26,7 +26,7 @@ getrinputs(rtyper, graph), getrresult(rtyper, graph)) -def callparse(rtyper, graph, hop, opname, is_method=False): +def callparse(rtyper, graph, hop, opname, r_self=None): """Parse the arguments of 'hop' when calling the given 'graph'. """ rinputs = getrinputs(rtyper, graph) @@ -34,7 +34,11 @@ def args_h(start): return [VarHolder(i, hop.args_s[i]) for i in range(start, hop.nb_args)] - start = 1 - is_method + if r_self is None: + start = 1 + else: + start = 0 + rinputs[0] = r_self if opname == "simple_call": arguments = Arguments(space, args_h(start)) elif opname == "call_args": Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Sat Jun 3 19:38:30 2006 @@ -123,7 +123,7 @@ anygraph = row_of_graphs.itervalues().next() # pick any witness hop2 = self.add_instance_arg_to_hop(hop, opname == "call_args") vlist = callparse.callparse(self.rtyper, anygraph, hop2, opname, - is_method=True) + r_self = self.r_im_self) rresult = callparse.getrresult(self.rtyper, anygraph) hop.exception_is_here() mangled = mangle(self.methodname) Modified: pypy/dist/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rpbc.py (original) +++ pypy/dist/pypy/rpython/test/test_rpbc.py Sat Jun 3 19:38:30 2006 @@ -31,6 +31,7 @@ class MySubclassWithoutMethods(MyBase): pass + class Freezing: def _freeze_(self): return True @@ -141,11 +142,36 @@ assert self.interpret(f, [42]) == 42 def test_class_method_inherited(self): - def f(a): - instance = MySubclassWithoutMethods() - instance.z = a - return instance.m(a) - assert self.interpret(f, [42]) == 84 + # The strange names for this test are taken from richards, + # where the problem originally arose. + class Task: + def waitTask(self, a): + return a+1 + + def fn(self, a): + raise NotImplementedError + + def runTask(self, a): + return self.fn(a) + + class HandlerTask(Task): + def fn(self, a): + return self.waitTask(a)+2 + + class DeviceTask(Task): + def fn(self, a): + return self.waitTask(a)+3 + + def f(a, b): + if b: + inst = HandlerTask() + else: + inst = DeviceTask() + + return inst.runTask(a) + + assert self.interpret(f, [42, True]) == 45 + assert self.interpret(f, [42, False]) == 46 def test_freezing(self): fr1 = Freezing() From mwh at codespeak.net Sat Jun 3 19:41:31 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Jun 2006 19:41:31 +0200 (CEST) Subject: [pypy-svn] r28192 - pypy/dist/pypy/rpython Message-ID: <20060603174131.F233B10060@code0.codespeak.net> Author: mwh Date: Sat Jun 3 19:41:29 2006 New Revision: 28192 Modified: pypy/dist/pypy/rpython/llinterp.py Log: sanity-check the return value of unsafe_call in the llinterpreter. didn't catch the problem we were looking for, but probably a good idea anyway. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Sat Jun 3 19:41:29 2006 @@ -512,6 +512,8 @@ args.append(arg.concretetype._defl()) frame = self.__class__(graph, args, self.llinterpreter, self) result = frame.eval() + from pypy.translator.stackless.frame import storage_type + assert storage_type(lltype.typeOf(result)) == TGT return lltype._cast_whatever(TGT, result) def op_malloc(self, obj): From mwh at codespeak.net Sat Jun 3 19:42:46 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Jun 2006 19:42:46 +0200 (CEST) Subject: [pypy-svn] r28193 - in pypy/dist/pypy: rpython translator/stackless translator/stackless/test Message-ID: <20060603174246.2720810060@code0.codespeak.net> Author: mwh Date: Sat Jun 3 19:42:39 2006 New Revision: 28193 Modified: pypy/dist/pypy/rpython/rstack.py pypy/dist/pypy/translator/stackless/code.py pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) code and test for resume_state_invoke(blah, blah, returns=int). Modified: pypy/dist/pypy/rpython/rstack.py ============================================================================== --- pypy/dist/pypy/rpython/rstack.py (original) +++ pypy/dist/pypy/rpython/rstack.py Sat Jun 3 19:42:39 2006 @@ -120,7 +120,7 @@ if 'i_returns' in kwds_i: assert len(kwds_i) == 1 returns_index = kwds_i['i_returns'] - v_return = args_v.pop(returns_index-1) + v_return = hop.args_v[returns_index] else: assert not kwds_i v_return = hop.inputconst(lltype.Void, None) Modified: pypy/dist/pypy/translator/stackless/code.py ============================================================================== --- pypy/dist/pypy/translator/stackless/code.py (original) +++ pypy/dist/pypy/translator/stackless/code.py Sat Jun 3 19:42:39 2006 @@ -214,6 +214,39 @@ INDEX_RESUME_AFTER_VOID = frame.RestartInfo.add_prebuilt(resume_after_void, [RESUME_AFTER_STATE, EMPTY_STATE]) + +def resume_after_long(state, retvalue): + if global_state.restart_substate == -1: + # normal entry point for a call to state.switch() + # first unwind the stack + u = UnwindException() + s = lltype.malloc(RESUME_AFTER_STATE) + s.header.f_restart = INDEX_RESUME_AFTER_LONG + s.c = state + global_state.retval_long = retvalue + add_frame_state(u, s.header) + raise u + elif global_state.restart_substate == 0: + # STATE 0: we didn't do anything so far, but the stack is unwound + global_state.restart_substate = -1 + # grab the frame corresponding to ourself + # the 'targetstate' local is garbage here, it must be read back from + # 's.c' where we saved it by the normal entry point above + mystate = global_state.top + s = lltype.cast_pointer(lltype.Ptr(RESUME_AFTER_STATE), mystate) + targetstate = s.c + resume_bottom = targetstate + while resume_bottom.f_back: + resume_bottom = resume_bottom.f_back + resume_bottom.f_back = mystate.f_back + global_state.top = targetstate + raise UnwindException() + +resume_after_long.stackless_explicit = True +INDEX_RESUME_AFTER_LONG = frame.RestartInfo.add_prebuilt(resume_after_long, + [RESUME_AFTER_STATE, + EMPTY_STATE]) + # ____________________________________________________________ class StacklessData: Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sat Jun 3 19:42:39 2006 @@ -50,9 +50,12 @@ rstack.resume_point("rp1", y, returns=z) return z+y def example(): - f(one(),one()+one()) - return 0 - transform_stackless_function(example) + v1 = f(one(),one()+one()) + s = rstack.resume_state_create(None, "rp1", 5*one()) + v2 = rstack.resume_state_invoke(int, s, returns=one()*7) + return v1*100 + v2 + res = llinterp_stackless_function(example) + assert res == 412 def test_call_exception_handling(): def g(x,y): @@ -140,3 +143,4 @@ return v1*100 + rstack.resume_state_invoke(C, s1).x res = llinterp_stackless_function(example) assert res == 204 + Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sat Jun 3 19:42:39 2006 @@ -233,10 +233,33 @@ self.yield_current_frame_to_caller_ptr = mixlevelannotator.constfunc( code.yield_current_frame_to_caller, [], s_StatePtr) - self.resume_after_void_ptr = mixlevelannotator.constfunc( - code.resume_after_void, [annmodel.SomePtr(lltype.Ptr(STATE_HEADER)), - annmodel.s_None], - annmodel.s_None) + s_hdrptr = annmodel.SomePtr(lltype.Ptr(STATE_HEADER)) + self.resume_afters = { + lltype.Void: mixlevelannotator.constfunc( + code.resume_after_void, + [s_hdrptr, annmodel.s_None], + annmodel.s_None), + lltype.Signed: mixlevelannotator.constfunc( + code.resume_after_long, + [s_hdrptr, annmodel.SomeInteger()], + annmodel.s_None), +## lltype.SignedLongLong: mixlevelannotator.constfunc( +## code.resume_after_longlong, +## [s_hdrptr, annmodel.SomeInteger(knowntype=rarithmetic.r_longlong)], +## annmodel.s_None), +## lltype.Float: mixlevelannotator.constfunc( +## code.resume_after_float, +## [s_hdrptr, annmodel.SomeFloat()], +## annmodel.s_None), +## llmemory.Address: mixlevelannotator.constfunc( +## code.resume_after_addr, +## [s_hdrptr, annmodel.SomeAddress()], +## annmodel.s_None), +## SAVED_REFERENCE: mixlevelannotator.constfunc( +## code.resume_after_ref, +## [s_hdrptr, annmodel.SomePtr(SAVED_REFERENCE)], +## annmodel.s_None), + } mixlevelannotator.finish() @@ -531,14 +554,12 @@ retvar = varoftype(lltype.Void) realrettype = op.result.concretetype v_returns = op.args[1] - if v_returns.concretetype == lltype.Signed: - raise NotImplementedError - elif v_returns.concretetype == lltype.Void: - args = [self.resume_after_void_ptr] + op.args - newop = model.SpaceOperation('direct_call', args, retvar) - block.operations[-1] = newop - else: + resume_after_ptr = self.resume_afters[storage_type(v_returns.concretetype)] + if storage_type(v_returns.concretetype) != v_returns.concretetype: raise NotImplementedError + args = [resume_after_ptr] + op.args + newop = model.SpaceOperation('direct_call', args, retvar) + block.operations[-1] = newop noexclink = block.exits[0].copy() for i, a in enumerate(noexclink.args): if a is op.result: From ac at codespeak.net Sat Jun 3 20:15:53 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sat, 3 Jun 2006 20:15:53 +0200 (CEST) Subject: [pypy-svn] r28197 - in pypy/dist/pypy/module/_weakref: . test Message-ID: <20060603181553.68A2E10060@code0.codespeak.net> Author: ac Date: Sat Jun 3 20:15:51 2006 New Revision: 28197 Modified: pypy/dist/pypy/module/_weakref/__init__.py pypy/dist/pypy/module/_weakref/test/test_weakref.py Log: (arre, cfbolz): fix typo + test Modified: pypy/dist/pypy/module/_weakref/__init__.py ============================================================================== --- pypy/dist/pypy/module/_weakref/__init__.py (original) +++ pypy/dist/pypy/module/_weakref/__init__.py Sat Jun 3 20:15:51 2006 @@ -9,6 +9,6 @@ 'getweakrefs': 'interp__weakref.getweakrefs', 'ReferenceType': 'interp__weakref.W_Weakref', 'ProxyType': 'interp__weakref.W_Proxy', - 'CallableProxyType': 'interp__weakref.W_Proxy', + 'CallableProxyType': 'interp__weakref.W_CallableProxy', 'proxy': 'interp__weakref.proxy' } Modified: pypy/dist/pypy/module/_weakref/test/test_weakref.py ============================================================================== --- pypy/dist/pypy/module/_weakref/test/test_weakref.py (original) +++ pypy/dist/pypy/module/_weakref/test/test_weakref.py Sat Jun 3 20:15:51 2006 @@ -234,6 +234,7 @@ # leads to the fact that the __del__ of _weakref.ref is not called. assert _weakref.getweakrefs(a)[0]() is a + class AppTestProxy(object): def setup_class(cls): space = gettestobjspace(usemodules=('_weakref',)) @@ -270,6 +271,15 @@ a_() assert global_a.x == 1 + def test_callable_proxy_type(self): + import _weakref + class Callable: + def __call__(self, x): + pass + o = Callable() + ref1 = _weakref.proxy(o) + assert type(ref1) is _weakref.CallableProxyType + def test_dont_create_directly(self): import _weakref raises(TypeError, _weakref.ProxyType, []) From mwh at codespeak.net Sat Jun 3 20:17:07 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Jun 2006 20:17:07 +0200 (CEST) Subject: [pypy-svn] r28198 - in pypy/dist/pypy/translator/stackless: . test Message-ID: <20060603181707.5603510060@code0.codespeak.net> Author: mwh Date: Sat Jun 3 20:17:04 2006 New Revision: 28198 Modified: pypy/dist/pypy/translator/stackless/code.py pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) a test and code for resume_state_invoke(blah, blah, returns=not-int). mwh learnt a lesson about slice assignment debugging this. Modified: pypy/dist/pypy/translator/stackless/code.py ============================================================================== --- pypy/dist/pypy/translator/stackless/code.py (original) +++ pypy/dist/pypy/translator/stackless/code.py Sat Jun 3 20:17:04 2006 @@ -2,7 +2,7 @@ from pypy.rpython import rarithmetic from pypy.rpython import extfunctable from pypy.translator.stackless import frame -from pypy.translator.stackless.frame import STATE_HEADER, SAVED_REFERENCE +from pypy.translator.stackless.frame import STATE_HEADER, SAVED_REFERENCE, STORAGE_FIELDS EMPTY_STATE = frame.make_state_header_type('empty_state') @@ -215,15 +215,16 @@ [RESUME_AFTER_STATE, EMPTY_STATE]) -def resume_after_long(state, retvalue): +template = """\ +def resume_after_%(typename)s(state, retvalue): if global_state.restart_substate == -1: # normal entry point for a call to state.switch() # first unwind the stack u = UnwindException() s = lltype.malloc(RESUME_AFTER_STATE) - s.header.f_restart = INDEX_RESUME_AFTER_LONG + s.header.f_restart = INDEX_RESUME_AFTER_%(TYPENAME)s s.c = state - global_state.retval_long = retvalue + global_state.retval_%(typename)s = retvalue add_frame_state(u, s.header) raise u elif global_state.restart_substate == 0: @@ -242,10 +243,16 @@ global_state.top = targetstate raise UnwindException() -resume_after_long.stackless_explicit = True -INDEX_RESUME_AFTER_LONG = frame.RestartInfo.add_prebuilt(resume_after_long, + +resume_after_%(typename)s.stackless_explicit = True +INDEX_RESUME_AFTER_%(TYPENAME)s = frame.RestartInfo.add_prebuilt(resume_after_%(typename)s, [RESUME_AFTER_STATE, EMPTY_STATE]) +""" + +for typename in STORAGE_FIELDS.values(): + if typename == 'weak': continue + exec template%dict(typename=typename, TYPENAME=typename.upper()) # ____________________________________________________________ Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sat Jun 3 20:17:04 2006 @@ -57,6 +57,24 @@ res = llinterp_stackless_function(example) assert res == 412 +def test_returns_with_instance(): + class C: + def __init__(self, x): + self.x = x + def g(x): + return C(x+1) + def f(x, y): + r = g(x) + rstack.resume_point("rp1", y, returns=r) + return r.x + y + def example(): + v1 = f(one(),one()+one()) + s = rstack.resume_state_create(None, "rp1", 5*one()) + v2 = rstack.resume_state_invoke(int, s, returns=C(one()*3)) + return v1*100 + v2 + res = llinterp_stackless_function(example, assert_unwind=False) + assert res == 408 + def test_call_exception_handling(): def g(x,y): if x == 0: Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sat Jun 3 20:17:04 2006 @@ -243,22 +243,22 @@ code.resume_after_long, [s_hdrptr, annmodel.SomeInteger()], annmodel.s_None), -## lltype.SignedLongLong: mixlevelannotator.constfunc( -## code.resume_after_longlong, -## [s_hdrptr, annmodel.SomeInteger(knowntype=rarithmetic.r_longlong)], -## annmodel.s_None), -## lltype.Float: mixlevelannotator.constfunc( -## code.resume_after_float, -## [s_hdrptr, annmodel.SomeFloat()], -## annmodel.s_None), -## llmemory.Address: mixlevelannotator.constfunc( -## code.resume_after_addr, -## [s_hdrptr, annmodel.SomeAddress()], -## annmodel.s_None), -## SAVED_REFERENCE: mixlevelannotator.constfunc( -## code.resume_after_ref, -## [s_hdrptr, annmodel.SomePtr(SAVED_REFERENCE)], -## annmodel.s_None), + lltype.SignedLongLong: mixlevelannotator.constfunc( + code.resume_after_longlong, + [s_hdrptr, annmodel.SomeInteger(knowntype=rarithmetic.r_longlong)], + annmodel.s_None), + lltype.Float: mixlevelannotator.constfunc( + code.resume_after_float, + [s_hdrptr, annmodel.SomeFloat()], + annmodel.s_None), + llmemory.Address: mixlevelannotator.constfunc( + code.resume_after_addr, + [s_hdrptr, annmodel.SomeAddress()], + annmodel.s_None), + SAVED_REFERENCE: mixlevelannotator.constfunc( + code.resume_after_ref, + [s_hdrptr, annmodel.SomePtr(SAVED_REFERENCE)], + annmodel.s_None), } mixlevelannotator.finish() @@ -551,16 +551,20 @@ # because the non-exceptional link has been stored in # self.resume_points and we don't want a constant "zero" in # there. - retvar = varoftype(lltype.Void) - realrettype = op.result.concretetype + v_state = op.args[0] v_returns = op.args[1] - resume_after_ptr = self.resume_afters[storage_type(v_returns.concretetype)] - if storage_type(v_returns.concretetype) != v_returns.concretetype: - raise NotImplementedError - args = [resume_after_ptr] + op.args - newop = model.SpaceOperation('direct_call', args, retvar) - block.operations[-1] = newop + erased_returns_type = storage_type(v_returns.concretetype) + resume_after_ptr = self.resume_afters[erased_returns_type] + llops = LowLevelOpList() + if erased_returns_type != v_returns.concretetype: + v_returns = gen_cast(llops, erased_returns_type, v_returns) + llops.genop('direct_call', [resume_after_ptr, v_state, v_returns], + resulttype=lltype.Void) + del block.operations[-1] + block.operations.extend(llops) + noexclink = block.exits[0].copy() + realrettype = op.result.concretetype for i, a in enumerate(noexclink.args): if a is op.result: noexclink.args[i] = model.Constant(realrettype._defl(), realrettype) From fijal at codespeak.net Sat Jun 3 20:21:25 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Jun 2006 20:21:25 +0200 (CEST) Subject: [pypy-svn] r28199 - in pypy/dist/pypy/translator/js2: . jssrc test Message-ID: <20060603182125.3120A10060@code0.codespeak.net> Author: fijal Date: Sat Jun 3 20:21:24 2006 New Revision: 28199 Modified: pypy/dist/pypy/translator/js2/asmgen.py pypy/dist/pypy/translator/js2/function.py pypy/dist/pypy/translator/js2/jssrc/misc.js pypy/dist/pypy/translator/js2/opcodes.py pypy/dist/pypy/translator/js2/test/test_class.py pypy/dist/pypy/translator/js2/test/test_exception.py Log: Added exception handling and isinstanceof. Works by terrible hack of exception value. Modified: pypy/dist/pypy/translator/js2/asmgen.py ============================================================================== --- pypy/dist/pypy/translator/js2/asmgen.py (original) +++ pypy/dist/pypy/translator/js2/asmgen.py Sat Jun 3 20:21:24 2006 @@ -113,13 +113,38 @@ self.right_hand.append("%s ( %s )" % (func_name, real_args)) def branch_if(self, arg, exitcase): - arg_name = self.subst_table.get(arg.name, arg.name) - self.codegenerator.write("if ( %s == %s )"%(arg_name, str(exitcase).lower())) + def mapping(exitc): + if exitc in ['True', 'False']: + return exitc.lower() + return exitc + + if hasattr(arg,'name'): + arg_name = self.subst_table.get(arg.name, arg.name) + else: + arg_name = arg + self.branch_if_string("%s == %s"%(arg_name, mapping(str(exitcase)))) + + def branch_if_string(self, arg): + self.codegenerator.writeline("if (%s)"%arg) + self.codegenerator.openblock() + + def branch_elsif_string(self, arg): + self.codegenerator.closeblock() + self.codegenerator.writeline("else if (%s)"%arg) self.codegenerator.openblock() + def branch_elsif(self, arg, exitcase): + self.codegenerator.closeblock() + self.branch_if(arg, exitcase, "else if") + def branch_while(self, arg, exitcase): + def mapping(exitc): + if exitc in ['True', 'False']: + return exitc.lower() + return exitc + arg_name = self.subst_table.get(arg.name, arg.name) - self.codegenerator.write("while ( %s == %s )"%(arg_name, str(exitcase).lower())) + self.codegenerator.write("while ( %s == %s )"%(arg_name, mapping(str(exitcase)))) self.codegenerator.openblock() def branch_while_true(self): @@ -229,8 +254,10 @@ self.codegenerator.write("try ") self.codegenerator.openblock() - def end_try(self): + def catch(self): self.codegenerator.closeblock() + self.codegenerator.write("catch (exc)") + self.codegenerator.openblock() def begin_for(self): self.codegenerator.writeline("var block = 0;") @@ -251,7 +278,10 @@ self.codegenerator.closeblock() def inherits(self, subclass_name, parent_name): - self.codegenerator.writeline("%s.inherits(%s);"%(subclass_name, parent_name)) + self.codegenerator.writeline("inherits(%s,%s);"%(subclass_name, parent_name)) + + def throw(self, var): + self.codegenerator.writeline("throw(%s);"%var.name) #def finish ( self ): # self . outfile . write ( "%r" % self . right_hand ) Modified: pypy/dist/pypy/translator/js2/function.py ============================================================================== --- pypy/dist/pypy/translator/js2/function.py (original) +++ pypy/dist/pypy/translator/js2/function.py Sat Jun 3 20:21:24 2006 @@ -16,6 +16,8 @@ from pypy.translator.js2.log import log +import re + class LoopFinder(object): def __init__(self, startblock): @@ -163,6 +165,9 @@ def render_block(self, startblock): """ Block rendering routine using for variable trick """ + def basename(x): + return str(x).split('.')[-1] + self.ilasm.begin_for() block_map = {} @@ -176,16 +181,41 @@ for block in graph.iterblocks(): self.ilasm.write_case(block_map[block]) + + is_exc_block = (block.exitswitch is flowmodel.c_last_exception) + + if is_exc_block: + self.ilasm.begin_try() + self.render_block_operations(block) if self._is_return_block(block): return_var = block.inputargs[0] #if return_var.concretetype is not Void: self.load(return_var) self.ilasm.ret() + elif self._is_raise_block(block): + self.ilasm.throw(block.inputargs[1]) elif block.exitswitch is None: self._setup_link(block.exits[0]) self.ilasm.jump_block(block_map[block.exits[0].target]) - elif block.exitswitch.concretetype is Bool: + elif block.exitswitch is flowmodel.c_last_exception: + link = [i for i in block.exits if i.exitcase is None][0] + self._setup_link(link) + self.ilasm.jump_block(block_map[link.target]) + self.ilasm.catch() + first = False + for link in [i for i in block.exits if i.exitcase is not None]: + s = "isinstanceof(exc, %s)"%basename(link.exitcase) + if not first: + first = True + self.ilasm.branch_if_string(s) + else: + self.ilasm.branch_elsif_string(s) + self._setup_link(link, True) + self.ilasm.jump_block(block_map[link.target]) + self.ilasm.close_branch() + self.ilasm.close_branch() + elif len(block.exits) == 2: self.ilasm.branch_if(block.exitswitch, True) self._setup_link(block.exits[True]) self.ilasm.jump_block(block_map[block.exits[True].target]) @@ -193,8 +223,6 @@ self._setup_link(block.exits[False]) self.ilasm.jump_block(block_map[block.exits[False].target]) self.ilasm.close_branch() - elif block.exitswitch is flowmodel.c_last_exception: - raise NotImplementedError("Exception work in progress") else: raise TypeError("Unknow block.exitswitch type %r"%block.exitswitch) @@ -231,11 +259,14 @@ else: self.db.record_function(self.graph, self.name) - def _setup_link(self, link): + def _setup_link(self, link, is_exc_link = False): target = link.target for to_load, to_store in zip(link.args, target.inputargs): if to_load.concretetype is not Void: - self.load(to_load) + if is_exc_link and isinstance(to_load, flowmodel.Variable) and re.match("last_exc_value", to_load.name): + self.ilasm.load_str("exc") + else: + self.load(to_load) self.store(to_store) Modified: pypy/dist/pypy/translator/js2/jssrc/misc.js ============================================================================== --- pypy/dist/pypy/translator/js2/jssrc/misc.js (original) +++ pypy/dist/pypy/translator/js2/jssrc/misc.js Sat Jun 3 20:21:24 2006 @@ -3,8 +3,28 @@ return this; }; -Function.method('inherits', function (parent) { +function inherits(child, parent) { + child.parent = parent; + for (i in parent.prototype) { + child.prototype[i] = parent.prototype[i]; + } +} + +function isinstanceof(self, what) { + t = self.constructor; + while ( t ) { + if (t == what) { + return (true); + } + t = t.parent; + } + return (false); +} + +Function.method('old_inherits', function (parent) { var d = 0, p = (this.prototype = new parent()); + //var p = new parent(); + //var d = 0; this.method('uber', function uber(name) { var f, r, t = d, v = parent.prototype; if (t) { Modified: pypy/dist/pypy/translator/js2/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js2/opcodes.py (original) +++ pypy/dist/pypy/translator/js2/opcodes.py Sat Jun 3 20:21:24 2006 @@ -19,13 +19,14 @@ class _SameAs(MicroInstruction): def render(self, generator, op): generator.change_name(op.result, op.args[0]) - + class _CastFun(MicroInstruction): def __init__(self, name, num): self.name = name self.num = num def render(self, generator, op): + log("Args: %r"%op.args) generator.cast_function(self.name, self.num) class _Prefix(MicroInstruction): @@ -41,6 +42,10 @@ def render(self, generator, op): raise NotImplementedError(self.reason) + +class _New(MicroInstruction): + def render(self, generator, op): + generator.new(op.args[0].value) class _CastString(MicroInstruction): def render(self, generator, op): @@ -121,6 +126,14 @@ method = op.args[0] self._render_method(generator, method.value, op.args[1:]) +class _IsInstance(MicroInstruction): + def render(self, generator, op): + # FIXME: just temporary hack + generator.load(op.args[0]) + generator.ilasm.load_const(op.args[1].value._name.split('.')[-1]) + generator.cast_function("isinstanceof", 2) + +IsInstance = _IsInstance() Call = _Call() CallMethod = _CallMethod() CopyName = [PushAllArgs, _SameAs ()] @@ -207,6 +220,7 @@ 'indirect_call' : [_NotImplemented("Indirect call not implemented")], 'same_as' : SameAs, 'new' : [New], + 'instanceof' : [IsInstance], # objects Modified: pypy/dist/pypy/translator/js2/test/test_class.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_class.py (original) +++ pypy/dist/pypy/translator/js2/test/test_class.py Sat Jun 3 20:21:24 2006 @@ -51,7 +51,7 @@ assert f() == 14 def test_flow_type(self): - py.test.skip("isinstanceof not implemented") + #py.test.skip("isinstanceof not implemented") f = compile_function(llvmsnippet.flow_type, []) assert f() == 16 @@ -81,7 +81,7 @@ assert f(15) == 25 def test_call_degrading_func(self): - py.test.skip("isinstanceof not implemented") + #py.test.skip("isinstanceof not implemented") f = compile_function(llvmsnippet.call_degrading_func, [bool]) assert f(True) == llvmsnippet.call_degrading_func(True) assert f(False) == llvmsnippet.call_degrading_func(False) Modified: pypy/dist/pypy/translator/js2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/js2/test/test_exception.py Sat Jun 3 20:21:24 2006 @@ -6,7 +6,7 @@ import sys -py.test.skip("Exception work in progress") +#py.test.skip("Exception work in progress") class TestException(Exception): pass From mwh at codespeak.net Sat Jun 3 20:25:49 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Jun 2006 20:25:49 +0200 (CEST) Subject: [pypy-svn] r28200 - pypy/dist/pypy/translator/stackless/test Message-ID: <20060603182549.4D5FC10060@code0.codespeak.net> Author: mwh Date: Sat Jun 3 20:25:48 2006 New Revision: 28200 Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py Log: (mwh, pedronis) a test about resuming and exceptions. it passes. Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sat Jun 3 20:25:48 2006 @@ -162,3 +162,20 @@ res = llinterp_stackless_function(example) assert res == 204 +def test_resume_and_raise(): + def g(x): + rstack.resume_point("rp0", x) + if x == 0: + raise KeyError + return x + 1 + def example(): + v1 = g(one()) + s = rstack.resume_state_create(None, "rp0", one()-1) + try: + v2 = rstack.resume_state_invoke(int, s) + except KeyError: + v2 = 42 + return v1*100 + v2 + res = llinterp_stackless_function(example) + assert res == 242 + From nik at codespeak.net Sun Jun 4 10:14:42 2006 From: nik at codespeak.net (nik at codespeak.net) Date: Sun, 4 Jun 2006 10:14:42 +0200 (CEST) Subject: [pypy-svn] r28209 - pypy/dist/pypy/rpython/module/test Message-ID: <20060604081442.6C43410070@code0.codespeak.net> Author: nik Date: Sun Jun 4 10:14:41 2006 New Revision: 28209 Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py Log: fix an import that caused test failures. Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_os.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_os.py Sun Jun 4 10:14:41 2006 @@ -1,6 +1,6 @@ import os from pypy.tool.udir import udir -from pypy.rpython.module.ll_os import * +from pypy.rpython.lltypesystem.module.ll_os import * def test_open_read_write_close(): From ericvrp at codespeak.net Sun Jun 4 10:38:10 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sun, 4 Jun 2006 10:38:10 +0200 (CEST) Subject: [pypy-svn] r28210 - in pypy/dist/pypy: interpreter interpreter/test module/_pickle_support Message-ID: <20060604083810.DCDD110069@code0.codespeak.net> Author: ericvrp Date: Sun Jun 4 10:38:06 2006 New Revision: 28210 Modified: pypy/dist/pypy/interpreter/generator.py pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/pytraceback.py pypy/dist/pypy/interpreter/test/test_pickle.py pypy/dist/pypy/interpreter/typedef.py pypy/dist/pypy/module/_pickle_support/__init__.py pypy/dist/pypy/module/_pickle_support/maker.py Log: Added Pickling of tracebacks and generator. (enable as described in r28152) Still todo are pickling of methods, staticmethods and classmethods. Plus frame pickling needs to be debugged some more. Modified: pypy/dist/pypy/interpreter/generator.py ============================================================================== --- pypy/dist/pypy/interpreter/generator.py (original) +++ pypy/dist/pypy/interpreter/generator.py Sun Jun 4 10:38:06 2006 @@ -43,6 +43,22 @@ self.running = False self.exhausted = False + def descr__reduce__(self, space): + raise Exception('generator pickling is work in progress') + from pypy.interpreter.mixedmodule import MixedModule + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) + new_inst = mod.get('generator_new') + w = space.wrap + + tup = [ + w(self.frame), + w(self.running), + w(self.exhausted), + ] + + return space.newtuple([new_inst, space.newtuple(tup)]) + def descr__iter__(self): """x.__iter__() <==> iter(x)""" return self.space.wrap(self) Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Sun Jun 4 10:38:06 2006 @@ -65,7 +65,7 @@ # For tracing self.instr_lb = 0 self.instr_ub = -1 - self.instr_prev = -1; + self.instr_prev = -1 def descr__reduce__(self, space): ''' @@ -86,10 +86,18 @@ else: f_lineno = self.f_lineno + valuestack = [w(item) for item in self.valuestack.items] + #print 'XXX valuestack=', valuestack + + blockstack = [w(item) for item in self.blockstack.items] + #print 'XXX blockstack=', blockstack + tup = [ w(self.f_back), w(self.builtin), w(self.pycode), + space.w_None, #space.newtuple(valuestack), #XXX causes AttributeError: 'NoneType' object has no attribute 'getclass' + space.w_None, #space.newtuple(blockstack), w(self.last_exception), #f_exc_traceback, f_exc_type, f_exc_value self.w_globals, w(self.last_instr), @@ -98,10 +106,14 @@ #space.newtuple(self.fastlocals_w), #XXX (application-level) PicklingError: Can't pickle : it's not found as __builtin__.AppTestInterpObjectPickling #self.getdictscope(), #XXX (application-level) PicklingError: Can't pickle : it's not found as __builtin__.AppTestInterpObjectPickling - space.w_None, #XXX placeholder + space.w_None, #XXX placeholder for f_locals #f_restricted requires no additional data! self.w_f_trace, + + w(self.instr_lb), #do we need these three (that are for tracing) + w(self.instr_ub), + w(self.instr_prev), ] #XXX what to do with valuestack and blockstack here? @@ -294,7 +306,7 @@ op = ord(code[addr]) if op in (SETUP_LOOP, SETUP_EXCEPT, SETUP_FINALLY): - delta_iblock += 1; + delta_iblock += 1 elif op == POP_BLOCK: delta_iblock -= 1 if delta_iblock < min_delta_iblock: Modified: pypy/dist/pypy/interpreter/pytraceback.py ============================================================================== --- pypy/dist/pypy/interpreter/pytraceback.py (original) +++ pypy/dist/pypy/interpreter/pytraceback.py Sun Jun 4 10:38:06 2006 @@ -18,6 +18,22 @@ self.lineno = lineno self.next = next + def descr__reduce__(self, space): + raise Exception('traceback pickling is work in progress') + from pypy.interpreter.mixedmodule import MixedModule + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) + new_inst = mod.get('traceback_new') + w = space.wrap + + tup = [ + w(self.frame), + w(self.lasti), + w(self.lineno), + w(self.next), + ] + + return space.newtuple([new_inst, space.newtuple(tup)]) def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Sun Jun 4 10:38:06 2006 @@ -1,5 +1,5 @@ class AppTestInterpObjectPickling: - + def test_pickle_code(self): def f(): return 42 @@ -71,7 +71,7 @@ result = pickle.loads(pckl) assert cell == result assert not (cell != result) - + def test_pickle_frame(self): ''' >>>> dir(frame) @@ -86,32 +86,33 @@ exc_type, exc, tb = exc_info() return tb.tb_frame import pickle - frame = f() - pckl = pickle.dumps(frame) - result = pickle.loads(pckl) - assert type(frame) is type(result) - assert dir(frame) == dir(result) - assert frame.__doc__ == result.__doc__ - assert type(frame.f_back) is type(result.f_back) - assert frame.f_builtins is result.f_builtins - assert frame.f_code == result.f_code - assert frame.f_exc_traceback is result.f_exc_traceback - assert frame.f_exc_type is result.f_exc_type - assert frame.f_exc_value is result.f_exc_value - - #print 'frame f_globals =', frame.f_globals #frame f_globals = {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } - #print 'result.f_globals=', result.f_globals #result.f_globals= {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } - #assert frame.f_globals == result.f_globals #XXX test_pickle_frame function not same identity (see pickle func tests, we don't compare by identity there!)? - - assert frame.f_lasti == result.f_lasti - assert frame.f_lineno == result.f_lineno - - #print 'frame.f_locals=', frame.f_locals #['exc_info', 'tb', 'exc_type', 'exc'] - #print 'result.f_locals=', result.f_locals #[] - #assert list(frame.f_locals) == list(result.f_locals) - - assert frame.f_restricted is result.f_restricted - assert frame.f_trace is result.f_trace + f1 = f() + pckl = pickle.dumps(f1) + f2 = pickle.loads(pckl) + + assert type(f1) is type(f2) + assert dir(f1) == dir(f2) + assert f1.__doc__ == f2.__doc__ + assert type(f1.f_back) is type(f2.f_back) + assert f1.f_builtins is f2.f_builtins + assert f1.f_code == f2.f_code + assert f1.f_exc_traceback is f2.f_exc_traceback + assert f1.f_exc_type is f2.f_exc_type + assert f1.f_exc_value is f2.f_exc_value + + #print 'f1.f_globals =', f1.f_globals #f1.f_globals = {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } + #print 'f2.f_globals=', f2.f_globals #f2.f_globals= {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } + #assert f1.f_globals == f2.f_globals #XXX test_pickle_frame function not same identity (see pickle func tests, we don't compare by identity there!)? + + assert f1.f_lasti == f2.f_lasti + assert f1.f_lineno == f2.f_lineno + + #print 'f1.f_locals=', f1.f_locals #['exc_info', 'tb', 'exc_type', 'exc'] + #print 'f2.f_locals=', f2.f_locals #[] + #assert list(f1.f_locals) == list(f2.f_locals) + + assert f1.f_restricted is f2.f_restricted + assert f1.f_trace is f2.f_trace def test_pickle_traceback(self): skip("work in progress") @@ -126,8 +127,39 @@ tb = f() pckl = pickle.dumps(tb) result = pickle.loads(pckl) - assert tb == result - + + assert type(tb) is type(result) + assert tb.tb_lasti == result.tb_lasti + assert tb.tb_lineno == result.tb_lineno + assert tb.tb_next == result.tb_next + + #XXX silly code duplication from frame pickling test + f1 = tb.tb_frame + f2 = result.tb_frame + assert type(f1) is type(f2) + assert dir(f1) == dir(f2) + assert f1.__doc__ == f2.__doc__ + assert type(f1.f_back) is type(f2.f_back) + assert f1.f_builtins is f2.f_builtins + assert f1.f_code == f2.f_code + assert f1.f_exc_traceback is f2.f_exc_traceback + assert f1.f_exc_type is f2.f_exc_type + assert f1.f_exc_value is f2.f_exc_value + + #print 'f1.f_globals =', f1.f_globals #f1.f_globals = {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } + #print 'f2.f_globals=', f2.f_globals #f2.f_globals= {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } + #assert f1.f_globals == f2.f_globals #XXX test_pickle_frame function not same identity (see pickle func tests, we don't compare by identity there!)? + + assert f1.f_lasti == f2.f_lasti + assert f1.f_lineno == f2.f_lineno + + #print 'f1.f_locals=', f1.f_locals #['exc_info', 'tb', 'exc_type', 'exc'] + #print 'f2.f_locals=', f2.f_locals #[] + #assert list(f1.f_locals) == list(f2.f_locals) + + assert f1.f_restricted is f2.f_restricted + assert f1.f_trace is f2.f_trace + def test_pickle_module(self): import pickle mod = pickle @@ -270,5 +302,39 @@ x = 0 while x < n: yield x - generator = giveme(10) - print pickle.dumps(generator) + g1 = giveme(10) + #print 'g1=', g1, dir(g1) + pckl = pickle.dumps(g1) + g2 = pickle.loads(pckl) + #print 'g2=', g2, dir(g2) + + assert type(g1) is type(g2) + assert g1.gi_running == g2.gi_running + #assert g1.gi_exhausted == g2.gi_exhausted #not exported! + + #XXX silly code duplication from frame pickling test + f1 = g1.gi_frame + f2 = g2.gi_frame + assert type(f1) is type(f2) + assert dir(f1) == dir(f2) + assert f1.__doc__ == f2.__doc__ + assert type(f1.f_back) is type(f2.f_back) + assert f1.f_builtins is f2.f_builtins + assert f1.f_code == f2.f_code + assert f1.f_exc_traceback is f2.f_exc_traceback + assert f1.f_exc_type is f2.f_exc_type + assert f1.f_exc_value is f2.f_exc_value + + #print 'f1.f_globals =', f1.f_globals #f1.f_globals = {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } + #print 'f2.f_globals=', f2.f_globals #f2.f_globals= {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } + #assert f1.f_globals == f2.f_globals #XXX test_pickle_frame function not same identity (see pickle func tests, we don't compare by identity there!)? + + assert f1.f_lasti == f2.f_lasti + assert f1.f_lineno == f2.f_lineno + + #print 'f1.f_locals=', f1.f_locals #['exc_info', 'tb', 'exc_type', 'exc'] + #print 'f2.f_locals=', f2.f_locals #[] + #assert list(f1.f_locals) == list(f2.f_locals) + + assert f1.f_restricted is f2.f_restricted + assert f1.f_trace is f2.f_trace Modified: pypy/dist/pypy/interpreter/typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/typedef.py (original) +++ pypy/dist/pypy/interpreter/typedef.py Sun Jun 4 10:38:06 2006 @@ -623,6 +623,8 @@ del BuiltinFunction.typedef.rawdict['__get__'] PyTraceback.typedef = TypeDef("traceback", + #__reduce__ = interp2app(PyTraceback.descr__reduce__, + # unwrap_spec=['self', ObjSpace]), tb_frame = interp_attrproperty('frame', cls=PyTraceback), tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = interp_attrproperty('lineno', cls=PyTraceback), @@ -630,6 +632,8 @@ ) GeneratorIterator.typedef = TypeDef("generator", + #__reduce__ = interp2app(GeneratorIterator.descr__reduce__, + # unwrap_spec=['self', ObjSpace]), next = interp2app(GeneratorIterator.descr_next), __iter__ = interp2app(GeneratorIterator.descr__iter__), gi_running = interp_attrproperty('running', cls=GeneratorIterator), Modified: pypy/dist/pypy/module/_pickle_support/__init__.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/__init__.py (original) +++ pypy/dist/pypy/module/_pickle_support/__init__.py Sun Jun 4 10:38:06 2006 @@ -16,4 +16,6 @@ 'seqiter_new' : 'maker.seqiter_new', 'reverseseqiter_new' : 'maker.reverseseqiter_new', #'frame_new' : 'maker.frame_new', + #'traceback_new' : 'maker.traceback_new', + #'generator_new' : 'maker.generator_new', } Modified: pypy/dist/pypy/module/_pickle_support/maker.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/maker.py (original) +++ pypy/dist/pypy/module/_pickle_support/maker.py Sun Jun 4 10:38:06 2006 @@ -3,6 +3,8 @@ from pypy.interpreter.function import Function, Method from pypy.interpreter.module import Module from pypy.interpreter.pyframe import PyFrame +from pypy.interpreter.pytraceback import PyTraceback +from pypy.interpreter.generator import GeneratorIterator from pypy.rpython.objectmodel import instantiate from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import ObjSpace, W_Root @@ -53,13 +55,16 @@ def frame_new(space, __args__): args_w, kwds_w = __args__.unpack() #stolen from std/fake.py args = [space.unwrap(w_arg) for w_arg in args_w] - f_back, builtin, pycode, last_exception, globals, last_instr, next_instr,\ - f_lineno, fastlocals, f_trace = args + f_back, builtin, pycode, valuestack, blockstack, last_exception,\ + globals, last_instr, next_instr, f_lineno, fastlocals, f_trace,\ + instr_lb, instr_ub, instr_prev = args w = space.wrap new_frame = PyFrame(space, pycode, w(globals), None) new_frame.f_back = f_back new_frame.builtin = builtin + #new_frame.blockstack = blockstack + #new_frame.valuestack = valuestack new_frame.last_exception = last_exception new_frame.last_instr = last_instr new_frame.next_instr = next_instr @@ -71,5 +76,26 @@ else: new_frame.w_f_trace = w(f_trace) + new_frame.instr_lb = instr_lb #the three for tracing + new_frame.instr_ub = instr_ub + new_frame.instr_prev = instr_prev + return space.wrap(new_frame) frame_new.unwrap_spec = [ObjSpace, Arguments] + +def traceback_new(space, __args__): + args_w, kwds_w = __args__.unpack() #stolen from std/fake.py + args = [space.unwrap(w_arg) for w_arg in args_w] + frame, lasti, lineno, next = args + return PyTraceback(space, frame, lasti, lineno, next) +traceback_new.unwrap_spec = [ObjSpace, Arguments] + +def generator_new(space, __args__): + args_w, kwds_w = __args__.unpack() #stolen from std/fake.py + args = [space.unwrap(w_arg) for w_arg in args_w] + frame, running, exhausted = args + new_generator = GeneratorIterator(frame) + new_generator.running = running + new_generator.exhausted = exhausted + return new_generator +generator_new.unwrap_spec = [ObjSpace, Arguments] From ac at codespeak.net Sun Jun 4 10:54:33 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 4 Jun 2006 10:54:33 +0200 (CEST) Subject: [pypy-svn] r28211 - pypy/dist/pypy/rpython Message-ID: <20060604085433.A58BC10070@code0.codespeak.net> Author: ac Date: Sun Jun 4 10:54:33 2006 New Revision: 28211 Modified: pypy/dist/pypy/rpython/llinterp.py Log: Add missing operations. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Sun Jun 4 10:54:33 2006 @@ -431,6 +431,12 @@ def op_resume_point(self, *args): pass + def op_resume_state_create(self, *args): + raise RuntimeError("resume_state_create can not be called.") + + def op_resume_state_invoke(self, *args): + raise RuntimeError("resume_state_invoke can not be called.") + def op_decode_arg(self, fname, i, name, vargs, vkwds): raise NotImplementedError("decode_arg") @@ -648,6 +654,10 @@ assert lltype.typeOf(wadr) == llmemory.WeakGcAddress return llmemory.cast_weakadr_to_ptr(wadr, TYPE) + def op_cast_weakadr_to_int(self, wadr): + assert lltype.typeOf(wadr) == llmemory.WeakGcAddress + return wadr.cast_to_int() + def op_cast_int_to_float(self, i): assert type(i) is int return float(i) @@ -760,6 +770,7 @@ def op_call_boehm_gc_alloc(self): raise NotImplementedError("call_boehm_gc_alloc") + # operations on pyobjects! for opname in opimpls.keys(): exec py.code.Source(""" From mwh at codespeak.net Sun Jun 4 10:59:28 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 10:59:28 +0200 (CEST) Subject: [pypy-svn] r28212 - pypy/dist/pypy/rpython/memory Message-ID: <20060604085928.B4AF010070@code0.codespeak.net> Author: mwh Date: Sun Jun 4 10:59:27 2006 New Revision: 28212 Modified: pypy/dist/pypy/rpython/memory/gctransform.py Log: translator can be None in gctransformer.__init__ -- breaks test_database. grr! Modified: pypy/dist/pypy/rpython/memory/gctransform.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform.py (original) +++ pypy/dist/pypy/rpython/memory/gctransform.py Sun Jun 4 10:59:27 2006 @@ -43,7 +43,7 @@ else: self.mixlevelannotator = None self.inline = inline - if inline: + if translator and inline: self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping() self.graphs_to_inline = {} if self.MinimalGCTransformer: From ale at codespeak.net Sun Jun 4 11:08:16 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Sun, 4 Jun 2006 11:08:16 +0200 (CEST) Subject: [pypy-svn] r28214 - pypy/dist/pypy/objspace/std/test Message-ID: <20060604090816.838BD10036@code0.codespeak.net> Author: ale Date: Sun Jun 4 11:08:15 2006 New Revision: 28214 Modified: pypy/dist/pypy/objspace/std/test/test_complexobject.py Log: Added test for subclasses of complex Modified: pypy/dist/pypy/objspace/std/test/test_complexobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_complexobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_complexobject.py Sun Jun 4 11:08:15 2006 @@ -296,6 +296,19 @@ for num in nums: h.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num)) + def test_complex_subclass_ctr(self): + import sys + class j(complex): + pass + assert j(100 + 0j) == 100 + 0j + assert isinstance(j(100),j) + assert j(100L + 0j) == 100 + 0j + assert j("100 + 0j") == 100 + 0j + x = j(1+0j) + x.foo = 42 + assert x.foo == 42 + assert type(complex(x)) == complex + def test_repr(self): h = self.helper h.assertEqual(repr(1+6j), '(1+6j)') From ale at codespeak.net Sun Jun 4 11:10:34 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Sun, 4 Jun 2006 11:10:34 +0200 (CEST) Subject: [pypy-svn] r28215 - pypy/dist/pypy/objspace/std Message-ID: <20060604091034.4280410069@code0.codespeak.net> Author: ale Date: Sun Jun 4 11:10:34 2006 New Revision: 28215 Modified: pypy/dist/pypy/objspace/std/complextype.py Log: Fixed some bugs concerning subclasses of complex. Still missing is pickling/unpickling with protocol 2 and a range check of real/imag values (we cant do like CPython I fear) Modified: pypy/dist/pypy/objspace/std/complextype.py ============================================================================== --- pypy/dist/pypy/objspace/std/complextype.py (original) +++ pypy/dist/pypy/objspace/std/complextype.py Sun Jun 4 11:10:34 2006 @@ -117,7 +117,9 @@ raise TypeError def descr__new__(space, w_complextype, w_real=0.0, w_imag=None): + from pypy.objspace.std.complexobject import W_ComplexObject + try: check_second_arg(space, w_imag) except TypeError: @@ -127,29 +129,12 @@ except TypeError: raise OperationError(space.w_TypeError, space.wrap(ERR_WRONG_SECOND)) # if arguments can be cast to a float, do it - try: - w_real = space.call_function(space.w_float,w_real) - except:pass - try: - w_imag = space.call_function(space.w_float,w_imag) - except:pass + if space.is_w(w_complextype, space.w_complex) and \ + space.eq_w(space.type(w_real), space.w_complex) and \ + space.eq_w(w_imag, space.w_None): + # common case + return w_real - # test for '__complex__' attribute and get result of - # __complex__ method - w_complex_first = extract_complex(space, w_real) - if not space.eq_w(w_complex_first, space.w_None): - w_real = w_complex_first - - # if w_real is a complex number and there is no second - # argument, return w_real - if space.is_true(space.isinstance(w_real, space.w_complex)) and \ - space.eq_w(w_imag, space.w_None): - return w_real - - elif not space.is_true(space.isinstance(w_real, space.w_str)) and \ - not space.eq_w(w_imag, space.w_None): - w_imag = space.mul(w_imag,space.newcomplex(0.0,1.0)) - return space.add(w_real,w_imag) if space.is_true(space.isinstance(w_real, space.w_str)) or \ space.is_true(space.isinstance(w_real, space.w_unicode)): try: @@ -162,16 +147,52 @@ imagval = interp_string_to_float(space, imagstr) except ParseStringError: raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED)) + else: + if space.is_w(w_complextype, space.w_complex): + # common case + w_obj = W_ComplexObject(realval, imagval) + else: + # We are dealing with a subclass of complex + w_obj = space.allocate_instance(W_ComplexObject, w_complextype) + W_ComplexObject.__init__(w_obj,realval, imagval) + + return w_obj + # w_imag is now either float or None + # w_real is either string, complex or float + # test for '__complex__' attribute and get result of + # __complex__ method + w_complex_first = extract_complex(space, w_real) + if not space.eq_w(w_complex_first, space.w_None): + w_real = w_complex_first + + # if w_real is a complex number and there is no second + # argument, return w_real after checking the type + if space.is_true(space.isinstance(w_real, space.w_complex)): + if not space.eq_w(w_imag, space.w_None): + if not space.is_true(space.isinstance(w_imag, space.w_complex)): + w_imag = space.call_function(space.w_float,w_imag) + w_tmp = space.newcomplex(0, 1) + w_tmp = space.mul(w_tmp,w_imag) + w_real = space.add(w_real,w_tmp) + + elif not space.is_true(space.isinstance(w_real, space.w_str)): + if space.eq_w(w_imag, space.w_None): + w_imag = space.wrap(0) + w_real = space.call_function(space.w_float,w_real) + if not space.is_true(space.isinstance(w_imag, space.w_complex)): + w_imag = space.call_function(space.w_float,w_imag) + tmp = space.newcomplex(0, 1) + w_imag = space.mul(w_imag,tmp) + w_real = space.add(w_real,w_imag) + if space.is_w(w_complextype, space.w_complex): + # common case + w_obj = W_ComplexObject(w_real.realval,w_real.imagval) else: - if space.eq_w(w_imag,space.w_None): - w_imag = space.wrap(0.0) - realval = space.float_w(w_real) - imagval = space.float_w(w_imag) - w_obj = space.allocate_instance(W_ComplexObject, w_complextype) - W_ComplexObject.__init__(w_obj, realval, imagval) - + # We are dealing with a subclass of complex + w_obj = space.allocate_instance(W_ComplexObject, w_complextype) + W_ComplexObject.__init__(w_obj, w_real.realval, w_real.imagval) return w_obj - + app = gateway.applevel(r""" def extract_complex(num): if not hasattr(num,'__complex__'): From tismer at codespeak.net Sun Jun 4 11:12:52 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 4 Jun 2006 11:12:52 +0200 (CEST) Subject: [pypy-svn] r28216 - in pypy/dist/pypy/translator: c tool Message-ID: <20060604091252.996D710074@code0.codespeak.net> Author: tismer Date: Sun Jun 4 11:12:51 2006 New Revision: 28216 Modified: pypy/dist/pypy/translator/c/pyobj.py pypy/dist/pypy/translator/tool/raymond.py Log: some stuff left over from the NFS sprint. Still to do: order exposed methods dynamically depending on the existance of annotation Modified: pypy/dist/pypy/translator/c/pyobj.py ============================================================================== --- pypy/dist/pypy/translator/c/pyobj.py (original) +++ pypy/dist/pypy/translator/c/pyobj.py Sun Jun 4 11:12:51 2006 @@ -7,7 +7,7 @@ from pypy.translator.gensupp import builtin_base, builtin_type_base from pypy.translator.c.support import log from pypy.translator.c.wrapper import gen_wrapper, new_method_graph -from pypy.translator.tool.raymond import should_expose_method +from pypy.translator.tool.raymond import should_expose from pypy.rpython.rarithmetic import r_int, r_uint from pypy.rpython.lltypesystem.lltype import pyobjectptr, LowLevelType Modified: pypy/dist/pypy/translator/tool/raymond.py ============================================================================== --- pypy/dist/pypy/translator/tool/raymond.py (original) +++ pypy/dist/pypy/translator/tool/raymond.py Sun Jun 4 11:12:51 2006 @@ -51,10 +51,13 @@ ret = [thetype or cls for thetype in pattern] return ret -def should_expose_method(func): +def should_expose(func): # expose all special methods but hide those starting with _ name = func.__name__ - return name in SPECIAL_METHODS or not name.startswith('_') + return name in SPECIAL_METHODS or not name.startswith('_') or must_expose(func) + +def must_expose(func): + return hasattr(func, '_initialannotation_') def get_compiled_module(func, view=conftest.option.view, inline_threshold=1, use_boehm=False, exports=None, expose_all=True): @@ -85,7 +88,7 @@ rtyper.add_wrapper(clsdef) for obj in cls.__dict__.values(): if isinstance(obj, types.FunctionType): - if should_expose_method(obj) and expose_all: + if should_expose(obj) and expose_all or must_expose(obj): if not ann.bookkeeper.getdesc(obj).querycallfamily(): # not annotated, so enforce it ann.build_types(obj, get_annotation(obj, [cls]), complete_now=False) From fijal at codespeak.net Sun Jun 4 11:13:52 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 4 Jun 2006 11:13:52 +0200 (CEST) Subject: [pypy-svn] r28217 - pypy/dist/pypy/translator/js2 Message-ID: <20060604091352.4AB7C10074@code0.codespeak.net> Author: fijal Date: Sun Jun 4 11:13:51 2006 New Revision: 28217 Modified: pypy/dist/pypy/translator/js2/_class.py pypy/dist/pypy/translator/js2/database.py pypy/dist/pypy/translator/js2/function.py pypy/dist/pypy/translator/js2/jts.py pypy/dist/pypy/translator/js2/opcodes.py Log: Fixed class names to support module names as well. Modified: pypy/dist/pypy/translator/js2/_class.py ============================================================================== --- pypy/dist/pypy/translator/js2/_class.py (original) +++ pypy/dist/pypy/translator/js2/_class.py Sun Jun 4 11:13:51 2006 @@ -10,7 +10,7 @@ self.db = db self.cts = db.type_system_class(db) self.classdef = classdef - self.name = classdef._name.split('.')[-1] + self.name = classdef._name.replace('.', '_')#[-1] if not self.is_root(classdef): self.parent = self.db.pending_class(classdef._superclass) @@ -64,7 +64,7 @@ self.db.record_class(self.classdef, self.name) def basename(self, name): - return name.split('.')[-1] + return name.replace('.', '_')#[-1] #def _ctor(self): # self.ilasm.begin_function('.ctor', [], 'void', False, 'specialname', 'rtspecialname', 'instance') Modified: pypy/dist/pypy/translator/js2/database.py ============================================================================== --- pypy/dist/pypy/translator/js2/database.py (original) +++ pypy/dist/pypy/translator/js2/database.py Sun Jun 4 11:13:51 2006 @@ -226,7 +226,7 @@ def init(self, ilasm): classdef = self.obj._TYPE - ilasm.new(classdef._name.split(".")[-1]) + ilasm.new(classdef._name.replace(".", "_")) def record_fields(self): # we support only primitives, tuples, strings and lists Modified: pypy/dist/pypy/translator/js2/function.py ============================================================================== --- pypy/dist/pypy/translator/js2/function.py (original) +++ pypy/dist/pypy/translator/js2/function.py Sun Jun 4 11:13:51 2006 @@ -166,7 +166,7 @@ """ Block rendering routine using for variable trick """ def basename(x): - return str(x).split('.')[-1] + return str(x).replace('.', '_')#[-1] self.ilasm.begin_for() Modified: pypy/dist/pypy/translator/js2/jts.py ============================================================================== --- pypy/dist/pypy/translator/js2/jts.py (original) +++ pypy/dist/pypy/translator/js2/jts.py Sun Jun 4 11:13:51 2006 @@ -21,7 +21,7 @@ self.db = db def __class(self, name): - return name.split(".")[-1] + return name.replace(".", "_") def llvar_to_cts(self, var): return 'var ', var.name Modified: pypy/dist/pypy/translator/js2/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js2/opcodes.py (original) +++ pypy/dist/pypy/translator/js2/opcodes.py Sun Jun 4 11:13:51 2006 @@ -130,7 +130,7 @@ def render(self, generator, op): # FIXME: just temporary hack generator.load(op.args[0]) - generator.ilasm.load_const(op.args[1].value._name.split('.')[-1]) + generator.ilasm.load_const(op.args[1].value._name.replace('.', '_'))#[-1]) generator.cast_function("isinstanceof", 2) IsInstance = _IsInstance() From mwh at codespeak.net Sun Jun 4 11:13:59 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 11:13:59 +0200 (CEST) Subject: [pypy-svn] r28218 - pypy/dist/pypy/translator/stackless Message-ID: <20060604091359.D2ECA10077@code0.codespeak.net> Author: mwh Date: Sun Jun 4 11:13:58 2006 New Revision: 28218 Modified: pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) Refactor transform_block to get it closer to fitting on one screen. Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sun Jun 4 11:13:58 2006 @@ -457,6 +457,7 @@ link = block.exits[0] else: link = support.split_block_with_keepalive(block, i+1) + i = 0 parms = op.args[1:] if not isinstance(parms[0], model.Variable): assert parms[0].value is None @@ -570,13 +571,77 @@ noexclink.args[i] = model.Constant(realrettype._defl(), realrettype) block.recloseblock(*((noexclink,) + block.exits[1:])) - def transform_block(self, block): - i = 0 - + def insert_unwind_handling(self, block, i): + # for the case where we are resuming to an except: + # block we need to store here a list of links that + # might be resumed to, and in insert_resume_handling + # we need to basically copy each link onto the + # resuming block. + # + # it probably also makes sense to compute the list of + # args to save once, here, and save that too. + # + # finally, it is important that the fetch_retval + # function be called right at the end of the resuming + # block, and that it is called even if the return + # value is not again used. + edata = self.translator.rtyper.getexceptiondata() etype = edata.lltype_of_exception_type evalue = edata.lltype_of_exception_value + if i == len(block.operations) - 1 \ + and block.exitswitch == model.c_last_exception: + link = block.exits[0] + exitcases = dict.fromkeys(l.exitcase for l in block.exits) + if code.UnwindException in exitcases: + return + else: + link = support.split_block_with_keepalive(block, i+1) + block.exitswitch = model.c_last_exception + link.llexitcase = None + # add a general Exception link, because all calls can + # raise anything + v_exctype = varoftype(etype) + v_excvalue = varoftype(evalue) + newlink = model.Link([v_exctype, v_excvalue], + self.curr_graph.exceptblock, + Exception) + newlink.last_exception = v_exctype + newlink.last_exc_value = v_excvalue + newexits = list(block.exits) + newexits.append(newlink) + block.recloseblock(*newexits) + self.translator.rtyper._convert_link(block, newlink) + + var_unwind_exception = varoftype(evalue) + + op = block.operations[i] + + args = vars_to_save(block) + + save_block, frame_state_type, fieldnames = \ + self.generate_save_block(args, var_unwind_exception) + + self.resume_points.append( + ResumePoint(op.result, args, tuple(block.exits), + frame_state_type, fieldnames)) + + newlink = model.Link(args + [var_unwind_exception], + save_block, code.UnwindException) + newlink.last_exception = model.Constant(code.UnwindException, + etype) + newlink.last_exc_value = var_unwind_exception + newexits = list(block.exits) + newexits.insert(1, newlink) + block.recloseblock(*newexits) + self.translator.rtyper._convert_link(block, newlink) + + return link + + def transform_block(self, block): + i = 0 + def replace_with_call(fnptr): args = [fnptr] + op.args[1:] newop = model.SpaceOperation('direct_call', args, op.result) @@ -620,64 +685,9 @@ i += 1 continue - if i == len(block.operations) - 1 \ - and block.exitswitch == model.c_last_exception: - link = block.exits[0] - exitcases = dict.fromkeys(l.exitcase for l in block.exits) - if code.UnwindException in exitcases: - return - else: - link = support.split_block_with_keepalive(block, i+1) - block.exitswitch = model.c_last_exception - link.llexitcase = None - # add a general Exception link, because all calls can - # raise anything - v_exctype = varoftype(etype) - v_excvalue = varoftype(evalue) - newlink = model.Link([v_exctype, v_excvalue], - self.curr_graph.exceptblock, - Exception) - newlink.last_exception = v_exctype - newlink.last_exc_value = v_excvalue - newexits = list(block.exits) - newexits.append(newlink) - block.recloseblock(*newexits) - self.translator.rtyper._convert_link(block, newlink) - - var_unwind_exception = varoftype(evalue) - - # for the case where we are resuming to an except: - # block we need to store here a list of links that - # might be resumed to, and in insert_resume_handling - # we need to basically copy each link onto the - # resuming block. - # - # it probably also makes sense to compute the list of - # args to save once, here, and save that too. - # - # finally, it is important that the fetch_retval - # function be called right at the end of the resuming - # block, and that it is called even if the return - # value is not again used. - - args = vars_to_save(block) - - save_block, frame_state_type, fieldnames = \ - self.generate_save_block(args, var_unwind_exception) - - self.resume_points.append( - ResumePoint(op.result, args, tuple(block.exits), - frame_state_type, fieldnames)) - - newlink = model.Link(args + [var_unwind_exception], - save_block, code.UnwindException) - newlink.last_exception = model.Constant(code.UnwindException, - etype) - newlink.last_exc_value = var_unwind_exception - newexits = list(block.exits) - newexits.insert(1, newlink) - block.recloseblock(*newexits) - self.translator.rtyper._convert_link(block, newlink) + link = self.insert_unwind_handling(block, i) + if link is None: + return # XXX -- remember why this is necessary! if op.opname == 'resume_state_invoke': self.handle_resume_state_invoke(block) From tismer at codespeak.net Sun Jun 4 11:14:09 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 4 Jun 2006 11:14:09 +0200 (CEST) Subject: [pypy-svn] r28219 - pypy/dist/pypy/interpreter Message-ID: <20060604091409.C3DF110074@code0.codespeak.net> Author: tismer Date: Sun Jun 4 11:14:07 2006 New Revision: 28219 Modified: pypy/dist/pypy/interpreter/pyframe.py Log: some comment about frame pickling. The reported error is to be expected, of course, because the frame stack can contain nulls. Please refer to prickelpit.c before reinventing the wheel. Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Sun Jun 4 11:14:07 2006 @@ -97,6 +97,8 @@ w(self.builtin), w(self.pycode), space.w_None, #space.newtuple(valuestack), #XXX causes AttributeError: 'NoneType' object has no attribute 'getclass' + #YYY sure! the stack can contain NULLs. + #YYY I'm again and again strongly recommending to *read* the existing implementation. space.w_None, #space.newtuple(blockstack), w(self.last_exception), #f_exc_traceback, f_exc_type, f_exc_value self.w_globals, From ale at codespeak.net Sun Jun 4 11:28:24 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Sun, 4 Jun 2006 11:28:24 +0200 (CEST) Subject: [pypy-svn] r28221 - pypy/dist/pypy/objspace/std/test Message-ID: <20060604092824.86E2510074@code0.codespeak.net> Author: ale Date: Sun Jun 4 11:28:23 2006 New Revision: 28221 Modified: pypy/dist/pypy/objspace/std/test/test_complexobject.py Log: Added an overflow test Modified: pypy/dist/pypy/objspace/std/test/test_complexobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_complexobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_complexobject.py Sun Jun 4 11:28:23 2006 @@ -308,7 +308,11 @@ x.foo = 42 assert x.foo == 42 assert type(complex(x)) == complex - + + def test_overflow(self): + h = self.helper + raises(ValueError, complex, unicode("1"*500)) + def test_repr(self): h = self.helper h.assertEqual(repr(1+6j), '(1+6j)') From hpk at codespeak.net Sun Jun 4 11:28:40 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Jun 2006 11:28:40 +0200 (CEST) Subject: [pypy-svn] r28222 - pypy/dist/pypy/rpython/rctypes/socketmodule Message-ID: <20060604092840.0F42110077@code0.codespeak.net> Author: hpk Date: Sun Jun 4 11:28:39 2006 New Revision: 28222 Modified: pypy/dist/pypy/rpython/rctypes/socketmodule/ctypes_socket.py Log: an include was missing for OSX 10.3.6 or so Modified: pypy/dist/pypy/rpython/rctypes/socketmodule/ctypes_socket.py ============================================================================== --- pypy/dist/pypy/rpython/rctypes/socketmodule/ctypes_socket.py (original) +++ pypy/dist/pypy/rpython/rctypes/socketmodule/ctypes_socket.py Sun Jun 4 11:28:39 2006 @@ -13,7 +13,8 @@ 'fcntl.h', 'stdio.h', 'netdb.h', - 'arpa/inet.h' + 'arpa/inet.h', + 'stdint.h', ) HEADER = ''.join(['#include <%s>\n' % filename for filename in includes]) constants = {} From ac at codespeak.net Sun Jun 4 11:36:47 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 4 Jun 2006 11:36:47 +0200 (CEST) Subject: [pypy-svn] r28223 - pypy/dist/pypy/interpreter Message-ID: <20060604093647.3D38710074@code0.codespeak.net> Author: ac Date: Sun Jun 4 11:36:46 2006 New Revision: 28223 Modified: pypy/dist/pypy/interpreter/baseobjspace.py Log: enable _weakref by default Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Sun Jun 4 11:36:46 2006 @@ -211,7 +211,7 @@ if name not in modules: modules.append(name) - modules.extend(['unicodedata', '_codecs', 'gc', + modules.extend(['unicodedata', '_codecs', 'gc', '_weakref', 'array', 'marshal', 'errno', 'math', '_sre']) modules.append('_pickle_support') From mwh at codespeak.net Sun Jun 4 11:37:50 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 11:37:50 +0200 (CEST) Subject: [pypy-svn] r28224 - pypy/dist/pypy/translator/stackless Message-ID: <20060604093750.BF57510074@code0.codespeak.net> Author: mwh Date: Sun Jun 4 11:37:49 2006 New Revision: 28224 Modified: pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) yay for refactoring * fix an over-strong assert * fix an old bug and old workaround that could lead to the operations getting transformed more than once. Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sun Jun 4 11:37:49 2006 @@ -435,7 +435,6 @@ newvar = gen_cast(llops, targettype, retvar) convertblock = unsimplify.insert_empty_block(None, link, llops) # begin ouch! - foundit = False for index, linkvar in enumerate(convertblock.exits[0].args): # does this var come from retval ? try: @@ -443,11 +442,9 @@ except ValueError: # e.g. linkvar is a Constant continue if link.args[index1] is retvar: - foundit = True # yes convertblock.exits[0].args[index] = newvar # end ouch! - assert foundit def handle_resume_point(self, block, i): # in some circumstances we might be able to reuse @@ -594,10 +591,10 @@ and block.exitswitch == model.c_last_exception: link = block.exits[0] exitcases = dict.fromkeys(l.exitcase for l in block.exits) - if code.UnwindException in exitcases: - return + nextblock = None else: link = support.split_block_with_keepalive(block, i+1) + nextblock = link.target block.exitswitch = model.c_last_exception link.llexitcase = None # add a general Exception link, because all calls can @@ -637,7 +634,7 @@ block.recloseblock(*newexits) self.translator.rtyper._convert_link(block, newlink) - return link + return nextblock def transform_block(self, block): i = 0 @@ -685,14 +682,14 @@ i += 1 continue - link = self.insert_unwind_handling(block, i) - if link is None: - return # XXX -- remember why this is necessary! - + nextblock = self.insert_unwind_handling(block, i) if op.opname == 'resume_state_invoke': self.handle_resume_state_invoke(block) - block = link.target + if nextblock is None: + return + + block = nextblock i = 0 else: i += 1 From ac at codespeak.net Sun Jun 4 11:39:26 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 4 Jun 2006 11:39:26 +0200 (CEST) Subject: [pypy-svn] r28225 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/test translator/c/src Message-ID: <20060604093926.A887C10074@code0.codespeak.net> Author: ac Date: Sun Jun 4 11:39:25 2006 New Revision: 28225 Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py pypy/dist/pypy/rpython/lltypesystem/lloperation.py pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/rpython/rmodel.py pypy/dist/pypy/rpython/test/test_objectmodel.py pypy/dist/pypy/translator/c/src/address.h Log: (cfbolz, arre): change the way the standard id is implemented: cast a hidden pointer to int instead of the real pointer (for everything except boehm, the hidden pointer is just the same as the pointer, so this is fine). The reason to do this is that otherwise the fact that the bit pattern of a pointer is stored in a dict as the hash of an object keeps the keys alive when using a WeakKeyDictionary (a similar bug can happen if you store ids sommewhere). Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/llmemory.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py Sun Jun 4 11:39:25 2006 @@ -483,6 +483,11 @@ def __init__(self, ob): if ob is not None: self.ref = weakref.ref(ob) + # umpf + if isinstance(ob, lltype._ptr): + self.id = ob._cast_to_int() + else: + self.id = id(ob) else: self.ref = None def get(self): @@ -498,6 +503,10 @@ else: s = str(self.ref) return '' % (s,) + def cast_to_int(self): + # this is not always the behaviour that is really happening + # but make sure that nobody depends on it + return self.id ^ ~3 WeakGcAddress = lltype.Primitive("WeakGcAddress", fakeweakaddress(None)) Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Sun Jun 4 11:39:25 2006 @@ -311,6 +311,7 @@ 'cast_adr_to_ptr': LLOp(canfold=True), 'cast_ptr_to_weakadr': LLOp(canfold=True), 'cast_weakadr_to_ptr': LLOp(canfold=True), + 'cast_weakadr_to_int': LLOp(canfold=True), 'cast_adr_to_int': LLOp(canfold=True), # __________ GC operations __________ Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Sun Jun 4 11:39:25 2006 @@ -110,6 +110,27 @@ resulttype = hop.r_result.lowleveltype) +def cast_weakgcaddress_to_int(address): + if address.ref is None: # NULL address + return 0 + return address.cast_to_int() + + +class Entry(ExtRegistryEntry): + _about_ = cast_weakgcaddress_to_int + + def compute_result_annotation(self, s_int): + return annmodel.SomeInteger() + + + def specialize_call(self, hop): + from pypy.rpython import raddress + assert isinstance(hop.args_r[0], raddress.WeakGcAddressRepr) + vlist = [hop.inputarg(raddress.weakgcaddress_repr, arg=0)] + return hop.genop('cast_weakadr_to_int', vlist, + resulttype = hop.r_result.lowleveltype) + + # __ hlinvoke XXX this doesn't seem completely the right place for this Modified: pypy/dist/pypy/rpython/rmodel.py ============================================================================== --- pypy/dist/pypy/rpython/rmodel.py (original) +++ pypy/dist/pypy/rpython/rmodel.py Sun Jun 4 11:39:25 2006 @@ -5,7 +5,7 @@ from pypy.rpython.lltypesystem.lltype import \ Void, Bool, Float, Signed, Char, UniChar, \ typeOf, LowLevelType, Ptr, PyObject, isCompatibleType -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype from pypy.rpython.error import TyperError, MissingRTypeOperation @@ -214,8 +214,10 @@ self,)) vobj, = hop.inputargs(self) # XXX - return hop.genop('cast_ptr_to_int', [vobj], resulttype=Signed) - + v_waddr = hop.genop('cast_ptr_to_weakadr', [vobj], + resulttype=llmemory.WeakGcAddress) + return hop.genop('cast_weakadr_to_int', [v_waddr], resulttype=Signed) + def rtype_hash(self, hop): ll_hash = self.get_ll_hash_function() v, = hop.inputargs(self) Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_objectmodel.py (original) +++ pypy/dist/pypy/rpython/test/test_objectmodel.py Sun Jun 4 11:39:25 2006 @@ -69,15 +69,28 @@ assert d.keys() == [] return True # for the tests below -def test_cast_to_and_from_address(): +def test_cast_to_and_from_weakaddress(): class A(object): pass class B(object): pass + def f(): + a = A() + addr = cast_object_to_weakgcaddress(a) + return a is cast_weakgcaddress_to_object(addr, A) + assert f() + res = interpret(f, []) + assert res a = A() - addr = cast_object_to_weakgcaddress(a) + addr = cast_object_to_weakgcaddress(A) py.test.raises(AssertionError, "cast_weakgcaddress_to_object(addr, B)") - assert a is cast_weakgcaddress_to_object(addr, A) + assert isinstance(cast_weakgcaddress_to_int(addr), int) + def g(): + a = A() + addr = cast_object_to_weakgcaddress(a) + return cast_weakgcaddress_to_int(addr) + assert isinstance(interpret(f, []), int) + def test_recursive_r_dict_repr(): import operator Modified: pypy/dist/pypy/translator/c/src/address.h ============================================================================== --- pypy/dist/pypy/translator/c/src/address.h (original) +++ pypy/dist/pypy/translator/c/src/address.h Sun Jun 4 11:39:25 2006 @@ -16,6 +16,8 @@ #define OP_ADR_LT(x,y,r) r = ((x) < (y)) #define OP_ADR_GE(x,y,r) r = ((x) >= (y)) +#define OP_CAST_WEAKADR_TO_INT(x, r) r = ((long)x) + #ifndef HIDE_POINTER #define HIDE_POINTER(p) (p) #ifdef REVEAL_POINTER From ale at codespeak.net Sun Jun 4 11:41:33 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Sun, 4 Jun 2006 11:41:33 +0200 (CEST) Subject: [pypy-svn] r28226 - pypy/dist/pypy/objspace/std Message-ID: <20060604094133.1BAE210069@code0.codespeak.net> Author: ale Date: Sun Jun 4 11:41:33 2006 New Revision: 28226 Modified: pypy/dist/pypy/objspace/std/complextype.py Log: Check for overflow. (inspired by the applevel implementation of complex, thank you Carl) Modified: pypy/dist/pypy/objspace/std/complextype.py ============================================================================== --- pypy/dist/pypy/objspace/std/complextype.py (original) +++ pypy/dist/pypy/objspace/std/complextype.py Sun Jun 4 11:41:33 2006 @@ -11,6 +11,9 @@ ERR_WRONG_SECOND = "complex() can't take second arg if first is a string" ERR_MALFORMED = "complex() arg is a malformed string" +OVERFLOWED_FLOAT = 1e200 +OVERFLOWED_FLOAT *= OVERFLOWED_FLOAT + complex_conjugate = StdObjSpaceMultiMethod('conjugate', 1) register_all(vars(),globals()) @@ -148,6 +151,10 @@ except ParseStringError: raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED)) else: + #check for overflow + if abs(realval) == OVERFLOWED_FLOAT or abs(imagval) == OVERFLOWED_FLOAT: + raise OperationError(space.w_ValueError,space.wrap( + "complex() literal too large to convert")) if space.is_w(w_complextype, space.w_complex): # common case w_obj = W_ComplexObject(realval, imagval) From mwh at codespeak.net Sun Jun 4 11:43:34 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 11:43:34 +0200 (CEST) Subject: [pypy-svn] r28228 - pypy/dist/pypy/translator/stackless/test Message-ID: <20060604094334.2A27110069@code0.codespeak.net> Author: mwh Date: Sun Jun 4 11:43:32 2006 New Revision: 28228 Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py Log: (mwh, pedronis) Add another test, which passes, but broken versions of it flushed out a number of bugs in the transform :) Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sun Jun 4 11:43:32 2006 @@ -179,3 +179,26 @@ res = llinterp_stackless_function(example) assert res == 242 +def test_resume_and_raise_and_catch(): + def g(x): + rstack.resume_point("rp0", x) + if x == 0: + raise KeyError + return x + 1 + def f(x): + x = x - 1 + try: + r = g(x) + rstack.resume_point("rp1", returns=r) + except KeyError: + r = 42 + return r - 1 + def example(): + v1 = f(one()+one()) + s1 = rstack.resume_state_create(None, "rp1") + s0 = rstack.resume_state_create(s1, "rp0", one()-1) + v2 = rstack.resume_state_invoke(int, s0) + return v1*100 + v2 + res = llinterp_stackless_function(example) + assert res == 141 + From hpk at codespeak.net Sun Jun 4 11:46:43 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Jun 2006 11:46:43 +0200 (CEST) Subject: [pypy-svn] r28230 - pypy/dist/pypy/doc Message-ID: <20060604094643.1873710069@code0.codespeak.net> Author: hpk Date: Sun Jun 4 11:46:42 2006 New Revision: 28230 Added: pypy/dist/pypy/doc/extcompiler.txt (contents, props changed) Log: start of a document on the "PyPy extension compiler" Added: pypy/dist/pypy/doc/extcompiler.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/extcompiler.txt Sun Jun 4 11:46:42 2006 @@ -0,0 +1,33 @@ +============================================ +PyPy Extension Compiler +============================================ + +This document describes the PyPy extension compiler +which is able to compile a single set of source code +to a PyPy or a CPython extension module. + +**WARNING: this is beta software, APIs and details may change.** + + + +required ctypes version +------------------------ + +As of this time, only `ctypes-0.9.9.6`_ is known to work. + +.. _`ctypes-0.9.9.6`: http://sourceforge.net/project/showfiles.php?group_id=71702&package_id=71318&release_id=411554 + +platform notes +----------------- + +Mac OSX +++++++++++++++++++++++++++ + +*ctypes 0.9.9.6 on OSX 10.3*: you need to change the ``RTLD_LOCAL`` default +in ctypes/__init__.py line 293 to:: + + def __init__(self, name, mode=RTLD_GLOBAL, handle=None): + +otherwise it will complain with "unable to open this file with RTLD_LOCAL" +when trying to load the C library. + From ac at codespeak.net Sun Jun 4 11:48:26 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 4 Jun 2006 11:48:26 +0200 (CEST) Subject: [pypy-svn] r28231 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060604094826.DC6E310053@code0.codespeak.net> Author: ac Date: Sun Jun 4 11:48:26 2006 New Revision: 28231 Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt Log: update planning Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/ddorf2006/planning.txt (original) +++ pypy/extradoc/sprintinfo/ddorf2006/planning.txt Sun Jun 4 11:48:26 2006 @@ -65,7 +65,7 @@ Many of the CPython tests are hopeless, we need modified-2.4.1/test/test_weakref.py. Exposing gc.collect() would help. - **cfbolz + arre** + **cfbolz + arre** DONE * 199 finish app-level stackless support @@ -79,7 +79,7 @@ No progress here. Hopefully not that hard. - (holger, later) + (arre, cfbolz) * 181 time module is incomplete From hpk at codespeak.net Sun Jun 4 11:51:54 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Jun 2006 11:51:54 +0200 (CEST) Subject: [pypy-svn] r28232 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060604095154.5829610076@code0.codespeak.net> Author: hpk Date: Sun Jun 4 11:51:49 2006 New Revision: 28232 Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt Log: updates to planning from my side Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/ddorf2006/planning.txt (original) +++ pypy/extradoc/sprintinfo/ddorf2006/planning.txt Sun Jun 4 11:51:49 2006 @@ -16,7 +16,7 @@ * running the compliance tests and getting results on the web again - (DONE) compliance is at 86% **Holger and Anders** + (DONE) compliance is at 89% **Holger and Anders** * ootypesystem stuff @@ -99,7 +99,7 @@ * 195 Make website doc generation more reliable - Holger! + (done, could be better) Holger * 21 _file.py needs more tests From mwh at codespeak.net Sun Jun 4 11:52:46 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 11:52:46 +0200 (CEST) Subject: [pypy-svn] r28233 - in pypy/dist/pypy: rpython translator/stackless/test Message-ID: <20060604095246.EA06210070@code0.codespeak.net> Author: mwh Date: Sun Jun 4 11:52:45 2006 New Revision: 28233 Modified: pypy/dist/pypy/rpython/rstack.py pypy/dist/pypy/translator/stackless/test/test_resume_point.py Log: (mwh, pedronis) rename the 'returns' kwarg of resume_state_invoke to 'returning' Modified: pypy/dist/pypy/rpython/rstack.py ============================================================================== --- pypy/dist/pypy/rpython/rstack.py (original) +++ pypy/dist/pypy/rpython/rstack.py Sun Jun 4 11:52:45 2006 @@ -117,9 +117,9 @@ from pypy.rpython.lltypesystem import lltype v_state = hop.args_v[1] - if 'i_returns' in kwds_i: + if 'i_returning' in kwds_i: assert len(kwds_i) == 1 - returns_index = kwds_i['i_returns'] + returns_index = kwds_i['i_returning'] v_return = hop.args_v[returns_index] else: assert not kwds_i Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sun Jun 4 11:52:45 2006 @@ -52,7 +52,7 @@ def example(): v1 = f(one(),one()+one()) s = rstack.resume_state_create(None, "rp1", 5*one()) - v2 = rstack.resume_state_invoke(int, s, returns=one()*7) + v2 = rstack.resume_state_invoke(int, s, returning=one()*7) return v1*100 + v2 res = llinterp_stackless_function(example) assert res == 412 @@ -70,7 +70,7 @@ def example(): v1 = f(one(),one()+one()) s = rstack.resume_state_create(None, "rp1", 5*one()) - v2 = rstack.resume_state_invoke(int, s, returns=C(one()*3)) + v2 = rstack.resume_state_invoke(int, s, returning=C(one()*3)) return v1*100 + v2 res = llinterp_stackless_function(example, assert_unwind=False) assert res == 408 @@ -97,7 +97,7 @@ return x*y def f(x, y): z = g(x,y) - rstack.resume_point("rp1", y, returns=z) + rstack.resume_point("rp1", y, returns=z) return z+y+x def example(): f(one(),one()+one()) From arigo at codespeak.net Sun Jun 4 12:02:40 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Jun 2006 12:02:40 +0200 (CEST) Subject: [pypy-svn] r28234 - in pypy/dist/pypy/translator/tool: . pygame Message-ID: <20060604100240.367E310077@code0.codespeak.net> Author: arigo Date: Sun Jun 4 12:02:38 2006 New Revision: 28234 Modified: pypy/dist/pypy/translator/tool/make_dot.py pypy/dist/pypy/translator/tool/pygame/graphdisplay.py Log: Slightly less verbose blocks in pygame graphs. Modified: pypy/dist/pypy/translator/tool/make_dot.py ============================================================================== --- pypy/dist/pypy/translator/tool/make_dot.py (original) +++ pypy/dist/pypy/translator/tool/make_dot.py Sun Jun 4 12:02:38 2006 @@ -75,6 +75,7 @@ class FlowGraphDotGen(DotGen): + VERBOSE = False def __init__(self, graphname, rankdir=None): DotGen.__init__(self, graphname.replace('.', '_'), rankdir) @@ -106,7 +107,11 @@ data = funcgraph.name if hasattr(funcgraph, 'source'): source = funcgraph.source - data += "\\n" + "\\l".join(source.split('\n')) + if self.VERBOSE: + data += "\\n" + else: + data = "" + data += "\\l".join(source.split('\n')) if hasattr(funcgraph, 'func'): self.func = funcgraph.func @@ -142,12 +147,16 @@ lines.append("exitswitch: %s" % block.exitswitch) iargs = " ".join(map(repr, block.inputargs)) - if block.exc_handler: - eh = ' (EH)' + if self.VERBOSE: + if block.exc_handler: + eh = ' (EH)' + else: + eh = '' + data = "%s%s%s\\n" % (name, block.at(), eh) else: - eh = '' - data = "%s%s%s\\ninputargs: %s\\n\\n" % (name, block.at(), eh, iargs) - if block.operations and self.func: + data = "%s\\n" % (name,) + data += "inputargs: %s\\n\\n" % (iargs,) + if self.VERBOSE and block.operations and self.func: maxoffs = max([op.offset for op in block.operations]) if maxoffs >= 0: minoffs = min([op.offset for op in block.operations Modified: pypy/dist/pypy/translator/tool/pygame/graphdisplay.py ============================================================================== --- pypy/dist/pypy/translator/tool/pygame/graphdisplay.py (original) +++ pypy/dist/pypy/translator/tool/pygame/graphdisplay.py Sun Jun 4 12:02:38 2006 @@ -682,7 +682,7 @@ def shortlabel(label): """Shorten a graph node label.""" - return label.replace('\\l', '').splitlines()[0] + return label.replace('\\l', '\n').splitlines()[0] def renderline(text, font, fgcolor, width, maxheight=sys.maxint, From ac at codespeak.net Sun Jun 4 12:05:18 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 4 Jun 2006 12:05:18 +0200 (CEST) Subject: [pypy-svn] r28235 - pypy/dist/pypy/objspace/std Message-ID: <20060604100518.DF11310077@code0.codespeak.net> Author: ac Date: Sun Jun 4 12:05:18 2006 New Revision: 28235 Modified: pypy/dist/pypy/objspace/std/complextype.py Log: (arre, cfbolz, some ale): add some assert isinstances to make the annotator a bit more happy Modified: pypy/dist/pypy/objspace/std/complextype.py ============================================================================== --- pypy/dist/pypy/objspace/std/complextype.py (original) +++ pypy/dist/pypy/objspace/std/complextype.py Sun Jun 4 12:05:18 2006 @@ -177,10 +177,10 @@ if space.is_true(space.isinstance(w_real, space.w_complex)): if not space.eq_w(w_imag, space.w_None): if not space.is_true(space.isinstance(w_imag, space.w_complex)): - w_imag = space.call_function(space.w_float,w_imag) + w_imag = space.call_function(space.w_float, w_imag) w_tmp = space.newcomplex(0, 1) - w_tmp = space.mul(w_tmp,w_imag) - w_real = space.add(w_real,w_tmp) + w_tmp = space.mul(w_tmp, w_imag) + w_real = space.add(w_real, w_tmp) elif not space.is_true(space.isinstance(w_real, space.w_str)): if space.eq_w(w_imag, space.w_None): @@ -189,11 +189,12 @@ if not space.is_true(space.isinstance(w_imag, space.w_complex)): w_imag = space.call_function(space.w_float,w_imag) tmp = space.newcomplex(0, 1) - w_imag = space.mul(w_imag,tmp) - w_real = space.add(w_real,w_imag) + w_imag = space.mul(w_imag, tmp) + w_real = space.add(w_real, w_imag) + assert isinstance(w_real, W_ComplexObject) if space.is_w(w_complextype, space.w_complex): # common case - w_obj = W_ComplexObject(w_real.realval,w_real.imagval) + w_obj = W_ComplexObject(w_real.realval, w_real.imagval) else: # We are dealing with a subclass of complex w_obj = space.allocate_instance(W_ComplexObject, w_complextype) From arigo at codespeak.net Sun Jun 4 12:09:12 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Jun 2006 12:09:12 +0200 (CEST) Subject: [pypy-svn] r28236 - in pypy/dist/pypy: bin rpython/rctypes/tool rpython/rctypes/tool/test Message-ID: <20060604100912.A490C10077@code0.codespeak.net> Author: arigo Date: Sun Jun 4 12:09:10 2006 New Revision: 28236 Modified: pypy/dist/pypy/bin/py.py pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py pypy/dist/pypy/rpython/rctypes/tool/test/test_ctypes_platform.py Log: RCTypes modules need udir even on top of py.py. Modified: pypy/dist/pypy/bin/py.py ============================================================================== --- pypy/dist/pypy/bin/py.py (original) +++ pypy/dist/pypy/bin/py.py Sun Jun 4 12:09:10 2006 @@ -78,9 +78,10 @@ space = make_objspace(Options) space._starttime = starttime - assert 'pypy.tool.udir' not in sys.modules, ( - "running py.py should not import pypy.tool.udir, which is\n" - "only for testing or translating purposes.") + #assert 'pypy.tool.udir' not in sys.modules, ( + # "running py.py should not import pypy.tool.udir, which is\n" + # "only for testing or translating purposes.") + # ^^^ _socket and other rctypes-based modules need udir space.setitem(space.sys.w_dict,space.wrap('executable'),space.wrap(argv[0])) # store the command-line arguments into sys.argv Modified: pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py ============================================================================== --- pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py (original) +++ pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py Sun Jun 4 12:09:10 2006 @@ -5,8 +5,6 @@ from pypy.translator.tool.cbuild import build_executable from pypy.tool.udir import udir -del sys.modules['pypy.tool.udir'] # Don't expose udir - # ____________________________________________________________ # # Helpers for simple cases Modified: pypy/dist/pypy/rpython/rctypes/tool/test/test_ctypes_platform.py ============================================================================== --- pypy/dist/pypy/rpython/rctypes/tool/test/test_ctypes_platform.py (original) +++ pypy/dist/pypy/rpython/rctypes/tool/test/test_ctypes_platform.py Sun Jun 4 12:09:10 2006 @@ -124,6 +124,7 @@ assert res == {'FILE': res['FILE'], 'ushort': ctypes.c_ushort, 'XYZZY': 42} + def test_nested_structs(): class CConfig: _header_ = """ From arigo at codespeak.net Sun Jun 4 12:14:10 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Jun 2006 12:14:10 +0200 (CEST) Subject: [pypy-svn] r28237 - in pypy/dist/pypy: objspace/cpy objspace/cpy/test translator/c Message-ID: <20060604101410.B25A410077@code0.codespeak.net> Author: arigo Date: Sun Jun 4 12:14:08 2006 New Revision: 28237 Added: pypy/dist/pypy/objspace/cpy/function.py - copied, changed from r28087, pypy/dist/pypy/objspace/cpy/wrappable.py pypy/dist/pypy/objspace/cpy/test/test_function.py - copied unchanged from r28087, pypy/dist/pypy/objspace/cpy/test/test_wrappable.py pypy/dist/pypy/objspace/cpy/test/test_typedef.py (contents, props changed) pypy/dist/pypy/objspace/cpy/typedef.py (contents, props changed) Removed: pypy/dist/pypy/objspace/cpy/test/test_wrappable.py pypy/dist/pypy/objspace/cpy/wrappable.py Modified: pypy/dist/pypy/objspace/cpy/ann_policy.py pypy/dist/pypy/objspace/cpy/capi.py pypy/dist/pypy/objspace/cpy/objspace.py pypy/dist/pypy/translator/c/pyobj.py Log: Start the work on TypeDef support in the CPyObjSpace. From a TypeDef, it generates a real CPython type object that is then translated by pyobj.py in genc. Not the cleanest solution, but a quick hack building on top of the existing pyobj, itself a hack. Modified: pypy/dist/pypy/objspace/cpy/ann_policy.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/ann_policy.py (original) +++ pypy/dist/pypy/objspace/cpy/ann_policy.py Sun Jun 4 12:14:08 2006 @@ -1,5 +1,4 @@ from pypy.translator.goal.ann_override import PyPyAnnotatorPolicy -from pypy.annotation.pairtype import pair from pypy.annotation import model as annmodel from pypy.interpreter.error import OperationError from pypy.objspace.cpy.ctypes_base import W_Object, rctypes_pyerrchecker @@ -23,9 +22,8 @@ pending.update(space.wrap_cache) if len(pending) == nb_done: break - for obj, w_obj in pending.items(): - pair(space, obj).follow_annotations(annotator.bookkeeper, - w_obj) + for w_obj, obj, follow in pending.values(): + follow(annotator.bookkeeper, w_obj) # restart this loop: for all we know follow_annotations() # could have found new objects Modified: pypy/dist/pypy/objspace/cpy/capi.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/capi.py (original) +++ pypy/dist/pypy/objspace/cpy/capi.py Sun Jun 4 12:14:08 2006 @@ -43,6 +43,17 @@ ## ('ml_doc', c_char_p)]) ## METH_VARARGS = ctypes_platform.ConstantInteger('METH_VARARGS') +## # NB. all integers fields can be specified as c_int, +## # which is replaced by the more precise type automatically. +## PyObject_HEAD = [('ob_refcnt', c_int), ('ob_type', +## PyTypeObject = ctypes_platform.Struct('PyTypeObject', [ +## ('tp_name', c_char_p), +## ('tp_basicsize', c_int), +## ('tp_flags', c_int), +## ('tp_doc', c_char_p), +## ]) +## Py_TPFLAGS_DEFAULT = ctypes_platform.ConstantInteger('Py_TPFLAGS_DEFAULT') + globals().update(ctypes_platform.configure(CConfig)) del CConfig Modified: pypy/dist/pypy/objspace/cpy/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/objspace.py (original) +++ pypy/dist/pypy/objspace/cpy/objspace.py Sun Jun 4 12:14:08 2006 @@ -1,8 +1,8 @@ from pypy.objspace.cpy.capi import * from pypy.objspace.cpy.refcount import Py_Incref -from pypy.annotation.pairtype import pair from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError +from pypy.interpreter.function import Function class CPyObjSpace(baseobjspace.ObjSpace): @@ -22,7 +22,6 @@ self.w_TypeError = W_Object(TypeError) self.w_KeyError = W_Object(KeyError) self.wrap_cache = {} - self.rev_wrap_cache = {} def _freeze_(self): return True @@ -33,15 +32,17 @@ def wrap(self, x): if isinstance(x, baseobjspace.Wrappable): x = x.__spacebind__(self) - if isinstance(x, baseobjspace.Wrappable): - try: - return self.wrap_cache[x] - except KeyError: - import pypy.objspace.cpy.wrappable - result = pair(self, x).wrap() - self.wrap_cache[x] = result - self.rev_wrap_cache[id(result)] = result, x - return result + # special cases + if isinstance(x, Function): + from pypy.objspace.cpy.function import FunctionCache + return self.fromcache(FunctionCache).getorbuild(x) + # normal case + from pypy.objspace.cpy.typedef import TypeDefCache + w_x = x.__cpy_wrapper__ + if w_x is None: + w_type = self.fromcache(TypeDefCache).getorbuild(x.typedef) + w_x = x.__cpy_wrapper__ = self.call_function(w_type) + return w_x if x is None: return self.w_None if isinstance(x, int): @@ -57,9 +58,11 @@ def interpclass_w(self, w_obj): try: - return self.rev_wrap_cache[id(w_obj)][1] + w_obj, obj, follow = self.wrap_cache[id(w_obj)] except KeyError: return None + else: + return obj # __________ operations with a direct CPython equivalent __________ Added: pypy/dist/pypy/objspace/cpy/test/test_typedef.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/cpy/test/test_typedef.py Sun Jun 4 12:14:08 2006 @@ -0,0 +1,25 @@ +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root +from pypy.interpreter.function import BuiltinFunction +from pypy.objspace.cpy.ann_policy import CPyAnnotatorPolicy +from pypy.objspace.cpy.objspace import CPyObjSpace +from pypy.translator.c.test.test_genc import compile + + +class W_MyType(Wrappable): + def __init__(self, space): + self.space = space + + +def test_simple(): + W_MyType.typedef = TypeDef("MyType") + space = CPyObjSpace() + + def make_mytype(): + return space.wrap(W_MyType(space)) + fn = compile(make_mytype, [], + annotatorpolicy = CPyAnnotatorPolicy(space)) + + res = fn() + assert type(res).__name__ == 'MyType' Added: pypy/dist/pypy/objspace/cpy/typedef.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/cpy/typedef.py Sun Jun 4 12:14:08 2006 @@ -0,0 +1,23 @@ +""" +Generic support to turn interpreter objects (subclasses of Wrappable) +into CPython objects (subclasses of W_Object) based on their typedef. +""" + +from pypy.objspace.cpy.capi import * +from pypy.interpreter.baseobjspace import Wrappable, SpaceCache + +class TypeDefCache(SpaceCache): + def build(cache, typedef): + space = cache.space + newtype = type(typedef.name, (), {}) + w_result = W_Object(newtype) + space.wrap_cache[id(w_result)] = w_result, typedef, follow_annotations + return w_result + + +def follow_annotations(bookkeeper, w_type): + pass + + +# hack! +Wrappable.__cpy_wrapper__ = None Modified: pypy/dist/pypy/translator/c/pyobj.py ============================================================================== --- pypy/dist/pypy/translator/c/pyobj.py (original) +++ pypy/dist/pypy/translator/c/pyobj.py Sun Jun 4 12:14:08 2006 @@ -400,8 +400,9 @@ baseargs = ", ".join(basenames) if baseargs: baseargs = '(%s)' % baseargs - self.initcode.append('class %s%s:' % (name, baseargs)) + self.initcode.append('class %s%s:' % (cls.__name__, baseargs)) self.initcode.append(' __metaclass__ = %s' % metaclass) + self.initcode.append('%s = %s' % (name, cls.__name__)) self.later(initclassobj()) return name From ac at codespeak.net Sun Jun 4 12:29:01 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 4 Jun 2006 12:29:01 +0200 (CEST) Subject: [pypy-svn] r28238 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20060604102901.62A171006F@code0.codespeak.net> Author: ac Date: Sun Jun 4 12:29:00 2006 New Revision: 28238 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py Log: add yet another missing collect. the rest of test_weakref.py passes :-) Modified: pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py Sun Jun 4 12:29:00 2006 @@ -755,6 +755,7 @@ dict = weakref.WeakValueDictionary() self.assertRaises(KeyError, dict.__getitem__, 1) dict[2] = C() + gc.collect() self.assertRaises(KeyError, dict.__getitem__, 2) def test_weak_keys(self): From mwh at codespeak.net Sun Jun 4 12:37:50 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 12:37:50 +0200 (CEST) Subject: [pypy-svn] r28240 - in pypy/dist/pypy: rpython rpython/lltypesystem translator/stackless translator/stackless/test Message-ID: <20060604103750.2A9EB1006F@code0.codespeak.net> Author: mwh Date: Sun Jun 4 12:37:48 2006 New Revision: 28240 Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py pypy/dist/pypy/rpython/rstack.py pypy/dist/pypy/translator/stackless/code.py pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) * support for Constant arguments to resume_state_create and resume_state_invoke. * some sanity checks here and there * add a raising= argument to resume_state_invoke, and test it. Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Sun Jun 4 12:37:48 2006 @@ -344,7 +344,7 @@ 'yield_current_frame_to_caller': LLOp(canraise=(StackException,)), # can always unwind, not just if stackless gc - 'resume_point': LLOp(), + 'resume_point': LLOp(canraise=(Exception,)), 'resume_state_create': LLOp(canraise=(MemoryError,), canunwindgc=True), 'resume_state_invoke': LLOp(canraise=(Exception, StackException)), Modified: pypy/dist/pypy/rpython/rstack.py ============================================================================== --- pypy/dist/pypy/rpython/rstack.py (original) +++ pypy/dist/pypy/rpython/rstack.py Sun Jun 4 12:37:48 2006 @@ -48,6 +48,7 @@ def specialize_call(self, hop, **kwds_i): from pypy.rpython.lltypesystem import lltype + from pypy.objspace.flow import model assert hop.args_s[0].is_constant() c_label = hop.inputconst(lltype.Void, hop.args_s[0].const) @@ -56,10 +57,15 @@ assert len(kwds_i) == 1 returns_index = kwds_i['i_returns'] v_return = args_v.pop(returns_index-1) + assert isinstance(v_return, model.Variable), \ + "resume_point returns= argument must be a Variable" else: assert not kwds_i v_return = hop.inputconst(lltype.Void, None) + for v in args_v: + assert isinstance(v, model.Variable), "resume_point arguments must be Variables" + hop.exception_is_here() return hop.genop('resume_point', [c_label, v_return] + args_v, hop.r_result) @@ -70,6 +76,16 @@ def resume_state_create(prevstate, label, *args): raise RuntimeError("cannot resume states in non-translated versions") +def concretify_argument(hop, index): + from pypy.objspace.flow import model + + v_arg = hop.args_v[index] + if isinstance(v_arg, model.Variable): + return v_arg + + r_arg = hop.rtyper.bindingrepr(v_arg) + return hop.inputarg(r_arg, arg=index) + class ResumeStateCreateFnEntry(ExtRegistryEntry): _about_ = resume_state_create @@ -86,8 +102,10 @@ c_label = hop.inputconst(lltype.Void, hop.args_s[1].const) v_state = hop.inputarg(hop.r_result, arg=0) - - args_v = hop.args_v[2:] + + args_v = [] + for i in range(2, len(hop.args_v)): + args_v.append(concretify_argument(hop, i)) hop.exception_is_here() return hop.genop('resume_state_create', [v_state, c_label] + args_v, @@ -119,14 +137,21 @@ if 'i_returning' in kwds_i: assert len(kwds_i) == 1 - returns_index = kwds_i['i_returning'] - v_return = hop.args_v[returns_index] + returning_index = kwds_i['i_returning'] + v_returning = concretify_argument(hop, returning_index) + v_raising = hop.inputconst(lltype.Void, None) + elif 'i_raising' in kwds_i: + assert len(kwds_i) == 1 + raising_index = kwds_i['i_raising'] + v_returning = hop.inputconst(lltype.Void, None) + v_raising = concretify_argument(hop, raising_index) else: assert not kwds_i - v_return = hop.inputconst(lltype.Void, None) + v_returning = hop.inputconst(lltype.Void, None) + v_raising = hop.inputconst(lltype.Void, None) hop.exception_is_here() - return hop.genop('resume_state_invoke', [v_state, v_return], + return hop.genop('resume_state_invoke', [v_state, v_returning, v_raising], hop.r_result) Modified: pypy/dist/pypy/translator/stackless/code.py ============================================================================== --- pypy/dist/pypy/translator/stackless/code.py (original) +++ pypy/dist/pypy/translator/stackless/code.py Sun Jun 4 12:37:48 2006 @@ -215,6 +215,39 @@ [RESUME_AFTER_STATE, EMPTY_STATE]) + +def resume_after_raising(state, exception): + if global_state.restart_substate == -1: + # normal entry point for a call to state.switch() + # first unwind the stack + u = UnwindException() + s = lltype.malloc(RESUME_AFTER_STATE) + s.header.f_restart = INDEX_RESUME_AFTER_RAISING + s.c = state + add_frame_state(u, s.header) + global_state.exception = exception + raise u + elif global_state.restart_substate == 0: + # STATE 0: we didn't do anything so far, but the stack is unwound + global_state.restart_substate = -1 + # grab the frame corresponding to ourself + # the 'targetstate' local is garbage here, it must be read back from + # 's.c' where we saved it by the normal entry point above + mystate = global_state.top + s = lltype.cast_pointer(lltype.Ptr(RESUME_AFTER_STATE), mystate) + targetstate = s.c + resume_bottom = targetstate + while resume_bottom.f_back: + resume_bottom = resume_bottom.f_back + resume_bottom.f_back = mystate.f_back + global_state.top = targetstate + raise UnwindException() + +resume_after_raising.stackless_explicit = True +INDEX_RESUME_AFTER_RAISING = frame.RestartInfo.add_prebuilt(resume_after_raising, + [RESUME_AFTER_STATE, + EMPTY_STATE]) + template = """\ def resume_after_%(typename)s(state, retvalue): if global_state.restart_substate == -1: Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sun Jun 4 12:37:48 2006 @@ -201,4 +201,25 @@ return v1*100 + v2 res = llinterp_stackless_function(example) assert res == 141 + +def test_invoke_raising(): + def g(x): + rstack.resume_point("rp0", x) + return x + 1 + def f(x): + x = x - 1 + try: + r = g(x) + rstack.resume_point("rp1", returns=r) + except KeyError: + r = 42 + return r - 1 + def example(): + v1 = f(one()+one()) + s1 = rstack.resume_state_create(None, "rp1") + s0 = rstack.resume_state_create(s1, "rp0", 0) + v2 = rstack.resume_state_invoke(int, s0, raising=KeyError()) + return v1*100 + v2 + res = llinterp_stackless_function(example) + assert res == 141 Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sun Jun 4 12:37:48 2006 @@ -260,6 +260,13 @@ [s_hdrptr, annmodel.SomePtr(SAVED_REFERENCE)], annmodel.s_None), } + exception_def = bk.getuniqueclassdef(Exception) + self.resume_after_raising_ptr = mixlevelannotator.constfunc( + code.resume_after_raising, + [s_hdrptr, annmodel.SomeInstance(exception_def)], + annmodel.s_None) + self.exception_type = getinstancerepr( + self.translator.rtyper, exception_def).lowleveltype mixlevelannotator.finish() @@ -550,14 +557,25 @@ # self.resume_points and we don't want a constant "zero" in # there. v_state = op.args[0] - v_returns = op.args[1] - erased_returns_type = storage_type(v_returns.concretetype) - resume_after_ptr = self.resume_afters[erased_returns_type] + v_returning = op.args[1] + v_raising = op.args[2] llops = LowLevelOpList() - if erased_returns_type != v_returns.concretetype: - v_returns = gen_cast(llops, erased_returns_type, v_returns) - llops.genop('direct_call', [resume_after_ptr, v_state, v_returns], + + if v_raising.concretetype == lltype.Void: + erased_type = storage_type(v_returning.concretetype) + resume_after_ptr = self.resume_afters[erased_type] + v_param = v_returning + else: + assert v_returning.concretetype == lltype.Void + erased_type = self.exception_type + resume_after_ptr = self.resume_after_raising_ptr + v_param = v_raising + + if erased_type != v_param.concretetype: + v_param = gen_cast(llops, erased_type, v_param) + llops.genop('direct_call', [resume_after_ptr, v_state, v_param], resulttype=lltype.Void) + del block.operations[-1] block.operations.extend(llops) From mwh at codespeak.net Sun Jun 4 12:53:26 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 12:53:26 +0200 (CEST) Subject: [pypy-svn] r28243 - in pypy/dist/pypy: rpython translator/stackless Message-ID: <20060604105326.D2F9810069@code0.codespeak.net> Author: mwh Date: Sun Jun 4 12:53:25 2006 New Revision: 28243 Modified: pypy/dist/pypy/rpython/rstack.py pypy/dist/pypy/translator/stackless/code.py pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) have resume_state_create etc deal in the same state types as yield_current_frame_to_caller and friends. Modified: pypy/dist/pypy/rpython/rstack.py ============================================================================== --- pypy/dist/pypy/rpython/rstack.py (original) +++ pypy/dist/pypy/rpython/rstack.py Sun Jun 4 12:53:25 2006 @@ -70,9 +70,6 @@ return hop.genop('resume_point', [c_label, v_return] + args_v, hop.r_result) -class ResumeState(object): - pass - def resume_state_create(prevstate, label, *args): raise RuntimeError("cannot resume states in non-translated versions") @@ -91,7 +88,7 @@ def compute_result_annotation(self, s_prevstate, s_label, *args_s): from pypy.annotation import model as annmodel - return annmodel.SomeExternalObject(ResumeState) + return annmodel.SomeExternalObject(frame_stack_top) def specialize_call(self, hop): from pypy.rpython.lltypesystem import lltype @@ -111,15 +108,6 @@ return hop.genop('resume_state_create', [v_state, c_label] + args_v, hop.r_result) -class ResumeStateEntry(ExtRegistryEntry): - _type_ = ResumeState - - def get_repr(self, rtyper, s_state): - from pypy.rpython.rmodel import SimplePointerRepr - from pypy.translator.stackless.frame import STATE_HEADER - from pypy.rpython.lltypesystem import lltype - return SimplePointerRepr(lltype.Ptr(STATE_HEADER)) - def resume_state_invoke(type, state, **kwds): raise NotImplementedError("only works in translated versions") Modified: pypy/dist/pypy/translator/stackless/code.py ============================================================================== --- pypy/dist/pypy/translator/stackless/code.py (original) +++ pypy/dist/pypy/translator/stackless/code.py Sun Jun 4 12:53:25 2006 @@ -191,7 +191,7 @@ u = UnwindException() s = lltype.malloc(RESUME_AFTER_STATE) s.header.f_restart = INDEX_RESUME_AFTER_VOID - s.c = state + s.c = lltype.cast_opaque_ptr(lltype.Ptr(STATE_HEADER), state) add_frame_state(u, s.header) raise u elif global_state.restart_substate == 0: @@ -223,7 +223,7 @@ u = UnwindException() s = lltype.malloc(RESUME_AFTER_STATE) s.header.f_restart = INDEX_RESUME_AFTER_RAISING - s.c = state + s.c = lltype.cast_opaque_ptr(lltype.Ptr(STATE_HEADER), state) add_frame_state(u, s.header) global_state.exception = exception raise u @@ -256,7 +256,7 @@ u = UnwindException() s = lltype.malloc(RESUME_AFTER_STATE) s.header.f_restart = INDEX_RESUME_AFTER_%(TYPENAME)s - s.c = state + s.c = lltype.cast_opaque_ptr(lltype.Ptr(STATE_HEADER), state) global_state.retval_%(typename)s = retvalue add_frame_state(u, s.header) raise u Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sun Jun 4 12:53:25 2006 @@ -237,33 +237,33 @@ self.resume_afters = { lltype.Void: mixlevelannotator.constfunc( code.resume_after_void, - [s_hdrptr, annmodel.s_None], + [s_StatePtr, annmodel.s_None], annmodel.s_None), lltype.Signed: mixlevelannotator.constfunc( code.resume_after_long, - [s_hdrptr, annmodel.SomeInteger()], + [s_StatePtr, annmodel.SomeInteger()], annmodel.s_None), lltype.SignedLongLong: mixlevelannotator.constfunc( code.resume_after_longlong, - [s_hdrptr, annmodel.SomeInteger(knowntype=rarithmetic.r_longlong)], + [s_StatePtr, annmodel.SomeInteger(knowntype=rarithmetic.r_longlong)], annmodel.s_None), lltype.Float: mixlevelannotator.constfunc( code.resume_after_float, - [s_hdrptr, annmodel.SomeFloat()], + [s_StatePtr, annmodel.SomeFloat()], annmodel.s_None), llmemory.Address: mixlevelannotator.constfunc( code.resume_after_addr, - [s_hdrptr, annmodel.SomeAddress()], + [s_StatePtr, annmodel.SomeAddress()], annmodel.s_None), SAVED_REFERENCE: mixlevelannotator.constfunc( code.resume_after_ref, - [s_hdrptr, annmodel.SomePtr(SAVED_REFERENCE)], + [s_StatePtr, annmodel.SomePtr(SAVED_REFERENCE)], annmodel.s_None), } exception_def = bk.getuniqueclassdef(Exception) self.resume_after_raising_ptr = mixlevelannotator.constfunc( code.resume_after_raising, - [s_hdrptr, annmodel.SomeInstance(exception_def)], + [s_StatePtr, annmodel.SomeInstance(exception_def)], annmodel.s_None) self.exception_type = getinstancerepr( self.translator.rtyper, exception_def).lowleveltype @@ -534,10 +534,12 @@ llops.genop('setfield', [v_state, model.Constant('f_restart', lltype.Void), model.Constant(symb, lltype.Signed)]) + v_prevstate = llops.genop('cast_opaque_ptr', [op.args[0]], + resulttype=lltype.Ptr(frame.STATE_HEADER)) llops.genop('setfield', [v_state, model.Constant('f_back', lltype.Void), - op.args[0]]) - llops.append(model.SpaceOperation('same_as', [v_state], op.result)) + v_prevstate]) + llops.append(model.SpaceOperation('cast_opaque_ptr', [v_state], op.result)) block.operations[i:i+1] = llops def handle_resume_state_invoke(self, block): From mwh at codespeak.net Sun Jun 4 13:10:44 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 13:10:44 +0200 (CEST) Subject: [pypy-svn] r28244 - in pypy/dist/pypy/translator: c stackless stackless/test Message-ID: <20060604111044.C1EAF1006F@code0.codespeak.net> Author: mwh Date: Sun Jun 4 13:10:43 2006 New Revision: 28244 Modified: pypy/dist/pypy/translator/c/primitive.py pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) Run the resume point tests after translation to C too. Fix an argh thus revealed. We think we're done for this subsubtask now. Modified: pypy/dist/pypy/translator/c/primitive.py ============================================================================== --- pypy/dist/pypy/translator/c/primitive.py (original) +++ pypy/dist/pypy/translator/c/primitive.py Sun Jun 4 13:10:43 2006 @@ -45,6 +45,9 @@ value = value.compute_fn() else: raise Exception("unimplemented symbolic %r"%value) + if value is None: + assert not db.completed + return None if value == -sys.maxint-1: # blame C return '(-%dL-1L)' % sys.maxint else: Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Sun Jun 4 13:10:43 2006 @@ -56,6 +56,8 @@ return v1*100 + v2 res = llinterp_stackless_function(example) assert res == 412 + res = run_stackless_function(example) + assert res == 412 def test_returns_with_instance(): class C: @@ -74,23 +76,8 @@ return v1*100 + v2 res = llinterp_stackless_function(example, assert_unwind=False) assert res == 408 - -def test_call_exception_handling(): - def g(x,y): - if x == 0: - raise KeyError - return x*y - def f(x, y): - try: - z = g(x,y) - rstack.resume_point("rp1", y, returns=z) - except KeyError: - return 0 - return z+y - def example(): - f(one(),one()+one()) - return 0 - transform_stackless_function(example) + res = run_stackless_function(example) + assert res == 408 def test_call_uncovered(): def g(x,y): @@ -120,7 +107,9 @@ s2 = rstack.resume_state_create(None, "rp2", 2*one()) s1 = rstack.resume_state_create(s2, "rp1", 4*one(), 5*one()) return 100*v1 + rstack.resume_state_invoke(int, s1) - res = llinterp_stackless_function(example, assert_unwind=False) + res = llinterp_stackless_function(example) + assert res == 811 + res = run_stackless_function(example) assert res == 811 def test_return_instance(): @@ -142,7 +131,9 @@ c.x = 4*one() s1 = rstack.resume_state_create(s2, "rp1", c) return v1*100 + rstack.resume_state_invoke(int, s1) - res = llinterp_stackless_function(example, assert_unwind=False) + res = llinterp_stackless_function(example) + assert res == 406 + res = run_stackless_function(example) assert res == 406 def test_really_return_instance(): @@ -161,6 +152,8 @@ return v1*100 + rstack.resume_state_invoke(C, s1).x res = llinterp_stackless_function(example) assert res == 204 + res = run_stackless_function(example) + assert res == 204 def test_resume_and_raise(): def g(x): @@ -178,6 +171,8 @@ return v1*100 + v2 res = llinterp_stackless_function(example) assert res == 242 + res = run_stackless_function(example) + assert res == 242 def test_resume_and_raise_and_catch(): def g(x): @@ -201,6 +196,8 @@ return v1*100 + v2 res = llinterp_stackless_function(example) assert res == 141 + res = run_stackless_function(example) + assert res == 141 def test_invoke_raising(): def g(x): @@ -222,4 +219,6 @@ return v1*100 + v2 res = llinterp_stackless_function(example) assert res == 141 + res = run_stackless_function(example) + assert res == 141 Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sun Jun 4 13:10:43 2006 @@ -56,12 +56,17 @@ # return retval + x + 1 class SymbolicRestartNumber(ComputedIntSymbolic): - def __init__(self, value=None): + def __init__(self, label, value=None): ComputedIntSymbolic.__init__(self, self._getvalue) + self.label = label self.value = value def _getvalue(self): - assert self.value is not None + # argh, we'd like to assert-fail if value is None here, but we + # get called too early (during databasing) for this to be + # valid. so we might return None and rely on the database + # checking that this only happens before the database is + # complete. return self.value class ResumePoint: @@ -499,7 +504,7 @@ assert symb.value is None symb.value = restart_number else: - symb = SymbolicRestartNumber(restart_number) + symb = SymbolicRestartNumber(label, restart_number) self.symbolic_restart_numbers[label] = symb return link.target, i @@ -528,7 +533,7 @@ if label in self.symbolic_restart_numbers: symb = self.symbolic_restart_numbers[label] else: - symb = SymbolicRestartNumber() + symb = SymbolicRestartNumber(label) self.symbolic_restart_numbers[label] = symb llops.genop('setfield', [v_state, From antocuni at codespeak.net Sun Jun 4 13:10:54 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Jun 2006 13:10:54 +0200 (CEST) Subject: [pypy-svn] r28245 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem ootypesystem/test Message-ID: <20060604111054.10D8310075@code0.codespeak.net> Author: antocuni Date: Sun Jun 4 13:10:52 2006 New Revision: 28245 Modified: pypy/dist/pypy/rpython/exceptiondata.py pypy/dist/pypy/rpython/lltypesystem/exceptiondata.py pypy/dist/pypy/rpython/ootypesystem/exceptiondata.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py Log: (antocuni, nik) Fixed a bug that prevented OSError to be raised in ootypesystem. Modified: pypy/dist/pypy/rpython/exceptiondata.py ============================================================================== --- pypy/dist/pypy/rpython/exceptiondata.py (original) +++ pypy/dist/pypy/rpython/exceptiondata.py Sun Jun 4 13:10:52 2006 @@ -1,5 +1,6 @@ from pypy.rpython import rclass from pypy.rpython.extfunctable import standardexceptions +from pypy.annotation import model as annmodel class AbstractExceptionData: """Public information for the code generators to help with exceptions.""" @@ -28,3 +29,10 @@ classdef = bk.getuniqueclassdef(cls) rclass.getclassrepr(rtyper, classdef).setup() + def make_raise_OSError(self, rtyper): + # ll_raise_OSError(errno) + def ll_raise_OSError(errno): + raise OSError(errno, None) + helper_fn = rtyper.annotate_helper_fn(ll_raise_OSError, [annmodel.SomeInteger()]) + return helper_fn + Modified: pypy/dist/pypy/rpython/lltypesystem/exceptiondata.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/exceptiondata.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/exceptiondata.py Sun Jun 4 13:10:52 2006 @@ -24,14 +24,6 @@ return helper_fn - def make_raise_OSError(self, rtyper): - # ll_raise_OSError(errno) - def ll_raise_OSError(errno): - raise OSError(errno, None) - helper_fn = rtyper.annotate_helper_fn(ll_raise_OSError, [annmodel.SomeInteger()]) - return helper_fn - - def make_type_of_exc_inst(self, rtyper): # ll_type_of_exc_inst(exception_instance) -> exception_vtable s_excinst = annmodel.SomePtr(self.lltype_of_exception_value) Modified: pypy/dist/pypy/rpython/ootypesystem/exceptiondata.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/exceptiondata.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/exceptiondata.py Sun Jun 4 13:10:52 2006 @@ -23,12 +23,14 @@ self.fn_exception_match = self.make_exception_matcher(rtyper) self.fn_pyexcclass2exc = self.make_pyexcclass2exc(rtyper) self.fn_type_of_exc_inst = self.make_type_of_exc_inst(rtyper) + self.fn_raise_OSError = self.make_raise_OSError(rtyper) def make_exception_matcher(self, rtyper): # ll_exception_matcher(real_exception_meta, match_exception_meta) s_classtype = annmodel.SomeOOInstance(self.lltype_of_exception_type) helper_fn = rtyper.annotate_helper_fn(rclass.ll_issubclass, [s_classtype, s_classtype]) return helper_fn + def make_type_of_exc_inst(self, rtyper): # ll_type_of_exc_inst(exception_instance) -> exception_vtable Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Sun Jun 4 13:10:52 2006 @@ -378,6 +378,14 @@ v_attr = hop.inputconst(ootype.Void, mangled) return hop.genop('oosetfield', [v_inst, v_attr, v_newval]) + def setfield(self, vinst, attr, vvalue, llops): + # this method emulates behaviour from the corresponding + # lltypesystem one. It is referenced in some obscure corners + # like rtyping of OSError. + mangled_name = mangle(attr) + cname = inputconst(ootype.Void, mangled_name) + llops.genop('oosetfield', [vinst, cname, vvalue]) + def rtype_is_true(self, hop): vinst, = hop.inputargs(self) return hop.genop('oononnull', [vinst], resulttype=ootype.Bool) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py Sun Jun 4 13:10:52 2006 @@ -232,3 +232,16 @@ for n in -42, 0, 42: for b in 8, 10, 16: assert interpret(oof, [n, b], type_system='ootype') == n + +def test_OSError(): + def oof(b): + try: + if b: + raise OSError + else: + return 1 + except OSError: + return 2 + + assert interpret(oof, [True], type_system='ootype') == 2 + assert interpret(oof, [False], type_system='ootype') == 1 From tismer at codespeak.net Sun Jun 4 13:11:49 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 4 Jun 2006 13:11:49 +0200 (CEST) Subject: [pypy-svn] r28246 - in pypy/dist/pypy: interpreter interpreter/test module/_pickle_support Message-ID: <20060604111149.9B34A10070@code0.codespeak.net> Author: tismer Date: Sun Jun 4 13:11:48 2006 New Revision: 28246 Modified: pypy/dist/pypy/interpreter/generator.py pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/pytraceback.py pypy/dist/pypy/interpreter/test/test_pickle.py pypy/dist/pypy/interpreter/typedef.py pypy/dist/pypy/module/_pickle_support/__init__.py Log: pickling now passes all tests, but this doesn't say too much, frame pickling is not ready, yet. Modified: pypy/dist/pypy/interpreter/generator.py ============================================================================== --- pypy/dist/pypy/interpreter/generator.py (original) +++ pypy/dist/pypy/interpreter/generator.py Sun Jun 4 13:11:48 2006 @@ -44,7 +44,6 @@ self.exhausted = False def descr__reduce__(self, space): - raise Exception('generator pickling is work in progress') from pypy.interpreter.mixedmodule import MixedModule w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Sun Jun 4 13:11:48 2006 @@ -68,37 +68,25 @@ self.instr_prev = -1 def descr__reduce__(self, space): - ''' - >>>> dir(frame) - ['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'f_back', 'f_builtins', 'f_code', 'f_exc_traceback', 'f_exc_type', 'f_exc_value', 'f_globals', 'f_lasti', 'f_lineno', 'f_locals', 'f_restricted', 'f_trace'] - ''' - raise Exception('frame pickling is work in progress') from pypy.interpreter.mixedmodule import MixedModule w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('frame_new') w = space.wrap - #XXX how to call PyFrame.fget_f_lineno(..) from here? just make it a staticmethod? - #f_lineno = PyFrame.fget_f_lineno(space, self) #TypeError: unbound method fget_f_lineno() must be called with PyFrame instance as first argument (got StdObjSpace instance instead) if self.w_f_trace is None: f_lineno = self.get_last_lineno() else: f_lineno = self.f_lineno valuestack = [w(item) for item in self.valuestack.items] - #print 'XXX valuestack=', valuestack - blockstack = [w(item) for item in self.blockstack.items] - #print 'XXX blockstack=', blockstack tup = [ w(self.f_back), w(self.builtin), w(self.pycode), space.w_None, #space.newtuple(valuestack), #XXX causes AttributeError: 'NoneType' object has no attribute 'getclass' - #YYY sure! the stack can contain NULLs. - #YYY I'm again and again strongly recommending to *read* the existing implementation. space.w_None, #space.newtuple(blockstack), w(self.last_exception), #f_exc_traceback, f_exc_type, f_exc_value self.w_globals, @@ -118,11 +106,6 @@ w(self.instr_prev), ] - #XXX what to do with valuestack and blockstack here? - #YYY well, we build the valuestack as a tuple (with a marker for NULL objects) - #YYY and we pickle the blockstack as well. - #YYY see frameobject_reduce line 722 in prickelpit.c in the stackless distro. - return space.newtuple([new_inst, space.newtuple(tup)]) def hide(self): Modified: pypy/dist/pypy/interpreter/pytraceback.py ============================================================================== --- pypy/dist/pypy/interpreter/pytraceback.py (original) +++ pypy/dist/pypy/interpreter/pytraceback.py Sun Jun 4 13:11:48 2006 @@ -19,7 +19,6 @@ self.next = next def descr__reduce__(self, space): - raise Exception('traceback pickling is work in progress') from pypy.interpreter.mixedmodule import MixedModule w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Sun Jun 4 13:11:48 2006 @@ -14,15 +14,17 @@ mod = new.module('mod') import sys sys.modules['mod'] = mod - def func(): - return 42 - mod.__dict__['func'] = func - func.__module__ = 'mod' - import pickle - pckl = pickle.dumps(func) - result = pickle.loads(pckl) - assert func is result - del sys.modules['mod'] + try: + def func(): + return 42 + mod.__dict__['func'] = func + func.__module__ = 'mod' + import pickle + pckl = pickle.dumps(func) + result = pickle.loads(pckl) + assert func is result + finally: + del sys.modules['mod'] def test_pickle_not_imported_module(self): import new @@ -33,7 +35,6 @@ result = pickle.loads(pckl) assert mod.__name__ == result.__name__ assert mod.__dict__ == result.__dict__ - #print mod.__dict__ def test_pickle_builtin_func(self): import pickle @@ -73,11 +74,6 @@ assert not (cell != result) def test_pickle_frame(self): - ''' - >>>> dir(frame) - ['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'f_back', 'f_builtins', 'f_code', 'f_exc_traceback', 'f_exc_type', 'f_exc_value', 'f_globals', 'f_lasti', 'f_lineno', 'f_locals', 'f_restricted', 'f_trace'] - ''' - skip("work in progress") from sys import exc_info def f(): try: @@ -115,7 +111,6 @@ assert f1.f_trace is f2.f_trace def test_pickle_traceback(self): - skip("work in progress") def f(): try: raise Exception() @@ -196,43 +191,54 @@ assert a == result def test_pickle_method(self): - skip("work in progress") class myclass(object): def f(self): - pass + return 42 def __reduce__(self): - return (myclass,()) - import pickle + return (myclass, ()) + import pickle, sys, new + myclass.__module__ = 'mod' myclass_inst = myclass() - method = myclass_inst.f - pckl = pickle.dumps(method) - result = pickle.loads(pckl) - assert method == result - + mod = new.module('mod') + mod.myclass = myclass + sys.modules['mod'] = mod + try: + method = myclass_inst.f + pckl = pickle.dumps(method) + result = pickle.loads(pckl) + # we cannot compare the objects, because the method will be a fresh one + assert method() == result() + finally: + del sys.modules['mod'] def test_pickle_staticmethod(self): - skip("work in progress") class myclass(object): - def f(self): - pass + def f(): + return 42 f = staticmethod(f) import pickle method = myclass.f pckl = pickle.dumps(method) result = pickle.loads(pckl) - assert method == result + assert method() == result() def test_pickle_classmethod(self): - skip("work in progress") class myclass(object): - def f(self): - pass + def f(cls): + return cls f = classmethod(f) - import pickle - method = myclass.f - pckl = pickle.dumps(method) - result = pickle.loads(pckl) - assert method == result + import pickle, sys, new + myclass.__module__ = 'mod' + mod = new.module('mod') + mod.myclass = myclass + sys.modules['mod'] = mod + try: + method = myclass.f + pckl = pickle.dumps(method) + result = pickle.loads(pckl) + assert method() == result() + finally: + del sys.modules['mod'] def test_pickle_sequenceiter(self): ''' @@ -296,7 +302,6 @@ assert list(result) == [2,3,4] def test_pickle_generator(self): - skip("work in progress (implement after frame pickling)") import pickle def giveme(n): x = 0 Modified: pypy/dist/pypy/interpreter/typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/typedef.py (original) +++ pypy/dist/pypy/interpreter/typedef.py Sun Jun 4 13:11:48 2006 @@ -521,8 +521,8 @@ ) PyFrame.typedef = TypeDef('frame', - #__reduce__ = interp2app(PyFrame.descr__reduce__, - # unwrap_spec=['self', ObjSpace]), + __reduce__ = interp2app(PyFrame.descr__reduce__, + unwrap_spec=['self', ObjSpace]), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), f_back = GetSetProperty(PyFrame.fget_f_back), @@ -623,8 +623,8 @@ del BuiltinFunction.typedef.rawdict['__get__'] PyTraceback.typedef = TypeDef("traceback", - #__reduce__ = interp2app(PyTraceback.descr__reduce__, - # unwrap_spec=['self', ObjSpace]), + __reduce__ = interp2app(PyTraceback.descr__reduce__, + unwrap_spec=['self', ObjSpace]), tb_frame = interp_attrproperty('frame', cls=PyTraceback), tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = interp_attrproperty('lineno', cls=PyTraceback), @@ -632,8 +632,8 @@ ) GeneratorIterator.typedef = TypeDef("generator", - #__reduce__ = interp2app(GeneratorIterator.descr__reduce__, - # unwrap_spec=['self', ObjSpace]), + __reduce__ = interp2app(GeneratorIterator.descr__reduce__, + unwrap_spec=['self', ObjSpace]), next = interp2app(GeneratorIterator.descr_next), __iter__ = interp2app(GeneratorIterator.descr__iter__), gi_running = interp_attrproperty('running', cls=GeneratorIterator), Modified: pypy/dist/pypy/module/_pickle_support/__init__.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/__init__.py (original) +++ pypy/dist/pypy/module/_pickle_support/__init__.py Sun Jun 4 13:11:48 2006 @@ -15,7 +15,7 @@ 'dictiter_surrogate_new' : 'maker.dictiter_surrogate_new', 'seqiter_new' : 'maker.seqiter_new', 'reverseseqiter_new' : 'maker.reverseseqiter_new', - #'frame_new' : 'maker.frame_new', - #'traceback_new' : 'maker.traceback_new', - #'generator_new' : 'maker.generator_new', + 'frame_new' : 'maker.frame_new', + 'traceback_new' : 'maker.traceback_new', + 'generator_new' : 'maker.generator_new', } From mwh at codespeak.net Sun Jun 4 13:14:59 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 13:14:59 +0200 (CEST) Subject: [pypy-svn] r28247 - pypy/branch/explicit_resume_pt_experiment Message-ID: <20060604111459.8572B10070@code0.codespeak.net> Author: mwh Date: Sun Jun 4 13:14:58 2006 New Revision: 28247 Removed: pypy/branch/explicit_resume_pt_experiment/ Log: remove the explicit_resume_pt_experiment branch. From mwh at codespeak.net Sun Jun 4 13:16:20 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 13:16:20 +0200 (CEST) Subject: [pypy-svn] r28248 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060604111620.077011006F@code0.codespeak.net> Author: mwh Date: Sun Jun 4 13:16:20 2006 New Revision: 28248 Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt Log: updates Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/ddorf2006/planning.txt (original) +++ pypy/extradoc/sprintinfo/ddorf2006/planning.txt Sun Jun 4 13:16:20 2006 @@ -49,16 +49,14 @@ No problem at all! hahahaha - - finish needed object type pickling/unpickling - - finish and integrate explict resume points support + - (in-progress) finish needed object type pickling/unpickling + - (DONE) finish and integrate explict resume points support - use the latter to implement restarting after unpickling (likely hack! hack! hack! until it works) Tasklet cloning has become completely different, that kind of works now (needs more testing). - **Samuele and mwh: finish and integrate explict resume points support** - * 81 weakrefs This is about 90% done, only the other 90% to go :) From pedronis at codespeak.net Sun Jun 4 14:08:05 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 4 Jun 2006 14:08:05 +0200 (CEST) Subject: [pypy-svn] r28249 - pypy/dist/pypy/module/_demo Message-ID: <20060604120805.1BFBC1006F@code0.codespeak.net> Author: pedronis Date: Sun Jun 4 14:08:04 2006 New Revision: 28249 Modified: pypy/dist/pypy/module/_demo/demo.py Log: fix for darwin Modified: pypy/dist/pypy/module/_demo/demo.py ============================================================================== --- pypy/dist/pypy/module/_demo/demo.py (original) +++ pypy/dist/pypy/module/_demo/demo.py Sun Jun 4 14:08:04 2006 @@ -17,7 +17,7 @@ elif sys.platform == 'linux2': mylib = cdll_load('libc.so.6') elif sys.platform == 'darwin': - mylib = cdll.c + mylib = cdll_load('libc.dylib') else: py.test.skip("don't know how to load the c lib for %s" % sys.platform) From antocuni at codespeak.net Sun Jun 4 14:49:07 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Jun 2006 14:49:07 +0200 (CEST) Subject: [pypy-svn] r28251 - in pypy/dist/pypy: rpython rpython/lltypesystem/module rpython/module rpython/module/test rpython/ootypesystem/module rpython/test translator/c Message-ID: <20060604124907.0E6B11006F@code0.codespeak.net> Author: antocuni Date: Sun Jun 4 14:49:05 2006 New Revision: 28251 Added: pypy/dist/pypy/rpython/lltypesystem/module/ll_os_path.py (contents, props changed) pypy/dist/pypy/rpython/ootypesystem/module/ll_os_path.py (contents, props changed) Removed: pypy/dist/pypy/rpython/ootypesystem/module/support.py Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py pypy/dist/pypy/rpython/module/ll_os.py pypy/dist/pypy/rpython/module/ll_os_path.py pypy/dist/pypy/rpython/module/ll_strtod.py pypy/dist/pypy/rpython/module/support.py pypy/dist/pypy/rpython/module/test/test_ll_os.py pypy/dist/pypy/rpython/module/test/test_ll_os_path.py pypy/dist/pypy/rpython/module/test/test_ll_strtod.py pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py pypy/dist/pypy/rpython/rgenop.py pypy/dist/pypy/rpython/test/test_rbuiltin.py pypy/dist/pypy/rpython/test/tool.py pypy/dist/pypy/translator/c/extfunc.py Log: (antocuni, nik) Make many external functions work in ootypesystem. Most functions (e.g., the ll_os ones) are now classmethods that make use of typesystem-specific helpers defined in rpython/module/support.py or in rpython/{ll,oo}typestem/module/ll_*.py. Then we fixed some places that referenced things that we moved and brought some tests to ootypesystem too. Due to this change genc had to be fixed, too. Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Sun Jun 4 14:49:05 2006 @@ -28,7 +28,7 @@ except AttributeError: mod = self.import_module("pypy.rpython.%s.module.%s" % (type_system.name, lastmodulename)) - ll_function = getattr(mod, ll_function_name) + ll_function = getattr(mod.Implementation, ll_function_name) return ll_function def import_module(self, module_name): @@ -155,9 +155,9 @@ return SomeInteger(nonneg=True) def statannotation(*args): + from pypy.rpython.lltypesystem.module.ll_os import Implementation from pypy.annotation.model import SomeInteger, SomeTuple - from pypy.rpython.module.ll_os import ll_stat_result - record_call(ll_stat_result, [SomeInteger()]*10, 'OS_STAT') + record_call(Implementation.ll_stat_result, [SomeInteger()]*10, 'OS_STAT') return SomeTuple((SomeInteger(),)*10) def frexpannotation(*args): Modified: pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/module/ll_os.py Sun Jun 4 14:49:05 2006 @@ -1,16 +1,29 @@ -import os -from pypy.rpython.module.support import from_rstr, to_rstr -from pypy.rpython.module.ll_os import * +from pypy.rpython.module.support import LLSupport +from pypy.rpython.module.ll_os import BaseOS +from pypy.rpython.lltypesystem import lltype +from pypy.rpython.rarithmetic import intmask -def ll_os_open(fname, flag, mode): - return os.open(from_rstr(fname), flag, mode) -ll_os_open.suggested_primitive = True +n = 10 +fieldnames = ['item%d' % i for i in range(n)] +lltypes = [lltype.Signed]*n +fields = tuple(zip(fieldnames, lltypes)) +STAT_RESULT = lltype.GcStruct('tuple%d' % n, *fields) -def ll_os_write(fd, astring): - return os.write(fd, from_rstr(astring)) -ll_os_write.suggested_primitive = True - -def ll_os_getcwd(): - return to_rstr(os.getcwd()) -ll_os_getcwd.suggested_primitive = True +class Implementation(BaseOS, LLSupport): + + def ll_stat_result(stat0, stat1, stat2, stat3, stat4, + stat5, stat6, stat7, stat8, stat9): + tup = lltype.malloc(STAT_RESULT) + tup.item0 = intmask(stat0) + tup.item1 = intmask(stat1) + tup.item2 = intmask(stat2) + tup.item3 = intmask(stat3) + tup.item4 = intmask(stat4) + tup.item5 = intmask(stat5) + tup.item6 = intmask(stat6) + tup.item7 = intmask(stat7) + tup.item8 = intmask(stat8) + tup.item9 = intmask(stat9) + return tup + ll_stat_result = staticmethod(ll_stat_result) Added: pypy/dist/pypy/rpython/lltypesystem/module/ll_os_path.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/lltypesystem/module/ll_os_path.py Sun Jun 4 14:49:05 2006 @@ -0,0 +1,7 @@ +from pypy.rpython.module.support import LLSupport +from pypy.rpython.module.ll_os_path import BaseOsPath + +class Implementation(BaseOsPath, LLSupport): + pass + + Modified: pypy/dist/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/module/ll_os.py Sun Jun 4 14:49:05 2006 @@ -16,143 +16,141 @@ import os, errno from pypy.rpython.lltypesystem.lltype import \ GcStruct, Signed, Array, Char, Ptr, malloc -from pypy.rpython.module.support import to_rstr, from_rstr, ll_strcpy, _ll_strfill +from pypy.rpython.module.support import ll_strcpy, _ll_strfill from pypy.rpython.module.support import to_opaque_object, from_opaque_object from pypy.rpython import ros from pypy.rpython.rarithmetic import r_longlong +from pypy.tool.staticmethods import ClassMethods +import stat -def ll_read_into(fd, buffer): - data = os.read(fd, len(buffer.chars)) - _ll_strfill(buffer, data, len(data)) - return len(data) -ll_read_into.suggested_primitive = True - -def ll_os_read(fd, count): - from pypy.rpython.lltypesystem.rstr import STR - if count < 0: - raise OSError(errno.EINVAL, None) - buffer = malloc(STR, count) - n = ll_read_into(fd, buffer) - if n != count: - s = malloc(STR, n) - ll_strcpy(s, buffer, n) - buffer = s - return buffer - - - -def ll_os_close(fd): - os.close(fd) -ll_os_close.suggested_primitive = True - - - -def ll_os_dup(fd): - return os.dup(fd) -ll_os_dup.suggested_primitive = True - -def ll_os_lseek(fd,pos,how): - return r_longlong(os.lseek(fd,pos,how)) -ll_os_lseek.suggested_primitive = True - -def ll_os_isatty(fd): - return os.isatty(fd) -ll_os_isatty.suggested_primitive = True - -def ll_os_ftruncate(fd,len): - return os.ftruncate(fd,len) -ll_os_ftruncate.suggested_primitive = True - -n = 10 -fieldnames = ['item%d' % i for i in range(n)] -lltypes = [Signed]*n -fields = tuple(zip(fieldnames, lltypes)) -STAT_RESULT = GcStruct('tuple%d' % n, *fields) - -from pypy.rpython.rarithmetic import intmask - -def ll_stat_result(stat0, stat1, stat2, stat3, stat4, - stat5, stat6, stat7, stat8, stat9): - tup = malloc(STAT_RESULT) - tup.item0 = intmask(stat0) - tup.item1 = intmask(stat1) - tup.item2 = intmask(stat2) - tup.item3 = intmask(stat3) - tup.item4 = intmask(stat4) - tup.item5 = intmask(stat5) - tup.item6 = intmask(stat6) - tup.item7 = intmask(stat7) - tup.item8 = intmask(stat8) - tup.item9 = intmask(stat9) - return tup - -def ll_os_fstat(fd): - (stat0, stat1, stat2, stat3, stat4, - stat5, stat6, stat7, stat8, stat9) = os.fstat(fd) - return ll_stat_result(stat0, stat1, stat2, stat3, stat4, - stat5, stat6, stat7, stat8, stat9) -ll_os_fstat.suggested_primitive = True - -def ll_os_stat(path): - (stat0, stat1, stat2, stat3, stat4, - stat5, stat6, stat7, stat8, stat9) = os.stat(from_rstr(path)) - return ll_stat_result(stat0, stat1, stat2, stat3, stat4, - stat5, stat6, stat7, stat8, stat9) -ll_os_stat.suggested_primitive = True - -def ll_os_strerror(errnum): - return to_rstr(os.strerror(errnum)) -ll_os_strerror.suggested_primitive = True - -def ll_os_system(cmd): - return os.system(from_rstr(cmd)) -ll_os_system.suggested_primitive = True - -def ll_os_unlink(path): - os.unlink(from_rstr(path)) -ll_os_unlink.suggested_primitive = True - -def ll_os_chdir(path): - os.chdir(from_rstr(path)) -ll_os_chdir.suggested_primitive = True - -def ll_os_mkdir(path, mode): - os.mkdir(from_rstr(path), mode) -ll_os_mkdir.suggested_primitive = True - -def ll_os_rmdir(path): - os.rmdir(from_rstr(path)) -ll_os_rmdir.suggested_primitive = True - -# this function is not really the os thing, but the internal one. -def ll_os_putenv(name_eq_value): - ros.putenv(from_rstr(name_eq_value)) -ll_os_putenv.suggested_primitive = True - -def ll_os_unsetenv(name): - os.unsetenv(from_rstr(name)) -ll_os_unsetenv.suggested_primitive = True - -# get the initial environment by indexing -def ll_os_environ(idx): - return ros.environ(idx) -ll_os_environ.suggested_primitive = True - -# ____________________________________________________________ -# opendir/readdir - -def ll_os_opendir(dirname): - dir = ros.opendir(from_rstr(dirname)) - return to_opaque_object(dir) -ll_os_opendir.suggested_primitive = True - -def ll_os_readdir(opaquedir): - dir = from_opaque_object(opaquedir) - nextentry = dir.readdir() - return to_rstr(nextentry) -ll_os_readdir.suggested_primitive = True - -def ll_os_closedir(opaquedir): - dir = from_opaque_object(opaquedir) - dir.closedir() -ll_os_closedir.suggested_primitive = True + + + +class BaseOS: + __metaclass__ = ClassMethods + + def ll_os_open(cls, fname, flag, mode): + return os.open(cls.from_rstr(fname), flag, mode) + ll_os_open.suggested_primitive = True + + def ll_os_write(cls, fd, astring): + return os.write(fd, cls.from_rstr(astring)) + ll_os_write.suggested_primitive = True + + def ll_os_getcwd(cls): + return cls.to_rstr(os.getcwd()) + ll_os_getcwd.suggested_primitive = True + + def ll_read_into(fd, buffer): + data = os.read(fd, len(buffer.chars)) + _ll_strfill(buffer, data, len(data)) + return len(data) + ll_read_into.suggested_primitive = True + ll_read_into = staticmethod(ll_read_into) + + def ll_os_read(cls, fd, count): + from pypy.rpython.lltypesystem.rstr import STR + if count < 0: + raise OSError(errno.EINVAL, None) + buffer = malloc(STR, count) + n = cls.ll_read_into(fd, buffer) + if n != count: + s = malloc(STR, n) + ll_strcpy(s, buffer, n) + buffer = s + return buffer + + + + def ll_os_close(cls, fd): + os.close(fd) + ll_os_close.suggested_primitive = True + + + + def ll_os_dup(cls, fd): + return os.dup(fd) + ll_os_dup.suggested_primitive = True + + def ll_os_lseek(cls, fd,pos,how): + return r_longlong(os.lseek(fd,pos,how)) + ll_os_lseek.suggested_primitive = True + + def ll_os_isatty(cls, fd): + return os.isatty(fd) + ll_os_isatty.suggested_primitive = True + + def ll_os_ftruncate(cls, fd,len): + return os.ftruncate(fd,len) + ll_os_ftruncate.suggested_primitive = True + + def ll_os_fstat(cls, fd): + (stat0, stat1, stat2, stat3, stat4, + stat5, stat6, stat7, stat8, stat9) = os.fstat(fd) + return cls.ll_stat_result(stat0, stat1, stat2, stat3, stat4, + stat5, stat6, stat7, stat8, stat9) + ll_os_fstat.suggested_primitive = True + + def ll_os_stat(cls, path): + (stat0, stat1, stat2, stat3, stat4, + stat5, stat6, stat7, stat8, stat9) = os.stat(cls.from_rstr(path)) + return cls.ll_stat_result(stat0, stat1, stat2, stat3, stat4, + stat5, stat6, stat7, stat8, stat9) + ll_os_stat.suggested_primitive = True + + def ll_os_strerror(cls, errnum): + return cls.to_rstr(os.strerror(errnum)) + ll_os_strerror.suggested_primitive = True + + def ll_os_system(cls, cmd): + return os.system(cls.from_rstr(cmd)) + ll_os_system.suggested_primitive = True + + def ll_os_unlink(cls, path): + os.unlink(cls.from_rstr(path)) + ll_os_unlink.suggested_primitive = True + + def ll_os_chdir(cls, path): + os.chdir(cls.from_rstr(path)) + ll_os_chdir.suggested_primitive = True + + def ll_os_mkdir(cls, path, mode): + os.mkdir(cls.from_rstr(path), mode) + ll_os_mkdir.suggested_primitive = True + + def ll_os_rmdir(cls, path): + os.rmdir(cls.from_rstr(path)) + ll_os_rmdir.suggested_primitive = True + + # this function is not really the os thing, but the internal one. + def ll_os_putenv(cls, name_eq_value): + ros.putenv(cls.from_rstr(name_eq_value)) + ll_os_putenv.suggested_primitive = True + + def ll_os_unsetenv(cls, name): + os.unsetenv(cls.from_rstr(name)) + ll_os_unsetenv.suggested_primitive = True + + # get the initial environment by indexing + def ll_os_environ(cls, idx): + return ros.environ(idx) + ll_os_environ.suggested_primitive = True + + # ____________________________________________________________ + # opendir/readdir + + def ll_os_opendir(cls, dirname): + dir = ros.opendir(cls.from_rstr(dirname)) + return to_opaque_object(dir) + ll_os_opendir.suggested_primitive = True + + def ll_os_readdir(cls, opaquedir): + dir = from_opaque_object(opaquedir) + nextentry = dir.readdir() + return cls.to_rstr(nextentry) + ll_os_readdir.suggested_primitive = True + + def ll_os_closedir(cls, opaquedir): + dir = from_opaque_object(opaquedir) + dir.closedir() + ll_os_closedir.suggested_primitive = True Modified: pypy/dist/pypy/rpython/module/ll_os_path.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_os_path.py (original) +++ pypy/dist/pypy/rpython/module/ll_os_path.py Sun Jun 4 14:49:05 2006 @@ -4,26 +4,29 @@ # see ll_os.py for comments -import os import stat -from pypy.rpython.module.support import to_rstr, from_rstr, ll_strcpy -from pypy.rpython.module.ll_os import ll_os_stat +import os +from pypy.tool.staticmethods import ClassMethods # Does a path exist? # This is false for dangling symbolic links. -def ll_os_path_exists(path): - """Test whether a path exists""" - try: - st = ll_os_stat(path) - except OSError: - return False - return True - -def ll_os_path_isdir(path): - try: - st = ll_os_stat(path) - except OSError: - return False - return stat.S_ISDIR(st.item0) +class BaseOsPath: + __metaclass__ = ClassMethods + + def ll_os_path_exists(cls, path): + """Test whether a path exists""" + try: + st = os.stat(cls.from_rstr(path)) + except OSError: + return False + return True + + def ll_os_path_isdir(cls, path): + try: + (stat0, stat1, stat2, stat3, stat4, + stat5, stat6, stat7, stat8, stat9) = os.stat(cls.from_rstr(path)) + except OSError: + return False + return stat.S_ISDIR(stat0) Modified: pypy/dist/pypy/rpython/module/ll_strtod.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_strtod.py (original) +++ pypy/dist/pypy/rpython/module/ll_strtod.py Sun Jun 4 14:49:05 2006 @@ -1,15 +1,15 @@ # string -> float helper from pypy.rpython import rarithmetic -from pypy.rpython.module.support import to_rstr, from_rstr, ll_strcpy +from pypy.rpython.module.support import LLSupport, ll_strcpy def ll_strtod_parts_to_float(sign, beforept, afterpt, exponent): - return rarithmetic.parts_to_float(from_rstr(sign), - from_rstr(beforept), - from_rstr(afterpt), - from_rstr(exponent)) + return rarithmetic.parts_to_float(LLSupport.from_rstr(sign), + LLSupport.from_rstr(beforept), + LLSupport.from_rstr(afterpt), + LLSupport.from_rstr(exponent)) ll_strtod_parts_to_float.suggested_primitive = True def ll_strtod_formatd(fmt, x): - return to_rstr(rarithmetic.formatd(from_rstr(fmt), x)) + return LLSupport.to_rstr(rarithmetic.formatd(LLSupport.from_rstr(fmt), x)) ll_strtod_formatd.suggested_primitive = True Modified: pypy/dist/pypy/rpython/module/support.py ============================================================================== --- pypy/dist/pypy/rpython/module/support.py (original) +++ pypy/dist/pypy/rpython/module/support.py Sun Jun 4 14:49:05 2006 @@ -1,24 +1,46 @@ from pypy.rpython.lltypesystem import lltype +from pypy.rpython.ootypesystem import ootype from pypy.rpython import extfunctable from pypy.rpython.lltypesystem.lltype import \ GcStruct, Signed, Array, Char, Ptr, malloc - # utility conversion functions -def to_rstr(s): - from pypy.rpython.lltypesystem.rstr import STR - if s is None: - return lltype.nullptr(STR) - p = malloc(STR, len(s)) - for i in range(len(s)): - p.chars[i] = s[i] - return p - -def from_rstr(rs): - if not rs: # null pointer - return None - else: - return ''.join([rs.chars[i] for i in range(len(rs.chars))]) + +class LLSupport: + _mixin_ = True + + def to_rstr(s): + from pypy.rpython.lltypesystem.rstr import STR + if s is None: + return lltype.nullptr(STR) + p = malloc(STR, len(s)) + for i in range(len(s)): + p.chars[i] = s[i] + return p + to_rstr = staticmethod(to_rstr) + + def from_rstr(rs): + if not rs: # null pointer + return None + else: + return ''.join([rs.chars[i] for i in range(len(rs.chars))]) + from_rstr = staticmethod(from_rstr) + + +class OOSupport: + _mixin_ = True + + def to_rstr(s): + return ootype.oostring(s, -1) + to_rstr = staticmethod(to_rstr) + + def from_rstr(rs): + if not rs: # null pointer + return None + else: + return "".join([rs.ll_stritem_nonneg(i) for i in range(rs.ll_strlen())]) + from_rstr = staticmethod(from_rstr) + def ll_strcpy(dst_s, src_s, n): dstchars = dst_s.chars Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_os.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_os.py Sun Jun 4 14:49:05 2006 @@ -1,44 +1,44 @@ import os from pypy.tool.udir import udir -from pypy.rpython.lltypesystem.module.ll_os import * +from pypy.rpython.lltypesystem.module.ll_os import Implementation as impl def test_open_read_write_close(): filename = str(udir.join('test_open_read_write_close.txt')) - rsfilename = to_rstr(filename) + rsfilename = impl.to_rstr(filename) - fd = ll_os_open(rsfilename, os.O_WRONLY | os.O_CREAT, 0777) - count = ll_os_write(fd, to_rstr("hello world\n")) + fd = impl.ll_os_open(rsfilename, os.O_WRONLY | os.O_CREAT, 0777) + count = impl.ll_os_write(fd, impl.to_rstr("hello world\n")) assert count == len("hello world\n") - ll_os_close(fd) + impl.ll_os_close(fd) - fd = ll_os_open(rsfilename, os.O_RDONLY, 0777) - data = ll_os_read(fd, 500) - assert from_rstr(data) == "hello world\n" - ll_os_close(fd) + fd = impl.ll_os_open(rsfilename, os.O_RDONLY, 0777) + data = impl.ll_os_read(fd, 500) + assert impl.from_rstr(data) == "hello world\n" + impl.ll_os_close(fd) os.unlink(filename) def test_getcwd(): - data = ll_os_getcwd() - assert from_rstr(data) == os.getcwd() + data = impl.ll_os_getcwd() + assert impl.from_rstr(data) == os.getcwd() def test_strerror(): - data = ll_os_strerror(2) - assert from_rstr(data) == os.strerror(2) + data = impl.ll_os_strerror(2) + assert impl.from_rstr(data) == os.strerror(2) def test_system(): filename = str(udir.join('test_system.txt')) - arg = to_rstr('python -c "print 1+1" > %s' % filename) - data = ll_os_system(arg) + arg = impl.to_rstr('python -c "print 1+1" > %s' % filename) + data = impl.ll_os_system(arg) assert data == 0 assert file(filename).read().strip() == '2' os.unlink(filename) def test_putenv_unsetenv(): filename = str(udir.join('test_putenv.txt')) - arg = to_rstr('abcdefgh=12345678') - ll_os_putenv(arg) + arg = impl.to_rstr('abcdefgh=12345678') + impl.ll_os_putenv(arg) cmd = '''python -c "import os; print os.environ['abcdefgh']" > %s''' % filename os.system(cmd) f = file(filename) @@ -48,7 +48,7 @@ os.unlink(filename) posix = __import__(os.name) if hasattr(posix, "unsetenv"): - ll_os_unsetenv(to_rstr("abcdefgh")) + impl.ll_os_unsetenv(impl.to_rstr("abcdefgh")) cmd = '''python -c "import os; print repr(os.getenv('abcdefgh'))" > %s''' % filename os.system(cmd) f = file(filename) @@ -60,12 +60,12 @@ test_src = """ import os from pypy.tool.udir import udir -from pypy.rpython.module.ll_os import * +from pypy.rpython.lltypesystem.module.ll_os import Implementation as impl def test_environ(): count = 0 while 1: - if not ll_os_environ(count): + if not impl.ll_os_environ(count): break count += 1 channel.send(count == len(os.environ.keys())) @@ -82,17 +82,17 @@ def test_opendir_readdir(): dirname = str(udir) - rsdirname = to_rstr(dirname) + rsdirname = impl.to_rstr(dirname) result = [] - DIR = ll_os_opendir(rsdirname) + DIR = impl.ll_os_opendir(rsdirname) try: while True: - nextentry = ll_os_readdir(DIR) + nextentry = impl.ll_os_readdir(DIR) if not nextentry: # null pointer check break - result.append(from_rstr(nextentry)) + result.append(impl.from_rstr(nextentry)) finally: - ll_os_closedir(DIR) + impl.ll_os_closedir(DIR) assert '.' in result assert '..' in result result.remove('.') Modified: pypy/dist/pypy/rpython/module/test/test_ll_os_path.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_os_path.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_os_path.py Sun Jun 4 14:49:05 2006 @@ -2,15 +2,15 @@ import os -from pypy.rpython.module.ll_os_path import * -from pypy.rpython.module.support import to_rstr, from_rstr, ll_strcpy +from pypy.rpython.lltypesystem.module.ll_os_path import Implementation as impl +from pypy.rpython.module.support import ll_strcpy from pypy.rpython.test.test_llinterp import interpret from pypy.tool.udir import udir def test_exists(): - filename = to_rstr(str(py.magic.autopath())) - assert ll_os_path_exists(filename) == True - assert not ll_os_path_exists(to_rstr( + filename = impl.to_rstr(str(py.magic.autopath())) + assert impl.ll_os_path_exists(filename) == True + assert not impl.ll_os_path_exists(impl.to_rstr( "strange_filename_that_looks_improbable.sde")) def test_posixpath(): Modified: pypy/dist/pypy/rpython/module/test/test_ll_strtod.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_strtod.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_strtod.py Sun Jun 4 14:49:05 2006 @@ -1,6 +1,6 @@ from pypy.rpython.module.ll_strtod import ll_strtod_parts_to_float, ll_strtod_formatd -from pypy.rpython.module.support import to_rstr, from_rstr +from pypy.rpython.module.support import LLSupport def test_parts_to_float(): @@ -14,9 +14,9 @@ ] for parts, val in data: - assert ll_strtod_parts_to_float(*map(to_rstr, parts)) == val + assert ll_strtod_parts_to_float(*map(LLSupport.to_rstr, parts)) == val def test_formatd(): - res = ll_strtod_formatd(to_rstr("%.2f"), 1.5) - assert from_rstr(res) == "1.50" + res = ll_strtod_formatd(LLSupport.to_rstr("%.2f"), 1.5) + assert LLSupport.from_rstr(res) == "1.50" Modified: pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/module/ll_os.py Sun Jun 4 14:49:05 2006 @@ -1,15 +1,30 @@ -import os -from pypy.rpython.ootypesystem.module.support import from_rstr, to_rstr +from pypy.rpython.module.support import OOSupport +from pypy.rpython.module.ll_os import BaseOS +from pypy.rpython.ootypesystem import ootype +from pypy.rpython.rarithmetic import intmask -def ll_os_open(fname, flag, mode): - return os.open(from_rstr(fname), flag, mode) -ll_os_open.suggested_primitive = True +n = 10 +fieldnames = ['item%d' % i for i in range(n)] +lltypes = [ootype.Signed]*n +fields = dict(zip(fieldnames, lltypes)) +STAT_RESULT = ootype.Record(fields) -def ll_os_write(fd, astring): - return os.write(fd, from_rstr(astring)) -ll_os_write.suggested_primitive = True +class Implementation(BaseOS, OOSupport): + + def ll_stat_result(stat0, stat1, stat2, stat3, stat4, + stat5, stat6, stat7, stat8, stat9): + tup = ootype.new(STAT_RESULT) + tup.item0 = intmask(stat0) + tup.item1 = intmask(stat1) + tup.item2 = intmask(stat2) + tup.item3 = intmask(stat3) + tup.item4 = intmask(stat4) + tup.item5 = intmask(stat5) + tup.item6 = intmask(stat6) + tup.item7 = intmask(stat7) + tup.item8 = intmask(stat8) + tup.item9 = intmask(stat9) + return tup + ll_stat_result = staticmethod(ll_stat_result) -def ll_os_getcwd(): - return to_rstr(os.getcwd()) -ll_os_getcwd.suggested_primitive = True Added: pypy/dist/pypy/rpython/ootypesystem/module/ll_os_path.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/ootypesystem/module/ll_os_path.py Sun Jun 4 14:49:05 2006 @@ -0,0 +1,5 @@ +from pypy.rpython.module.support import OOSupport +from pypy.rpython.module.ll_os_path import BaseOsPath + +class Implementation(BaseOsPath, OOSupport): + pass Modified: pypy/dist/pypy/rpython/rgenop.py ============================================================================== --- pypy/dist/pypy/rpython/rgenop.py (original) +++ pypy/dist/pypy/rpython/rgenop.py Sun Jun 4 14:49:05 2006 @@ -9,7 +9,7 @@ from pypy.translator.simplify import eliminate_empty_blocks, join_blocks from pypy.rpython.module.support import init_opaque_object from pypy.rpython.module.support import to_opaque_object, from_opaque_object -from pypy.rpython.module.support import from_rstr +from pypy.rpython.module.support import LLSupport from pypy.rpython.extregistry import ExtRegistryEntry @@ -54,7 +54,7 @@ # is opname a runtime value? def genop(blockcontainer, opname, vars, gv_RESULT_TYPE): if not isinstance(opname, str): - opname = from_rstr(opname) + opname = LLSupport.from_rstr(opname) block = from_opaque_object(blockcontainer.obj) assert block.exits == [], "block already closed" RESULT_TYPE = from_opaque_object(gv_RESULT_TYPE).value Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Sun Jun 4 14:49:05 2006 @@ -6,67 +6,9 @@ from pypy.tool import udir from pypy.rpython.rarithmetic import r_uint, intmask from pypy.annotation.builtin import * -from pypy.rpython.module.support import to_rstr from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin import py -def test_rbuiltin_list(): - def f(): - l=list((1,2,3)) - return l == [1,2,3] - def g(): - l=list(('he','llo')) - return l == ['he','llo'] - def r(): - l = ['he','llo'] - l1=list(l) - return l == l1 and l is not l1 - result = interpret(f,[]) - assert result - - result = interpret(g,[]) - assert result - - result = interpret(r,[]) - assert result - -def test_int_min(): - def fn(i, j): - return min(i,j) - ev_fun = interpret(fn, [0, 0]) - assert interpret(fn, (1, 2)) == 1 - assert interpret(fn, (1, -1)) == -1 - assert interpret(fn, (2, 2)) == 2 - assert interpret(fn, (-1, -12)) == -12 - -def test_int_max(): - def fn(i, j): - return max(i,j) - assert interpret(fn, (1, 2)) == 2 - assert interpret(fn, (1, -1)) == 1 - assert interpret(fn, (2, 2)) == 2 - assert interpret(fn, (-1, -12)) == -1 - -def test_builtin_math_floor(): - import math - def fn(f): - return math.floor(f) - import random - for i in range(5): - rv = 1000 * float(i-10) #random.random() - res = interpret(fn, [rv]) - assert fn(rv) == res - -def test_builtin_math_fmod(): - import math - def fn(f,y): - return math.fmod(f,y) - - for i in range(10): - for j in range(10): - rv = 1000 * float(i-10) - ry = 100 * float(i-10) +0.1 - assert fn(rv,ry) == interpret(fn, (rv, ry)) def enum_direct_calls(translator, func): blocks = [] @@ -76,173 +18,8 @@ if op.opname == 'direct_call': yield op -def test_os_dup(): - import os - def fn(fd): - return os.dup(fd) - res = interpret(fn, [0]) - try: - os.close(res) - except OSError: - pass - count = 0 - from pypy.rpython.module import ll_os - for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, fn): - cfptr = dir_call.args[0] - assert cfptr.value._obj._callable == ll_os.ll_os_dup - count += 1 - assert count == 1 - -def test_os_open(): - tmpdir = str(udir.udir.join("os_open_test")) - import os - def wr_open(fname): - return os.open(fname, os.O_WRONLY|os.O_CREAT, 0777) - def f(): - return wr_open(tmpdir) - res = interpret(f, []) - os.close(res) - count = 0 - from pypy.rpython.lltypesystem.module import ll_os - for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, wr_open): - cfptr = dir_call.args[0] - assert cfptr.value._obj._callable == ll_os.ll_os_open - count += 1 - assert count == 1 - -def test_os_path_exists(): - import os - def f(fn): - return os.path.exists(fn) - filename = to_rstr(str(py.magic.autopath())) - assert interpret(f, [filename]) == True - assert interpret(f, [ - to_rstr("strange_filename_that_looks_improbable.sde")]) == False - -def test_os_isdir(): - import os - def f(fn): - return os.path.isdir(fn) - assert interpret(f, [to_rstr("/")]) == True - assert interpret(f, [to_rstr(str(py.magic.autopath()))]) == False - assert interpret(f, [to_rstr("another/unlikely/directory/name")]) == False -def test_pbc_isTrue(): - class C: - def f(self): - pass - - def g(obj): - return bool(obj) - def fn(neg): - c = C.f - return g(c) - assert interpret(fn, [True]) - def fn(neg): - c = None - return g(c) - assert not interpret(fn, [True]) - -def test_instantiate(): - class A: - pass - def f(): - return instantiate(A) - res = interpret(f, []) - assert res.super.typeptr.name[0] == 'A' - -def test_instantiate_multiple(): - class A: - pass - class B(A): - pass - def f(i): - if i == 1: - cls = A - else: - cls = B - return instantiate(cls) - res = interpret(f, [1]) - assert res.super.typeptr.name[0] == 'A' - res = interpret(f, [2]) - assert res.super.typeptr.name[0] == 'B' - - -def test_isinstance_obj(): - _1 = lltype.pyobjectptr(1) - def f(x): - return isinstance(x, int) - res = interpret(f, [_1], someobjects=True) - assert res is True - _1_0 = lltype.pyobjectptr(1.0) - res = interpret(f, [_1_0], someobjects=True) - assert res is False - - -def test_const_isinstance(): - class B(object): - pass - def f(): - b = B() - return isinstance(b, B) - res = interpret(f, []) - assert res is True - -def test_isinstance(): - class A(object): - pass - class B(A): - pass - class C(A): - pass - def f(x, y): - if x == 1: - a = A() - elif x == 2: - a = B() - else: - a = C() - if y == 1: - res = isinstance(a, A) - cls = A - elif y == 2: - res = isinstance(a, B) - cls = B - else: - res = isinstance(a, C) - cls = C - return int(res) + 2 * isinstance(a, cls) - for x in [1, 2, 3]: - for y in [1, 2, 3]: - res = interpret(f, [x, y]) - assert res == isinstance([A(), B(), C()][x-1], [A, B, C][y-1]) * 3 - -def test_isinstance_list(): - def f(i): - if i == 0: - l = [] - else: - l = None - return isinstance(l, list) - res = interpret(f, [0]) - assert res is True - res = interpret(f, [1]) - assert res is False - -def test_hasattr(): - class A(object): - def __init__(self): - self.x = 42 - def f(i): - a = A() - if i==0: return int(hasattr(A, '__init__')) - if i==1: return int(hasattr(A, 'y')) - if i==2: return int(hasattr(42, 'x')) - for x, y in zip(range(3), (1, 0, 0)): - res = interpret(f, [x]) - assert res._obj.value == y - # hmm, would like to test against PyObj, is this the wrong place/way? def test_we_are_translated(): def f(): @@ -333,6 +110,65 @@ class BaseTestExtfunc(BaseRtypingTest): + def test_rbuiltin_list(self): + def f(): + l=list((1,2,3)) + return l == [1,2,3] + def g(): + l=list(('he','llo')) + return l == ['he','llo'] + def r(): + l = ['he','llo'] + l1=list(l) + return l == l1 and l is not l1 + result = self.interpret(f,[]) + assert result + + result = self.interpret(g,[]) + assert result + + result = self.interpret(r,[]) + assert result + + def test_int_min(self): + def fn(i, j): + return min(i,j) + ev_fun = self.interpret(fn, [0, 0]) + assert self.interpret(fn, (1, 2)) == 1 + assert self.interpret(fn, (1, -1)) == -1 + assert self.interpret(fn, (2, 2)) == 2 + assert self.interpret(fn, (-1, -12)) == -12 + + def test_int_max(self): + def fn(i, j): + return max(i,j) + assert self.interpret(fn, (1, 2)) == 2 + assert self.interpret(fn, (1, -1)) == 1 + assert self.interpret(fn, (2, 2)) == 2 + assert self.interpret(fn, (-1, -12)) == -1 + + def test_builtin_math_floor(self): + import math + def fn(f): + return math.floor(f) + import random + for i in range(5): + rv = 1000 * float(i-10) #random.random() + res = self.interpret(fn, [rv]) + assert fn(rv) == res + + def test_builtin_math_fmod(self): + import math + def fn(f,y): + return math.fmod(f,y) + + for i in range(10): + for j in range(10): + rv = 1000 * float(i-10) + ry = 100 * float(i-10) +0.1 + assert fn(rv,ry) == self.interpret(fn, (rv, ry)) + + def test_os_getcwd(self): import os def fn(): @@ -354,9 +190,58 @@ hello = open(tmpdir).read() assert hello == "hello world" -class TestOOtype(BaseTestExtfunc, OORtypeMixin): - pass + def test_os_dup(self): + import os + def fn(fd): + return os.dup(fd) + res = self.interpret(fn, [0]) + try: + os.close(res) + except OSError: + pass + count = 0 + for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, fn): + cfptr = dir_call.args[0] + assert self.get_callable(cfptr.value) == self.ll_os.Implementation.ll_os_dup.im_func + count += 1 + assert count == 1 -class TestLLtype(BaseTestExtfunc, LLRtypeMixin): - pass + def test_os_open(self): + tmpdir = str(udir.udir.join("os_open_test")) + import os + def wr_open(fname): + return os.open(fname, os.O_WRONLY|os.O_CREAT, 0777) + def f(): + return wr_open(tmpdir) + res = self.interpret(f, []) + os.close(res) + count = 0 + for dir_call in enum_direct_calls(test_llinterp.typer.annotator.translator, wr_open): + cfptr = dir_call.args[0] + assert self.get_callable(cfptr.value) == self.ll_os.Implementation.ll_os_open.im_func + count += 1 + assert count == 1 + + def test_os_path_exists(self): + import os + def f(fn): + return os.path.exists(fn) + filename = self.string_to_ll(str(py.magic.autopath())) + assert self.interpret(f, [filename]) == True + assert self.interpret(f, [ + self.string_to_ll("strange_filename_that_looks_improbable.sde")]) == False + + def test_os_isdir(self): + import os + def f(fn): + return os.path.isdir(fn) + assert self.interpret(f, [self.string_to_ll("/")]) == True + assert self.interpret(f, [self.string_to_ll(str(py.magic.autopath()))]) == False + assert self.interpret(f, [self.string_to_ll("another/unlikely/directory/name")]) == False + +class TestLLtype(BaseTestExtfunc, LLRtypeMixin): + from pypy.rpython.lltypesystem.module import ll_os + +class TestOOtype(BaseTestExtfunc, OORtypeMixin): + from pypy.rpython.ootypesystem.module import ll_os Modified: pypy/dist/pypy/rpython/test/tool.py ============================================================================== --- pypy/dist/pypy/rpython/test/tool.py (original) +++ pypy/dist/pypy/rpython/test/tool.py Sun Jun 4 14:49:05 2006 @@ -20,9 +20,16 @@ def ll_to_string(self, s): return ''.join(s.chars) + def string_to_ll(self, s): + from pypy.rpython.module.support import LLSupport + return LLSupport.to_rstr(s) + def ll_to_list(self, l): return map(None, l.ll_items())[:l.ll_length()] + def get_callable(self, fnptr): + return fnptr._obj._callable + def class_name(self, value): return "".join(value.super.typeptr.name)[:-1] @@ -43,9 +50,16 @@ def ll_to_string(self, s): return s._str + def string_to_ll(self, s): + from pypy.rpython.module.support import OOSupport + return OOSupport.to_rstr(s) + def ll_to_list(self, l): return l._list[:] + def get_callable(self, sm): + return sm._callable + def class_name(self, value): return ootype.dynamicType(value)._name.split(".")[-1] Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Sun Jun 4 14:49:05 2006 @@ -7,34 +7,37 @@ from pypy.rpython.lltypesystem import rlist from pypy.rpython.module import ll_time, ll_math, ll_strtod from pypy.rpython.module import ll_stackless, ll_stack -from pypy.rpython.lltypesystem.module import ll_os +from pypy.rpython.lltypesystem.module.ll_os import STAT_RESULT, Implementation as impl from pypy.module.thread.rpython import ll_thread # table of functions hand-written in src/ll_*.h +# Note about *.im_func: The annotator and the rtyper expect direct +# references to functions, so we cannot insert classmethods here. + EXTERNALS = { - ll_os .ll_os_open: 'LL_os_open', - ll_os .ll_read_into: 'LL_read_into', - ll_os .ll_os_write: 'LL_os_write', - ll_os .ll_os_close: 'LL_os_close', - ll_os .ll_os_dup: 'LL_os_dup', - ll_os .ll_os_stat: 'LL_os_stat', - ll_os .ll_os_fstat: 'LL_os_fstat', - ll_os .ll_os_lseek: 'LL_os_lseek', - ll_os .ll_os_isatty: 'LL_os_isatty', - ll_os .ll_os_ftruncate:'LL_os_ftruncate', - ll_os .ll_os_strerror: 'LL_os_strerror', - ll_os .ll_os_system: 'LL_os_system', - ll_os .ll_os_unlink: 'LL_os_unlink', - ll_os .ll_os_getcwd: 'LL_os_getcwd', - ll_os .ll_os_chdir: 'LL_os_chdir', - ll_os .ll_os_mkdir: 'LL_os_mkdir', - ll_os .ll_os_rmdir: 'LL_os_rmdir', - ll_os .ll_os_putenv: 'LL_os_putenv', - ll_os .ll_os_unsetenv:'LL_os_unsetenv', - ll_os .ll_os_environ: 'LL_os_environ', - ll_os .ll_os_opendir: 'LL_os_opendir', - ll_os .ll_os_readdir: 'LL_os_readdir', - ll_os .ll_os_closedir:'LL_os_closedir', + impl.ll_os_open.im_func: 'LL_os_open', + impl.ll_read_into: 'LL_read_into', # it's a staticmethod + impl.ll_os_write.im_func: 'LL_os_write', + impl.ll_os_close.im_func: 'LL_os_close', + impl.ll_os_dup.im_func: 'LL_os_dup', + impl.ll_os_stat.im_func: 'LL_os_stat', + impl.ll_os_fstat.im_func: 'LL_os_fstat', + impl.ll_os_lseek.im_func: 'LL_os_lseek', + impl.ll_os_isatty.im_func: 'LL_os_isatty', + impl.ll_os_ftruncate.im_func:'LL_os_ftruncate', + impl.ll_os_strerror.im_func: 'LL_os_strerror', + impl.ll_os_system.im_func: 'LL_os_system', + impl.ll_os_unlink.im_func: 'LL_os_unlink', + impl.ll_os_getcwd.im_func: 'LL_os_getcwd', + impl.ll_os_chdir.im_func: 'LL_os_chdir', + impl.ll_os_mkdir.im_func: 'LL_os_mkdir', + impl.ll_os_rmdir.im_func: 'LL_os_rmdir', + impl.ll_os_putenv.im_func: 'LL_os_putenv', + impl.ll_os_unsetenv.im_func:'LL_os_unsetenv', + impl.ll_os_environ.im_func: 'LL_os_environ', + impl.ll_os_opendir.im_func: 'LL_os_opendir', + impl.ll_os_readdir.im_func: 'LL_os_readdir', + impl.ll_os_closedir.im_func:'LL_os_closedir', ll_time.ll_time_clock: 'LL_time_clock', ll_time.ll_time_sleep: 'LL_time_sleep', ll_time.ll_time_time: 'LL_time_time', @@ -88,7 +91,7 @@ yield ('RPyListOfString', LIST_OF_STR) yield ('RPyFREXP_RESULT', ll_math.FREXP_RESULT) yield ('RPyMODF_RESULT', ll_math.MODF_RESULT) - yield ('RPySTAT_RESULT', ll_os.STAT_RESULT) + yield ('RPySTAT_RESULT', STAT_RESULT) def predeclare_utility_functions(db, rtyper, optimize=True): # Common utility functions From antocuni at codespeak.net Sun Jun 4 14:50:17 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Jun 2006 14:50:17 +0200 (CEST) Subject: [pypy-svn] r28252 - pypy/dist/pypy/tool Message-ID: <20060604125017.8E3851006F@code0.codespeak.net> Author: antocuni Date: Sun Jun 4 14:50:16 2006 New Revision: 28252 Modified: pypy/dist/pypy/tool/staticmethods.py Log: (antocuni, nik) Forgotten from the last checkin. Modified: pypy/dist/pypy/tool/staticmethods.py ============================================================================== --- pypy/dist/pypy/tool/staticmethods.py (original) +++ pypy/dist/pypy/tool/staticmethods.py Sun Jun 4 14:50:16 2006 @@ -1,10 +1,20 @@ import types -class StaticMethods(type): - """ - Metaclass that turns plain methods into staticmethods. - """ +class AbstractMethods(type): def __new__(cls, cls_name, bases, cls_dict): for key, value in cls_dict.iteritems(): if isinstance(value, types.FunctionType): - cls_dict[key] = staticmethod(value) + cls_dict[key] = cls.decorator(value) return type.__new__(cls, cls_name, bases, cls_dict) + + +class StaticMethods(AbstractMethods): + """ + Metaclass that turns plain methods into staticmethods. + """ + decorator = staticmethod + +class ClassMethods(AbstractMethods): + """ + Metaclass that turns plain methods into classmethods. + """ + decorator = classmethod From hpk at codespeak.net Sun Jun 4 14:58:20 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Jun 2006 14:58:20 +0200 (CEST) Subject: [pypy-svn] r28253 - in pypy/dist/pypy/rpython/rctypes/tool: . test Message-ID: <20060604125820.354911006F@code0.codespeak.net> Author: hpk Date: Sun Jun 4 14:58:19 2006 New Revision: 28253 Added: pypy/dist/pypy/rpython/rctypes/tool/libc.py (contents, props changed) pypy/dist/pypy/rpython/rctypes/tool/test/test_libc.py (contents, props changed) Log: add loading of libc in a central place (to be used by modules and tests etc.) Added: pypy/dist/pypy/rpython/rctypes/tool/libc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/rctypes/tool/libc.py Sun Jun 4 14:58:19 2006 @@ -0,0 +1,22 @@ +import sys +from ctypes import * + +# __________ the standard C library __________ + +# LoadLibrary is deprecated in ctypes, this should be removed at some point +if "load" in dir(cdll): + cdll_load = cdll.load +else: + cdll_load = cdll.LoadLibrary + +if sys.platform == 'win32': + libc = cdll_load('msvcrt.dll') +elif sys.platform == 'linux2': + libc = cdll_load('libc.so.6') +elif sys.platform == 'darwin': + libc = cdll_load('libc.dylib') +else: + raise ImportError("don't know how to load the c lib for %s" % sys.platform) +# ____________________________________________ + + Added: pypy/dist/pypy/rpython/rctypes/tool/test/test_libc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/rctypes/tool/test/test_libc.py Sun Jun 4 14:58:19 2006 @@ -0,0 +1,4 @@ + +def test_libc(): + from pypy.rpython.rctypes.tool.libc import libc + t = libc.time From hpk at codespeak.net Sun Jun 4 14:58:42 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Jun 2006 14:58:42 +0200 (CEST) Subject: [pypy-svn] r28254 - pypy/dist/pypy/rpython/rctypes/tool Message-ID: <20060604125842.8E5BA1006F@code0.codespeak.net> Author: hpk Date: Sun Jun 4 14:58:42 2006 New Revision: 28254 Added: pypy/dist/pypy/rpython/rctypes/tool/autopath.py (contents, props changed) Modified: pypy/dist/pypy/rpython/rctypes/tool/compilemodule.py Log: fix import path issue for the ext compiler Added: pypy/dist/pypy/rpython/rctypes/tool/autopath.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/rctypes/tool/autopath.py Sun Jun 4 14:58:42 2006 @@ -0,0 +1,112 @@ +""" +self cloning, automatic path configuration + +copy this into any subdirectory of pypy from which scripts need +to be run, typically all of the test subdirs. +The idea is that any such script simply issues + + import autopath + +and this will make sure that the parent directory containing "pypy" +is in sys.path. + +If you modify the master "autopath.py" version (in pypy/tool/autopath.py) +you can directly run it which will copy itself on all autopath.py files +it finds under the pypy root directory. + +This module always provides these attributes: + + pypydir pypy root directory path + this_dir directory where this autopath.py resides + +""" + + +def __dirinfo(part): + """ return (partdir, this_dir) and insert parent of partdir + into sys.path. If the parent directories don't have the part + an EnvironmentError is raised.""" + + import sys, os + try: + head = this_dir = os.path.realpath(os.path.dirname(__file__)) + except NameError: + head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0])) + + while head: + partdir = head + head, tail = os.path.split(head) + if tail == part: + break + else: + raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir) + + pypy_root = os.path.join(head, '') + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) + + munged = {} + for name, mod in sys.modules.items(): + fn = getattr(mod, '__file__', None) + if '.' in name or not isinstance(fn, str): + continue + newname = os.path.splitext(os.path.basename(fn))[0] + if not newname.startswith(part + '.'): + continue + path = os.path.join(os.path.dirname(os.path.realpath(fn)), '') + if path.startswith(pypy_root) and newname != part: + modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep) + if newname != '__init__': + modpaths.append(newname) + modpath = '.'.join(modpaths) + if modpath not in sys.modules: + munged[modpath] = mod + + for name, mod in munged.iteritems(): + if name not in sys.modules: + sys.modules[name] = mod + if '.' in name: + prename = name[:name.rfind('.')] + postname = name[len(prename)+1:] + if prename not in sys.modules: + __import__(prename) + if not hasattr(sys.modules[prename], postname): + setattr(sys.modules[prename], postname, mod) + + return partdir, this_dir + +def __clone(): + """ clone master version of autopath.py into all subdirs """ + from os.path import join, walk + if not this_dir.endswith(join('pypy','tool')): + raise EnvironmentError("can only clone master version " + "'%s'" % join(pypydir, 'tool',_myname)) + + + def sync_walker(arg, dirname, fnames): + if _myname in fnames: + fn = join(dirname, _myname) + f = open(fn, 'rwb+') + try: + if f.read() == arg: + print "checkok", fn + else: + print "syncing", fn + f = open(fn, 'w') + f.write(arg) + finally: + f.close() + s = open(join(pypydir, 'tool', _myname), 'rb').read() + walk(pypydir, sync_walker, s) + +_myname = 'autopath.py' + +# set guaranteed attributes + +pypydir, this_dir = __dirinfo('pypy') + +if __name__ == '__main__': + __clone() Modified: pypy/dist/pypy/rpython/rctypes/tool/compilemodule.py ============================================================================== --- pypy/dist/pypy/rpython/rctypes/tool/compilemodule.py (original) +++ pypy/dist/pypy/rpython/rctypes/tool/compilemodule.py Sun Jun 4 14:58:42 2006 @@ -5,7 +5,7 @@ Compiles the PyPy extension module from pypy/module// into a regular CPython extension module. """ - +import autopath import sys From hpk at codespeak.net Sun Jun 4 15:01:14 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Jun 2006 15:01:14 +0200 (CEST) Subject: [pypy-svn] r28255 - pypy/dist/pypy/module/_demo Message-ID: <20060604130114.2A8B710070@code0.codespeak.net> Author: hpk Date: Sun Jun 4 15:01:13 2006 New Revision: 28255 Modified: pypy/dist/pypy/module/_demo/demo.py Log: have demo use tool's libc Modified: pypy/dist/pypy/module/_demo/demo.py ============================================================================== --- pypy/dist/pypy/module/_demo/demo.py (original) +++ pypy/dist/pypy/module/_demo/demo.py Sun Jun 4 15:01:13 2006 @@ -1,36 +1,16 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.rpython.rctypes.tool import ctypes_platform +from pypy.rpython.rctypes.tool.libc import libc import sys from ctypes import * -# __________ the standard C library __________ - -# LoadLibrary is deprecated in ctypes, this should be removed at some point -if "load" in dir(cdll): - cdll_load = cdll.load -else: - cdll_load = cdll.LoadLibrary - -if sys.platform == 'win32': - mylib = cdll_load('msvcrt.dll') -elif sys.platform == 'linux2': - mylib = cdll_load('libc.so.6') -elif sys.platform == 'darwin': - mylib = cdll_load('libc.dylib') -else: - py.test.skip("don't know how to load the c lib for %s" % - sys.platform) -# ____________________________________________ - - time_t = ctypes_platform.getsimpletype('time_t', '#include ', c_long) -time = mylib.time +time = libc.time time.argtypes = [POINTER(time_t)] time.restype = time_t - def get(space, name): w_module = space.getbuiltinmodule('_demo') return space.getattr(w_module, space.wrap(name)) From antocuni at codespeak.net Sun Jun 4 15:07:03 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Jun 2006 15:07:03 +0200 (CEST) Subject: [pypy-svn] r28256 - pypy/dist/pypy/rpython/test Message-ID: <20060604130703.AB5371006F@code0.codespeak.net> Author: antocuni Date: Sun Jun 4 15:07:02 2006 New Revision: 28256 Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py pypy/dist/pypy/rpython/test/tool.py Log: (antocuni, nik) Some more test for ootypesystem. Three of those skips because ootypesystem doesn't support isinstance and hasattr, yet. Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Sun Jun 4 15:07:02 2006 @@ -239,9 +239,127 @@ assert self.interpret(f, [self.string_to_ll(str(py.magic.autopath()))]) == False assert self.interpret(f, [self.string_to_ll("another/unlikely/directory/name")]) == False + def test_pbc_isTrue(self): + class C: + def f(self): + pass + + def g(obj): + return bool(obj) + def fn(neg): + c = C.f + return g(c) + assert self.interpret(fn, [True]) + def fn(neg): + c = None + return g(c) + assert not self.interpret(fn, [True]) + + def test_const_isinstance(self): + class B(object): + pass + def f(): + b = B() + return isinstance(b, B) + res = self.interpret(f, []) + assert res is True + + def test_isinstance(self): + self._skip_oo('isinstance') + class A(object): + pass + class B(A): + pass + class C(A): + pass + def f(x, y): + if x == 1: + a = A() + elif x == 2: + a = B() + else: + a = C() + if y == 1: + res = isinstance(a, A) + cls = A + elif y == 2: + res = isinstance(a, B) + cls = B + else: + res = isinstance(a, C) + cls = C + return int(res) + 2 * isinstance(a, cls) + for x in [1, 2, 3]: + for y in [1, 2, 3]: + res = self.interpret(f, [x, y]) + assert res == isinstance([A(), B(), C()][x-1], [A, B, C][y-1]) * 3 + + def test_isinstance_list(self): + self._skip_oo('isinstance') + def f(i): + if i == 0: + l = [] + else: + l = None + return isinstance(l, list) + res = self.interpret(f, [0]) + assert res is True + res = self.interpret(f, [1]) + assert res is False + + def test_hasattr(self): + self._skip_oo('hasattr') + class A(object): + def __init__(self): + self.x = 42 + def f(i): + a = A() + if i==0: return int(hasattr(A, '__init__')) + if i==1: return int(hasattr(A, 'y')) + if i==2: return int(hasattr(42, 'x')) + for x, y in zip(range(3), (1, 0, 0)): + res = self.interpret(f, [x]) + assert res._obj.value == y + # hmm, would like to test against PyObj, is this the wrong place/way? + class TestLLtype(BaseTestExtfunc, LLRtypeMixin): from pypy.rpython.lltypesystem.module import ll_os + + def test_instantiate(self): + class A: + pass + def f(): + return instantiate(A) + res = self.interpret(f, []) + assert res.super.typeptr.name[0] == 'A' + + def test_instantiate_multiple(self): + class A: + pass + class B(A): + pass + def f(i): + if i == 1: + cls = A + else: + cls = B + return instantiate(cls) + res = self.interpret(f, [1]) + assert res.super.typeptr.name[0] == 'A' + res = self.interpret(f, [2]) + assert res.super.typeptr.name[0] == 'B' + + def test_isinstance_obj(self): + _1 = lltype.pyobjectptr(1) + def f(x): + return isinstance(x, int) + res = self.interpret(f, [_1], someobjects=True) + assert res is True + _1_0 = lltype.pyobjectptr(1.0) + res = self.interpret(f, [_1_0], someobjects=True) + assert res is False + class TestOOtype(BaseTestExtfunc, OORtypeMixin): from pypy.rpython.ootypesystem.module import ll_os Modified: pypy/dist/pypy/rpython/test/tool.py ============================================================================== --- pypy/dist/pypy/rpython/test/tool.py (original) +++ pypy/dist/pypy/rpython/test/tool.py Sun Jun 4 15:07:02 2006 @@ -3,11 +3,11 @@ from pypy.rpython.test.test_llinterp import interpret, interpret_raises class BaseRtypingTest(object): - def interpret(self, fn, args): - return interpret(fn, args, type_system=self.type_system) + def interpret(self, fn, args, **kwds): + return interpret(fn, args, type_system=self.type_system, **kwds) - def interpret_raises(self, exc, fn, args): - return interpret_raises(exc, fn, args, type_system=self.type_system) + def interpret_raises(self, exc, fn, args, **kwds): + return interpret_raises(exc, fn, args, type_system=self.type_system, **kwds) def _skip_oo(self, reason): if self.type_system == 'ootype': From mwh at codespeak.net Sun Jun 4 15:56:47 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 15:56:47 +0200 (CEST) Subject: [pypy-svn] r28258 - pypy/dist/pypy/interpreter Message-ID: <20060604135647.898611006F@code0.codespeak.net> Author: mwh Date: Sun Jun 4 15:56:46 2006 New Revision: 28258 Modified: pypy/dist/pypy/interpreter/typedef.py Log: comment out some __reduce__s in typedef, the better to unbreak translation forwith. Modified: pypy/dist/pypy/interpreter/typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/typedef.py (original) +++ pypy/dist/pypy/interpreter/typedef.py Sun Jun 4 15:56:46 2006 @@ -521,8 +521,8 @@ ) PyFrame.typedef = TypeDef('frame', - __reduce__ = interp2app(PyFrame.descr__reduce__, - unwrap_spec=['self', ObjSpace]), + #__reduce__ = interp2app(PyFrame.descr__reduce__, + # unwrap_spec=['self', ObjSpace]), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), f_back = GetSetProperty(PyFrame.fget_f_back), @@ -623,8 +623,8 @@ del BuiltinFunction.typedef.rawdict['__get__'] PyTraceback.typedef = TypeDef("traceback", - __reduce__ = interp2app(PyTraceback.descr__reduce__, - unwrap_spec=['self', ObjSpace]), + #__reduce__ = interp2app(PyTraceback.descr__reduce__, + # unwrap_spec=['self', ObjSpace]), tb_frame = interp_attrproperty('frame', cls=PyTraceback), tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = interp_attrproperty('lineno', cls=PyTraceback), @@ -632,8 +632,8 @@ ) GeneratorIterator.typedef = TypeDef("generator", - __reduce__ = interp2app(GeneratorIterator.descr__reduce__, - unwrap_spec=['self', ObjSpace]), + #__reduce__ = interp2app(GeneratorIterator.descr__reduce__, + # unwrap_spec=['self', ObjSpace]), next = interp2app(GeneratorIterator.descr_next), __iter__ = interp2app(GeneratorIterator.descr__iter__), gi_running = interp_attrproperty('running', cls=GeneratorIterator), From antocuni at codespeak.net Sun Jun 4 15:57:29 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Jun 2006 15:57:29 +0200 (CEST) Subject: [pypy-svn] r28259 - in pypy/dist/pypy/rpython: ootypesystem test Message-ID: <20060604135729.648B91006F@code0.codespeak.net> Author: antocuni Date: Sun Jun 4 15:57:28 2006 New Revision: 28259 Modified: pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py pypy/dist/pypy/rpython/test/test_rbuiltin.py Log: (antocuni, nik) Implemented isinstance for ootypesystem. Modified: pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py Sun Jun 4 15:57:28 2006 @@ -2,7 +2,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.ootypesystem import rclass from pypy.objspace.flow.model import Constant - +from pypy.rpython.error import TyperError def rtype_new(hop): assert hop.args_s[0].is_constant() @@ -44,7 +44,8 @@ if hop.args_s[1].is_constant() and hop.args_s[1].const == list: if hop.args_s[0].knowntype != list: raise TyperError("isinstance(x, list) expects x to be known statically to be a list or None") - raise TyperError("XXX missing impl of isinstance(x, list)") + v_list = hop.inputarg(hop.args_r[0], arg=0) + return hop.genop('oononnull', [v_list], resulttype=ootype.Bool) class_repr = rclass.get_type_repr(hop.rtyper) instance_repr = hop.args_r[0] @@ -55,7 +56,12 @@ c_cls = hop.inputconst(ootype.Void, v_cls.value.class_._INSTANCE) return hop.genop('instanceof', [v_obj, c_cls], resulttype=ootype.Bool) else: - raise TyperError("XXX missing impl of isinstance(x, variable)") + return hop.gendirectcall(ll_isinstance, v_obj, v_cls) + +def ll_isinstance(inst, meta): + c1 = inst.meta.class_ + c2 = meta.class_ + return ootype.subclassof(c1, c2) BUILTIN_TYPER = {} BUILTIN_TYPER[ootype.new] = rtype_new Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Sun Jun 4 15:57:28 2006 @@ -265,7 +265,6 @@ assert res is True def test_isinstance(self): - self._skip_oo('isinstance') class A(object): pass class B(A): @@ -295,7 +294,6 @@ assert res == isinstance([A(), B(), C()][x-1], [A, B, C][y-1]) * 3 def test_isinstance_list(self): - self._skip_oo('isinstance') def f(i): if i == 0: l = [] From antocuni at codespeak.net Sun Jun 4 16:01:25 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Jun 2006 16:01:25 +0200 (CEST) Subject: [pypy-svn] r28261 - pypy/dist/pypy/rpython/test Message-ID: <20060604140125.64DF21006F@code0.codespeak.net> Author: antocuni Date: Sun Jun 4 16:01:24 2006 New Revision: 28261 Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py Log: (antocuni, nik) We don't really want hasattr to be tested on ootypesystem. Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Sun Jun 4 16:01:24 2006 @@ -305,22 +305,6 @@ res = self.interpret(f, [1]) assert res is False - def test_hasattr(self): - self._skip_oo('hasattr') - class A(object): - def __init__(self): - self.x = 42 - def f(i): - a = A() - if i==0: return int(hasattr(A, '__init__')) - if i==1: return int(hasattr(A, 'y')) - if i==2: return int(hasattr(42, 'x')) - for x, y in zip(range(3), (1, 0, 0)): - res = self.interpret(f, [x]) - assert res._obj.value == y - # hmm, would like to test against PyObj, is this the wrong place/way? - - class TestLLtype(BaseTestExtfunc, LLRtypeMixin): from pypy.rpython.lltypesystem.module import ll_os @@ -358,6 +342,20 @@ res = self.interpret(f, [_1_0], someobjects=True) assert res is False + def test_hasattr(self): + class A(object): + def __init__(self): + self.x = 42 + def f(i): + a = A() + if i==0: return int(hasattr(A, '__init__')) + if i==1: return int(hasattr(A, 'y')) + if i==2: return int(hasattr(42, 'x')) + for x, y in zip(range(3), (1, 0, 0)): + res = self.interpret(f, [x]) + assert res._obj.value == y + # hmm, would like to test against PyObj, is this the wrong place/way? + class TestOOtype(BaseTestExtfunc, OORtypeMixin): from pypy.rpython.ootypesystem.module import ll_os From antocuni at codespeak.net Sun Jun 4 16:43:43 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Jun 2006 16:43:43 +0200 (CEST) Subject: [pypy-svn] r28264 - in pypy/dist/pypy/rpython: ootypesystem test Message-ID: <20060604144343.0CC2F1006F@code0.codespeak.net> Author: antocuni Date: Sun Jun 4 16:43:42 2006 New Revision: 28264 Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py pypy/dist/pypy/rpython/test/test_rpbc.py Log: (antocuni, nik) Fixed a bug that prevented StaticMethods to be called inside low level helpers when they are not constant. Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rootype.py Sun Jun 4 16:43:42 2006 @@ -22,6 +22,14 @@ def rtyper_makekey(self): return self.__class__, self.ootype, self.name +class __extend__(annmodel.SomeOOStaticMeth): + def rtyper_makerepr(self, rtyper): + return OOStaticMethRepr(self.method) + def rtyper_makekey(self): + return self.__class__, self.method + + + class OOClassRepr(Repr): lowleveltype = Class ooclass_repr = OOClassRepr() @@ -77,7 +85,12 @@ hop.exception_is_here() return hop.genop("oosend", [cname]+vlist, resulttype = hop.r_result.lowleveltype) - + + +class OOStaticMethRepr(Repr): + def __init__(self, METHODTYPE): + self.lowleveltype = METHODTYPE + class __extend__(pairtype(OOInstanceRepr, OOBoundMethRepr)): Modified: pypy/dist/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rpbc.py (original) +++ pypy/dist/pypy/rpython/test/test_rpbc.py Sun Jun 4 16:43:42 2006 @@ -490,7 +490,6 @@ assert res == 42 def test_simple_function_pointer(self): - py.test.skip("a problem with ootypesystem") def f1(x): return x + 1 def f2(x): From cfbolz at codespeak.net Sun Jun 4 16:46:00 2006 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Jun 2006 16:46:00 +0200 (CEST) Subject: [pypy-svn] r28265 - in pypy/dist/pypy/lib: . test2 Message-ID: <20060604144600.ECB181006F@code0.codespeak.net> Author: cfbolz Date: Sun Jun 4 16:46:00 2006 New Revision: 28265 Added: pypy/dist/pypy/lib/test2/test_sio.py - copied, changed from r28249, pypy/dist/pypy/lib/test2/FIXME_test_sio.py Removed: pypy/dist/pypy/lib/test2/FIXME_test_sio.py Modified: pypy/dist/pypy/lib/_sio.py Log: (ac, cfbolz): 17000 revision later: finish fixing test_sio.py. One tiny tiny bug in _sio found. Modified: pypy/dist/pypy/lib/_sio.py ============================================================================== --- pypy/dist/pypy/lib/_sio.py (original) +++ pypy/dist/pypy/lib/_sio.py Sun Jun 4 16:46:00 2006 @@ -525,7 +525,7 @@ def write(self, data): buflen = len(self.buf) datalen = len(data) - if datalen + buflen <= self.bufsize: + if datalen + buflen < self.bufsize: self.buf += data elif buflen: self.buf += data[:self.bufsize-buflen] From tismer at codespeak.net Sun Jun 4 16:51:09 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 4 Jun 2006 16:51:09 +0200 (CEST) Subject: [pypy-svn] r28266 - pypy/dist/pypy/interpreter Message-ID: <20060604145109.5459A1006F@code0.codespeak.net> Author: tismer Date: Sun Jun 4 16:51:08 2006 New Revision: 28266 Modified: pypy/dist/pypy/interpreter/generator.py Log: generators need to detach their frame's f_back after next() Modified: pypy/dist/pypy/interpreter/generator.py ============================================================================== --- pypy/dist/pypy/interpreter/generator.py (original) +++ pypy/dist/pypy/interpreter/generator.py Sun Jun 4 16:51:08 2006 @@ -78,6 +78,7 @@ self.exhausted = True raise finally: + self.frame.f_back = None self.running = False # From tismer at codespeak.net Sun Jun 4 17:20:32 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 4 Jun 2006 17:20:32 +0200 (CEST) Subject: [pypy-svn] r28272 - pypy/dist/pypy/interpreter Message-ID: <20060604152032.5B7871006F@code0.codespeak.net> Author: tismer Date: Sun Jun 4 17:20:31 2006 New Revision: 28272 Modified: pypy/dist/pypy/interpreter/pycode.py Log: interface for getting the right frame class Modified: pypy/dist/pypy/interpreter/pycode.py ============================================================================== --- pypy/dist/pypy/interpreter/pycode.py (original) +++ pypy/dist/pypy/interpreter/pycode.py Sun Jun 4 17:20:31 2006 @@ -86,7 +86,7 @@ code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, hidden_applevel=False, magic = 62061 | 0x0a0d0000): # value for Python 2.4.1 - """Initialize a new code objects from parameters given by + """Initialize a new code object from parameters given by the pypy compiler""" self.space = space eval.Code.__init__(self, name) @@ -254,8 +254,7 @@ frame.init_cells() return frame.run() - def create_frame(self, space, w_globals, closure=None): - "Create an empty PyFrame suitable for this code object." + def get_frame_class(self): # select the appropriate kind of frame if not frame_classes: setup_frame_classes() # lazily @@ -265,7 +264,11 @@ if self.co_flags & CO_GENERATOR: choose |= GENERATOR Frame = frame_classes[choose] - return Frame(space, self, w_globals, closure) + return Frame + + def create_frame(self, space, w_globals, closure=None): + "Create an empty PyFrame suitable for this code object." + return self.get_frame_class()(space, self, w_globals, closure) def getvarnames(self): return self.co_varnames From ale at codespeak.net Sun Jun 4 17:20:51 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Sun, 4 Jun 2006 17:20:51 +0200 (CEST) Subject: [pypy-svn] r28273 - pypy/dist/pypy/objspace/std Message-ID: <20060604152051.A179710076@code0.codespeak.net> Author: ale Date: Sun Jun 4 17:20:50 2006 New Revision: 28273 Modified: pypy/dist/pypy/objspace/std/setobject.py Log: __reduce__ should return the __dict__ as well Modified: pypy/dist/pypy/objspace/std/setobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/setobject.py (original) +++ pypy/dist/pypy/objspace/std/setobject.py Sun Jun 4 17:20:50 2006 @@ -559,7 +559,8 @@ return '%s(%s)' % (s.__class__.__name__, [x for x in s]) def reduce__Set(s): - return (s.__class__,(tuple(s),),None) + dict = getattr(s,'__dict__', None) + return (s.__class__, (tuple(s),), dict) """, filename=__file__) From hpk at codespeak.net Sun Jun 4 17:23:18 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Jun 2006 17:23:18 +0200 (CEST) Subject: [pypy-svn] r28274 - in pypy/dist/pypy/objspace/cpy: . test Message-ID: <20060604152318.9746F10070@code0.codespeak.net> Author: hpk Date: Sun Jun 4 17:23:18 2006 New Revision: 28274 Modified: pypy/dist/pypy/objspace/cpy/capi.py pypy/dist/pypy/objspace/cpy/objspace.py pypy/dist/pypy/objspace/cpy/test/test_objspace.py Log: add support for wrapping and unwrapping floats Modified: pypy/dist/pypy/objspace/cpy/capi.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/capi.py (original) +++ pypy/dist/pypy/objspace/cpy/capi.py Sun Jun 4 17:23:18 2006 @@ -157,6 +157,14 @@ PyInt_AsLong.argtypes = [W_Object] PyInt_AsLong.restype = c_long +PyFloat_FromDouble = cpyapi.PyFloat_FromDouble +PyFloat_FromDouble.argtypes = [c_double] +PyFloat_FromDouble.restype = W_Object + +PyFloat_AsDouble = cpyapi.PyFloat_AsDouble +PyFloat_AsDouble.argtypes = [W_Object] +PyFloat_AsDouble.restype = c_double + ################################################### # ____________________ Strings ____________________ Modified: pypy/dist/pypy/objspace/cpy/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/objspace.py (original) +++ pypy/dist/pypy/objspace/cpy/objspace.py Sun Jun 4 17:23:18 2006 @@ -49,6 +49,8 @@ return PyInt_FromLong(x) if isinstance(x, str): return PyString_FromStringAndSize(x, len(x)) + if isinstance(x, float): + return PyFloat_FromDouble(x) raise TypeError("wrap(%r)" % (x,)) wrap._annspecialcase_ = "specialize:wrap" @@ -70,6 +72,7 @@ getitem = staticmethod(PyObject_GetItem) setitem = staticmethod(PyObject_SetItem) int_w = staticmethod(PyInt_AsLong) + float_w = staticmethod(PyFloat_AsDouble) str_w = staticmethod(PyString_AsString) iter = staticmethod(PyObject_GetIter) type = staticmethod(PyObject_Type) Modified: pypy/dist/pypy/objspace/cpy/test/test_objspace.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/test/test_objspace.py (original) +++ pypy/dist/pypy/objspace/cpy/test/test_objspace.py Sun Jun 4 17:23:18 2006 @@ -10,6 +10,13 @@ wback = space.getitem(d,wk1) assert space.eq_w(wback,wone) +def test_wrap(): + space = CPyObjSpace() + w_res = space.add(space.wrap(1.0), space.wrap(1.5)) + assert space.eq_w(w_res, space.wrap(2.5)) + res = space.float_w(w_res) + assert res == 2.5 + def test_demo(): from pypy.module._demo import demo space = CPyObjSpace() From antocuni at codespeak.net Sun Jun 4 17:23:50 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Jun 2006 17:23:50 +0200 (CEST) Subject: [pypy-svn] r28276 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem Message-ID: <20060604152350.B39A610070@code0.codespeak.net> Author: antocuni Date: Sun Jun 4 17:23:49 2006 New Revision: 28276 Modified: pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py pypy/dist/pypy/rpython/rbuiltin.py Log: (antocuni, nik) Make the r_dict rtyping typesystem-specific. Modified: pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py Sun Jun 4 17:23:49 2006 @@ -2,6 +2,7 @@ from pypy.annotation import model as annmodel from pypy.rpython.lltypesystem import lltype from pypy.rpython.lltypesystem import rclass +from pypy.rpython.lltypesystem.rdict import rtype_r_dict from pypy.rpython import objectmodel from pypy.rpython.rmodel import TyperError, Constant from pypy.rpython.robject import pyobj_repr @@ -64,3 +65,4 @@ BUILTIN_TYPER[isinstance] = rtype_builtin_isinstance BUILTIN_TYPER[hasattr] = rtype_builtin_hasattr BUILTIN_TYPER[__import__] = rtype_builtin___import__ +BUILTIN_TYPER[objectmodel.r_dict] = rtype_r_dict Modified: pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py Sun Jun 4 17:23:49 2006 @@ -1,7 +1,9 @@ from pypy.annotation import model as annmodel from pypy.rpython.ootypesystem import ootype from pypy.rpython.ootypesystem import rclass +from pypy.rpython.ootypesystem.rdict import rtype_r_dict from pypy.objspace.flow.model import Constant +from pypy.rpython import objectmodel from pypy.rpython.error import TyperError def rtype_new(hop): @@ -71,3 +73,4 @@ BUILTIN_TYPER[ootype.runtimenew] = rtype_runtimenew BUILTIN_TYPER[ootype.ooidentityhash] = rtype_ooidentityhash BUILTIN_TYPER[isinstance] = rtype_builtin_isinstance +BUILTIN_TYPER[objectmodel.r_dict] = rtype_r_dict Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Sun Jun 4 17:23:49 2006 @@ -9,7 +9,6 @@ from pypy.rpython import rstr from pypy.rpython import rptr from pypy.rpython.robject import pyobj_repr -from pypy.rpython.lltypesystem.rdict import rtype_r_dict # TODO: typesystem? from pypy.tool import sourcetools from pypy.rpython import extregistry @@ -445,7 +444,6 @@ BUILTIN_TYPER[lltype.Ptr] = rtype_const_result BUILTIN_TYPER[lltype.runtime_type_info] = rtype_runtime_type_info BUILTIN_TYPER[rarithmetic.intmask] = rtype_intmask -BUILTIN_TYPER[objectmodel.r_dict] = rtype_r_dict BUILTIN_TYPER[objectmodel.we_are_translated] = rtype_we_are_translated BUILTIN_TYPER[rstack.yield_current_frame_to_caller] = ( rtype_yield_current_frame_to_caller) From mwh at codespeak.net Sun Jun 4 17:28:27 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 17:28:27 +0200 (CEST) Subject: [pypy-svn] r28277 - pypy/dist/pypy/module/_pickle_support Message-ID: <20060604152827.A10C110070@code0.codespeak.net> Author: mwh Date: Sun Jun 4 17:28:26 2006 New Revision: 28277 Modified: pypy/dist/pypy/module/_pickle_support/maker.py Log: comment out wads of translation-breaking code. please don't re-break translation when you uncomment it again :) Modified: pypy/dist/pypy/module/_pickle_support/maker.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/maker.py (original) +++ pypy/dist/pypy/module/_pickle_support/maker.py Sun Jun 4 17:28:26 2006 @@ -53,49 +53,52 @@ return W_ReverseSeqIterObject(space, w_seq, index) def frame_new(space, __args__): - args_w, kwds_w = __args__.unpack() #stolen from std/fake.py - args = [space.unwrap(w_arg) for w_arg in args_w] - f_back, builtin, pycode, valuestack, blockstack, last_exception,\ - globals, last_instr, next_instr, f_lineno, fastlocals, f_trace,\ - instr_lb, instr_ub, instr_prev = args - w = space.wrap - - new_frame = PyFrame(space, pycode, w(globals), None) - new_frame.f_back = f_back - new_frame.builtin = builtin - #new_frame.blockstack = blockstack - #new_frame.valuestack = valuestack - new_frame.last_exception = last_exception - new_frame.last_instr = last_instr - new_frame.next_instr = next_instr - new_frame.f_lineno = f_lineno - #new_frame.fastlocals_w = w(fastlocals) - - if space.is_w(f_trace, space.w_None): - new_frame.w_f_trace = None - else: - new_frame.w_f_trace = w(f_trace) - - new_frame.instr_lb = instr_lb #the three for tracing - new_frame.instr_ub = instr_ub - new_frame.instr_prev = instr_prev + return None +## args_w, kwds_w = __args__.unpack() #stolen from std/fake.py +## args = [space.unwrap(w_arg) for w_arg in args_w] +## f_back, builtin, pycode, valuestack, blockstack, last_exception,\ +## globals, last_instr, next_instr, f_lineno, fastlocals, f_trace,\ +## instr_lb, instr_ub, instr_prev = args +## w = space.wrap + +## new_frame = PyFrame(space, pycode, w(globals), None) +## new_frame.f_back = f_back +## new_frame.builtin = builtin +## #new_frame.blockstack = blockstack +## #new_frame.valuestack = valuestack +## new_frame.last_exception = last_exception +## new_frame.last_instr = last_instr +## new_frame.next_instr = next_instr +## new_frame.f_lineno = f_lineno +## #new_frame.fastlocals_w = w(fastlocals) + +## if space.is_w(f_trace, space.w_None): +## new_frame.w_f_trace = None +## else: +## new_frame.w_f_trace = w(f_trace) + +## new_frame.instr_lb = instr_lb #the three for tracing +## new_frame.instr_ub = instr_ub +## new_frame.instr_prev = instr_prev - return space.wrap(new_frame) +## return space.wrap(new_frame) frame_new.unwrap_spec = [ObjSpace, Arguments] def traceback_new(space, __args__): - args_w, kwds_w = __args__.unpack() #stolen from std/fake.py - args = [space.unwrap(w_arg) for w_arg in args_w] - frame, lasti, lineno, next = args - return PyTraceback(space, frame, lasti, lineno, next) + return None +## args_w, kwds_w = __args__.unpack() #stolen from std/fake.py +## args = [space.unwrap(w_arg) for w_arg in args_w] +## frame, lasti, lineno, next = args +## return PyTraceback(space, frame, lasti, lineno, next) traceback_new.unwrap_spec = [ObjSpace, Arguments] def generator_new(space, __args__): - args_w, kwds_w = __args__.unpack() #stolen from std/fake.py - args = [space.unwrap(w_arg) for w_arg in args_w] - frame, running, exhausted = args - new_generator = GeneratorIterator(frame) - new_generator.running = running - new_generator.exhausted = exhausted - return new_generator + return None +## args_w, kwds_w = __args__.unpack() #stolen from std/fake.py +## args = [space.unwrap(w_arg) for w_arg in args_w] +## frame, running, exhausted = args +## new_generator = GeneratorIterator(frame) +## new_generator.running = running +## new_generator.exhausted = exhausted +## return new_generator generator_new.unwrap_spec = [ObjSpace, Arguments] From hpk at codespeak.net Sun Jun 4 17:46:06 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Jun 2006 17:46:06 +0200 (CEST) Subject: [pypy-svn] r28280 - in pypy/dist/pypy/module/time2: . test Message-ID: <20060604154606.DAF1710075@code0.codespeak.net> Author: hpk Date: Sun Jun 4 17:46:06 2006 New Revision: 28280 Added: pypy/dist/pypy/module/time2/ pypy/dist/pypy/module/time2/README pypy/dist/pypy/module/time2/__init__.py (contents, props changed) pypy/dist/pypy/module/time2/interp_time.py (contents, props changed) pypy/dist/pypy/module/time2/test/ pypy/dist/pypy/module/time2/test/__init__.py (contents, props changed) pypy/dist/pypy/module/time2/test/test_time.py (contents, props changed) Log: add my try at a rctypes based time module Added: pypy/dist/pypy/module/time2/README ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/time2/README Sun Jun 4 17:46:06 2006 @@ -0,0 +1,5 @@ + +This is just some experimental code, likely +we cannot implement a time module on top of rctypes +as a mixed module because it would make life too hard +for ootype backends. Added: pypy/dist/pypy/module/time2/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/time2/__init__.py Sun Jun 4 17:46:06 2006 @@ -0,0 +1,11 @@ +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + """A demo built-in module based on ctypes.""" + + interpleveldefs = { + 'clock' : 'interp_time.clock', + } + + appleveldefs = { + } Added: pypy/dist/pypy/module/time2/interp_time.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/time2/interp_time.py Sun Jun 4 17:46:06 2006 @@ -0,0 +1,26 @@ +from pypy.interpreter.error import OperationError +from pypy.interpreter.baseobjspace import ObjSpace, W_Root +from pypy.rpython.rctypes.tool import ctypes_platform +from pypy.rpython.rctypes.tool.clib import clib + +import sys +from ctypes import * + +class CConfig: + _header_ = """#include +""" + time_t = ctypes_platform.SimpleType('time_t', c_int) + clock_t = ctypes_platform.SimpleType('clock_t', c_int) + CLOCKS_PER_SEC = ctypes_platform.DefinedConstantInteger('CLOCKS_PER_SEC') + +cconfig = ctypes_platform.configure(CConfig) + +clock_t = cconfig['clock_t'] +CLOCKS_PER_SEC = cconfig['CLOCKS_PER_SEC'] + +c_clock = clib.clock +c_clock.restype = clock_t + +def clock(space): + return space.wrap(float(c_clock()) / CLOCKS_PER_SEC) +clock.unwrap_spec = [ObjSpace, ] Added: pypy/dist/pypy/module/time2/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/time2/test/__init__.py Sun Jun 4 17:46:06 2006 @@ -0,0 +1 @@ +# Added: pypy/dist/pypy/module/time2/test/test_time.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/time2/test/test_time.py Sun Jun 4 17:46:06 2006 @@ -0,0 +1,25 @@ +from pypy.objspace.std import StdObjSpace +import time + +def setup_module(mod): + mod.space = StdObjSpace(usemodules=['time2']) + +class TestTime: + def test_clock(self): + t0 = time.clock() + w_t1 = space.appexec([], """(): import time2; return time2.clock()""") + t2 = time.clock() + assert t0 <= space.unwrap(w_t1) <= t2 + + def XXXtest_time(self): + t0 = time.time() + w_t1 = space.appexec([], """(): import time; return time.time()""") + t2 = time.time() + assert t0 <= space.unwrap(w_t1) <= t2 + + def XXXtest_sleep(self): + w_sleep = space.appexec([], """(): import time; return time.sleep""") + t0 = time.time() + space.call_function(w_sleep, space.wrap(0.3)) + t1 = time.time() + assert t1-t0 > 0.25 From fijal at codespeak.net Sun Jun 4 18:19:42 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 4 Jun 2006 18:19:42 +0200 (CEST) Subject: [pypy-svn] r28282 - in pypy/dist/pypy/translator/js2: . modules test test/html Message-ID: <20060604161942.2DCFE10070@code0.codespeak.net> Author: fijal Date: Sun Jun 4 18:19:37 2006 New Revision: 28282 Added: pypy/dist/pypy/translator/js2/modules/ pypy/dist/pypy/translator/js2/modules/__init__.py pypy/dist/pypy/translator/js2/modules/dom.py pypy/dist/pypy/translator/js2/test/html/ pypy/dist/pypy/translator/js2/test/html/test.html pypy/dist/pypy/translator/js2/test/test_dom.py Modified: pypy/dist/pypy/translator/js2/_builtin.py pypy/dist/pypy/translator/js2/database.py pypy/dist/pypy/translator/js2/function.py pypy/dist/pypy/translator/js2/opcodes.py pypy/dist/pypy/translator/js2/support.py pypy/dist/pypy/translator/js2/test/browsertest.py pypy/dist/pypy/translator/js2/test/runtest.py pypy/dist/pypy/translator/js2/test/test_jseval.py Log: Preliminary DOM support. Modified: pypy/dist/pypy/translator/js2/_builtin.py ============================================================================== --- pypy/dist/pypy/translator/js2/_builtin.py (original) +++ pypy/dist/pypy/translator/js2/_builtin.py Sun Jun 4 18:19:37 2006 @@ -2,7 +2,7 @@ """ several builtins mapping """ -from pypy.rpython.ootypesystem.ootype import List, Meth, Void, String +from pypy.rpython.ootypesystem.ootype import List, Meth, Void, String, Instance from pypy.translator.js2.log import log @@ -11,45 +11,49 @@ SETITEM = 1 class _Builtins(object): + # Returns builtin function mapping + property flag or attribute to call (plain string) BUILTIN_MAP = { - 'js_jseval' : ('eval', False), - 'newlist' : ('[]', True), - 'alloc_and_set' : ('alloc_and_set', False), - 'strconcat' : ('strconcat', False), - 'stritem' : ('stritem', False), - 'delitem_nonneg' : ('delitem', False), - 'streq' : 'equal', - 'strcmp' : ('strcmp', False), - 'startswith' : ('startswith', False), - 'endswith' : ('endswith', False), + 'll_js_jseval' : ('eval', False), + 'll_newlist' : ('[]', True), + 'll_alloc_and_set' : ('alloc_and_set', False), + 'll_strconcat' : ('strconcat', False), + 'll_stritem' : ('stritem', False), + 'll_delitem_nonneg' : ('delitem', False), + 'll_streq' : ['equal'], + 'll_strcmp' : ('strcmp', False), + 'll_startswith' : ('startswith', False), + 'll_endswith' : ('endswith', False), + 'll_int' : ('parseInt', False), + 'get_document' : ('document', True), } BUILTIN_METHOD_MAP = { List: { - 'll_setitem_fast' : 'list_ll_setitem', - 'll_getitem_fast' : 'list_ll_getitem', - '_ll_resize' : 'list_ll_resize', - '_ll_resize_ge' : 'list_ll_resize', - '_ll_resize_le' : 'list_ll_resize', + 'll_setitem_fast' : ['list_ll_setitem'], + 'll_getitem_fast' : ['list_ll_getitem'], + '_ll_resize' : ['list_ll_resize'], + '_ll_resize_ge' : ['list_ll_resize'], + '_ll_resize_le' : ['list_ll_resize'], 'll_length' : ('length', True), }, String.__class__: { 'll_strlen' : ('length', True), - 'll_stritem_nonneg' : 'list_ll_getitem', + 'll_stritem_nonneg' : ['list_ll_getitem'], + } + } + + # Return builtin class/method property mapping + getter/setter flag + BUILTINS_METHOD_PROPERTY_MAP = { + 'dom.Node': { + 'setInnerHTML' : ('innerHTML', True), } } def real_name(self, _name): - name = _name.split('__')[0] - m = re.match("^ll_(.*)$", name) - if not m: - return None - return m.group(1) + return _name.split('__')[0] def map_builtin_function(self, const, inst, args, generator): name = self.real_name(const.value._name) - if name is None: - return None if getattr(const.value, 'suggested_primitive', False): log("Suggested primitive %r"%const) @@ -58,20 +62,38 @@ if isinstance(model, tuple): return model else: - getattr(inst, model)(None, args, generator) + getattr(inst, model[0])(None, args, generator, *model[1:]) return False except KeyError: return None + def is_builtin_object(self, _class, obj, method, args): + if not _class is Instance: + return None + m = re.search("js2\.modules\.(.*)", obj.concretetype._name) + if m: + real_name = obj.concretetype._methods[method]._name[1:] + try: + # We define property and property setters here + name,val = self.BUILTINS_METHOD_PROPERTY_MAP[m.group(1)][real_name] + if val: + return ['setitem',name] + return name, True + except KeyError: + return real_name, False + return None + def map_builtin_method(self, base_obj, method, args, inst, generator): try: log("Baseobj: %r, method: %r"%(base_obj.concretetype, method)) - model = self.BUILTIN_METHOD_MAP[base_obj.concretetype.__class__][method] + model = self.is_builtin_object(base_obj.concretetype.__class__, base_obj, method, args) + if not model: + model = self.BUILTIN_METHOD_MAP[base_obj.concretetype.__class__][method] if isinstance(model,tuple): log("Suggested simple mapping %r"%(model,)) return model else: - getattr(inst, model)(base_obj, args, generator) + getattr(inst, model[0])(base_obj, args, generator, *model[1:]) return False except KeyError: return None Modified: pypy/dist/pypy/translator/js2/database.py ============================================================================== --- pypy/dist/pypy/translator/js2/database.py (original) +++ pypy/dist/pypy/translator/js2/database.py Sun Jun 4 18:19:37 2006 @@ -16,6 +16,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.objspace.flow.model import Variable, Constant +from pypy.translator.js2.modules import dom try: set @@ -39,6 +40,16 @@ self.name_manager = JavascriptNameManager(self) self.pending_consts = [] self.cts = type_system_class(self) + self.prepare_builtins() + + def prepare_builtins(self): + # Document Object Model elements + #for module in [dom]: + # for i in dir(module): + # if not i.startswith('__'): + # # FIXME: shit, strange way of doing it + # self.consts[BuiltinConst(module[i])] = i + return def is_primitive(self, type_): if type_ in [Void, Bool, Float, Signed, Unsigned, SignedLongLong, UnsignedLongLong, Char, UniChar] or \ @@ -153,9 +164,12 @@ if self.is_primitive(type_): ilasm.load_const(self.cts.primitive_repr(type_, value)) else: - name = self.record_const(value) - ilasm.load_local(self.const_var) - ilasm.get_field(name) + try: + return self.consts[BuiltinConst(value)] + except KeyError: + name = self.record_const(value) + ilasm.load_local(self.const_var) + ilasm.get_field(name) #assert False, 'Unknown constant %s' % const @@ -322,3 +336,21 @@ def init_fields(self, ilasm, const_var, name): pass +class BuiltinConst(AbstractConst): + def __init__(self, name): + self.name = name + + def __hash__(self): + return hash(self.name) + + def __eq__(self, other): + return self.name == other.name + + def get_name(self): + return self.name + + def init_fields(self, *args): + pass + + def init(self, ilasm): + ilasm.load_str(self.name) Modified: pypy/dist/pypy/translator/js2/function.py ============================================================================== --- pypy/dist/pypy/translator/js2/function.py (original) +++ pypy/dist/pypy/translator/js2/function.py Sun Jun 4 18:19:37 2006 @@ -14,6 +14,8 @@ from pypy.translator.cli.node import Node from pypy.translator.cli.class_ import Class +from pypy.translator.js2._builtin import Builtins + from pypy.translator.js2.log import log import re Added: pypy/dist/pypy/translator/js2/modules/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/modules/__init__.py Sun Jun 4 18:19:37 2006 @@ -0,0 +1,3 @@ + +""" Support classes needed for javascript to translate +""" Added: pypy/dist/pypy/translator/js2/modules/dom.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/modules/dom.py Sun Jun 4 18:19:37 2006 @@ -0,0 +1,20 @@ + +""" Document Object Model support +http://www.w3.org/DOM/ - main standart +http://www.w3schools.com/dhtml/dhtml_dom.asp - more informal stuff +""" + +# FIXME: this should map somehow to xml.dom interface, or something else + +class Node(object): + def __init__(self): + self.innerHTML = "" + + def getElementById(self, id): + return Node() + + def setInnerHTML(self, data): + self.innerHTML = data + +def get_document(): + return Node() Modified: pypy/dist/pypy/translator/js2/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js2/opcodes.py (original) +++ pypy/dist/pypy/translator/js2/opcodes.py Sun Jun 4 18:19:37 2006 @@ -58,7 +58,10 @@ graph = op.args[0].value.graph #method_name = oopspec.get_method_name(graph, op) #if method_name is None: - bt = Builtins.map_builtin_function(op.args[0], self, op.args, generator) + if op.args[0] in generator.db.name_manager.predefined: + bt = op.args[0], False + else: + bt = Builtins.map_builtin_function(op.args[0], self, op.args, generator) if bt: builtin, is_property = bt self._render_builtin(generator, builtin, op.args, is_property) @@ -105,6 +108,11 @@ def do_nothing(self, base_obj, args, generator): generator.load_void() + def setitem(self, base_obj, args, generator, real_name): + generator.load(base_obj) + generator.load(args[1]) + generator.set_field(None, real_name) + def equal(self, base_obj, args, generator): generator.load(args[1]) generator.load(args[2]) Modified: pypy/dist/pypy/translator/js2/support.py ============================================================================== --- pypy/dist/pypy/translator/js2/support.py (original) +++ pypy/dist/pypy/translator/js2/support.py Sun Jun 4 18:19:37 2006 @@ -49,6 +49,8 @@ self.reserved[name] = True self.make_reserved_names(' '.join(self.reserved)) + + self.predefined = set(predefined_classes_and_objects) def uniquename(self, name): #if self.js.compress and name != self.js.functions[0].func_name and is_optimized_function(name) and name.startswith("ll_issubclass__object_vtablePtr_object_vtablePtr"): Modified: pypy/dist/pypy/translator/js2/test/browsertest.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/browsertest.py (original) +++ pypy/dist/pypy/translator/js2/test/browsertest.py Sun Jun 4 18:19:37 2006 @@ -1,13 +1,15 @@ -from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +from BaseHTTPServer import HTTPServer as BaseHTTPServer, BaseHTTPRequestHandler import py from os import system from cgi import parse_qs from sys import platform from time import sleep -from webbrowser import open as webbrowser_open +import webbrowser from pypy.translator.js2.log import log log = log.browsertest +class HTTPServer(BaseHTTPServer): + allow_reuse_address = True class config: http_port = 10001 @@ -86,7 +88,15 @@ jsfilename = jstest.jsfilename jstestcase = jstest.jstestcase jscode = jstest.jscode - html_page = config.html_page % locals() + if self.server.html_page: + if self.server.is_interactive: + isinteractive = '' + else: + isinteractive = 'resultform.submit();' + html_page = open(self.server.html_page).read() % locals() + else: + html_page = config.html_page % locals() + open("html_page.html", "w").write(html_page) self.serve_data('text/html', html_page) do_status = 'do_GET' @@ -97,8 +107,15 @@ self.send_error(404, "File not found") return form = parse_qs(self.rfile.read(int(self.headers['content-length']))) - jstest.result = form['result'][0] - + if self.server.is_interactive: + if not form.has_key('ok'): + jstest.result = 'Not clicked OK' + else: + jstest.result = 'OK' + #assert False, "Clicked not ok" + else: + jstest.result = form['result'][0] + #we force a page refresh here because of two reason: # 1. we don't have the next testcase ready yet # 2. browser should ask again when we do have a test @@ -120,9 +137,11 @@ class BrowserTest(object): """The browser driver""" - def start_server(self, port): + def start_server(self, port, html_page, is_interactive): server_address = ('', port) self.httpd = HTTPServer(server_address, TestHandler) + self.httpd.is_interactive = is_interactive + self.httpd.html_page = html_page def get_result(self): global do_status @@ -134,16 +153,20 @@ return jstest.result -def jstest(jsfilename, jstestcase): +def jstest(jsfilename, jstestcase, browser_to_use, html_page = None, is_interactive = False): global driver, jstest jstest = TestCase(str(jsfilename), str(jstestcase)) try: - driver + driver.httpd.html_page = html_page + driver.httpd.is_interactive = is_interactive except: driver = BrowserTest() - driver.start_server(config.http_port) - webbrowser_open('http://localhost:%d/test.html' % config.http_port) + driver.start_server(config.http_port, html_page, is_interactive) + if browser_to_use == 'default': + browser_to_use = None + if browser_to_use != 'none': + webbrowser.get(browser_to_use).open('http://localhost:%d/test.html' % config.http_port) result = driver.get_result() return result Added: pypy/dist/pypy/translator/js2/test/html/test.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/test/html/test.html Sun Jun 4 18:19:37 2006 @@ -0,0 +1,35 @@ + + + + + +

Blah

+
+ + + + + Modified: pypy/dist/pypy/translator/js2/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/runtest.py (original) +++ pypy/dist/pypy/translator/js2/test/runtest.py Sun Jun 4 18:19:37 2006 @@ -8,11 +8,11 @@ from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.js2.js import JS from pypy.translator.js2.test.browsertest import jstest -from pypy.translator.js import conftest +from pypy.translator.js2 import conftest from pypy.translator.js2.log import log from pypy.conftest import option log = log.runtest -use_browsertest = conftest.option.jsbrowser +use_browsertest = conftest.option.browser def _CLI_is_on_path(): try: @@ -22,10 +22,12 @@ return True class compile_function(object): - def __init__(self, function, annotation, stackless=False, view=False): + def __init__(self, function, annotation, stackless=False, view=False, html=None, is_interactive=False): if not use_browsertest and not _CLI_is_on_path(): py.test.skip('Javascript CLI (js) not found') + self.html = html + self.is_interactive = is_interactive t = TranslationContext() t.buildannotator().build_types(function, annotation) @@ -54,7 +56,8 @@ # function_call = "slp_entry_point('%s')" % function_call if use_browsertest: - output = jstest(self.js.filename, function_call) + log("Used html: %r" % self.html) + output = jstest(self.js.filename, function_call, use_browsertest, self.html, self.is_interactive) else: cmd = 'echo "load(\'%s\'); print(%s)" | js 2>&1' % (self.js.filename, function_call) log(cmd) Added: pypy/dist/pypy/translator/js2/test/test_dom.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/test/test_dom.py Sun Jun 4 18:19:37 2006 @@ -0,0 +1,23 @@ + +""" test of DOM related functions +""" + +import py + +from pypy.translator.js2.test.runtest import compile_function +from pypy.translator.js2.modules.dom import get_document +from pypy.translator.js2 import conftest + +import time + +if not conftest.option.browser: + py.test.skip("Works only in browser (right now?)") + +class TestDOM(object): + def test_document_base(self): + def f(): + get_document().getElementById("dupa").setInnerHTML("

Fire!

") + return get_document().getElementById("dupa") + + fn = compile_function(f, [], html = 'html/test.html') + assert fn() == '[object HTMLHeadingElement]' Modified: pypy/dist/pypy/translator/js2/test/test_jseval.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_jseval.py (original) +++ pypy/dist/pypy/translator/js2/test/test_jseval.py Sun Jun 4 18:19:37 2006 @@ -4,7 +4,7 @@ from pypy.translator.js2.test.runtest import compile_function from pypy.rpython.lltypesystem import lltype from pypy.rpython.rjs import jseval -from pypy.translator.js import conftest +from pypy.translator.js2 import conftest def jsnative(cmd): def do(): @@ -34,7 +34,8 @@ assert jsnative1_fn() == localtime()[2] callbacks = [] -n_times_called = lltype.malloc(lltype.GcArray(lltype.Signed), 1) +#n_times_called = lltype.malloc(lltype.GcArray(lltype.Signed), 1) +n_times_called = [0] def callback_function(): n_times_called[0] += 1 @@ -42,7 +43,8 @@ jseval("setTimeout('callback_function()', 100)") def test_register_callback(): - if not conftest.option.jsbrowser: + py.test.skip("Hangs") + if not conftest.option.browser: py.test.skip("works only in a browser (use py.test --browser)") def register_callback(): From cfbolz at codespeak.net Sun Jun 4 18:32:45 2006 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Jun 2006 18:32:45 +0200 (CEST) Subject: [pypy-svn] r28283 - in pypy/dist/pypy/lib: . test2 Message-ID: <20060604163245.D28F110069@code0.codespeak.net> Author: cfbolz Date: Sun Jun 4 18:32:44 2006 New Revision: 28283 Modified: pypy/dist/pypy/lib/_sio.py pypy/dist/pypy/lib/test2/test_sio.py Log: (cfbolz, arre) Make BufferedInputStream actually buffer. Modified: pypy/dist/pypy/lib/_sio.py ============================================================================== --- pypy/dist/pypy/lib/_sio.py (original) +++ pypy/dist/pypy/lib/_sio.py Sun Jun 4 18:32:44 2006 @@ -446,7 +446,7 @@ more = [data] k = len(data) while k < n: - data = self.do_read(min(self.bufsize, n-k)) + data = self.do_read(max(self.bufsize, n-k)) k += len(data) more.append(data) if not data: Modified: pypy/dist/pypy/lib/test2/test_sio.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_sio.py (original) +++ pypy/dist/pypy/lib/test2/test_sio.py Sun Jun 4 18:32:44 2006 @@ -15,6 +15,7 @@ self.orig_packets = list(packets) self.packets = list(packets) self.pos = 0 + self.chunks = [] def tell(self): return self.pos @@ -43,6 +44,7 @@ if len(data) > n: data, rest = data[:n], data[n:] self.packets.insert(0, rest) + self.chunks.append((n, len(data), self.pos)) self.pos += len(data) return data @@ -121,6 +123,7 @@ def makeStream(self, tell=False, seek=False, bufsize=None): base = TSource(self.packets) + self.source = base def f(*args): raise NotImplementedError if not tell: @@ -316,6 +319,14 @@ rest = file.readall() assert rest == all[seekto:] +class TestBufferedRead(TestBufferingInputStreamTests): + def test_dont_read_small(self): + import sys + file = self.makeStream(bufsize=4) + while file.read(1): pass + for want, got, pos in self.source.chunks: + assert want >= 4 + class TestBufferingOutputStream: def test_write(self): @@ -428,6 +439,8 @@ print "can't remove %s: %s" % (tfn, msg) def makeStream(self, tell=None, seek=None, bufsize=None, mode="r"): + mmapmode = 0 + filemode = 0 import mmap if "r" in mode: mmapmode = mmap.ACCESS_READ @@ -710,7 +723,7 @@ f = opener(fn, "r") lines = bytes = 0 t0 = time.clock() - for line in f: + for line in iter(f.readline, ""): lines += 1 bytes += len(line) t1 = time.clock() @@ -719,19 +732,29 @@ def speed_main(): def diskopen(fn, mode): - base = sio.DiskFile(fn, mode) + filemode = 0 + import mmap + if "r" in mode: + filemode = os.O_RDONLY + if "w" in mode: + filemode |= os.O_WRONLY + + fd = os.open(fn, filemode) + base = sio.DiskFile(fd) return sio.BufferingInputStream(base) + def mmapopen(fn, mode): + mmapmode = 0 + filemode = 0 + import mmap + if "r" in mode: + mmapmode = mmap.ACCESS_READ + filemode = os.O_RDONLY + if "w" in mode: + mmapmode |= mmap.ACCESS_WRITE + filemode |= os.O_WRONLY + fd = os.open(fn, filemode) + return sio.MMapFile(fd, mmapmode) timeit(opener=diskopen) - timeit(opener=sio.MMapFile) + timeit(opener=mmapopen) timeit(opener=open) -# Functional test - -def functional_main(): - f = sio.DiskFile("sio.py") - f = sio.DecodingInputFilter(f) - f = sio.TextInputFilter(f) - f = sio.BufferingInputStream(f) - for i in range(10): - print repr(f.readline()) - From tismer at codespeak.net Sun Jun 4 19:13:25 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 4 Jun 2006 19:13:25 +0200 (CEST) Subject: [pypy-svn] r28284 - in pypy/dist/pypy: interpreter interpreter/test module/_pickle_support Message-ID: <20060604171325.226331006F@code0.codespeak.net> Author: tismer Date: Sun Jun 4 19:13:24 2006 New Revision: 28284 Modified: pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/test/test_pickle.py pypy/dist/pypy/interpreter/typedef.py pypy/dist/pypy/module/_pickle_support/maker.py Log: partially working frame pickling. missing is pickling of blockstack and correct handling of closures Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Sun Jun 4 19:13:24 2006 @@ -69,6 +69,7 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule + from pypy.module._pickle_support import maker # helper fns w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('frame_new') @@ -79,34 +80,71 @@ else: f_lineno = self.f_lineno - valuestack = [w(item) for item in self.valuestack.items] - blockstack = [w(item) for item in self.blockstack.items] - - tup = [ +# valuestack = [w(item) for item in self.valuestack.items] + # blockstack = [w(item) for item in self.blockstack.items] + w_valuestack = maker.slp_into_tuple_with_nulls(space, self.valuestack.items) + w_blockstack = space.w_None ## + w_fastlocals = maker.slp_into_tuple_with_nulls(space, self.fastlocals_w) + tup_base = [ + w(self.pycode), + ] + tup_state = [ w(self.f_back), w(self.builtin), w(self.pycode), - space.w_None, #space.newtuple(valuestack), #XXX causes AttributeError: 'NoneType' object has no attribute 'getclass' - space.w_None, #space.newtuple(blockstack), - w(self.last_exception), #f_exc_traceback, f_exc_type, f_exc_value + w_valuestack, + space.w_None, ## w_blockstack, + space.w_None, ## w(self.last_exception), #f_exc_traceback, f_exc_type, f_exc_value self.w_globals, w(self.last_instr), - w(self.next_instr), #not in PyFrame.typedef! - w(f_lineno), #why not w(self.f_lineno)? something with self.w_f_trace? - - #space.newtuple(self.fastlocals_w), #XXX (application-level) PicklingError: Can't pickle : it's not found as __builtin__.AppTestInterpObjectPickling - #self.getdictscope(), #XXX (application-level) PicklingError: Can't pickle : it's not found as __builtin__.AppTestInterpObjectPickling + w(self.next_instr), + w(f_lineno), + w_fastlocals, space.w_None, #XXX placeholder for f_locals #f_restricted requires no additional data! - self.w_f_trace, + space.w_None, ## self.w_f_trace, ignore for now w(self.instr_lb), #do we need these three (that are for tracing) w(self.instr_ub), w(self.instr_prev), ] - return space.newtuple([new_inst, space.newtuple(tup)]) + return space.newtuple([new_inst, space.newtuple(tup_base), space.newtuple(tup_state)]) + + def descr__setstate__(self, space, w_args): + from pypy.module._pickle_support import maker # helper fns + args_w = space.unpackiterable(w_args) + w_f_back, w_builtin, w_pycode, w_valuestack, w_blockstack, w_last_exception,\ + w_globals, w_last_instr, w_next_instr, w_f_lineno, w_fastlocals, w_f_locals, \ + w_f_trace, w_instr_lb, w_instr_ub, w_instr_prev = args_w + w = space.wrap + u = space.unwrap + + #new_frame = PyFrame(space, pycode, w(globals), None) + # let the code object create the right kind of frame + # the distinction is a little over-done but computable + new_frame = self + pycode = space.unwrap(w_pycode) + new_frame.__init__(space, pycode, w_globals, None) + new_frame.f_back = u(w_f_back) + new_frame.builtin = u(w_builtin) + #new_frame.blockstack = blockstack + new_frame.valuestack.items = maker.slp_from_tuple_with_nulls(space, w_valuestack) + new_frame.last_exception = u(w_last_exception) + new_frame.last_instr = space.int_w(w_last_instr) + new_frame.next_instr = space.int_w(w_next_instr) + new_frame.f_lineno = space.int_w(w_f_lineno) + new_frame.fastlocals_w = maker.slp_from_tuple_with_nulls(space, w_fastlocals) + + if space.is_w(w_f_trace, space.w_None): + new_frame.w_f_trace = None + else: + new_frame.w_f_trace = w_f_trace + + new_frame.instr_lb = space.int_w(w_instr_lb) #the three for tracing + new_frame.instr_ub = space.int_w(w_instr_ub) + new_frame.instr_prev = space.int_w(w_instr_prev) def hide(self): return self.pycode.hidden_applevel Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Sun Jun 4 19:13:24 2006 @@ -95,18 +95,8 @@ assert f1.f_exc_traceback is f2.f_exc_traceback assert f1.f_exc_type is f2.f_exc_type assert f1.f_exc_value is f2.f_exc_value - - #print 'f1.f_globals =', f1.f_globals #f1.f_globals = {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } - #print 'f2.f_globals=', f2.f_globals #f2.f_globals= {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } - #assert f1.f_globals == f2.f_globals #XXX test_pickle_frame function not same identity (see pickle func tests, we don't compare by identity there!)? - assert f1.f_lasti == f2.f_lasti assert f1.f_lineno == f2.f_lineno - - #print 'f1.f_locals=', f1.f_locals #['exc_info', 'tb', 'exc_type', 'exc'] - #print 'f2.f_locals=', f2.f_locals #[] - #assert list(f1.f_locals) == list(f2.f_locals) - assert f1.f_restricted is f2.f_restricted assert f1.f_trace is f2.f_trace @@ -302,44 +292,24 @@ assert list(result) == [2,3,4] def test_pickle_generator(self): - import pickle - def giveme(n): - x = 0 - while x < n: - yield x - g1 = giveme(10) - #print 'g1=', g1, dir(g1) - pckl = pickle.dumps(g1) - g2 = pickle.loads(pckl) - #print 'g2=', g2, dir(g2) - - assert type(g1) is type(g2) - assert g1.gi_running == g2.gi_running - #assert g1.gi_exhausted == g2.gi_exhausted #not exported! - - #XXX silly code duplication from frame pickling test - f1 = g1.gi_frame - f2 = g2.gi_frame - assert type(f1) is type(f2) - assert dir(f1) == dir(f2) - assert f1.__doc__ == f2.__doc__ - assert type(f1.f_back) is type(f2.f_back) - assert f1.f_builtins is f2.f_builtins - assert f1.f_code == f2.f_code - assert f1.f_exc_traceback is f2.f_exc_traceback - assert f1.f_exc_type is f2.f_exc_type - assert f1.f_exc_value is f2.f_exc_value - - #print 'f1.f_globals =', f1.f_globals #f1.f_globals = {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } - #print 'f2.f_globals=', f2.f_globals #f2.f_globals= {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } - #assert f1.f_globals == f2.f_globals #XXX test_pickle_frame function not same identity (see pickle func tests, we don't compare by identity there!)? - - assert f1.f_lasti == f2.f_lasti - assert f1.f_lineno == f2.f_lineno - - #print 'f1.f_locals=', f1.f_locals #['exc_info', 'tb', 'exc_type', 'exc'] - #print 'f2.f_locals=', f2.f_locals #[] - #assert list(f1.f_locals) == list(f2.f_locals) - - assert f1.f_restricted is f2.f_restricted - assert f1.f_trace is f2.f_trace + import new + mod = new.module('mod') + import sys + sys.modules['mod'] = mod + try: + def giveme(n): + x = 0 + while x < n: + yield x + x += 1 + import pickle + mod.giveme = giveme + giveme.__module__ = mod + g1 = mod.giveme(10) + #g1.next() + #g1.next() + pckl = pickle.dumps(g1) + g2 = pickle.loads(pckl) + assert list(g1) == list(g2) + finally: + del sys.modules['mod'] Modified: pypy/dist/pypy/interpreter/typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/typedef.py (original) +++ pypy/dist/pypy/interpreter/typedef.py Sun Jun 4 19:13:24 2006 @@ -521,8 +521,10 @@ ) PyFrame.typedef = TypeDef('frame', - #__reduce__ = interp2app(PyFrame.descr__reduce__, - # unwrap_spec=['self', ObjSpace]), + __reduce__ = interp2app(PyFrame.descr__reduce__, + unwrap_spec=['self', ObjSpace]), + __setstate__ = interp2app(PyFrame.descr__setstate__, + unwrap_spec=['self', ObjSpace, W_Root]), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), f_back = GetSetProperty(PyFrame.fget_f_back), @@ -623,8 +625,8 @@ del BuiltinFunction.typedef.rawdict['__get__'] PyTraceback.typedef = TypeDef("traceback", - #__reduce__ = interp2app(PyTraceback.descr__reduce__, - # unwrap_spec=['self', ObjSpace]), + __reduce__ = interp2app(PyTraceback.descr__reduce__, + unwrap_spec=['self', ObjSpace]), tb_frame = interp_attrproperty('frame', cls=PyTraceback), tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = interp_attrproperty('lineno', cls=PyTraceback), @@ -632,8 +634,8 @@ ) GeneratorIterator.typedef = TypeDef("generator", - #__reduce__ = interp2app(GeneratorIterator.descr__reduce__, - # unwrap_spec=['self', ObjSpace]), + __reduce__ = interp2app(GeneratorIterator.descr__reduce__, + unwrap_spec=['self', ObjSpace]), next = interp2app(GeneratorIterator.descr_next), __iter__ = interp2app(GeneratorIterator.descr__iter__), gi_running = interp_attrproperty('running', cls=GeneratorIterator), Modified: pypy/dist/pypy/module/_pickle_support/maker.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/maker.py (original) +++ pypy/dist/pypy/module/_pickle_support/maker.py Sun Jun 4 19:13:24 2006 @@ -53,52 +53,66 @@ return W_ReverseSeqIterObject(space, w_seq, index) def frame_new(space, __args__): - return None -## args_w, kwds_w = __args__.unpack() #stolen from std/fake.py -## args = [space.unwrap(w_arg) for w_arg in args_w] -## f_back, builtin, pycode, valuestack, blockstack, last_exception,\ -## globals, last_instr, next_instr, f_lineno, fastlocals, f_trace,\ -## instr_lb, instr_ub, instr_prev = args -## w = space.wrap - -## new_frame = PyFrame(space, pycode, w(globals), None) -## new_frame.f_back = f_back -## new_frame.builtin = builtin -## #new_frame.blockstack = blockstack -## #new_frame.valuestack = valuestack -## new_frame.last_exception = last_exception -## new_frame.last_instr = last_instr -## new_frame.next_instr = next_instr -## new_frame.f_lineno = f_lineno -## #new_frame.fastlocals_w = w(fastlocals) - -## if space.is_w(f_trace, space.w_None): -## new_frame.w_f_trace = None -## else: -## new_frame.w_f_trace = w(f_trace) - -## new_frame.instr_lb = instr_lb #the three for tracing -## new_frame.instr_ub = instr_ub -## new_frame.instr_prev = instr_prev - -## return space.wrap(new_frame) + args_w, kwds_w = __args__.unpack() #stolen from std/fake.py + w_pycode, = args_w + pycode = space.interp_w(PyCode, w_pycode) + w = space.wrap + + # let the code object create the right kind of frame + # the distinction is a littleover-done but computable + Klass = pycode.get_frame_class() + new_frame = instantiate(Klass) + return space.wrap(new_frame) frame_new.unwrap_spec = [ObjSpace, Arguments] def traceback_new(space, __args__): - return None -## args_w, kwds_w = __args__.unpack() #stolen from std/fake.py -## args = [space.unwrap(w_arg) for w_arg in args_w] -## frame, lasti, lineno, next = args -## return PyTraceback(space, frame, lasti, lineno, next) + args_w, kwds_w = __args__.unpack() #stolen from std/fake.py + w_frame, w_lasti, w_lineno, w_next = args_w + frame = space.interp_w(PyFrame, w_frame) + lasti = space.int_w(w_lasti) + lineno = space.int_w(w_lineno) + next = space.interp_w(PyTraceback, w_next, can_be_None=True) + return space.wrap(PyTraceback(space, frame, lasti, lineno, next)) traceback_new.unwrap_spec = [ObjSpace, Arguments] def generator_new(space, __args__): - return None -## args_w, kwds_w = __args__.unpack() #stolen from std/fake.py -## args = [space.unwrap(w_arg) for w_arg in args_w] -## frame, running, exhausted = args -## new_generator = GeneratorIterator(frame) -## new_generator.running = running -## new_generator.exhausted = exhausted -## return new_generator + args_w, kwds_w = __args__.unpack() #stolen from std/fake.py + w_frame, w_running, w_exhausted = args_w + frame = space.interp_w(PyFrame, w_frame) + running = space.int_w(w_running) + exhausted = space.int_w(w_exhausted) + new_generator = GeneratorIterator(frame) + new_generator.running = running + new_generator.exhausted = exhausted + return space.wrap(new_generator) generator_new.unwrap_spec = [ObjSpace, Arguments] + +# ___________________________________________________________________ +# Helper functions for internal use + +# adopted from prickelpit.c (but almost completely different) + +def slp_into_tuple_with_nulls(space, seq_w): + """ + create a tuple with the object and store + a tuple with the positions of NULLs as first element. + """ + nulls = [] + tup = [space.w_None] + w = space.wrap + + for w_obj in seq_w: + if w_obj is None: + nulls.append(w(len(tup)-1)) + w_obj = space.w_None + tup.append(w_obj) + tup[0] = space.newtuple(nulls) + return space.newtuple(tup) + +def slp_from_tuple_with_nulls(space, w_tup): + tup_w = space.unpackiterable(w_tup) + nulls = space.unpackiterable(tup_w.pop(0)) + for w_p in nulls: + p = space.int_w(w_p) + tup_w[p] = None + return tup_w \ No newline at end of file From ale at codespeak.net Sun Jun 4 19:14:39 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Sun, 4 Jun 2006 19:14:39 +0200 (CEST) Subject: [pypy-svn] r28285 - pypy/dist/pypy/objspace/std Message-ID: <20060604171439.C92841006F@code0.codespeak.net> Author: ale Date: Sun Jun 4 19:14:38 2006 New Revision: 28285 Modified: pypy/dist/pypy/objspace/std/complextype.py Log: Complextype needs __getnewargs__ for pickling with protocol 2 ? Modified: pypy/dist/pypy/objspace/std/complextype.py ============================================================================== --- pypy/dist/pypy/objspace/std/complextype.py (original) +++ pypy/dist/pypy/objspace/std/complextype.py Sun Jun 4 19:14:38 2006 @@ -222,13 +222,19 @@ space.wrap("descriptor is for 'complex'")) return space.newfloat(getattr(w_obj, name)) return GetSetProperty(fget) - + +def descr___getnewargs__(space, w_self): + from pypy.objspace.std.complexobject import W_ComplexObject + assert isinstance(w_self, W_ComplexObject) + return space.newtuple([space.newcomplex(w_self.realval,w_self.imagval)]) + complex_typedef = StdTypeDef("complex", __doc__ = """complex(real[, imag]) -> complex number Create a complex number from a real part and an optional imaginary part. This is equivalent to (real + imag*1j) where imag defaults to 0.""", __new__ = newmethod(descr__new__), + __getnewargs__ = newmethod(descr___getnewargs__), real = complexwprop('realval'), imag = complexwprop('imagval'), ) From mwh at codespeak.net Sun Jun 4 19:41:50 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Jun 2006 19:41:50 +0200 (CEST) Subject: [pypy-svn] r28286 - in pypy/dist/pypy/interpreter: . test Message-ID: <20060604174150.F2D541006F@code0.codespeak.net> Author: mwh Date: Sun Jun 4 19:41:49 2006 New Revision: 28286 Modified: pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/test/test_pickle.py Log: (mwh, pedronis, tismer) most unwrap removal Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Sun Jun 4 19:41:49 2006 @@ -114,24 +114,25 @@ def descr__setstate__(self, space, w_args): from pypy.module._pickle_support import maker # helper fns + from pypy.interpreter.pycode import PyCode + from pypy.interpreter.module import Module args_w = space.unpackiterable(w_args) w_f_back, w_builtin, w_pycode, w_valuestack, w_blockstack, w_last_exception,\ w_globals, w_last_instr, w_next_instr, w_f_lineno, w_fastlocals, w_f_locals, \ w_f_trace, w_instr_lb, w_instr_ub, w_instr_prev = args_w w = space.wrap - u = space.unwrap #new_frame = PyFrame(space, pycode, w(globals), None) # let the code object create the right kind of frame # the distinction is a little over-done but computable new_frame = self - pycode = space.unwrap(w_pycode) + pycode = space.interp_w(PyCode, w_pycode) new_frame.__init__(space, pycode, w_globals, None) - new_frame.f_back = u(w_f_back) - new_frame.builtin = u(w_builtin) + new_frame.f_back = space.interp_w(PyFrame, w_f_back, can_be_None=True) + new_frame.builtin = space.interp_w(Module, w_builtin) #new_frame.blockstack = blockstack new_frame.valuestack.items = maker.slp_from_tuple_with_nulls(space, w_valuestack) - new_frame.last_exception = u(w_last_exception) + new_frame.last_exception = None#XXX (w_last_exception) new_frame.last_instr = space.int_w(w_last_instr) new_frame.next_instr = space.int_w(w_next_instr) new_frame.f_lineno = space.int_w(w_f_lineno) Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Sun Jun 4 19:41:49 2006 @@ -74,6 +74,7 @@ assert not (cell != result) def test_pickle_frame(self): + skip("in-progress") from sys import exc_info def f(): try: @@ -101,6 +102,7 @@ assert f1.f_trace is f2.f_trace def test_pickle_traceback(self): + skip("in-progress") def f(): try: raise Exception() From mwh at codespeak.net Mon Jun 5 11:18:16 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 5 Jun 2006 11:18:16 +0200 (CEST) Subject: [pypy-svn] r28305 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20060605091816.204AA10053@code0.codespeak.net> Author: mwh Date: Mon Jun 5 11:18:15 2006 New Revision: 28305 Added: pypy/dist/lib-python/modified-2.4.1/test/test_traceback.py - copied, changed from r28303, pypy/dist/lib-python/2.4.1/test/test_traceback.py Log: remove test_nocaret from test_traceback, it's testing that an error message cpython produces in a certain situations sucks. bah! From pedronis at codespeak.net Mon Jun 5 11:30:42 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 5 Jun 2006 11:30:42 +0200 (CEST) Subject: [pypy-svn] r28306 - pypy/dist/pypy/interpreter/test Message-ID: <20060605093042.2C8FB10053@code0.codespeak.net> Author: pedronis Date: Mon Jun 5 11:30:41 2006 New Revision: 28306 Modified: pypy/dist/pypy/interpreter/test/test_pickle.py Log: hide top frame helpers for test_pickle_frame Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Mon Jun 5 11:30:41 2006 @@ -1,5 +1,44 @@ +def _attach_helpers(space): + def hide_top_frame(space, w_frame): + w_last = None + while w_frame.f_back: + w_last = w_frame + w_frame = w_frame.f_back + assert w_last + w_saved = w_last.f_back + w_last.f_back = None + return w_saved + + def restore_top_frame(space, w_frame, w_saved): + while w_frame.f_back: + w_frame = w_frame.f_back + w_frame.f_back = w_saved + + from pypy.interpreter import gateway + + hide_gw = gateway.interp2app(hide_top_frame) + space.setitem(space.builtin.w_dict, + space.wrap('hide_top_frame'), + space.wrap(hide_gw)) + restore_gw = gateway.interp2app(restore_top_frame) + space.setitem(space.builtin.w_dict, + space.wrap('restore_top_frame'), + space.wrap(restore_gw)) + +def _detatch_helpers(space): + space.delitem(space.builtin.w_dict, + space.wrap('hide_top_frame')) + space.delitem(space.builtin.w_dict, + space.wrap('restore_top_frame')) + class AppTestInterpObjectPickling: + def setup_class(cls): + _attach_helpers(cls.space) + + def teardown_class(cls): + _detatch_helpers(cls.space) + def test_pickle_code(self): def f(): return 42 @@ -84,7 +123,9 @@ return tb.tb_frame import pickle f1 = f() + saved = hide_top_frame(f1) pckl = pickle.dumps(f1) + restore_top_frame(f1, saved) f2 = pickle.loads(pckl) assert type(f1) is type(f2) From hpk at codespeak.net Mon Jun 5 11:31:33 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Jun 2006 11:31:33 +0200 (CEST) Subject: [pypy-svn] r28307 - pypy/dist/pypy/rpython/rctypes/tool Message-ID: <20060605093133.D205910069@code0.codespeak.net> Author: hpk Date: Mon Jun 5 11:31:33 2006 New Revision: 28307 Modified: pypy/dist/pypy/rpython/rctypes/tool/util.py Log: add a load library helper Modified: pypy/dist/pypy/rpython/rctypes/tool/util.py ============================================================================== --- pypy/dist/pypy/rpython/rctypes/tool/util.py (original) +++ pypy/dist/pypy/rpython/rctypes/tool/util.py Mon Jun 5 11:31:33 2006 @@ -90,6 +90,12 @@ return None return _get_soname(lib) +if "load" in dir(ctypes.cdll): + load_library = ctypes.cdll.load +else: + load_library = ctypes.cdll.LoadLibrary + + ################################################################ # test code From hpk at codespeak.net Mon Jun 5 11:36:27 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Jun 2006 11:36:27 +0200 (CEST) Subject: [pypy-svn] r28308 - in pypy/dist: lib-python pypy/module/crypt pypy/module/crypt/test Message-ID: <20060605093627.B795310050@code0.codespeak.net> Author: hpk Date: Mon Jun 5 11:36:27 2006 New Revision: 28308 Added: pypy/dist/pypy/module/crypt/ pypy/dist/pypy/module/crypt/__init__.py (contents, props changed) pypy/dist/pypy/module/crypt/interp_crypt.py (contents, props changed) pypy/dist/pypy/module/crypt/test/ pypy/dist/pypy/module/crypt/test/__init__.py (contents, props changed) pypy/dist/pypy/module/crypt/test/test_crypt.py (contents, props changed) Modified: pypy/dist/lib-python/conftest.py Log: add a ctypes based crypt module, passes compliancy tests (yeah, it's a simple module, admittedly :) Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Mon Jun 5 11:36:27 2006 @@ -458,7 +458,7 @@ RegrTest('test_copy.py', enabled=True, core=True), RegrTest('test_copy_reg.py', enabled=True, core=True), RegrTest('test_cpickle.py', enabled=True, core=True), - RegrTest('test_crypt.py', enabled=False, dumbtest=1), + RegrTest('test_crypt.py', usemodules='crypt', enabled=False, dumbtest=1), RegrTest('test_csv.py', enabled=False), #rev 10840: ImportError: _csv Added: pypy/dist/pypy/module/crypt/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/crypt/__init__.py Mon Jun 5 11:36:27 2006 @@ -0,0 +1,11 @@ +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + """A demo built-in module based on ctypes.""" + + interpleveldefs = { + 'crypt' : 'interp_crypt.crypt', + } + + appleveldefs = { + } Added: pypy/dist/pypy/module/crypt/interp_crypt.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/crypt/interp_crypt.py Mon Jun 5 11:36:27 2006 @@ -0,0 +1,30 @@ +from pypy.interpreter.error import OperationError +from pypy.interpreter.baseobjspace import ObjSpace, W_Root +from pypy.rpython.rctypes.tool import ctypes_platform +from pypy.rpython.rctypes.tool.clib import clib +from pypy.rpython.rctypes.tool.util import find_library, load_library + +import sys +from ctypes import * + +class CConfig: + _header_ = """#include +""" + +cryptfn = find_library("crypt") +cryptdll = load_library(cryptfn) + +c_crypt = cryptdll.crypt +c_crypt.argtypes = [c_char_p, c_char_p] +c_crypt.restype = c_char_p + +def crypt(space, word, salt): + """word will usually be a user's password. salt is a 2-character string + which will be used to select one of 4096 variations of DES. The characters + in salt must be either ".", "/", or an alphanumeric character. Returns + the hashed password as a string, which will be composed of characters from + the same alphabet as the salt.""" + res = c_crypt(word, salt) + return space.wrap(res) + +crypt.unwrap_spec = [ObjSpace, str, str] Added: pypy/dist/pypy/module/crypt/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/crypt/test/__init__.py Mon Jun 5 11:36:27 2006 @@ -0,0 +1 @@ +# Added: pypy/dist/pypy/module/crypt/test/test_crypt.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/crypt/test/test_crypt.py Mon Jun 5 11:36:27 2006 @@ -0,0 +1,11 @@ +from pypy.objspace.std import StdObjSpace + +class AppTestCrypt: + def setup_class(cls): + cls.space = StdObjSpace(usemodules=['crypt']) + def test_crypt(self): + import crypt + res = crypt.crypt("pass", "ab") + assert isinstance(res, str) + assert res + From tismer at codespeak.net Mon Jun 5 11:40:36 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 5 Jun 2006 11:40:36 +0200 (CEST) Subject: [pypy-svn] r28310 - pypy/dist/pypy/interpreter/test Message-ID: <20060605094036.5C0CB10050@code0.codespeak.net> Author: tismer Date: Mon Jun 5 11:40:35 2006 New Revision: 28310 Modified: pypy/dist/pypy/interpreter/test/test_pickle.py Log: changed test case for the frame hiding patch Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Mon Jun 5 11:40:35 2006 @@ -113,13 +113,14 @@ assert not (cell != result) def test_pickle_frame(self): - skip("in-progress") - from sys import exc_info + #import sys + # avoid creating a closure for now def f(): try: raise Exception() except: - exc_type, exc, tb = exc_info() + import sys + exc_type, exc, tb = sys.exc_info() return tb.tb_frame import pickle f1 = f() @@ -131,7 +132,7 @@ assert type(f1) is type(f2) assert dir(f1) == dir(f2) assert f1.__doc__ == f2.__doc__ - assert type(f1.f_back) is type(f2.f_back) + assert f2.f_back is None # mecause we pruned it assert f1.f_builtins is f2.f_builtins assert f1.f_code == f2.f_code assert f1.f_exc_traceback is f2.f_exc_traceback From hpk at codespeak.net Mon Jun 5 12:01:41 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Jun 2006 12:01:41 +0200 (CEST) Subject: [pypy-svn] r28311 - pypy/dist/pypy/objspace/cpy Message-ID: <20060605100141.5FF7B10053@code0.codespeak.net> Author: hpk Date: Mon Jun 5 12:01:40 2006 New Revision: 28311 Added: pypy/dist/pypy/objspace/cpy/wrappable.py (contents, props changed) Log: restored the wrappable.reraise function (part of the removal in rev 27237). it is still used by compilemodule. Added: pypy/dist/pypy/objspace/cpy/wrappable.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/cpy/wrappable.py Mon Jun 5 12:01:40 2006 @@ -0,0 +1,20 @@ +""" +Support to turn interpreter objects (subclasses of Wrappable) +into CPython objects (subclasses of W_Object). +""" + +from pypy.objspace.cpy.capi import * +from pypy.objspace.cpy.refcount import Py_XIncref + +def reraise(e): + w_type = e.w_type + w_value = e.w_value + w_traceback = e.application_traceback + if e.application_traceback is None: + w_traceback = W_Object() # NULL + else: + Py_XIncref(w_traceback) + Py_XIncref(w_type) + Py_XIncref(w_value) + RAW_PyErr_Restore(e.w_type, e.w_value, w_traceback) + From pedronis at codespeak.net Mon Jun 5 12:01:57 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 5 Jun 2006 12:01:57 +0200 (CEST) Subject: [pypy-svn] r28312 - pypy/dist/pypy/interpreter/test Message-ID: <20060605100157.ABEC110069@code0.codespeak.net> Author: pedronis Date: Mon Jun 5 12:01:56 2006 New Revision: 28312 Modified: pypy/dist/pypy/interpreter/test/test_pickle.py Log: now test pickle traceback fails with a recursion problem Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Mon Jun 5 12:01:56 2006 @@ -1,4 +1,5 @@ def _attach_helpers(space): + from pypy.interpreter import pytraceback def hide_top_frame(space, w_frame): w_last = None while w_frame.f_back: @@ -132,7 +133,7 @@ assert type(f1) is type(f2) assert dir(f1) == dir(f2) assert f1.__doc__ == f2.__doc__ - assert f2.f_back is None # mecause we pruned it + assert f2.f_back is None # because we pruned it assert f1.f_builtins is f2.f_builtins assert f1.f_code == f2.f_code assert f1.f_exc_traceback is f2.f_exc_traceback @@ -144,7 +145,7 @@ assert f1.f_trace is f2.f_trace def test_pickle_traceback(self): - skip("in-progress") + skip("in-progress: recursion problem") def f(): try: raise Exception() @@ -154,6 +155,7 @@ return tb import pickle tb = f() + saved = hide_top_frame(tb.tb_frame) pckl = pickle.dumps(tb) result = pickle.loads(pckl) @@ -189,6 +191,8 @@ assert f1.f_restricted is f2.f_restricted assert f1.f_trace is f2.f_trace + restore_top_frame(tb.tb_frame, saved) + def test_pickle_module(self): import pickle mod = pickle From hpk at codespeak.net Mon Jun 5 12:05:13 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Jun 2006 12:05:13 +0200 (CEST) Subject: [pypy-svn] r28314 - pypy/dist/pypy/module/crypt Message-ID: <20060605100513.BA69610053@code0.codespeak.net> Author: hpk Date: Mon Jun 5 12:05:13 2006 New Revision: 28314 Modified: pypy/dist/pypy/module/crypt/interp_crypt.py Log: aehem, remove unused and wrong line Modified: pypy/dist/pypy/module/crypt/interp_crypt.py ============================================================================== --- pypy/dist/pypy/module/crypt/interp_crypt.py (original) +++ pypy/dist/pypy/module/crypt/interp_crypt.py Mon Jun 5 12:05:13 2006 @@ -1,7 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.rpython.rctypes.tool import ctypes_platform -from pypy.rpython.rctypes.tool.clib import clib from pypy.rpython.rctypes.tool.util import find_library, load_library import sys From hpk at codespeak.net Mon Jun 5 12:12:25 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Jun 2006 12:12:25 +0200 (CEST) Subject: [pypy-svn] r28315 - in pypy/dist/pypy: objspace/cpy rpython/rctypes/tool Message-ID: <20060605101225.5D99A10053@code0.codespeak.net> Author: hpk Date: Mon Jun 5 12:12:24 2006 New Revision: 28315 Removed: pypy/dist/pypy/objspace/cpy/wrappable.py Modified: pypy/dist/pypy/rpython/rctypes/tool/compilemodule.py Log: okok, reraise was moved to function.py, don't know why i didn't find it before. Modified: pypy/dist/pypy/rpython/rctypes/tool/compilemodule.py ============================================================================== --- pypy/dist/pypy/rpython/rctypes/tool/compilemodule.py (original) +++ pypy/dist/pypy/rpython/rctypes/tool/compilemodule.py Mon Jun 5 12:12:24 2006 @@ -13,7 +13,7 @@ "Compile a PyPy module for CPython." import pypy.rpython.rctypes.implementation from pypy.objspace.cpy.objspace import CPyObjSpace - from pypy.objspace.cpy.wrappable import reraise + from pypy.objspace.cpy.function import reraise from pypy.objspace.cpy.ann_policy import CPyAnnotatorPolicy from pypy.translator.driver import TranslationDriver from pypy.interpreter.error import OperationError From hpk at codespeak.net Mon Jun 5 12:12:51 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Jun 2006 12:12:51 +0200 (CEST) Subject: [pypy-svn] r28316 - pypy/dist/pypy/objspace/cpy Message-ID: <20060605101251.A976010053@code0.codespeak.net> Author: hpk Date: Mon Jun 5 12:12:51 2006 New Revision: 28316 Modified: pypy/dist/pypy/objspace/cpy/function.py Log: add string unwrapping (thanks michael) Modified: pypy/dist/pypy/objspace/cpy/function.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/function.py (original) +++ pypy/dist/pypy/objspace/cpy/function.py Mon Jun 5 12:12:51 2006 @@ -30,7 +30,7 @@ def visit__object(self, el, orig_sig, tramp): convertermap = {int: '___PyInt_AsLong', - str: 'XXX', + str: '___PyString_AsString', float: 'XXX'} argname = orig_sig.next_arg() assert not argname.startswith('w_') @@ -102,6 +102,7 @@ '___space': space, '___W_Object': CPyObjSpace.W_Object, '___PyInt_AsLong': PyInt_AsLong, + '___PyString_AsString': PyString_AsString, '___bltin': bltin, '___OperationError': OperationError, '___reraise': reraise, From tismer at codespeak.net Mon Jun 5 12:15:46 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 5 Jun 2006 12:15:46 +0200 (CEST) Subject: [pypy-svn] r28318 - in pypy/dist/pypy/interpreter: . test Message-ID: <20060605101546.C52F710053@code0.codespeak.net> Author: tismer Date: Mon Jun 5 12:15:46 2006 New Revision: 28318 Modified: pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/test/test_pickle.py Log: added support for nested scopes Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Mon Jun 5 12:15:46 2006 @@ -70,18 +70,22 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule from pypy.module._pickle_support import maker # helper fns + from pypy.interpreter.nestedscope import PyNestedScopeFrame w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('frame_new') w = space.wrap + if isinstance(self, PyNestedScopeFrame): + w_cells = w([w(cell) for cell in self.cells]) + else: + w_cells = space.w_None + if self.w_f_trace is None: f_lineno = self.get_last_lineno() else: f_lineno = self.f_lineno -# valuestack = [w(item) for item in self.valuestack.items] - # blockstack = [w(item) for item in self.blockstack.items] w_valuestack = maker.slp_into_tuple_with_nulls(space, self.valuestack.items) w_blockstack = space.w_None ## w_fastlocals = maker.slp_into_tuple_with_nulls(space, self.fastlocals_w) @@ -108,6 +112,7 @@ w(self.instr_lb), #do we need these three (that are for tracing) w(self.instr_ub), w(self.instr_prev), + w_cells, ] return space.newtuple([new_inst, space.newtuple(tup_base), space.newtuple(tup_state)]) @@ -116,10 +121,11 @@ from pypy.module._pickle_support import maker # helper fns from pypy.interpreter.pycode import PyCode from pypy.interpreter.module import Module + from pypy.interpreter.nestedscope import PyNestedScopeFrame, Cell args_w = space.unpackiterable(w_args) w_f_back, w_builtin, w_pycode, w_valuestack, w_blockstack, w_last_exception,\ w_globals, w_last_instr, w_next_instr, w_f_lineno, w_fastlocals, w_f_locals, \ - w_f_trace, w_instr_lb, w_instr_ub, w_instr_prev = args_w + w_f_trace, w_instr_lb, w_instr_ub, w_instr_prev, w_cells = args_w w = space.wrap #new_frame = PyFrame(space, pycode, w(globals), None) @@ -127,7 +133,9 @@ # the distinction is a little over-done but computable new_frame = self pycode = space.interp_w(PyCode, w_pycode) - new_frame.__init__(space, pycode, w_globals, None) + # do not use the instance's __init__ but the base's, because we set + # everything like cells from here + PyFrame.__init__(self, space, pycode, w_globals, None) new_frame.f_back = space.interp_w(PyFrame, w_f_back, can_be_None=True) new_frame.builtin = space.interp_w(Module, w_builtin) #new_frame.blockstack = blockstack @@ -147,6 +155,10 @@ new_frame.instr_ub = space.int_w(w_instr_ub) new_frame.instr_prev = space.int_w(w_instr_prev) + if isinstance(self, PyNestedScopeFrame): + cells_w = space.unpackiterable(w_cells) + self.cells = [space.interp_w(Cell, w_cell) for w_cell in cells_w] + def hide(self): return self.pycode.hidden_applevel Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Mon Jun 5 12:15:46 2006 @@ -144,6 +144,23 @@ assert f1.f_restricted is f2.f_restricted assert f1.f_trace is f2.f_trace + def test_pickle_frame_clos(self): + # similar to above, therefore skipping the asserts. + # we just want to see that the closure works + import sys # this is the difference! + def f(): + try: + raise Exception() + except: + exc_type, exc, tb = sys.exc_info() + return tb.tb_frame + import pickle + f1 = f() + saved = hide_top_frame(f1) + pckl = pickle.dumps(f1) + restore_top_frame(f1, saved) + f2 = pickle.loads(pckl) + def test_pickle_traceback(self): skip("in-progress: recursion problem") def f(): From hpk at codespeak.net Mon Jun 5 12:16:57 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Jun 2006 12:16:57 +0200 (CEST) Subject: [pypy-svn] r28319 - in pypy/dist/pypy/module: crypt time2 Message-ID: <20060605101657.75CE410053@code0.codespeak.net> Author: hpk Date: Mon Jun 5 12:16:57 2006 New Revision: 28319 Modified: pypy/dist/pypy/module/crypt/interp_crypt.py pypy/dist/pypy/module/time2/interp_time.py Log: fixes to modules to be become translatable (thanks again, michael) Modified: pypy/dist/pypy/module/crypt/interp_crypt.py ============================================================================== --- pypy/dist/pypy/module/crypt/interp_crypt.py (original) +++ pypy/dist/pypy/module/crypt/interp_crypt.py Mon Jun 5 12:16:57 2006 @@ -6,10 +6,6 @@ import sys from ctypes import * -class CConfig: - _header_ = """#include -""" - cryptfn = find_library("crypt") cryptdll = load_library(cryptfn) Modified: pypy/dist/pypy/module/time2/interp_time.py ============================================================================== --- pypy/dist/pypy/module/time2/interp_time.py (original) +++ pypy/dist/pypy/module/time2/interp_time.py Mon Jun 5 12:16:57 2006 @@ -1,7 +1,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.rpython.rctypes.tool import ctypes_platform -from pypy.rpython.rctypes.tool.clib import clib +from pypy.rpython.rctypes.tool.libc import libc import sys from ctypes import * @@ -18,7 +18,7 @@ clock_t = cconfig['clock_t'] CLOCKS_PER_SEC = cconfig['CLOCKS_PER_SEC'] -c_clock = clib.clock +c_clock = libc.clock c_clock.restype = clock_t def clock(space): From pedronis at codespeak.net Mon Jun 5 12:25:06 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 5 Jun 2006 12:25:06 +0200 (CEST) Subject: [pypy-svn] r28321 - pypy/dist/pypy/translator/backendopt/test Message-ID: <20060605102506.AFDF610053@code0.codespeak.net> Author: pedronis Date: Mon Jun 5 12:25:05 2006 New Revision: 28321 Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py Log: remove unused and now failing import Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_all.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_all.py Mon Jun 5 12:25:05 2006 @@ -113,8 +113,6 @@ entry_point_graph = graphof(t, entry_point) - from pypy.rpython.module.support import to_rstr - argv = t.rtyper.getrepr(inputtypes[0]).convert_const(['./pypy-c']) interp = LLInterpreter(t.rtyper) From tismer at codespeak.net Mon Jun 5 12:41:15 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 5 Jun 2006 12:41:15 +0200 (CEST) Subject: [pypy-svn] r28322 - in pypy/dist/pypy: interpreter interpreter/test module/_pickle_support Message-ID: <20060605104115.403C910053@code0.codespeak.net> Author: tismer Date: Mon Jun 5 12:41:14 2006 New Revision: 28322 Modified: pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/pytraceback.py pypy/dist/pypy/interpreter/test/test_pickle.py pypy/dist/pypy/interpreter/typedef.py pypy/dist/pypy/module/_pickle_support/maker.py Log: traceback pickling works now, using __setstate__ or course Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Mon Jun 5 12:41:14 2006 @@ -115,7 +115,8 @@ w_cells, ] - return space.newtuple([new_inst, space.newtuple(tup_base), space.newtuple(tup_state)]) + nt = space.newtuple + return nt([new_inst, nt(tup_base), nt(tup_state)]) def descr__setstate__(self, space, w_args): from pypy.module._pickle_support import maker # helper fns Modified: pypy/dist/pypy/interpreter/pytraceback.py ============================================================================== --- pypy/dist/pypy/interpreter/pytraceback.py (original) +++ pypy/dist/pypy/interpreter/pytraceback.py Mon Jun 5 12:41:14 2006 @@ -25,14 +25,24 @@ new_inst = mod.get('traceback_new') w = space.wrap - tup = [ + tup_base = [] + tup_state = [ w(self.frame), w(self.lasti), w(self.lineno), w(self.next), ] + nt = space.newtuple + return nt([new_inst, nt(tup_base), nt(tup_state)]) - return space.newtuple([new_inst, space.newtuple(tup)]) + def descr__setstate__(self, space, w_args): + from pypy.interpreter.pyframe import PyFrame + args_w = space.unpackiterable(w_args) + w_frame, w_lasti, w_lineno, w_next = args_w + self.frame = space.interp_w(PyFrame, w_frame) + self.lasti = space.int_w(w_lasti) + self.lineno = space.int_w(w_lineno) + self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Mon Jun 5 12:41:14 2006 @@ -162,7 +162,7 @@ f2 = pickle.loads(pckl) def test_pickle_traceback(self): - skip("in-progress: recursion problem") + #skip("in-progress: recursion problem") def f(): try: raise Exception() Modified: pypy/dist/pypy/interpreter/typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/typedef.py (original) +++ pypy/dist/pypy/interpreter/typedef.py Mon Jun 5 12:41:14 2006 @@ -627,6 +627,8 @@ PyTraceback.typedef = TypeDef("traceback", __reduce__ = interp2app(PyTraceback.descr__reduce__, unwrap_spec=['self', ObjSpace]), + __setstate__ = interp2app(PyTraceback.descr__setstate__, + unwrap_spec=['self', ObjSpace, W_Root]), tb_frame = interp_attrproperty('frame', cls=PyTraceback), tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = interp_attrproperty('lineno', cls=PyTraceback), Modified: pypy/dist/pypy/module/_pickle_support/maker.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/maker.py (original) +++ pypy/dist/pypy/module/_pickle_support/maker.py Mon Jun 5 12:41:14 2006 @@ -53,7 +53,7 @@ return W_ReverseSeqIterObject(space, w_seq, index) def frame_new(space, __args__): - args_w, kwds_w = __args__.unpack() #stolen from std/fake.py + args_w, kwds_w = __args__.unpack() w_pycode, = args_w pycode = space.interp_w(PyCode, w_pycode) w = space.wrap @@ -65,15 +65,10 @@ return space.wrap(new_frame) frame_new.unwrap_spec = [ObjSpace, Arguments] -def traceback_new(space, __args__): - args_w, kwds_w = __args__.unpack() #stolen from std/fake.py - w_frame, w_lasti, w_lineno, w_next = args_w - frame = space.interp_w(PyFrame, w_frame) - lasti = space.int_w(w_lasti) - lineno = space.int_w(w_lineno) - next = space.interp_w(PyTraceback, w_next, can_be_None=True) - return space.wrap(PyTraceback(space, frame, lasti, lineno, next)) -traceback_new.unwrap_spec = [ObjSpace, Arguments] +def traceback_new(space): + tb = instantiate(PyTraceback) + return space.wrap(tb) +traceback_new.unwrap_spec = [ObjSpace] def generator_new(space, __args__): args_w, kwds_w = __args__.unpack() #stolen from std/fake.py From ac at codespeak.net Mon Jun 5 12:53:46 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 5 Jun 2006 12:53:46 +0200 (CEST) Subject: [pypy-svn] r28323 - pypy/dist/pypy/rpython/lltypesystem Message-ID: <20060605105346.362EA10053@code0.codespeak.net> Author: ac Date: Mon Jun 5 12:53:45 2006 New Revision: 28323 Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py Log: Fix id() when run on memorysimulator. Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/llmemory.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py Mon Jun 5 12:53:45 2006 @@ -484,7 +484,8 @@ if ob is not None: self.ref = weakref.ref(ob) # umpf - if isinstance(ob, lltype._ptr): + from pypy.rpython.memory import lltypesimulation + if isinstance(ob, (lltype._ptr,lltypesimulation.simulatorptr)): self.id = ob._cast_to_int() else: self.id = id(ob) From mwh at codespeak.net Mon Jun 5 12:55:36 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 5 Jun 2006 12:55:36 +0200 (CEST) Subject: [pypy-svn] r28324 - pypy/dist/pypy/doc/discussion Message-ID: <20060605105536.7D08410053@code0.codespeak.net> Author: mwh Date: Mon Jun 5 12:55:35 2006 New Revision: 28324 Added: pypy/dist/pypy/doc/discussion/readline.py (contents, props changed) Log: an Idea! Added: pypy/dist/pypy/doc/discussion/readline.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/discussion/readline.py Mon Jun 5 12:55:35 2006 @@ -0,0 +1,33 @@ +# this is a sketch of how one might one day be able to define a pretty simple +# ctypes-using module, suitable for feeding to the ext-compiler + +from pypy.interpreter.ctypesmodule import CTypesModule +from pypy.interpreter.baseobjspace import ObjSpace +import ctypes + +class Module(CTypesModule): + """readline""" + + def init(self, space): + space.readline_func = self.dict_w['readline'] + + interpleveldefs = { + 'readline' : '.readline', + } + +class CConfig: + _header_ = """#include """ + _libraries_ = ('readline',) + +cconfig = Module.cconfig(CConfig) + +libreadline = cconfig.ctypes_lib['readline'] + +c_readline = libreadline.readline +c_readline.restype = ctypes.c_char_p + +def readline(space, prompt): + return space.wrap(c_readline(prompt)) +readline.unwrap_spec = [ObjSpace, str] + + From ac at codespeak.net Mon Jun 5 13:17:26 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 5 Jun 2006 13:17:26 +0200 (CEST) Subject: [pypy-svn] r28325 - in pypy/dist/pypy: bin interpreter translator/goal Message-ID: <20060605111726.0CA9210068@code0.codespeak.net> Author: ac Date: Mon Jun 5 13:17:26 2006 New Revision: 28325 Modified: pypy/dist/pypy/bin/py.py pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: (cfbolz, arre) Add the methods setup and finish to objectspaces. Modified: pypy/dist/pypy/bin/py.py ============================================================================== --- pypy/dist/pypy/bin/py.py (original) +++ pypy/dist/pypy/bin/py.py Mon Jun 5 13:17:26 2006 @@ -111,26 +111,27 @@ banner = None try: - # compile and run it - if not main.run_toplevel(space, doit, verbose=Options.verbose): - exit_status = 1 + def do_start(): + space.startup() + if main.run_toplevel(space, do_start, verbose=Options.verbose): + # compile and run it + if not main.run_toplevel(space, doit, verbose=Options.verbose): + exit_status = 1 - # start the interactive console - if go_interactive: - con = interactive.PyPyConsole(space, verbose=Options.verbose, - completer=Options.completer) - if banner == '': - banner = '%s / %s'%(con.__class__.__name__, - repr(space)) - con.interact(banner) - exit_status = 0 + # start the interactive console + if go_interactive: + con = interactive.PyPyConsole( + space, verbose=Options.verbose, + completer=Options.completer) + if banner == '': + banner = '%s / %s'%(con.__class__.__name__, + repr(space)) + con.interact(banner) + exit_status = 0 finally: - # call the sys.exitfunc() - w_exitfunc = space.sys.getdictvalue_w(space, 'exitfunc') - if w_exitfunc is not None: - def doit(): - space.call_function(w_exitfunc) - main.run_toplevel(space, doit, verbose=Options.verbose) + def doit(): + space.finish() + main.run_toplevel(space, doit, verbose=Options.verbose) return exit_status Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Mon Jun 5 13:17:26 2006 @@ -158,6 +158,15 @@ # override this in subclasses for extra-options pass + def startup(self): + # To be called before using the space + pass + + def finish(self): + w_exitfunc = self.sys.getdictvalue_w(self, 'exitfunc') + if w_exitfunc is not None: + self.call_function(w_exitfunc) + def __repr__(self): try: return self._this_space_repr_ Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Mon Jun 5 13:17:26 2006 @@ -30,19 +30,30 @@ for arg in argv: debug(" argv -> " + arg) try: - w_executable = space.wrap(argv[0]) - w_argv = space.newlist([space.wrap(s) for s in argv[1:]]) - w_exitcode = space.call_function(w_entry_point, w_executable, w_argv) - # try to pull it all in - ## from pypy.interpreter import main, interactive, error - ## con = interactive.PyPyConsole(space) - ## con.interact() - except OperationError, e: - debug("OperationError:") - debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) - return 1 - return space.int_w(w_exitcode) + try: + space.call_function(w_run_toplevel, w_call_startup) + w_executable = space.wrap(argv[0]) + w_argv = space.newlist([space.wrap(s) for s in argv[1:]]) + w_exitcode = space.call_function(w_entry_point, w_executable, w_argv) + exitcode = space.int_w(w_exitcode) + # try to pull it all in + ## from pypy.interpreter import main, interactive, error + ## con = interactive.PyPyConsole(space) + ## con.interact() + except OperationError, e: + debug("OperationError:") + debug(" operror-type: " + e.w_type.getname(space, '?')) + debug(" operror-value: " + space.str_w(space.str(e.w_value))) + return 1 + finally: + try: + space.call_function(w_run_toplevel, w_call_finish) + except OperationError, e: + debug("OperationError:") + debug(" operror-type: " + e.w_type.getname(space, '?')) + debug(" operror-value: " + space.str_w(space.str(e.w_value))) + return 1 + return exitcode # _____ Define and setup target ___ @@ -64,6 +75,18 @@ opt_parser().print_help() +def call_finish(space): + space.finish() + +w_call_finish = gateway.interp2app(call_finish) + +def call_startup(space): + space.startup() + +w_call_startup = gateway.interp2app(call_startup) + + + def target(driver, args): driver.exe_name = 'pypy-%(backend)s' options = driver.options @@ -72,7 +95,7 @@ translate.log_options(tgt_options, "target PyPy options in effect") - global space, w_entry_point + global space, w_entry_point, w_run_toplevel geninterp = not getattr(options, 'lowmem', False) @@ -103,6 +126,7 @@ w_dict = space.newdict([]) space.exec_(open(filename).read(), w_dict, w_dict) w_entry_point = space.getitem(w_dict, space.wrap('entry_point')) + w_run_toplevel = space.getitem(w_dict, space.wrap('run_toplevel')) # sanity-check: call the entry point res = entry_point(["pypy", "app_basic_example.py"]) From hpk at codespeak.net Mon Jun 5 13:58:27 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Jun 2006 13:58:27 +0200 (CEST) Subject: [pypy-svn] r28327 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060605115827.624B010063@code0.codespeak.net> Author: hpk Date: Mon Jun 5 13:58:26 2006 New Revision: 28327 Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt Log: a bit of updating the planning Modified: pypy/extradoc/sprintinfo/ddorf2006/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/ddorf2006/planning.txt (original) +++ pypy/extradoc/sprintinfo/ddorf2006/planning.txt Mon Jun 5 13:58:26 2006 @@ -1,16 +1,23 @@ Sprint Planning DDorf ========================================= -Armin isn't here yet. - Before the sprint, there were two somewhat-similar, somewhat-conflicting goals: finish off wp7 functionality (stackless stuff, and more...) and -getting the 0.9 release out of the door. We decided that the priority of this sprint, or at least the next two days should be on wp7 and particularly -stackless relates features. +getting the 0.9 release out of the door. We decided that the priority +of this sprint, or at least the next two days should be on wp7 and +particularly stackless related features. + +time plan: monday afternoon: breakday + tuesday afternoon: EU technical project planning + + Some things that don't really have issues yet: * the ext compiler + (armin, carl, michael, arre, holger) + * design user level usage + implement it * Document using ext-compiler getting-started + * readline support for translated PyPy * documentation @@ -20,6 +27,7 @@ * ootypesystem stuff + ootype is mostly complete (r_dict missing) **Nik and Antonio are working on ootype completion ** ** Maciek will join later ** @@ -38,7 +46,8 @@ **Arre, cfbolz to do more testing** * ??? expose coroutine cloning to app level. - + + (Armin) * settle on APIs on RPython level * experiment a bit with exposing it to applevel * document for 0.9 release @@ -47,26 +56,21 @@ * 198 implement tasklet pickling - No problem at all! hahahaha + (christian) - (in-progress) finish needed object type pickling/unpickling - (DONE) finish and integrate explict resume points support - - use the latter to implement restarting after unpickling + - (christian, samuele) use the latter to implement restarting after unpickling (likely hack! hack! hack! until it works) Tasklet cloning has become completely different, that kind of works now (needs more testing). -* 81 weakrefs - - This is about 90% done, only the other 90% to go :) - Many of the CPython tests are hopeless, we need - modified-2.4.1/test/test_weakref.py. Exposing gc.collect() would help. + (armin) write up documentation on how to use tasklet cloning - **cfbolz + arre** DONE * 199 finish app-level stackless support - + (stephan is working on it) This should be rated 'critical'! Not sure what the status is. Greenlets could be done quickly. @@ -75,7 +79,7 @@ * 137 Control-C runtime support - No progress here. Hopefully not that hard. + it is quite hard. (arre, cfbolz) From tismer at codespeak.net Mon Jun 5 14:53:30 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 5 Jun 2006 14:53:30 +0200 (CEST) Subject: [pypy-svn] r28328 - in pypy/dist/pypy/interpreter: . test Message-ID: <20060605125330.9CAE610050@code0.codespeak.net> Author: tismer Date: Mon Jun 5 14:53:29 2006 New Revision: 28328 Modified: pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/test/test_pickle.py Log: pickling of the blockstack is working! I hope it translates, but I guess so. The idea to find the right classes is modelled after the way we get the frame classes, too. Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Mon Jun 5 14:53:29 2006 @@ -7,7 +7,7 @@ from pypy.interpreter import pytraceback from pypy.rpython.rarithmetic import r_uint, intmask import opcode -from pypy.rpython.objectmodel import we_are_translated +from pypy.rpython.objectmodel import we_are_translated, instantiate # Define some opcodes used @@ -75,6 +75,7 @@ mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('frame_new') w = space.wrap + nt = space.newtuple if isinstance(self, PyNestedScopeFrame): w_cells = w([w(cell) for cell in self.cells]) @@ -87,7 +88,7 @@ f_lineno = self.f_lineno w_valuestack = maker.slp_into_tuple_with_nulls(space, self.valuestack.items) - w_blockstack = space.w_None ## + w_blockstack = nt([block._get_state_(space) for block in self.blockstack.items]) w_fastlocals = maker.slp_into_tuple_with_nulls(space, self.fastlocals_w) tup_base = [ w(self.pycode), @@ -97,7 +98,7 @@ w(self.builtin), w(self.pycode), w_valuestack, - space.w_None, ## w_blockstack, + w_blockstack, space.w_None, ## w(self.last_exception), #f_exc_traceback, f_exc_type, f_exc_value self.w_globals, w(self.last_instr), @@ -115,7 +116,6 @@ w_cells, ] - nt = space.newtuple return nt([new_inst, nt(tup_base), nt(tup_state)]) def descr__setstate__(self, space, w_args): @@ -139,7 +139,8 @@ PyFrame.__init__(self, space, pycode, w_globals, None) new_frame.f_back = space.interp_w(PyFrame, w_f_back, can_be_None=True) new_frame.builtin = space.interp_w(Module, w_builtin) - #new_frame.blockstack = blockstack + new_frame.blockstack.items = [unpickle_block(space, w_blk) + for w_blk in space.unpackiterable(w_blockstack)] new_frame.valuestack.items = maker.slp_from_tuple_with_nulls(space, w_valuestack) new_frame.last_exception = None#XXX (w_last_exception) new_frame.last_instr = space.int_w(w_last_instr) @@ -435,6 +436,32 @@ ### Frame Blocks ### +block_classes = {} + +def setup_block_classes(): + "NOT_RPYTHON" + import types + for cls in globals().values(): + if isinstance(cls, (types.ClassType,type)): + if issubclass(cls, FrameBlock) and hasattr(cls, '_opname'): + block_classes[cls._opname] = cls + +def get_block_class(opname): + # select the appropriate kind of block + if not block_classes: + setup_block_classes() # lazily + return block_classes[opname] + +def unpickle_block(space, w_tup): + w_opname, w_handlerposition, w_valuestackdepth = space.unpackiterable(w_tup) + opname = space.str_w(w_opname) + handlerposition = space.int_w(w_handlerposition) + valuestackdepth = space.int_w(w_valuestackdepth) + blk = instantiate(get_block_class(opname)) + blk.handlerposition = handlerposition + blk.valuestackdepth = valuestackdepth + return blk + class FrameBlock: """Abstract base class for frame blocks from the blockstack, @@ -468,10 +495,17 @@ self.cleanupstack(frame) return False # continue to unroll + # internal pickling interface, not using the standard protocol + def _get_state_(self, space): + w = space.wrap + return space.newtuple([w(self._opname), w(self.handlerposition), + w(self.valuestackdepth)]) class LoopBlock(FrameBlock): """A loop block. Stores the end-of-loop pointer in case of 'break'.""" + _opname = 'SETUP_LOOP' + def unroll(self, frame, unroller): if isinstance(unroller, SContinueLoop): # re-push the loop block without cleaning up the value stack, @@ -491,6 +525,8 @@ class ExceptBlock(FrameBlock): """An try:except: block. Stores the position of the exception handler.""" + _opname = 'SETUP_EXCEPT' + def unroll(self, frame, unroller): self.cleanupstack(frame) if isinstance(unroller, SApplicationException): @@ -513,6 +549,8 @@ class FinallyBlock(FrameBlock): """A try:finally: block. Stores the position of the exception handler.""" + _opname = 'SETUP_FINALLY' + def cleanup(self, frame): # upon normal entry into the finally: part, the standard Python # bytecode pushes a single None for END_FINALLY. In our case we Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Mon Jun 5 14:53:29 2006 @@ -355,7 +355,7 @@ result = pickle.loads(pckl) assert type(riter) is type(result) assert list(result) == [2,3,4] - + def test_pickle_generator(self): import new mod = new.module('mod') @@ -378,3 +378,27 @@ assert list(g1) == list(g2) finally: del sys.modules['mod'] + + def test_pickle_generator_blk(self): + # same as above but with the generator inside a block + import new + mod = new.module('mod') + import sys + sys.modules['mod'] = mod + try: + def giveme(n): + x = 0 + while x < n: + yield x + x += 1 + import pickle + mod.giveme = giveme + giveme.__module__ = mod + g1 = mod.giveme(10) + g1.next() + g1.next() + pckl = pickle.dumps(g1) + g2 = pickle.loads(pckl) + assert list(g1) == list(g2) + finally: + del sys.modules['mod'] From tismer at codespeak.net Mon Jun 5 15:21:27 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 5 Jun 2006 15:21:27 +0200 (CEST) Subject: [pypy-svn] r28330 - pypy/dist/pypy/interpreter/test Message-ID: <20060605132127.B8A4910063@code0.codespeak.net> Author: tismer Date: Mon Jun 5 15:21:27 2006 New Revision: 28330 Modified: pypy/dist/pypy/interpreter/test/test_pickle.py Log: small cleanups. Missing last spot: what to do about frame.last_exception? Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Mon Jun 5 15:21:27 2006 @@ -162,7 +162,6 @@ f2 = pickle.loads(pckl) def test_pickle_traceback(self): - #skip("in-progress: recursion problem") def f(): try: raise Exception() @@ -181,33 +180,6 @@ assert tb.tb_lineno == result.tb_lineno assert tb.tb_next == result.tb_next - #XXX silly code duplication from frame pickling test - f1 = tb.tb_frame - f2 = result.tb_frame - assert type(f1) is type(f2) - assert dir(f1) == dir(f2) - assert f1.__doc__ == f2.__doc__ - assert type(f1.f_back) is type(f2.f_back) - assert f1.f_builtins is f2.f_builtins - assert f1.f_code == f2.f_code - assert f1.f_exc_traceback is f2.f_exc_traceback - assert f1.f_exc_type is f2.f_exc_type - assert f1.f_exc_value is f2.f_exc_value - - #print 'f1.f_globals =', f1.f_globals #f1.f_globals = {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } - #print 'f2.f_globals=', f2.f_globals #f2.f_globals= {'__builtins__': , '__name__': '__builtin__', 'test_pickle_frame': } - #assert f1.f_globals == f2.f_globals #XXX test_pickle_frame function not same identity (see pickle func tests, we don't compare by identity there!)? - - assert f1.f_lasti == f2.f_lasti - assert f1.f_lineno == f2.f_lineno - - #print 'f1.f_locals=', f1.f_locals #['exc_info', 'tb', 'exc_type', 'exc'] - #print 'f2.f_locals=', f2.f_locals #[] - #assert list(f1.f_locals) == list(f2.f_locals) - - assert f1.f_restricted is f2.f_restricted - assert f1.f_trace is f2.f_trace - restore_top_frame(tb.tb_frame, saved) def test_pickle_module(self): From stephan at codespeak.net Mon Jun 5 19:19:15 2006 From: stephan at codespeak.net (stephan at codespeak.net) Date: Mon, 5 Jun 2006 19:19:15 +0200 (CEST) Subject: [pypy-svn] r28338 - pypy/dist/pypy/module/stackless/test Message-ID: <20060605171915.5D16A10053@code0.codespeak.net> Author: stephan Date: Mon Jun 5 19:19:13 2006 New Revision: 28338 Added: pypy/dist/pypy/module/stackless/test/coroutine_dummy.py (contents, props changed) pypy/dist/pypy/module/stackless/test/test_scheduling.py (contents, props changed) Modified: pypy/dist/pypy/module/stackless/test/stackless_.py Log: new (but not finished) app level stackless implementation. the implementation now tries to follow the c implementation as close as possible. Scheduling is back to a specific scheduler. This is not finished and debugging is difficult, because 1. There is a MemoryError creeping up somewhere and 2. pypy can't be translated at the moment Added: pypy/dist/pypy/module/stackless/test/coroutine_dummy.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/stackless/test/coroutine_dummy.py Mon Jun 5 19:19:13 2006 @@ -0,0 +1,8 @@ +class coroutine(object): + + @staticmethod + def getcurrent():pass + + def kill(self):pass + + def bind(self, func, *argl, **argd):pass Modified: pypy/dist/pypy/module/stackless/test/stackless_.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/stackless_.py (original) +++ pypy/dist/pypy/module/stackless/test/stackless_.py Mon Jun 5 19:19:13 2006 @@ -4,8 +4,15 @@ Please refer to their documentation. """ -from stackless import coroutine -from collections import deque +DEBUG = True + +try: + from stackless import coroutine +except ImportError: + if not DEBUG: + raise + from coroutine_dummy import coroutine + __all__ = 'run getcurrent getmain schedule tasklet channel'.split() @@ -21,6 +28,11 @@ This is a necessary Stackless 3.1 feature. """ +# thread related stuff: assuming NON threaded execution for now + +def check_for_deadlock(): + return True + last_thread_id = 0 def restore_exception(etype, value, stack): @@ -83,6 +95,15 @@ def _explode(self): restore_exception(self.type, self.value, self.traceback) +def make_deadlock_bomb(): + return bomb(RuntimeError, + RuntimeError("Deadlock: the last runnable tasklet cannot be blocked."), + None) + +def curexc_to_bomb(): + import sys + return bomb(*sys.exc_info()) + # channel: see below note = """ @@ -166,73 +187,18 @@ # end interface -# implicit scheduler - -def _next(): - c = getcurrent() - if c.next is c: - return c - nt = c.next - if nt is main_tasklet and nt.next is not c: - return nt.next - else: - return nt - -def _insert(other): - "put other on the end tasklet queue" - this = getcurrent() - #print '_insert:',this, - #_print_queue() - prev = this.prev - this.prev = other - other.next = this - other.prev = prev - prev.next = other - other.blocked = False - -def _priority_insert(other): - "other will be the next tasklet" - this = getcurrent() - #print '_priority_insert:',this, - #_print_queue() - next = this.next - this.next = other - other.prev = this - other.next = next - next.prev = other - other.blocked = False - -def _remove(this): - #print '_remove:',this, - #_print_queue() - if this.next is this: - return - t = c = getcurrent() - count = 0 - while t is not this: - if t is c and count: - break - count += 1 - t = t.next - this.next.prev = this.prev - this.prev.next = this.next - -def _print_queue(): - c = s = getcurrent() - print '[',c, - while c.next is not s: - c = c.next - print c, - print ']' - -# end implicit scheduler - main_tasklet = None main_coroutine = None +scheduler = None +channel_hook = None +schedlock = False +_schedule_fasthook = None def __init(): global main_tasklet global main_coroutine + global scheduler + scheduler = Scheduler() main_coroutine = c = coroutine.getcurrent() main_tasklet = TaskletProxy(c) main_tasklet.next = main_tasklet.prev = main_tasklet @@ -278,25 +244,9 @@ tasklet as default. schedule_remove(retval=stackless.current) -- ditto, and remove self. """ - #print 'schedule: before switch', - #_print_queue() - curr = getcurrent() - curr.is_current = False - nt = _next() - if curr.blocked: - _remove(curr) - nt.is_current = True - nt.switch() - #print 'schedule: after switch', - #_print_queue() - curr = getcurrent() - if type(curr.tempval) is bomb: - raise curr.tempval._explode() - if retval is None: - return getcurrent() - else: - return retval - + prev = getcurrent() + next = prev.next + return scheduler.schedule_task(prev, next, 0) """ /*************************************************************************** @@ -385,8 +335,8 @@ self.is_main = False self.nesting_level = 0 self.next = None - self.paused = False self.prev = None + self.paused = False self.recursion_depth = 0 self.restorable = False self.scheduled = False @@ -415,13 +365,21 @@ raise TypeError('tasklet function must be a callable') self.tempval = func + def _is_dead(self): + return False + def insert(self): """ Insert this tasklet at the end of the scheduler list, given that it isn't blocked. Blocked tasklets need to be reactivated by channels. """ - _insert(self) + if self.blocked: + raise RuntimeError('You cannot run a blocked tasklet') + if self._is_dead(): + raise RuntimeError('You cannot run an unbound(dead) tasklet') + if self.next is None: + scheduler.current_insert(self) ## note: this is needed. please call coroutine.kill() def kill(self): @@ -452,15 +410,14 @@ unwanted side-effects. Therefore it is recommended to either run tasklets to the end or to explicitly kill() them. """ - _remove(self) + scheduler.current_remove(self) def run(self): """ Run this tasklet, given that it isn't blocked. Blocked tasks need to be reactivated by channels. """ - _remove(self) - _priority_insert(self) + self.insert() ## note: please support different schedulers ## and don't mix calls to module functions with scheduler methods. schedule() @@ -538,9 +495,10 @@ ***************************************************************************/ """ + class channel(object): """ - A channel object is used for communication between tasklets. + A channel object is used for communication between tasklets. By sending on a channel, a tasklet that is waiting to receive is resumed. If there is no waiting receiver, the sender is suspended. By receiving from a channel, a tasklet that is waiting to send @@ -552,19 +510,115 @@ def __init__(self): self.balance = 0 - ## note: this is a deque candidate. - self.queue = deque() self.closing = False self.preference = 0 + self.head = self.tail = None def __str__(self): return 'channel(' + str(self.balance) + ' : ' + str(self.queue) + ')' def _get_closed(self): - return self.closing and not self.queue + return self.closing and self.next is None closed = property(_get_closed) + def _channel_insert(self, task, d): + self._ins(task) + self.balance += d + task.blocked = dir + + def _queue(self): + if self.head is self: + return None + else: + return self.head + + def _channel_remove(self, d): + ret = self.head + assert isinstance(ret,tasklet) + self.balance -= d + self._rem(ret) + ret.blocked = 0 + + return ret + + def channel_remove_specific(self, dir, task): + # note: we assume that the task is in the channel + self.balance -= dir + self._rem(task) + task.blocked = False + return task + + def _ins(self, task): + assert task.next is None + assert task.prev is None + # insert at end + task.prev = self.head.prev + task.next = self.head + self.prev.next = task + self.prev = task + + def _rem(self, task): + assert task.next is not None + assert task.prev is not None + #remove at end + task.next.prev = task.prev + task.prev.next = task.next + task.next = task.prev = None + + def _notify(self, task, dir, cando, res): + global schedlock + if channel_hook is not None: + if schedlock: + raise RuntimeError('Recursive channel call due to callbacks!') + schedlock = 1 + channel_callback(self, task, dir > 0, not cando) + schedlock = 0 + + def _channel_action(self, arg, dir, stackl): + source = getcurrent() + target = self.head + interthread = 0 # no interthreading at the moment + if dir > 0: + cando = self.balance < 0 + else: + cando = self.balance > 0 + + assert abs(dir) == 1 + + source.tempval = arg + if not interthread: + self._notify(source, dir, cando, None) + if cando: + # communication 1): there is somebody waiting + target = self._channel_remove(-dir) + source.tempval, target.tempval = target.tempval, source.tempval + if interthread: + raise Exception('no interthreading: I can not be reached...') + else: + if self.schedule_all: + scheduler.current_insert(target) + target = source.next + elif self.preference == -dir: + scheduler.current = source.next + scheduler.current_insert(target) + scheduler.current = source + else: + scheduler.current_insert(target) + target = source + else: + if source.block_trap: + raise RuntimeError("this tasklet does not like to be blocked") + if self.closing: + raise StopIteration() + scheduler.current_remove() + self._channel_insert(source, dir) + target = getcurrent() + retval = scheduler.schedule_task(source, target, stackl) + if interthread: + self._notify(source, dir, cando, None) + return retval + ## note: needed def close(self): """ @@ -582,7 +636,7 @@ """ if self.closing and not self.balance: raise StopIteration() - return self.receive() + yield self.receive() ## note: needed def open(self): @@ -639,25 +693,7 @@ the runnables list. The above policy can be changed by setting channel flags. """ - if self.closing: - raise StopIteration - if self.balance > 0: # Receiving 1 - wt = self.queue.popleft() - retval = wt.tempval - wt.tempval = None - _insert(wt) - self.balance -= 1 - return retval - else: # Receiving 2 - ct = getcurrent() - #_remove(ct) - ct.blocked = True - self.queue.append(ct) - self.balance -= 1 - schedule() - retval = ct.tempval - ct.tempval = None - return retval + return self._channel_action(None, -1, 1) def send(self, msg): """ @@ -667,23 +703,7 @@ be activated immediately, and the sender is put at the end of the runnables list. """ - if self.closing: - raise StopIteration - ct = getcurrent() - if ct.tempval is not None: - print 'THERE IS STILL SOME CHANNEL SEND VALUE',ct.tempval - if self.balance < 0: # Sending 1 - wt = self.queue.popleft() - wt.tempval = msg - _priority_insert(wt) - self.balance += 1 - else: # Sending 2 - ct.tempval = msg - #_remove(ct) - ct.blocked = True - self.queue.append(ct) - self.balance += 1 - schedule() + return self._channel_action(msg, 1, 1) ## note: see the C implementation on how to use bombs. def send_exception(self, exc, value): @@ -707,5 +727,150 @@ for item in value: self.send(item) +class Scheduler(object): + + def __init__(self): + self.chain = None + self.current = None + + def reset(self): + self.__init__() + + def __len__(self): + return len(self._content()) + + def _content(self): + visited = set() + items = [] + if self.chain: + next = self.chain + while next is not None and next not in visited: + items.append(next) + visited.add(next) + next = next.next + return items + + def __str__(self): + parts = ['%s' % x.thread_id for x in self._content()] + currid = (self.current and self.current.thread_id) or -1 + return '===== Scheduler ====\nchain:' + \ + ' -> '.join(parts) + '\ncurrent: %s' % currid + \ + '\n====================' + + def _chain_insert(self, task): + assert task.next is None + assert task.prev is None + if self.chain is None: + task.next = task.prev = task + self.chain = task + else: + r = self.chain + l = r.prev + l.next = r.prev = task + task.prev = l + task.next = r + + def _chain_remove(self): + if self.chain is None: + return None + task = self.chain + l = task.prev + r = task.next + l.next = r + r.prev = l + self.chain = r + if r == task: + self.chain = None + task.prev = task.next = None + + return task + + + def current_insert(self, task): + self.chain = self.current or getcurrent() + self._chain_insert(task) + self.current = None + + def current_insert_after(self, task): + curr = self.current or getcurrent() + self.chain = curr.next + self._chain_insert(task) + self.chain = curr + self.current = None + + def current_remove(self): + self.chain = self.current or getcurrent() + self.current = None + return self._chain_remove() + + def channel_remove_slow(self, task): + prev = task.prev + while not isinstance(prev, channel): + prev = prev.prev + chan = prev + assert chan.balance + if chan.balance > 0: + dir = 1 + else: + dir = -1 + return chan.channel_remove_specific(dir, task) + + def bomb_explode(self, task): + thisbomb = task.tempval + assert isinstance(thisbomb, bomb) + task.tempval = None + bomb._explode() + + def _notify_schedule(self, prev, next, errflag): + if _schedule_fasthook is not None: + global schedlock + if schedlock: + raise RuntimeError('Recursive scheduler call due to callbacks!') + schedlock = True + ret = _schedule_fasthook(prev, next) + schedlock = False + if ret: + return errflag + + def schedule_task_block(self, prev, stackl): + next = None + if check_for_deadlock(): + if main_tasklet.next is None: + if isinstance(prev.tempval, bomb): + main_tasklet.tempval = prev.tempval + return self.schedule_task(prev, main_tasklet, stackl) + retval = make_deadlock_bomb() + prev.tempval = retval + + return self.schedule_task(prev, prev, stackl) + + def schedule_task(self, prev, next, stackl): + if next is None: + return self.schedule_task_block(prev, stackl) + if next.blocked: + self.channel_remove_slow(next) + self.current_insert(next) + elif next.next is None: + self.current_insert(next) + if prev is next: + retval = prev.tempval + if isinstance(retval, bomb): + self.bomb_explode(retval) + retval._explode() + return retval + self._notify_schedule(prev, next, None) + + # lots of soft-/ hard switching stuff in C source + + next.switch() + + retval = next.tempval + if isinstance(retval, bomb): + self.bomb_explode(next) + + return retval + + + __init() Added: pypy/dist/pypy/module/stackless/test/test_scheduling.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/stackless/test/test_scheduling.py Mon Jun 5 19:19:13 2006 @@ -0,0 +1,85 @@ +from stackless_ import scheduler + +class task_mock(object): + number = 0 + @classmethod + def new_id(cls): + cls.number += 1 + return cls.number + + def __init__(self): + self.thread_id = task_mock.new_id() + self.next = self.prev = None + +main_task = task_mock() +main_task.next = main_task.prev = main_task + +def setmain(): + scheduler.current = main_task + +def check_chain(chain): + assert chain.next is not None + assert chain.prev is not None + visited = set() + nextcount = prevcount = 0 + if chain.next == chain.prev == chain: + return True + next = chain.next + while next is not chain: + if next in visited: + return False + nextcount += 1 + visited.add(next) + next = next.next + visited = set() + prev = chain.prev + while prev is not chain: + if prev in visited: + return False + prevcount += 1 + visited.add(prev) + prev = prev.prev + + return nextcount == prevcount + + +class TestStackless(object): + + def setup_method(self, name): + scheduler.reset() + main_task.next = main_task.prev = main_task + task_mock.number = 1 + setmain() + + def test_insert(self): + t1 = task_mock() + t2 = task_mock() + scheduler.current_insert(t1) + assert check_chain(scheduler.chain) + setmain() + scheduler.current_insert(t2) + assert check_chain(scheduler.chain) + assert main_task.next is t1 + assert main_task.prev is t2 + + def test_insert_after(self): + t1 = task_mock() + t2 = task_mock() + scheduler.current_insert_after(t1) + assert check_chain(scheduler.chain) + setmain() + scheduler.current_insert_after(t2) + assert check_chain(scheduler.chain) + assert main_task.prev is t1 + assert main_task.next is t2 + + def test_current_remove(self): + t1 = task_mock() + t2 = task_mock() + scheduler.current_insert(t1) + setmain() + scheduler.current_insert(t2) + scheduler.current = t1 + assert len(scheduler) == 3 + scheduler.current_remove() + assert len(scheduler) == 2 and t1 not in scheduler._content() From antocuni at codespeak.net Tue Jun 6 10:34:35 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 10:34:35 +0200 (CEST) Subject: [pypy-svn] r28347 - in pypy/dist/pypy/module/_socket/rpython: . test Message-ID: <20060606083435.089361006F@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 10:34:34 2006 New Revision: 28347 Modified: pypy/dist/pypy/module/_socket/rpython/ll__socket.py pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py Log: Fixed a wrong import bug caused by external function refactoring. Modified: pypy/dist/pypy/module/_socket/rpython/ll__socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/ll__socket.py (original) +++ pypy/dist/pypy/module/_socket/rpython/ll__socket.py Tue Jun 6 10:34:34 2006 @@ -2,10 +2,13 @@ from pypy.rpython.lltypesystem.rstr import STR from pypy.rpython.lltypesystem.lltype import GcStruct, Signed, Array, Char, Ptr, malloc -from pypy.rpython.module.support import to_rstr, from_rstr +from pypy.rpython.module.support import LLSupport from pypy.rpython.module.support import to_opaque_object, from_opaque_object from pypy.module._socket.rpython import rsocket +to_rstr = LLSupport.to_rstr +from_rstr = LLSupport.from_rstr + def ll__socket_gethostname(): return to_rstr(_socket.gethostname()) ll__socket_gethostname.suggested_primitive = True Modified: pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py (original) +++ pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py Tue Jun 6 10:34:34 2006 @@ -4,7 +4,7 @@ from pypy.module._socket.rpython.ll__socket import * from pypy.annotation.annrpython import RPythonAnnotator from pypy.rpython.test.test_llinterp import interpret -from pypy.rpython.module.support import from_rstr +from pypy.rpython.module.support import LLSupport from pypy.rpython.module.support import to_opaque_object, from_opaque_object def test_ntohs(): @@ -19,13 +19,13 @@ return _socket.gethostname() a = RPythonAnnotator() res = interpret(fn, []) - assert from_rstr(res) == _socket.gethostname() + assert LLSupport.from_rstr(res) == _socket.gethostname() def test_getaddrinfo(): host = "localhost" port = 25 result = [] - addr = ll__socket_getaddrinfo(to_rstr(host), port, 0, 0, 0, 0) + addr = ll__socket_getaddrinfo(LLSupport.to_rstr(host), port, 0, 0, 0, 0) info = ll__socket_nextaddrinfo(addr) info = info[:4] + (info[4:],) assert info == _socket.getaddrinfo(host, port)[0] From arigo at codespeak.net Tue Jun 6 10:58:46 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 6 Jun 2006 10:58:46 +0200 (CEST) Subject: [pypy-svn] r28351 - in pypy/dist/pypy/objspace/cpy: . test Message-ID: <20060606085846.33E411006F@code0.codespeak.net> Author: arigo Date: Tue Jun 6 10:58:45 2006 New Revision: 28351 Modified: pypy/dist/pypy/objspace/cpy/objspace.py pypy/dist/pypy/objspace/cpy/test/test_typedef.py pypy/dist/pypy/objspace/cpy/typedef.py Log: Reorganized typedef a bit. Next goal is to special-case the rpython2cpython() and cpython2rpython() functions during translation... Modified: pypy/dist/pypy/objspace/cpy/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/objspace.py (original) +++ pypy/dist/pypy/objspace/cpy/objspace.py Tue Jun 6 10:58:45 2006 @@ -37,12 +37,8 @@ from pypy.objspace.cpy.function import FunctionCache return self.fromcache(FunctionCache).getorbuild(x) # normal case - from pypy.objspace.cpy.typedef import TypeDefCache - w_x = x.__cpy_wrapper__ - if w_x is None: - w_type = self.fromcache(TypeDefCache).getorbuild(x.typedef) - w_x = x.__cpy_wrapper__ = self.call_function(w_type) - return w_x + from pypy.objspace.cpy.typedef import rpython2cpython + return rpython2cpython(self, x) if x is None: return self.w_None if isinstance(x, int): @@ -62,7 +58,8 @@ try: w_obj, obj, follow = self.wrap_cache[id(w_obj)] except KeyError: - return None + from pypy.objspace.cpy.typedef import cpython2rpython + return cpython2rpython(self, w_obj) else: return obj Modified: pypy/dist/pypy/objspace/cpy/test/test_typedef.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/test/test_typedef.py (original) +++ pypy/dist/pypy/objspace/cpy/test/test_typedef.py Tue Jun 6 10:58:45 2006 @@ -12,7 +12,19 @@ self.space = space +def test_direct(): + W_MyType.typedef = TypeDef("MyType") + space = CPyObjSpace() + x = W_MyType(space) + y = W_MyType(space) + w_x = space.wrap(x) + w_y = space.wrap(y) + assert space.interpclass_w(w_x) is x + assert space.interpclass_w(w_y) is y + + def test_simple(): + import py; py.test.skip("in-progress") W_MyType.typedef = TypeDef("MyType") space = CPyObjSpace() Modified: pypy/dist/pypy/objspace/cpy/typedef.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/typedef.py (original) +++ pypy/dist/pypy/objspace/cpy/typedef.py Tue Jun 6 10:58:45 2006 @@ -6,10 +6,39 @@ from pypy.objspace.cpy.capi import * from pypy.interpreter.baseobjspace import Wrappable, SpaceCache + +class rpython_object(object): + __slots__ = ('data',) +rpython_data = rpython_object.data +del rpython_object.data + +def init_rpython_data(w_object, value): + rpython_data.__set__(w_object.value, value) + value.__cpy_wrapper__ = w_object + +def get_rpython_data(w_object): + return rpython_data.__get__(w_object.value) + +def rpython2cpython(space, x): + w_x = x.__cpy_wrapper__ + if w_x is None: + w_type = space.fromcache(TypeDefCache).getorbuild(x.typedef) + w_x = space.call_function(w_type) + init_rpython_data(w_x, x) + return w_x + +def cpython2rpython(space, w_obj): + if isinstance(w_obj.value, rpython_object): + return get_rpython_data(w_obj) + else: + return None + +# ____________________________________________________________ + class TypeDefCache(SpaceCache): def build(cache, typedef): space = cache.space - newtype = type(typedef.name, (), {}) + newtype = type(typedef.name, (rpython_object,), {}) w_result = W_Object(newtype) space.wrap_cache[id(w_result)] = w_result, typedef, follow_annotations return w_result From hpk at codespeak.net Tue Jun 6 12:07:48 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 6 Jun 2006 12:07:48 +0200 (CEST) Subject: [pypy-svn] r28353 - pypy/dist/pypy/doc/discussion Message-ID: <20060606100748.ECFD110053@code0.codespeak.net> Author: hpk Date: Tue Jun 6 12:07:48 2006 New Revision: 28353 Modified: pypy/dist/pypy/doc/discussion/readline.py Log: (arre, holger) extended draft example for readline Modified: pypy/dist/pypy/doc/discussion/readline.py ============================================================================== --- pypy/dist/pypy/doc/discussion/readline.py (original) +++ pypy/dist/pypy/doc/discussion/readline.py Tue Jun 6 12:07:48 2006 @@ -5,16 +5,25 @@ from pypy.interpreter.baseobjspace import ObjSpace import ctypes +# XXX raw_input needs to check for space.readline_func and use +# it if its there + class Module(CTypesModule): - """readline""" + """Importing this module enables command line editing using GNU readline.""" + # the above line is the doc string of the translated module def init(self, space): + setup_readline(space, self) space.readline_func = self.dict_w['readline'] interpleveldefs = { 'readline' : '.readline', } +#------------------------------------------------------------ +# configuration for binding to external readline library +# through rctypes +# class CConfig: _header_ = """#include """ _libraries_ = ('readline',) @@ -26,8 +35,29 @@ c_readline = libreadline.readline c_readline.restype = ctypes.c_char_p -def readline(space, prompt): +c_rl_initialize = libreadline.rl_initiliaze +c_rl_initialize.argtypes = [] +#c_rl_initialize.restype = void + +#------------------------------------------------------------ +# special initialization of readline + +def setup_readline(space): + # XXX ... + c_rl_initialize() + +#------------------------------------------------------------ +# exported API (see interpleveldefs above) +# +def readline(space, w_prompt): + prompt = space.str_w(w_prompt) return space.wrap(c_readline(prompt)) -readline.unwrap_spec = [ObjSpace, str] +def setcompleter(space, w_callback): + """Set or remove the completer function. + The function is called as function(text, state), + for state in 0, 1, 2, ..., until it returns a non-string. + It should return the next possible completion starting with 'text'. + """ + # XXX set internal completion function From hpk at codespeak.net Tue Jun 6 12:11:54 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 6 Jun 2006 12:11:54 +0200 (CEST) Subject: [pypy-svn] r28354 - pypy/dist/pypy/doc Message-ID: <20060606101154.3F43410053@code0.codespeak.net> Author: hpk Date: Tue Jun 6 12:11:53 2006 New Revision: 28354 Modified: pypy/dist/pypy/doc/extcompiler.txt Log: (arre, holger) inprogress checkin of draft documentation Modified: pypy/dist/pypy/doc/extcompiler.txt ============================================================================== --- pypy/dist/pypy/doc/extcompiler.txt (original) +++ pypy/dist/pypy/doc/extcompiler.txt Tue Jun 6 12:11:53 2006 @@ -9,16 +9,69 @@ **WARNING: this is beta software, APIs and details may change.** +Understanding the ext compiler +---------------------------------- + +- using rctypes for binding to external libraries +- exchangeability of CPyObjspace and StdObjSpace + * translation to CPython + * translation to PyPy + +Using the ext compiler +---------------------------------------------------- + +XXXXXXXXXXXXXXXX THIS IS DOCUMENTATION WITHOUT CODE XXXXXXXXXXXXXXXXXXXXXX + +writing a module (provide example) ++++++++++++++++++++++++++++++++++++++++++ + +see `pypy/module/readline.py`_ + +XXX testing a module +XXX translating a module (to CPython extension) +XXX integration as a PyPy module + +translating a module +++++++++++++++++++++++++ + +:: + python2.4 pypy/bin/extcompiler.py path/to/readline.py + +The extension compiler imports the specified module/package +and produces a shared library importable from your local +python2.4 installation. The produced shared library is +put into the current working directory by default. + +XXX think about isolation (to only import the specified file and + not implicitely include the parent directory in sys.path) + +XXX think about shared state of imported modules (e.g. linecache + or other modules which might get imported from the ext-package) + +XXX what actually happens to applevel code in an extension module? + +somewhere-in-PYTHONPATH: + supportpackage/somecode.py + + + + +Installation notes requirements +-------------------------------------------------- + +XXX more verbose, links +you need to have a full PyPy checkout, refer to getting started required ctypes version ------------------------- +++++++++++++++++++++++++++++ As of this time, only `ctypes-0.9.9.6`_ is known to work. .. _`ctypes-0.9.9.6`: http://sourceforge.net/project/showfiles.php?group_id=71702&package_id=71318&release_id=411554 platform notes ------------------ +++++++++++++++++++ + Mac OSX ++++++++++++++++++++++++++ From antocuni at codespeak.net Tue Jun 6 12:41:56 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 12:41:56 +0200 (CEST) Subject: [pypy-svn] r28358 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20060606104156.895B110053@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 12:41:56 2006 New Revision: 28358 Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py Log: Factored two helper functions out of MethodsPBCRepr.call. Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Tue Jun 6 12:41:56 2006 @@ -111,28 +111,37 @@ return self.call("call_args", hop) def call(self, opname, hop): - bk = self.rtyper.annotator.bookkeeper - args = bk.build_args(opname, hop.args_s[1:]) - args = args.prepend(self.s_im_self) - s_pbc = hop.args_s[0] # possibly more precise than self.s_pbc - descs = [desc.funcdesc for desc in s_pbc.descriptions] - callfamily = descs[0].getcallfamily() - shape, index = description.FunctionDesc.variant_for_call_site( - bk, callfamily, descs, args) + s_pbc = hop.args_s[0] # possibly more precise than self.s_pbc + args_s = hop.args_s[1:] + shape, index, callfamily = self._get_shape_index_callfamily(opname, s_pbc, args_s) row_of_graphs = callfamily.calltables[shape][index] anygraph = row_of_graphs.itervalues().next() # pick any witness hop2 = self.add_instance_arg_to_hop(hop, opname == "call_args") vlist = callparse.callparse(self.rtyper, anygraph, hop2, opname, r_self = self.r_im_self) rresult = callparse.getrresult(self.rtyper, anygraph) + derived_mangled = self._get_method_name(opname, s_pbc, args_s) + cname = hop.inputconst(ootype.Void, derived_mangled) hop.exception_is_here() + v = hop.genop("oosend", [cname]+vlist, resulttype=rresult) + return hop.llops.convertvar(v, rresult, hop.r_result) + + def _get_shape_index_callfamily(self, opname, s_pbc, args_s): + bk = self.rtyper.annotator.bookkeeper + args = bk.build_args(opname, args_s) + args = args.prepend(self.s_im_self) + descs = [desc.funcdesc for desc in s_pbc.descriptions] + callfamily = descs[0].getcallfamily() + shape, index = description.FunctionDesc.variant_for_call_site( + bk, callfamily, descs, args) + return shape, index, callfamily + + def _get_method_name(self, opname, s_pbc, args_s): + shape, index, callfamily = self._get_shape_index_callfamily(opname, s_pbc, args_s) mangled = mangle(self.methodname) row = self.concretetable[shape, index] derived_mangled = row_method_name(mangled, row.attrname) - cname = hop.inputconst(ootype.Void, derived_mangled) - v = hop.genop("oosend", [cname]+vlist, resulttype=rresult) - return hop.llops.convertvar(v, rresult, hop.r_result) - + return derived_mangled class __extend__(pairtype(InstanceRepr, MethodsPBCRepr)): From hpk at codespeak.net Tue Jun 6 12:50:05 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 6 Jun 2006 12:50:05 +0200 (CEST) Subject: [pypy-svn] r28360 - in pypy/dist/pypy: doc doc/discussion module/readline module/readline/test Message-ID: <20060606105005.C8D6C10053@code0.codespeak.net> Author: hpk Date: Tue Jun 6 12:50:05 2006 New Revision: 28360 Added: pypy/dist/pypy/module/readline/ pypy/dist/pypy/module/readline/__init__.py - copied, changed from r28353, pypy/dist/pypy/doc/discussion/readline.py pypy/dist/pypy/module/readline/c_readline.py (contents, props changed) pypy/dist/pypy/module/readline/interp_readline.py - copied, changed from r28353, pypy/dist/pypy/doc/discussion/readline.py pypy/dist/pypy/module/readline/test/ pypy/dist/pypy/module/readline/test/__init__.py (contents, props changed) pypy/dist/pypy/module/readline/test/test_readline.py (contents, props changed) Removed: pypy/dist/pypy/doc/discussion/readline.py Modified: pypy/dist/pypy/doc/extcompiler.txt Log: (arre,hpk) refinements/new directory structure for readline example + extcompiler draft documentation Modified: pypy/dist/pypy/doc/extcompiler.txt ============================================================================== --- pypy/dist/pypy/doc/extcompiler.txt (original) +++ pypy/dist/pypy/doc/extcompiler.txt Tue Jun 6 12:50:05 2006 @@ -25,26 +25,38 @@ writing a module (provide example) +++++++++++++++++++++++++++++++++++++++++ -see `pypy/module/readline.py`_ +You have to put your module into its own directory in `pypy/module/`_ +of your local `pypy checkout`_. -XXX testing a module -XXX translating a module (to CPython extension) -XXX integration as a PyPy module +see `pypy/module/readline`_ for an example. + +XXX describe directory structure here -translating a module +testing a module ++++++++++++++++++++++++ +:: + python2.4 pypy/test_all.py pypy/module/readline/test/test_readline.py + +or:: + py.test pypy/module/readline/test/test_readline.py + +# XXX + +`pypy/module/readline/test/test_readline.py`_. + + +translating a module to a CPython extension +++++++++++++++++++++++++++++++++++++++++++++++++++++ + :: - python2.4 pypy/bin/extcompiler.py path/to/readline.py + python2.4 pypy/bin/extcompiler.py readline #""" + _libraries_ = ('readline',) + +cconfig = Module.cconfig(CConfig) + +libreadline = cconfig.ctypes_lib['readline'] + +c_readline = libreadline.readline +c_readline.restype = ctypes.c_char_p + +c_rl_initialize = libreadline.rl_initiliaze +c_rl_initialize.argtypes = [] +#c_rl_initialize.restype = void + +#------------------------------------------------------------ +# special initialization of readline + +def setup_readline(space): + # XXX ... + c_rl_initialize() Added: pypy/dist/pypy/module/readline/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/readline/test/__init__.py Tue Jun 6 12:50:05 2006 @@ -0,0 +1 @@ +# Added: pypy/dist/pypy/module/readline/test/test_readline.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/readline/test/test_readline.py Tue Jun 6 12:50:05 2006 @@ -0,0 +1,10 @@ + + +def setup_mod(mod): + #mod.space = StdObjSpace(usemodules=['readline']) + mod.space = CPyObjSpace(usemodules=['readline']) + +def app_test_basic_import(): + import readline + readline.set_completer + # test more From hpk at codespeak.net Tue Jun 6 12:53:17 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 6 Jun 2006 12:53:17 +0200 (CEST) Subject: [pypy-svn] r28361 - pypy/dist/pypy/module/time2/test Message-ID: <20060606105317.2797C10053@code0.codespeak.net> Author: hpk Date: Tue Jun 6 12:53:16 2006 New Revision: 28361 Modified: pypy/dist/pypy/module/time2/test/test_time.py Log: add a comments that we'd like to have the test be runnable with CPyObjSpace (but it lacks support for the PyPy interpreter) Modified: pypy/dist/pypy/module/time2/test/test_time.py ============================================================================== --- pypy/dist/pypy/module/time2/test/test_time.py (original) +++ pypy/dist/pypy/module/time2/test/test_time.py Tue Jun 6 12:53:16 2006 @@ -1,8 +1,9 @@ -from pypy.objspace.std import StdObjSpace +from pypy.objspace.std import Space +#from pypy.objspace.cpy import Space # XXX should work! import time def setup_module(mod): - mod.space = StdObjSpace(usemodules=['time2']) + mod.space = Space(usemodules=['time2']) class TestTime: def test_clock(self): From antocuni at codespeak.net Tue Jun 6 13:08:42 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 13:08:42 +0200 (CEST) Subject: [pypy-svn] r28362 - in pypy/dist/pypy/rpython: . ootypesystem ootypesystem/test test Message-ID: <20060606110842.118B510064@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 13:08:40 2006 New Revision: 28362 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rdict.py pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py pypy/dist/pypy/rpython/test/test_objectmodel.py Log: Basic r_dict ootypesystem support. ootype.py has been refactored a bit: the ability of handling generic types has been moved from BuiltinADTType to the new SpecializableType; StaticMethod is now a SpecializableType, too. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Tue Jun 6 13:08:40 2006 @@ -999,6 +999,33 @@ def op_runtimenew(self, class_): return ootype.runtimenew(class_) + def _get_func_or_boundmethod(self, func, method_name): + if method_name is None: + # eq_func is a HalfConcreteWrapper wrapping a StaticMethod + self_arg = [] + func_graph = func.concretize().value.graph + else: + # eq_func is an instance, we want to call 'method_name' on it + self_arg = [func] + func_graph = func._TYPE._methods[method_name].graph + + def interp_func(*args): + graph_args = self_arg + list(args) + return self.llinterpreter.eval_graph(func_graph, args=graph_args) + return func_graph.name, interp_func + + def op_oonewcustomdict(self, DICT, eq_func, eq_method_name, hash_func, hash_method_name): + eq_name, interp_eq = self._get_func_or_boundmethod(eq_func, eq_method_name) + EQ_FUNC = ootype.StaticMethod([DICT._KEYTYPE, DICT._KEYTYPE], ootype.Bool) + sm_eq = ootype.static_meth(EQ_FUNC, eq_name, _callable=interp_eq) + + hash_name, interp_hash = self._get_func_or_boundmethod(hash_func, hash_method_name) + HASH_FUNC = ootype.StaticMethod([DICT._KEYTYPE], ootype.Signed) + sm_hash = ootype.static_meth(HASH_FUNC, hash_name, _callable=interp_hash) + + # XXX: is it fine to have StaticMethod type for bound methods, too? + return ootype.newcustomdict(DICT, sm_eq, sm_hash) + def op_oosetfield(self, inst, name, value): assert checkinst(inst) assert isinstance(name, str) Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Tue Jun 6 13:08:40 2006 @@ -2,6 +2,7 @@ from pypy.rpython.lltypesystem.lltype import Bool, Void, UniChar, typeOf, \ Primitive, isCompatibleType, enforce, saferecursive from pypy.rpython.lltypesystem.lltype import frozendict, isCompatibleType +from pypy.rpython import objectmodel from pypy.tool.uid import uid STATICNESS = True @@ -159,8 +160,19 @@ all.update(self._fields) return all +class SpecializableType(OOType): + def _specialize_type(self, TYPE, generic_types): + if isinstance(TYPE, SpecializableType): + res = TYPE._specialize(generic_types) + else: + res = generic_types.get(TYPE, TYPE) + assert res is not None + return res + + def _specialize(self, generic_types): + raise NotImplementedError -class StaticMethod(OOType): +class StaticMethod(SpecializableType): __slots__ = ['_null'] def __init__(self, args, result): @@ -174,14 +186,24 @@ def _defl(self): return null(self) - + + def __repr__(self): + return "" % (list(self.ARGS), self.RESULT) + + def _specialize(self, generic_types): + ARGS = tuple([self._specialize_type(ARG, generic_types) + for ARG in self.ARGS]) + RESULT = self._specialize_type(self.RESULT, generic_types) + return self.__class__(ARGS, RESULT) + + class Meth(StaticMethod): def __init__(self, args, result): StaticMethod.__init__(self, args, result) -class BuiltinType(OOType): +class BuiltinType(SpecializableType): def _example(self): return new(self) @@ -241,22 +263,11 @@ def _setup_methods(self, generic_types): methods = {} for name, meth in self._GENERIC_METHODS.iteritems(): - #args = [generic_types.get(arg, arg) for arg in meth.ARGS] - #result = generic_types.get(meth.RESULT, meth.RESULT) args = [self._specialize_type(arg, generic_types) for arg in meth.ARGS] result = self._specialize_type(meth.RESULT, generic_types) methods[name] = Meth(args, result) self._METHODS = frozendict(methods) - def _specialize_type(self, type_, generic_types): - if isinstance(type_, BuiltinADTType): - return type_._specialize(generic_types) - else: - return generic_types.get(type_, type_) - - def _specialize(self, generic_types): - raise NotImplementedError - def _lookup(self, meth_name): METH = self._METHODS.get(meth_name) meth = None @@ -434,11 +445,11 @@ return self._KEYTYPE is not None and self._VALUETYPE is not None def _init_methods(self): - generic_types = { + self._generic_types = frozendict({ self.SELFTYPE_T: self, self.KEYTYPE_T: self._KEYTYPE, self.VALUETYPE_T: self._VALUETYPE - } + }) self._GENERIC_METHODS = frozendict({ "ll_length": Meth([], Signed), @@ -450,7 +461,7 @@ "ll_get_items_iterator": Meth([], DictItemsIterator(self.KEYTYPE_T, self.VALUETYPE_T)), }) - self._setup_methods(generic_types) + self._setup_methods(self._generic_types) # NB: We are expecting Dicts of the same KEYTYPE, VALUETYPE to # compare/hash equal. We don't redefine __eq__/__hash__ since the @@ -487,6 +498,27 @@ self._KEYTYPE = KEYTYPE self._VALUETYPE = VALUETYPE self._init_methods() + + +class CustomDict(Dict): + def __init__(self, KEYTYPE=None, VALUETYPE=None): + Dict.__init__(self, KEYTYPE, VALUETYPE) + self._null = _null_custom_dict(self) + + if self._is_initialized(): + self._init_methods() + + def _init_methods(self): + Dict._init_methods(self) + EQ_FUNC = StaticMethod([self.KEYTYPE_T, self.KEYTYPE_T], Bool) + HASH_FUNC = StaticMethod([self.KEYTYPE_T], Signed) + self._GENERIC_METHODS['ll_set_functions'] = Meth([EQ_FUNC, HASH_FUNC], Void) + self._GENERIC_METHODS['ll_copy'] = Meth([], self.SELFTYPE_T) + self._setup_methods(self._generic_types) + + def _get_interp_class(self): + return _custom_dict + class DictItemsIterator(BuiltinADTType): SELFTYPE_T = object() @@ -1033,6 +1065,26 @@ def __init__(self, DICT): self.__dict__["_TYPE"] = DICT +class _custom_dict(_dict): + def __init__(self, DICT): + self._TYPE = DICT + self._dict = 'DICT_NOT_CREATED_YET' # it's created inside ll_set_functions + + def ll_set_functions(self, sm_eq, sm_hash): + "NOT_RPYTHON" + key_eq = sm_eq._callable + key_hash = sm_hash._callable + self._dict = objectmodel.r_dict(key_eq, key_hash) + + def ll_copy(self): + "NOT_RPYTHON" + res = self.__class__(self._TYPE) + res._dict = self._dict.copy() + return res + +class _null_custom_dict(_null_mixin(_custom_dict), _custom_dict): + def __init__(self, DICT): + self.__dict__["_TYPE"] = DICT class _dict_items_iterator(_builtin_type): def __init__(self, ITER): @@ -1108,6 +1160,11 @@ elif isinstance(TYPE, BuiltinType): return TYPE._get_interp_class()(TYPE) +def oonewcustomdict(DICT, ll_eq, ll_hash): + d = new(DICT) + d.ll_set_functions(ll_eq, ll_hash) + return d + def runtimenew(class_): assert isinstance(class_, _class) assert class_ is not nullruntimeclass @@ -1207,6 +1264,9 @@ def setDictTypes(DICT, KEYTYPE, VALUETYPE): return DICT._set_types(KEYTYPE, VALUETYPE) +def setDictFunctions(DICT, ll_eq, ll_hash): + return DICT._set_functions(ll_eq, ll_hash) + def hasDictTypes(DICT): return DICT._is_initialized() Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rdict.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rdict.py Tue Jun 6 13:08:40 2006 @@ -32,10 +32,15 @@ else: self.external_value_repr, self.value_repr = self.pickrepr(value_repr) + if self.custom_eq_hash: + Dict = ootype.CustomDict + else: + Dict = ootype.Dict + if already_computed: - self.DICT = ootype.Dict(key_repr.lowleveltype, value_repr.lowleveltype) + self.DICT = Dict(key_repr.lowleveltype, value_repr.lowleveltype) else: - self.DICT = ootype.Dict() + self.DICT = Dict() self.lowleveltype = self.DICT self.dictkey = dictkey @@ -58,6 +63,9 @@ ootype.setDictTypes(self.DICT, self.key_repr.lowleveltype, self.value_repr.lowleveltype) + if self.custom_eq_hash: + self.r_rdict_eqfn, self.r_rdict_hashfn = self._custom_eq_hash_repr() + def send_message(self, hop, message, can_raise=False, v_args=None): if v_args is None: v_args = hop.inputargs(self, *hop.args_r[1:]) @@ -97,7 +105,11 @@ v_dict, = hop.inputargs(self) cDICT = hop.inputconst(ootype.Void, self.lowleveltype) hop.exception_cannot_occur() - return hop.gendirectcall(ll_dict_copy, cDICT, v_dict) + if self.custom_eq_hash: + c_copy = hop.inputconst(ootype.Void, 'll_copy') + return hop.genop('oosend', [c_copy, v_dict], resulttype=hop.r_result.lowleveltype) + else: + return hop.gendirectcall(ll_dict_copy, cDICT, v_dict) def rtype_method_update(self, hop): v_dict1, v_dict2 = hop.inputargs(self, self) @@ -193,7 +205,39 @@ def rtype_r_dict(hop): - pass # TODO + r_dict = hop.r_result + if not r_dict.custom_eq_hash: + raise TyperError("r_dict() call does not return an r_dict instance") + v_eqfn, v_hashfn = hop.inputargs(r_dict.r_rdict_eqfn, + r_dict.r_rdict_hashfn) + cDICT = hop.inputconst(ootype.Void, r_dict.DICT) + hop.exception_cannot_occur() + + if r_dict.r_rdict_eqfn.lowleveltype == ootype.Void: + c_eq_method_name = hop.inputconst(ootype.Void, None) + else: + # simulate a call to the method to get the exact variant name we need + s_pbc_eq = hop.args_s[0] # the instance which we take key_eq from + s_key = r_dict.dictkey.s_value + methodname = r_dict.r_rdict_eqfn._get_method_name("simple_call", s_pbc_eq, [s_key, s_key]) + c_eq_method_name = hop.inputconst(ootype.Void, methodname) + + if r_dict.r_rdict_hashfn.lowleveltype == ootype.Void: + c_hash_method_name = hop.inputconst(ootype.Void, None) + else: + # same as above + s_pbc_hash = hop.args_s[1] # the instance which we take key_hash from + s_key = r_dict.dictkey.s_value + methodname = r_dict.r_rdict_hashfn._get_method_name("simple_call", s_pbc_hash, [s_key]) + c_hash_method_name = hop.inputconst(ootype.Void, methodname) + + # the signature of oonewcustomdict is a bit complicated: v_eqfn + # can be either a function (with lowleveltype StaticMethod) or a + # bound method (with lowleveltype Instance). In the first case + # c_eq_method_name is None, in the latter it's a constant Void + # string containing the name of the method we want to call. + return hop.genop("oonewcustomdict", [cDICT, v_eqfn, c_eq_method_name, v_hashfn, c_hash_method_name], + resulttype=hop.r_result.lowleveltype) def ll_newdict(DICT): return ootype.new(DICT) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py Tue Jun 6 13:08:40 2006 @@ -7,6 +7,7 @@ from pypy.objspace.flow import FlowObjSpace from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.test.test_llinterp import interpret +from pypy.rpython.objectmodel import r_dict from pypy.rpython.ootypesystem import ooregistry # side effects def gengraph(f, args=[], viewBefore=False, viewAfter=False): @@ -245,3 +246,28 @@ assert interpret(oof, [True], type_system='ootype') == 2 assert interpret(oof, [False], type_system='ootype') == 1 + +def test_r_dict(): + def strange_key_eq(key1, key2): + return key1[0] == key2[0] # only the 1st character is relevant + def strange_key_hash(key): + return ord(key[0]) + def oof(): + d = r_dict(strange_key_eq, strange_key_hash) + d['x'] = 42 + return d['x'] + assert interpret(oof, [], type_system='ootype') == 42 + +def test_r_dict_bm(): + class Strange: + def key_eq(strange, key1, key2): + return key1[0] == key2[0] # only the 1st character is relevant + def key_hash(strange, key): + return ord(key[0]) + + def oof(): + strange = Strange() + d = r_dict(strange.key_eq, strange.key_hash) + d['x'] = 42 + return d['x'] + assert interpret(oof, [], type_system='ootype') == 42 Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_objectmodel.py (original) +++ pypy/dist/pypy/rpython/test/test_objectmodel.py Tue Jun 6 13:08:40 2006 @@ -2,6 +2,7 @@ from pypy.rpython.objectmodel import * from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.test.test_llinterp import interpret +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin def test_we_are_translated(): assert we_are_translated() == False @@ -145,13 +146,15 @@ assert a.binding(graph.getargs()[0]).knowntype == Strange_def assert a.binding(graph.getargs()[1]).knowntype == str -def test_rtype_r_dict(): - res = interpret(test_r_dict, []) - assert res is True - -def test_rtype_r_dict_bm(): - res = interpret(test_r_dict_bm, []) - assert res is True +class BaseTestObjectModel(BaseRtypingTest): + + def test_rtype_r_dict(self): + res = self.interpret(test_r_dict, []) + assert res is True + + def test_rtype_r_dict_bm(self): + res = self.interpret(test_r_dict_bm, []) + assert res is True def test_rtype_constant_r_dicts(): d1 = r_dict(strange_key_eq, strange_key_hash) @@ -288,3 +291,10 @@ s2 = Symbolic() py.test.raises(TypeError, "s1 < s2") py.test.raises(TypeError, "hash(s1)") + + +class TestLLtype(BaseTestObjectModel, LLRtypeMixin): + pass + +class TestOOtype(BaseTestObjectModel, OORtypeMixin): + pass From hpk at codespeak.net Tue Jun 6 13:14:43 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 6 Jun 2006 13:14:43 +0200 (CEST) Subject: [pypy-svn] r28365 - in pypy/dist/pypy: doc module/readline module/readline/test Message-ID: <20060606111443.CB23110064@code0.codespeak.net> Author: hpk Date: Tue Jun 6 13:14:43 2006 New Revision: 28365 Added: pypy/dist/pypy/module/readline/test/test_c_readline.py (contents, props changed) Modified: pypy/dist/pypy/doc/extcompiler.txt pypy/dist/pypy/module/readline/__init__.py pypy/dist/pypy/module/readline/test/test_readline.py Log: (arre, holger) we should be able to just test bindings and resolved a circular import Modified: pypy/dist/pypy/doc/extcompiler.txt ============================================================================== --- pypy/dist/pypy/doc/extcompiler.txt (original) +++ pypy/dist/pypy/doc/extcompiler.txt Tue Jun 6 13:14:43 2006 @@ -35,7 +35,11 @@ testing a module ++++++++++++++++++++++++ -:: +testing only the (ctypes) bindings:: + + python2.4 pypy/test_all.py pypy/module/readline/test/test_c_readline.py + +testing the (wrapped) package:: python2.4 pypy/test_all.py pypy/module/readline/test/test_readline.py or:: Modified: pypy/dist/pypy/module/readline/__init__.py ============================================================================== --- pypy/dist/pypy/module/readline/__init__.py (original) +++ pypy/dist/pypy/module/readline/__init__.py Tue Jun 6 13:14:43 2006 @@ -2,7 +2,6 @@ # ctypes-using module, suitable for feeding to the ext-compiler from pypy.interpreter.ctypesmodule import CTypesModule -from pypy.module.readline import c_readline # XXX raw_input needs to check for space.readline_func and use # it if its there @@ -12,6 +11,7 @@ # the above line is the doc string of the translated module def init(self, space): + from pypy.module.readline import c_readline c_readline.setup_readline(space, self) space.readline_func = self.dict_w['readline'] Added: pypy/dist/pypy/module/readline/test/test_c_readline.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/readline/test/test_c_readline.py Tue Jun 6 13:14:43 2006 @@ -0,0 +1,5 @@ + +from pypy.module.readline import c_readline + +def test_basic_import(): + c_readline.c_rl_initialize() Modified: pypy/dist/pypy/module/readline/test/test_readline.py ============================================================================== --- pypy/dist/pypy/module/readline/test/test_readline.py (original) +++ pypy/dist/pypy/module/readline/test/test_readline.py Tue Jun 6 13:14:43 2006 @@ -1,8 +1,8 @@ -def setup_mod(mod): - #mod.space = StdObjSpace(usemodules=['readline']) - mod.space = CPyObjSpace(usemodules=['readline']) +#def setup_mod(mod): +# mod.space = StdObjSpace(usemodules=['readline']) +# mod.space = CPyObjSpace(usemodules=['readline']) def app_test_basic_import(): import readline From mwh at codespeak.net Tue Jun 6 13:19:47 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 6 Jun 2006 13:19:47 +0200 (CEST) Subject: [pypy-svn] r28366 - in pypy/dist/pypy: module/stackless translator/stackless translator/stackless/test Message-ID: <20060606111947.D059710069@code0.codespeak.net> Author: mwh Date: Tue Jun 6 13:19:45 2006 New Revision: 28366 Added: pypy/dist/pypy/translator/stackless/test/test_coroutine_reconstruction.py (contents, props changed) Modified: pypy/dist/pypy/module/stackless/interp_coroutine.py pypy/dist/pypy/translator/stackless/code.py pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) A test and implementation of building a coroutine by hand using the resume_point machinery. * add two resume_points in interp_coroutine. * add names (for passing to resume_state_create) to all the prebuilt restart points. * this required making the stackless helpers and regular code use the same frame types when the saved state erases to the same types. * we advise against reading some of the new code in StacklessTransfomer.__init__ (will clean up soon). Modified: pypy/dist/pypy/module/stackless/interp_coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/interp_coroutine.py (original) +++ pypy/dist/pypy/module/stackless/interp_coroutine.py Tue Jun 6 13:19:45 2006 @@ -30,7 +30,7 @@ """ from pypy.interpreter.baseobjspace import Wrappable -from pypy.rpython.rstack import yield_current_frame_to_caller +from pypy.rpython.rstack import yield_current_frame_to_caller, resume_point import sys, os @@ -127,6 +127,7 @@ try: costate.do_things_to_do() thunk.call() + resume_point("coroutine__bind", self, state) except CoroutineExit: # ignore a shutdown exception pass @@ -146,6 +147,7 @@ raise CoroutineDamage state = self.costate incoming_frame = state.update(self).switch() + resume_point("coroutine_switch", self, state, returns=incoming_frame) left = state.last left.frame = incoming_frame left.goodbye() Modified: pypy/dist/pypy/translator/stackless/code.py ============================================================================== --- pypy/dist/pypy/translator/stackless/code.py (original) +++ pypy/dist/pypy/translator/stackless/code.py Tue Jun 6 13:19:45 2006 @@ -181,17 +181,14 @@ INDEX_CAPTURE = frame.RestartInfo.add_prebuilt(ll_stack_capture, [EMPTY_STATE]) -RESUME_AFTER_STATE = frame.make_state_header_type('resume_after_state', - ('c', lltype.Ptr(STATE_HEADER)),) - def resume_after_void(state, retvalue): if global_state.restart_substate == -1: # normal entry point for a call to state.switch() # first unwind the stack u = UnwindException() - s = lltype.malloc(RESUME_AFTER_STATE) + s = lltype.malloc(SWITCH_STATE) s.header.f_restart = INDEX_RESUME_AFTER_VOID - s.c = lltype.cast_opaque_ptr(lltype.Ptr(STATE_HEADER), state) + s.c = lltype.cast_opaque_ptr(SAVED_REFERENCE, state) add_frame_state(u, s.header) raise u elif global_state.restart_substate == 0: @@ -201,8 +198,8 @@ # the 'targetstate' local is garbage here, it must be read back from # 's.c' where we saved it by the normal entry point above mystate = global_state.top - s = lltype.cast_pointer(lltype.Ptr(RESUME_AFTER_STATE), mystate) - targetstate = s.c + s = lltype.cast_pointer(lltype.Ptr(SWITCH_STATE), mystate) + targetstate = lltype.cast_opaque_ptr(lltype.Ptr(STATE_HEADER), s.c) resume_bottom = targetstate while resume_bottom.f_back: resume_bottom = resume_bottom.f_back @@ -212,7 +209,7 @@ resume_after_void.stackless_explicit = True INDEX_RESUME_AFTER_VOID = frame.RestartInfo.add_prebuilt(resume_after_void, - [RESUME_AFTER_STATE, + [SWITCH_STATE, EMPTY_STATE]) @@ -221,9 +218,9 @@ # normal entry point for a call to state.switch() # first unwind the stack u = UnwindException() - s = lltype.malloc(RESUME_AFTER_STATE) + s = lltype.malloc(SWITCH_STATE) s.header.f_restart = INDEX_RESUME_AFTER_RAISING - s.c = lltype.cast_opaque_ptr(lltype.Ptr(STATE_HEADER), state) + s.c = lltype.cast_opaque_ptr(SAVED_REFERENCE, state) add_frame_state(u, s.header) global_state.exception = exception raise u @@ -234,8 +231,8 @@ # the 'targetstate' local is garbage here, it must be read back from # 's.c' where we saved it by the normal entry point above mystate = global_state.top - s = lltype.cast_pointer(lltype.Ptr(RESUME_AFTER_STATE), mystate) - targetstate = s.c + s = lltype.cast_pointer(lltype.Ptr(SWITCH_STATE), mystate) + targetstate = lltype.cast_opaque_ptr(lltype.Ptr(STATE_HEADER), s.c) resume_bottom = targetstate while resume_bottom.f_back: resume_bottom = resume_bottom.f_back @@ -245,7 +242,7 @@ resume_after_raising.stackless_explicit = True INDEX_RESUME_AFTER_RAISING = frame.RestartInfo.add_prebuilt(resume_after_raising, - [RESUME_AFTER_STATE, + [SWITCH_STATE, EMPTY_STATE]) template = """\ @@ -254,9 +251,9 @@ # normal entry point for a call to state.switch() # first unwind the stack u = UnwindException() - s = lltype.malloc(RESUME_AFTER_STATE) + s = lltype.malloc(SWITCH_STATE) s.header.f_restart = INDEX_RESUME_AFTER_%(TYPENAME)s - s.c = lltype.cast_opaque_ptr(lltype.Ptr(STATE_HEADER), state) + s.c = lltype.cast_opaque_ptr(SAVED_REFERENCE, state) global_state.retval_%(typename)s = retvalue add_frame_state(u, s.header) raise u @@ -267,8 +264,8 @@ # the 'targetstate' local is garbage here, it must be read back from # 's.c' where we saved it by the normal entry point above mystate = global_state.top - s = lltype.cast_pointer(lltype.Ptr(RESUME_AFTER_STATE), mystate) - targetstate = s.c + s = lltype.cast_pointer(lltype.Ptr(SWITCH_STATE), mystate) + targetstate = lltype.cast_opaque_ptr(lltype.Ptr(STATE_HEADER), s.c) resume_bottom = targetstate while resume_bottom.f_back: resume_bottom = resume_bottom.f_back @@ -279,7 +276,7 @@ resume_after_%(typename)s.stackless_explicit = True INDEX_RESUME_AFTER_%(TYPENAME)s = frame.RestartInfo.add_prebuilt(resume_after_%(typename)s, - [RESUME_AFTER_STATE, + [SWITCH_STATE, EMPTY_STATE]) """ Added: pypy/dist/pypy/translator/stackless/test/test_coroutine_reconstruction.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/stackless/test/test_coroutine_reconstruction.py Tue Jun 6 13:19:45 2006 @@ -0,0 +1,61 @@ +from pypy.module.stackless import interp_coroutine +from pypy.rpython import rstack +from pypy.rpython.rstack import resume_state_create +from pypy.translator.stackless.test.test_transform import llinterp_stackless_function +from pypy.rpython.lltypesystem.lloperation import llop +from pypy.rpython.lltypesystem import lltype + +class TestCoroutineReconstruction: + + def setup_meth(self): + interp_coroutine.costate.__init__() + + def test_simple_ish(self): + + output = [] + def f(coro, n, x): + if n == 0: + coro.switch() + rstack.resume_point("f_0") + return + f(coro, n-1, 2*x) + rstack.resume_point("f_1", coro, n, x) + output.append(x) + + class T(interp_coroutine.AbstractThunk): + def __init__(self, arg_coro, arg_n, arg_x): + self.arg_coro = arg_coro + self.arg_n = arg_n + self.arg_x = arg_x + def call(self): + f(self.arg_coro, self.arg_n, self.arg_x) + + def example(): + main_coro = interp_coroutine.costate.main + sub_coro = interp_coroutine.Coroutine() + thunk_f = T(main_coro, 5, 1) + sub_coro.bind(thunk_f) + sub_coro.switch() + + new_coro = interp_coroutine.Coroutine() + new_thunk_f = T(main_coro, 5, 1) + new_coro.bind(new_thunk_f) + + bottom = resume_state_create(None, "yield_current_frame_to_caller_1") + _bind_frame = resume_state_create(bottom, "coroutine__bind", new_coro, interp_coroutine.costate) + f_frame_1 = resume_state_create(_bind_frame, "f_1", main_coro, 5, 1) + f_frame_2 = resume_state_create(f_frame_1, "f_1", main_coro, 4, 2) + f_frame_3 = resume_state_create(f_frame_2, "f_1", main_coro, 3, 4) + f_frame_4 = resume_state_create(f_frame_3, "f_1", main_coro, 2, 8) + f_frame_5 = resume_state_create(f_frame_4, "f_1", main_coro, 1, 16) + f_frame_0 = resume_state_create(f_frame_5, "f_0") + switch_frame = resume_state_create(f_frame_0, "coroutine_switch", new_coro, interp_coroutine.costate) + + new_coro.frame = switch_frame + + new_coro.switch() + return output == [16, 8, 4, 2, 1] + + res = llinterp_stackless_function(example) + assert res == 1 + Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Tue Jun 6 13:19:45 2006 @@ -83,11 +83,11 @@ def __init__(self): self.frametypes = {} - def frame_type_for_vars(self, vars): + def _key_fieldnames_for_types(self, types): fieldnames = [] counts = {} - for v in vars: - t = storage_type(v.concretetype) + for tt in types: + t = storage_type(tt) if t is lltype.Void: fieldnames.append(None) else: @@ -95,12 +95,31 @@ fieldnames.append('state_%s_%d' % (STORAGE_FIELDS[t], n)) counts[t] = n + 1 key = lltype.frozendict(counts) + return key, fieldnames + + + def frame_type_for_vars(self, vars): + key, fieldnames = self._key_fieldnames_for_types([v.concretetype for v in vars]) if key in self.frametypes: T = self.frametypes[key] + it = iter(T._names[1:]) + rfieldnames = [] + for name in fieldnames: + if name is None: + rfieldnames.append(None) + else: + rfieldnames.append(it.next()) + try: + it.next() + except StopIteration: + pass + else: + assert False, "field name count mismatch" + return T, rfieldnames else: fields = [] for t in STORAGE_TYPES: - for j in range(counts.get(t, 0)): + for j in range(key.get(t, 0)): fields.append(('state_%s_%d' % (STORAGE_FIELDS[t], j), t)) T = frame.make_state_header_type("FrameState", *fields) self.frametypes[key] = T @@ -299,8 +318,25 @@ self.symbolic_restart_numbers = {} - # register the prebuilt restartinfos + # register the prebuilt restartinfos & give them names for use + # with resume_state_create + # the mauling of frame_typer internals should be a method on FrameTyper. for restartinfo in frame.RestartInfo.prebuilt: + name = restartinfo.func_or_graph.__name__ + for i in range(len(restartinfo.frame_types)): + label = name + '_' + str(i) + assert label not in self.symbolic_restart_numbers + # XXX we think this is right: + self.symbolic_restart_numbers[label] = SymbolicRestartNumber( + label, len(self.masterarray1) + i) + frame_type = restartinfo.frame_types[i] + self.explicit_resume_point_data[label] = frame_type + key, fieldnames = self.frametyper._key_fieldnames_for_types( + [frame_type._flds[n] for n in frame_type._names[1:]]) + assert len(fieldnames) <= 1, "nasty field ordering issues need to be solved XXX mwh, pedronis" + if key in self.frametyper.frametypes: + assert self.frametyper.frametypes[key] is frame_type + self.frametyper.frametypes[key] = frame_type self.register_restart_info(restartinfo) def transform_all(self): @@ -475,12 +511,12 @@ for a in args: if a not in parms: raise Exception, "not covered needed value at resume_point" - if parms[0] is not None: # returns= case - res = parms[0] - args = [arg for arg in args if arg is not res] - else: - args = args - res = op.result + if parms[0] is not None: # returns= case + res = parms[0] + args = [arg for arg in args if arg is not res] + else: + args = args + res = op.result (frame_type, fieldnames) = self.frametyper.frame_type_for_vars(parms[1:]) From ac at codespeak.net Tue Jun 6 13:32:35 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 6 Jun 2006 13:32:35 +0200 (CEST) Subject: [pypy-svn] r28367 - pypy/dist/pypy/module/readline Message-ID: <20060606113235.11AF010069@code0.codespeak.net> Author: ac Date: Tue Jun 6 13:32:34 2006 New Revision: 28367 Modified: pypy/dist/pypy/module/readline/c_readline.py Log: (holger, arre) Refine the desired interface with rctypes. Modified: pypy/dist/pypy/module/readline/c_readline.py ============================================================================== --- pypy/dist/pypy/module/readline/c_readline.py (original) +++ pypy/dist/pypy/module/readline/c_readline.py Tue Jun 6 13:32:34 2006 @@ -1,5 +1,6 @@ from pypy.module.readline import Module -import ctypes +from ctypes import * +from pypy.rpython.rctypes.tool.ctypes_platform import Library #------------------------------------------------------------ # configuration for binding to external readline library @@ -7,18 +8,19 @@ # class CConfig: _header_ = """#include """ - _libraries_ = ('readline',) + readline = Library('readline') + + cconfig = Module.cconfig(CConfig) -libreadline = cconfig.ctypes_lib['readline'] +libreadline = cconfig.readline -c_readline = libreadline.readline -c_readline.restype = ctypes.c_char_p - -c_rl_initialize = libreadline.rl_initiliaze -c_rl_initialize.argtypes = [] -#c_rl_initialize.restype = void +# get a binding to c library functions and define their args and return types +# char *readline(char *) +c_readline = libreadline.get_func('readline', [c_char_p], c_char_p) +# void rl_initiliaze(void) +c_rl_initialize = libreadline.get_func('rl_initiliaze', [], None) #------------------------------------------------------------ # special initialization of readline From antocuni at codespeak.net Tue Jun 6 14:16:00 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 14:16:00 +0200 (CEST) Subject: [pypy-svn] r28368 - pypy/dist/pypy/rpython Message-ID: <20060606121600.DC57D10053@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 14:15:59 2006 New Revision: 28368 Modified: pypy/dist/pypy/rpython/llinterp.py Log: Have a global wrap_func_or_boundmethod instead of LLFrame._get_func_or_boundmethod. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Tue Jun 6 14:15:59 2006 @@ -999,32 +999,19 @@ def op_runtimenew(self, class_): return ootype.runtimenew(class_) - def _get_func_or_boundmethod(self, func, method_name): - if method_name is None: - # eq_func is a HalfConcreteWrapper wrapping a StaticMethod - self_arg = [] - func_graph = func.concretize().value.graph - else: - # eq_func is an instance, we want to call 'method_name' on it - self_arg = [func] - func_graph = func._TYPE._methods[method_name].graph - - def interp_func(*args): - graph_args = self_arg + list(args) - return self.llinterpreter.eval_graph(func_graph, args=graph_args) - return func_graph.name, interp_func - def op_oonewcustomdict(self, DICT, eq_func, eq_method_name, hash_func, hash_method_name): - eq_name, interp_eq = self._get_func_or_boundmethod(eq_func, eq_method_name) + eq_name, interp_eq = \ + wrap_func_or_boundmethod(self.llinterpreter, eq_func, eq_method_name) EQ_FUNC = ootype.StaticMethod([DICT._KEYTYPE, DICT._KEYTYPE], ootype.Bool) sm_eq = ootype.static_meth(EQ_FUNC, eq_name, _callable=interp_eq) - hash_name, interp_hash = self._get_func_or_boundmethod(hash_func, hash_method_name) + hash_name, interp_hash = \ + wrap_func_or_boundmethod(self.llinterpreter, hash_func, hash_method_name) HASH_FUNC = ootype.StaticMethod([DICT._KEYTYPE], ootype.Signed) sm_hash = ootype.static_meth(HASH_FUNC, hash_name, _callable=interp_hash) # XXX: is it fine to have StaticMethod type for bound methods, too? - return ootype.newcustomdict(DICT, sm_eq, sm_hash) + return ootype.oonewcustomdict(DICT, sm_eq, sm_hash) def op_oosetfield(self, inst, name, value): assert checkinst(inst) @@ -1168,6 +1155,24 @@ text = '%s' % (text,) self.file.write(text.replace('\n', '\n'+self.indentation)) +def wrap_func_or_boundmethod(llinterpreter, func, method_name): + """ + Returns a callable that inteprets the given func or method_name when called. + """ + if method_name is None: + # eq_func is a HalfConcreteWrapper wrapping a StaticMethod + self_arg = [] + func_graph = func.concretize().value.graph + else: + # eq_func is an instance, we want to call 'method_name' on it + self_arg = [func] + func_graph = func._TYPE._methods[method_name].graph + + def interp_func(*args): + graph_args = self_arg + list(args) + return llinterpreter.eval_graph(func_graph, args=graph_args) + return func_graph.name, interp_func + # by default we route all logging messages to nothingness # e.g. tests can then switch on logging to get more help From antocuni at codespeak.net Tue Jun 6 14:29:19 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 14:29:19 +0200 (CEST) Subject: [pypy-svn] r28369 - in pypy/dist/pypy/rpython: ootypesystem test Message-ID: <20060606122919.3B84010070@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 14:29:18 2006 New Revision: 28369 Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py pypy/dist/pypy/rpython/test/test_objectmodel.py Log: Added support for r_dict constants to ootypesystem. Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rdict.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rdict.py Tue Jun 6 14:29:18 2006 @@ -1,3 +1,4 @@ +from pypy.rpython.error import TyperError from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant @@ -10,6 +11,7 @@ from pypy.rpython import robject from pypy.rpython import objectmodel from pypy.rpython import rmodel +from pypy.rpython import llinterp class DictRepr(AbstractDictRepr): @@ -153,7 +155,7 @@ def convert_const(self, dictobj): if dictobj is None: return self.DICT._defl() - if not isinstance(dictobj, dict): + if not isinstance(dictobj, dict) and not isinstance(dictobj, objectmodel.r_dict): raise TyperError("expected a dict: %r" % (dictobj,)) try: key = Constant(dictobj) @@ -161,15 +163,31 @@ except KeyError: self.setup() l_dict = ll_newdict(self.DICT) + if self.custom_eq_hash: + interp = llinterp.LLInterpreter(self.rtyper) + # key equality function + eq_func = self.r_rdict_eqfn.convert_const(dictobj.key_eq) + eq_name, interp_eq = llinterp.wrap_func_or_boundmethod(interp, eq_func, None) + EQ_FUNC = ootype.StaticMethod([self.DICT._KEYTYPE, self.DICT._KEYTYPE], ootype.Bool) + sm_eq = ootype.static_meth(EQ_FUNC, eq_name, _callable=interp_eq) + # key hashing function + hash_func = self.r_rdict_hashfn.convert_const(dictobj.key_hash) + hash_name, interp_hash = llinterp.wrap_func_or_boundmethod(interp, hash_func, None) + HASH_FUNC = ootype.StaticMethod([self.DICT._KEYTYPE], ootype.Signed) + sm_hash = ootype.static_meth(HASH_FUNC, hash_name, _callable=interp_hash) + l_dict.ll_set_functions(sm_eq, sm_hash) + self.dict_cache[key] = l_dict r_key = self.key_repr r_value = self.value_repr - # XXX need handling of r_dict here for dictkey, dictvalue in dictobj.items(): llkey = r_key.convert_const(dictkey) llvalue = r_value.convert_const(dictvalue) - l_dict.ll_set(llkey, llvalue) + if self.custom_eq_hash: + l_dict._dict._dict[llkey] = llvalue # XXX: am I cheating? + else: + l_dict.ll_set(llkey, llvalue) return l_dict class __extend__(pairtype(DictRepr, rmodel.Repr)): Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_objectmodel.py (original) +++ pypy/dist/pypy/rpython/test/test_objectmodel.py Tue Jun 6 14:29:18 2006 @@ -156,22 +156,22 @@ res = self.interpret(test_r_dict_bm, []) assert res is True -def test_rtype_constant_r_dicts(): - d1 = r_dict(strange_key_eq, strange_key_hash) - d1['hello'] = 666 - d2 = r_dict(strange_key_eq, strange_key_hash) - d2['hello'] = 777 - d2['world'] = 888 - def fn(i): - if i == 1: - d = d1 - else: - d = d2 - return len(d) - res = interpret(fn, [1]) - assert res == 1 - res = interpret(fn, [2]) - assert res == 2 + def test_rtype_constant_r_dicts(self): + d1 = r_dict(strange_key_eq, strange_key_hash) + d1['hello'] = 666 + d2 = r_dict(strange_key_eq, strange_key_hash) + d2['hello'] = 777 + d2['world'] = 888 + def fn(i): + if i == 1: + d = d1 + else: + d = d2 + return len(d) + res = self.interpret(fn, [1]) + assert res == 1 + res = self.interpret(fn, [2]) + assert res == 2 def test_rtype_r_dict_exceptions(): def raising_hash(obj): From fijal at codespeak.net Tue Jun 6 14:46:41 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 14:46:41 +0200 (CEST) Subject: [pypy-svn] r28370 - pypy/dist/pypy/translator/cli Message-ID: <20060606124641.8E44B10076@code0.codespeak.net> Author: fijal Date: Tue Jun 6 14:46:40 2006 New Revision: 28370 Modified: pypy/dist/pypy/translator/cli/metavm.py Log: Added support for direct calling (for convinience) Modified: pypy/dist/pypy/translator/cli/metavm.py ============================================================================== --- pypy/dist/pypy/translator/cli/metavm.py (original) +++ pypy/dist/pypy/translator/cli/metavm.py Tue Jun 6 14:46:40 2006 @@ -24,6 +24,9 @@ instr.render(generator, op) else: generator.emit(instr) + + def __call__(self, *args): + return self.render(*args) class MicroInstruction(object): @@ -32,7 +35,9 @@ def __str__(self): return self.__class__.__name__ - + + def __call__(self, *args): + return self.render(*args) class PushArg(MicroInstruction): def __init__(self, n): From fijal at codespeak.net Tue Jun 6 14:47:48 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 14:47:48 +0200 (CEST) Subject: [pypy-svn] r28371 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20060606124748.F3D6F10076@code0.codespeak.net> Author: fijal Date: Tue Jun 6 14:47:48 2006 New Revision: 28371 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py Log: Added rpython hinter. Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Tue Jun 6 14:47:48 2006 @@ -37,8 +37,9 @@ class Instance(OOType): """this is the type of user-defined objects""" def __init__(self, name, superclass, fields={}, methods={}, - _is_root=False): + _is_root=False, _hints = {}): self._name = name + self._hints = frozendict(_hints) if _is_root: self._superclass = None Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Tue Jun 6 14:47:48 2006 @@ -162,7 +162,11 @@ else: b = OBJECT - self.lowleveltype = ootype.Instance(classdef.name, b, {}, {}) + if hasattr(classdef.classdesc.pyobj, '_rpython_hints'): + hints = classdef.classdesc.pyobj._rpython_hints + else: + hints = {} + self.lowleveltype = ootype.Instance(classdef.name, b, {}, {}, _hints = hints) self.prebuiltinstances = {} # { id(x): (x, _ptr) } self.object_type = self.lowleveltype From fijal at codespeak.net Tue Jun 6 14:52:27 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 14:52:27 +0200 (CEST) Subject: [pypy-svn] r28372 - in pypy/dist/pypy/translator/js2: . jssrc modules test Message-ID: <20060606125227.2D40110064@code0.codespeak.net> Author: fijal Date: Tue Jun 6 14:52:25 2006 New Revision: 28372 Added: pypy/dist/pypy/translator/js2/metavm.py Removed: pypy/dist/pypy/translator/js2/_builtin.py Modified: pypy/dist/pypy/translator/js2/ (props changed) pypy/dist/pypy/translator/js2/function.py pypy/dist/pypy/translator/js2/jssrc/misc.js pypy/dist/pypy/translator/js2/modules/dom.py pypy/dist/pypy/translator/js2/opcodes.py pypy/dist/pypy/translator/js2/test/ (props changed) pypy/dist/pypy/translator/js2/test/test_dom.py pypy/dist/pypy/translator/js2/test/test_genllvm.py Log: Added svn:ignore for *.pyc Refactored builtin code support, so DOM support should be much easier now. Modified: pypy/dist/pypy/translator/js2/function.py ============================================================================== --- pypy/dist/pypy/translator/js2/function.py (original) +++ pypy/dist/pypy/translator/js2/function.py Tue Jun 6 14:52:25 2006 @@ -451,8 +451,3 @@ self.load(base_obj) self.load(item) self.ilasm.list_getitem() - - def list_resize(self, lst, new_size): - self.load(lst) - self.load(new_size) - self.set_field(None, 'length') Modified: pypy/dist/pypy/translator/js2/jssrc/misc.js ============================================================================== --- pypy/dist/pypy/translator/js2/jssrc/misc.js (original) +++ pypy/dist/pypy/translator/js2/jssrc/misc.js Tue Jun 6 14:52:25 2006 @@ -21,40 +21,6 @@ return (false); } -Function.method('old_inherits', function (parent) { - var d = 0, p = (this.prototype = new parent()); - //var p = new parent(); - //var d = 0; - this.method('uber', function uber(name) { - var f, r, t = d, v = parent.prototype; - if (t) { - while (t) { - v = v.constructor.prototype; - t -= 1; - } - f = v[name]; - } else { - f = p[name]; - if (f == this[name]) { - f = v[name]; - } - } - d += 1; - r = f.apply(this, Array.prototype.slice.apply(arguments, [1])); - d -= 1; - return r; - }); - return this; -}); - -Function.method('swiss', function (parent) { - for (var i = 1; i < arguments.length; i += 1) { - var name = arguments[i]; - this.prototype[name] = parent.prototype[name]; - } - return this; -}); - function alloc_and_set(L0, len, elem) { l = []; for(i = 0; i < len; ++i){ Added: pypy/dist/pypy/translator/js2/metavm.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/metavm.py Tue Jun 6 14:52:25 2006 @@ -0,0 +1,238 @@ + +""" Opcode meaning objects, descendants of MicroInstruction +""" + +#from pypy.translator.js2.jsbuiltin import Builtins +from pypy.translator.cli.metavm import PushArg, PushAllArgs, StoreResult,\ + InstructionList, New, SetField, GetField, RuntimeNew, MicroInstruction + +from pypy.translator.js2.log import log +from pypy.rpython.ootypesystem import ootype + +class _ListSetitem(MicroInstruction): + def render(self, generator, op): + generator.load(op.args[1]) + generator.load(op.args[3]) + generator.load(op.args[2]) + generator.ilasm.list_setitem() +ListSetitem = _ListSetitem() + +class _ListGetitem(MicroInstruction): + def render(self, generator, op): + generator.load(op.args[1]) + generator.load(op.args[2]) + generator.ilasm.list_getitem() +ListGetitem = _ListGetitem() + +class _Call(MicroInstruction): + def render(self, generator, op): + graph = op.args[0].value.graph + self._render_function(generator, graph, op.args) + + def _render_builtin(self, generator, builtin, args): + for func_arg in args[1:]: # push parameters + generator.load(func_arg) + generator.call_external(builtin, args[1:]) + + def _render_builtin_method(self, generator, builtin, args, is_property): + if not is_property: + for func_arg in args: + generator.load(func_arg) + generator.call_external_method(builtin, len(args)-1) + else: + generator.load(args[0]) + generator.get_field(None, builtin) + + def _render_function(self, generator, graph, args): + for func_arg in args[1:]: # push parameters + generator.load(func_arg) + generator.call_graph(graph) + + # Various low level function-to-operator mappings + + def _render_method(self, generator, method_name, args): + this = args[0] + for arg in args: # push parametes + generator.load(arg) + generator.call_method(this.concretetype, method_name) + +Call = _Call() + +class CallBuiltin(_Call): + def __init__(self, builtin): + self.builtin = builtin + + def render(self, generator, op): + self._render_builtin(generator, self.builtin, op.args) + +class _Builtins(object): + def __init__(self): + list_resize = lambda g,op: SetBuiltinField.run_it(g, op.args[1], 'length', op.args[2]) + + self.builtin_map = { + 'll_js_jseval' : CallBuiltin('eval'), + 'll_newlist' : lambda g,op: g.ilasm.load_const("[]"), + 'll_alloc_and_set' : CallBuiltin('alloc_and_set'), + } + self.builtin_obj_map = { + ootype.String.__class__: { + 'll_strconcat' : InstructionList([PushAllArgs, '+']), + 'll_strlen' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'), + 'll_stritem_nonneg' : ListGetitem, + 'll_streq' : InstructionList([PushAllArgs, '==']), + 'll_strcmp' : CallBuiltin('strcmp'), + 'll_startswith' : CallBuiltin('startswith'), + 'll_endswith' : CallBuiltin('endswith'), + }, + ootype.List: { + 'll_setitem_fast' : ListSetitem, + 'll_getitem_fast' : ListGetitem, + '_ll_resize' : list_resize, + '_ll_resize_ge' : list_resize, + '_ll_resize_le' : list_resize, + 'll_length' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'), + } + } + +Builtins = _Builtins() + +class _SameAs(MicroInstruction): + def render(self, generator, op): + generator.change_name(op.result, op.args[0]) + +class _CastFun(MicroInstruction): + def __init__(self, name, num): + self.name = name + self.num = num + + def render(self, generator, op): + log("Args: %r"%op.args) + generator.cast_function(self.name, self.num) + +class _Prefix(MicroInstruction): + def __init__(self, st): + self.st = st + + def render(self, generator, op): + generator.prefix_op(self.st) + +class _NotImplemented(MicroInstruction): + def __init__(self, reason): + self.reason = reason + + def render(self, generator, op): + raise NotImplementedError(self.reason) + +class _New(MicroInstruction): + def render(self, generator, op): + generator.new(op.args[0].value) + +class _CastString(MicroInstruction): + def render(self, generator, op): + this = op.args[0] + generator.load(this) + generator.call_external_method("toString", 0) + +class _GetBuiltinField(MicroInstruction): + def render(self, generator, op): + this = op.args[0] + field = op.args[1] + field_name = this.value.methods[field].name[1:] + self.run_it(generator, this, field_name) + + def run_it(self, generator, this, field_name): + generator.load(this) + generator.get_field(None, field_name) + +GetBuiltinField = _GetBuiltinField() + +class _SetBuiltinField(MicroInstruction): + def render(self, generator, op): + this = op.args[0] + field = op.args[1] + value = op.args[2] + field_name = this.value.methods[field].name[1:] + self.run_it(generator, this, field_name, value) + + def run_it(self, generator, this, field_name, value): + generator.load(this) + generator.load(value) + generator.set_field(None, field_name) + +SetBuiltinField = _SetBuiltinField() + +class _CallMethod(_Call): + def render(self, generator, op): + method = op.args[0] + self._render_method(generator, method.value, op.args[1:]) + +class _IsInstance(MicroInstruction): + def render(self, generator, op): + # FIXME: just temporary hack + generator.load(op.args[0]) + generator.ilasm.load_const(op.args[1].value._name.replace('.', '_'))#[-1]) + generator.cast_function("isinstanceof", 2) + +# There are three distinct possibilities where we need to map call differently: +# 1. Object is marked with rpython_hints as a builtin, so every attribut access +# and function call goes as builtin +# 2. Function called is a builtin, so it might be mapped to attribute access, builtin function call +# or even method call +# 3. Object on which method is called is primitive object and method is mapped to some +# method/function/attribute access +class _GeneralDispatcher(MicroInstruction): + def render(self, generator, op): + raise NotImplementedError("pure virtual class") + + def check_builtin(self, this): + if not isinstance(this, ootype.Instance): + return False + return this._hints.get('_suggested_external') + +class _MethodDispatcher(_GeneralDispatcher): + def render(self, generator, op): + method = op.args[0].value + this = op.args[1].concretetype + if self.check_builtin(this): + return CallBuiltinObject.render(generator, op) + try: + Builtins.builtin_obj_map[this.__class__][method](generator, op) + log("%r.%r declared builtin" % (this, method)) + except KeyError: + log("%r.%r declared normal" % (this, method)) + CallMethod.render(generator, op) + +class _CallDispatcher(_GeneralDispatcher): + def render(self, generator, op): + func = op.args[0] + if getattr(func.value._callable, 'suggested_primitive', False): + func_name = func.value._name.split("__")[0] + log("Function name: %s suggested primitive" % func_name) + if Builtins.builtin_map.has_key(func_name): + return Builtins.builtin_map[func_name](generator, op) + else: + return Call.render(generator, op) + +class _GetFieldDispatcher(_GeneralDispatcher): + def render(self, generator, op): + if self.check_builtin(op.args[0].concretetype): + return GetBuiltinField.render(generator, op) + else: + return GetField.render(generator, op) + +class _SetFieldDispatcher(_GeneralDispatcher): + def render(self, generator, op): + if self.check_builtin(op.args[0].concretetype): + return SetBuiltinField.render(generator, op) + else: + return SetField.render(generator, op) + +MethodDispatcher = _MethodDispatcher() +CallDispatcher = _CallDispatcher() +GetFieldDispatcher = _GetFieldDispatcher() +SetFieldDispatcher = _SetFieldDispatcher() +IsInstance = _IsInstance() +CallMethod = _CallMethod() +CopyName = [PushAllArgs, _SameAs ()] +CastString = _CastString() +SameAs = CopyName Modified: pypy/dist/pypy/translator/js2/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js2/modules/dom.py (original) +++ pypy/dist/pypy/translator/js2/modules/dom.py Tue Jun 6 14:52:25 2006 @@ -6,15 +6,47 @@ # FIXME: this should map somehow to xml.dom interface, or something else +import time + +class Style(object): + def __init__(self, s_str): + self.left = "0" + self.top = "0" + + def setLeft(self, left): + self.left = left + + def getLeft(self): + return self.left + + def setTop(self, top): + self.top = top + + def getTop(self): + return self.top + class Node(object): + _rpython_hints = {'_suggested_external' : True} + def __init__(self): self.innerHTML = "" + self.style = None def getElementById(self, id): return Node() def setInnerHTML(self, data): self.innerHTML = data + + def setAttribute(self, name, style_str): + if name == 'style': + self.style = Style( style_str) + + def getStyle(self): + return self.style + +document = Node() -def get_document(): - return Node() +def setTimeout(func, delay): + # scheduler call, but we don't want to mess with threads right now + return func Modified: pypy/dist/pypy/translator/js2/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js2/opcodes.py (original) +++ pypy/dist/pypy/translator/js2/opcodes.py Tue Jun 6 14:52:25 2006 @@ -3,151 +3,16 @@ """ from pypy.translator.cli.metavm import PushArg, PushAllArgs, StoreResult,\ - InstructionList, New, SetField, GetField, RuntimeNew, MicroInstruction + InstructionList, New, SetField, GetField, RuntimeNew, MicroInstruction + +from pypy.translator.js2.metavm import SameAs, IsInstance, Call, CallMethod, CopyName, CastString,\ + _Prefix, _CastFun, _NotImplemented, GetFieldDispatcher, SetFieldDispatcher, CallDispatcher, MethodDispatcher DoNothing = [PushAllArgs] from pypy.translator.js2._builtin import Builtins from pypy.translator.js2.log import log -##class _GetField(MicroInstruction): -## def render(self, generator, op): -## this, field = op.args -## generator.load(this) -## generator.get_field(this.concretetype, field.value) - -class _SameAs(MicroInstruction): - def render(self, generator, op): - generator.change_name(op.result, op.args[0]) - -class _CastFun(MicroInstruction): - def __init__(self, name, num): - self.name = name - self.num = num - - def render(self, generator, op): - log("Args: %r"%op.args) - generator.cast_function(self.name, self.num) - -class _Prefix(MicroInstruction): - def __init__(self, st): - self.st = st - - def render(self, generator, op): - generator.prefix_op(self.st) - -class _NotImplemented(MicroInstruction): - def __init__(self, reason): - self.reason = reason - - def render(self, generator, op): - raise NotImplementedError(self.reason) - -class _New(MicroInstruction): - def render(self, generator, op): - generator.new(op.args[0].value) - -class _CastString(MicroInstruction): - def render(self, generator, op): - this = op.args[0] - generator.load(this) - generator.call_external_method("toString", 0) - -class _Call(MicroInstruction): - def render(self, generator, op): - graph = op.args[0].value.graph - #method_name = oopspec.get_method_name(graph, op) - #if method_name is None: - if op.args[0] in generator.db.name_manager.predefined: - bt = op.args[0], False - else: - bt = Builtins.map_builtin_function(op.args[0], self, op.args, generator) - if bt: - builtin, is_property = bt - self._render_builtin(generator, builtin, op.args, is_property) - log("Suggested builtin %r %r"%(bt, is_property)) - if bt is None: - self._render_function(generator, graph, op.args) - #else: - # self._render_method(generator, method_name, op.args[1:]) - - def _render_builtin(self, generator, builtin, args, is_property): - if not is_property: - for func_arg in args[1:]: # push parameters - generator.load(func_arg) - generator.call_external(builtin, args[1:]) - else: - generator.load_str(builtin) - - def _render_builtin_method(self, generator, builtin, args, is_property): - if not is_property: - for func_arg in args: - generator.load(func_arg) - generator.call_external_method(builtin, len(args)-1) - else: - generator.load(args[0]) - generator.get_field(None, builtin) - - def _render_function(self, generator, graph, args): - #func_sig = generator.function_signature(graph) - for func_arg in args[1:]: # push parameters - generator.load(func_arg) - generator.call_graph(graph) - - # Various low level function-to-operator mappings - - def list_ll_setitem(self, base_obj, args, generator): - generator.list_setitem(base_obj, args[1], args[2]) - - def list_ll_getitem(self, base_obj, args, generator): - generator.list_getitem(base_obj, args[1]) - - def list_ll_resize(self, base_obj, args, generator): - generator.list_resize(base_obj, args[1]) - - def do_nothing(self, base_obj, args, generator): - generator.load_void() - - def setitem(self, base_obj, args, generator, real_name): - generator.load(base_obj) - generator.load(args[1]) - generator.set_field(None, real_name) - - def equal(self, base_obj, args, generator): - generator.load(args[1]) - generator.load(args[2]) - generator.emit("==") - - def _render_method(self, generator, method_name, args): - this = args[0] - bt = Builtins.map_builtin_method(this, method_name, args, self, generator) - if bt: - function,is_property = bt - self._render_builtin_method(generator, function, args, is_property) - if bt is None: - for arg in args: # push parametes - generator.load(arg) - generator.call_method(this.concretetype, method_name) - -class _CallMethod(_Call): - def render(self, generator, op): - method = op.args[0] - self._render_method(generator, method.value, op.args[1:]) - -class _IsInstance(MicroInstruction): - def render(self, generator, op): - # FIXME: just temporary hack - generator.load(op.args[0]) - generator.ilasm.load_const(op.args[1].value._name.replace('.', '_'))#[-1]) - generator.cast_function("isinstanceof", 2) - -IsInstance = _IsInstance() -Call = _Call() -CallMethod = _CallMethod() -CopyName = [PushAllArgs, _SameAs ()] -CastString = _CastString() -SameAs = CopyName - opcodes = {'int_mul': '*', 'int_add': '+', 'int_sub': '-', @@ -224,7 +89,7 @@ 'uint_is_true': [PushAllArgs,_Prefix('!!')], 'float_is_true': [PushAllArgs,_Prefix('!!')], - 'direct_call' : [Call], + 'direct_call' : [CallDispatcher], 'indirect_call' : [_NotImplemented("Indirect call not implemented")], 'same_as' : SameAs, 'new' : [New], @@ -232,9 +97,9 @@ # objects - 'oosetfield' : [SetField], - 'oogetfield' : [GetField], - 'oosend' : [CallMethod], + 'oosetfield' : [SetFieldDispatcher], + 'oogetfield' : [GetFieldDispatcher], + 'oosend' : [MethodDispatcher], #'ooupcast' : [_NotImplemented("Inheritance not implemented (ooupcast)")], #'oodowncast' : [_NotImplemented("Inheritance not implemented (oodowncast)")], 'ooupcast' : DoNothing, Modified: pypy/dist/pypy/translator/js2/test/test_dom.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_dom.py (original) +++ pypy/dist/pypy/translator/js2/test/test_dom.py Tue Jun 6 14:52:25 2006 @@ -5,7 +5,7 @@ import py from pypy.translator.js2.test.runtest import compile_function -from pypy.translator.js2.modules.dom import get_document +from pypy.translator.js2.modules.dom import document, setTimeout, Node from pypy.translator.js2 import conftest import time @@ -16,8 +16,30 @@ class TestDOM(object): def test_document_base(self): def f(): - get_document().getElementById("dupa").setInnerHTML("

Fire!

") - return get_document().getElementById("dupa") + return document.getElementById("dupa") + #document.getElementById("dupa").setInnerHTML("

Fire!

") + #return document.getElementById("dupa") fn = compile_function(f, [], html = 'html/test.html') assert fn() == '[object HTMLHeadingElement]' + + def test_anim(self): + def move_it_by(obj, dx, dy, dir): + if dir < 0: + dx = -dx + dy = -dy + obj.getStyle().setLeft(str(int(obj.getStyle().getLeft()) + dx) + "px") + obj.getStyle().setTop(str(int(obj.getStyle().getTop()) + dy) + "px") + + def move_it(): + move_it_by(get_document().getElementById("anim_img"), 3, 3, 1) + setTimeout('move_it()', 100) + + def anim_fun(): + obj = get_document().getElementById("anim_img") + obj.setAttribute('style', 'position: absolute; top: 0; left: 0;') + setTimeout('move_it()', 100) + move_it() + + fn = compile_function(anim_fun, [], html = 'html/anim.html', is_interactive = True) + assert fn() == 'ok' Modified: pypy/dist/pypy/translator/js2/test/test_genllvm.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_genllvm.py (original) +++ pypy/dist/pypy/translator/js2/test/test_genllvm.py Tue Jun 6 14:52:25 2006 @@ -411,3 +411,11 @@ f = compile_function(testf, [int]) assert f(1) == testf(1) assert f(2) == testf(2) + +def test_cast_str(): + def cast_str(x): + return str(x)+str(x)+'px' + + f = compile_function(cast_str, [int]) + assert f(1) == cast_str(1) + assert f(10) == cast_str(10) From fijal at codespeak.net Tue Jun 6 14:55:03 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 14:55:03 +0200 (CEST) Subject: [pypy-svn] r28373 - pypy/dist/pypy/translator/js2 Message-ID: <20060606125503.708E31006F@code0.codespeak.net> Author: fijal Date: Tue Jun 6 14:55:02 2006 New Revision: 28373 Modified: pypy/dist/pypy/translator/js2/function.py pypy/dist/pypy/translator/js2/metavm.py pypy/dist/pypy/translator/js2/opcodes.py Log: Removed unused import Modified: pypy/dist/pypy/translator/js2/function.py ============================================================================== --- pypy/dist/pypy/translator/js2/function.py (original) +++ pypy/dist/pypy/translator/js2/function.py Tue Jun 6 14:55:02 2006 @@ -14,8 +14,6 @@ from pypy.translator.cli.node import Node from pypy.translator.cli.class_ import Class -from pypy.translator.js2._builtin import Builtins - from pypy.translator.js2.log import log import re Modified: pypy/dist/pypy/translator/js2/metavm.py ============================================================================== --- pypy/dist/pypy/translator/js2/metavm.py (original) +++ pypy/dist/pypy/translator/js2/metavm.py Tue Jun 6 14:55:02 2006 @@ -48,8 +48,6 @@ generator.load(func_arg) generator.call_graph(graph) - # Various low level function-to-operator mappings - def _render_method(self, generator, method_name, args): this = args[0] for arg in args: # push parametes Modified: pypy/dist/pypy/translator/js2/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js2/opcodes.py (original) +++ pypy/dist/pypy/translator/js2/opcodes.py Tue Jun 6 14:55:02 2006 @@ -10,7 +10,6 @@ DoNothing = [PushAllArgs] -from pypy.translator.js2._builtin import Builtins from pypy.translator.js2.log import log opcodes = {'int_mul': '*', From antocuni at codespeak.net Tue Jun 6 15:09:57 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 15:09:57 +0200 (CEST) Subject: [pypy-svn] r28374 - pypy/dist/pypy/rpython Message-ID: <20060606130957.9D2C310064@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 15:09:56 2006 New Revision: 28374 Modified: pypy/dist/pypy/rpython/typesystem.py Log: Make possibile to use operator 'is' on BuiltinADTTypes too in ootypesystem. Modified: pypy/dist/pypy/rpython/typesystem.py ============================================================================== --- pypy/dist/pypy/rpython/typesystem.py (original) +++ pypy/dist/pypy/rpython/typesystem.py Tue Jun 6 15:09:56 2006 @@ -125,8 +125,8 @@ robj1 = robj2 elif robj2.lowleveltype is lltype.Void: robj2 = robj1 - if (not isinstance(robj1.lowleveltype, ootype.Instance) or - not isinstance(robj2.lowleveltype, ootype.Instance)) and \ + if (not isinstance(robj1.lowleveltype, (ootype.Instance, ootype.BuiltinADTType)) or + not isinstance(robj2.lowleveltype, (ootype.Instance, ootype.BuiltinADTType))) and \ (robj1.lowleveltype is not ootype.Class or robj2.lowleveltype is not ootype.Class): raise TyperError('is of instances of the non-instances: %r, %r' % ( From antocuni at codespeak.net Tue Jun 6 15:11:02 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 15:11:02 +0200 (CEST) Subject: [pypy-svn] r28375 - in pypy/dist/pypy/rpython: ootypesystem test Message-ID: <20060606131102.4C97110064@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 15:11:01 2006 New Revision: 28375 Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py pypy/dist/pypy/rpython/test/test_objectmodel.py Log: More tests for ootypesystem's r_dict. Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rdict.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rdict.py Tue Jun 6 15:11:01 2006 @@ -209,12 +209,12 @@ def rtype_setitem((r_dict, r_key), hop): v_dict, v_key, v_value = hop.inputargs(r_dict, r_dict.key_repr, r_dict.value_repr) -## if r_dict.custom_eq_hash: -## hop.exception_is_here() + if r_dict.custom_eq_hash: + hop.exception_is_here() ## else: ## hop.exception_cannot_occur() ## hop.exception_is_here() - return r_dict.send_message(hop, 'll_set', can_raise=True) + return r_dict.send_message(hop, 'll_set', can_raise=r_dict.custom_eq_hash) def rtype_contains((r_dict, r_key), hop): v_dict, v_key = hop.inputargs(r_dict, r_dict.key_repr) Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_objectmodel.py (original) +++ pypy/dist/pypy/rpython/test/test_objectmodel.py Tue Jun 6 15:11:01 2006 @@ -173,45 +173,81 @@ res = self.interpret(fn, [2]) assert res == 2 -def test_rtype_r_dict_exceptions(): - def raising_hash(obj): - if obj.startswith("bla"): - raise TypeError - return 1 - def eq(obj1, obj2): - return obj1 is obj2 - def f(): - d1 = r_dict(eq, raising_hash) - d1['xxx'] = 1 - try: - x = d1["blabla"] - except Exception: - return 42 - return x - res = interpret(f, []) - assert res == 42 - - def f(): - d1 = r_dict(eq, raising_hash) - d1['xxx'] = 1 - try: - x = d1["blabla"] - except TypeError: - return 42 - return x - res = interpret(f, []) - assert res == 42 - - def f(): - d1 = r_dict(eq, raising_hash) - d1['xxx'] = 1 - try: - d1["blabla"] = 2 - except TypeError: - return 42 - return 0 - res = interpret(f, []) - assert res == 42 + def test_rtype_r_dict_exceptions(self): + self._skip_oo('r_dict exception handling') + def raising_hash(obj): + if obj.startswith("bla"): + raise TypeError + return 1 + def eq(obj1, obj2): + return obj1 is obj2 + def f(): + d1 = r_dict(eq, raising_hash) + d1['xxx'] = 1 + try: + x = d1["blabla"] + except Exception: + return 42 + return x + res = self.interpret(f, []) + assert res == 42 + + def f(): + d1 = r_dict(eq, raising_hash) + d1['xxx'] = 1 + try: + x = d1["blabla"] + except TypeError: + return 42 + return x + res = self.interpret(f, []) + assert res == 42 + + def f(): + d1 = r_dict(eq, raising_hash) + d1['xxx'] = 1 + try: + d1["blabla"] = 2 + except TypeError: + return 42 + return 0 + res = self.interpret(f, []) + assert res == 42 + + def test_access_in_try(self): + h = lambda x: 1 + eq = lambda x,y: x==y + def f(d): + try: + return d[2] + except ZeroDivisionError: + return 42 + return -1 + def g(n): + d = r_dict(eq, h) + d[1] = n + d[2] = 2*n + return f(d) + res = self.interpret(g, [3]) + assert res == 6 + + def test_access_in_try_set(self): + self._skip_oo('r_dict exception handling') + h = lambda x: 1 + eq = lambda x,y: x==y + def f(d): + try: + d[2] = 77 + except ZeroDivisionError: + return 42 + return -1 + def g(n): + d = r_dict(eq, h) + d[1] = n + f(d) + return d[2] + res = self.interpret(g, [3]) + assert res == 77 def test_rtype_keepalive(): @@ -233,41 +269,6 @@ res = interpret(f, []) assert res == 5 - -def test_access_in_try(): - h = lambda x: 1 - eq = lambda x,y: x==y - def f(d): - try: - return d[2] - except ZeroDivisionError: - return 42 - return -1 - def g(n): - d = r_dict(eq, h) - d[1] = n - d[2] = 2*n - return f(d) - res = interpret(g, [3]) - assert res == 6 - -def test_access_in_try_set(): - h = lambda x: 1 - eq = lambda x,y: x==y - def f(d): - try: - d[2] = 77 - except ZeroDivisionError: - return 42 - return -1 - def g(n): - d = r_dict(eq, h) - d[1] = n - f(d) - return d[2] - res = interpret(g, [3]) - assert res == 77 - def test_unboxed_value(): class Base(object): pass From antocuni at codespeak.net Tue Jun 6 15:20:41 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 15:20:41 +0200 (CEST) Subject: [pypy-svn] r28376 - pypy/dist/pypy/rpython/test Message-ID: <20060606132041.14B3210064@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 15:20:40 2006 New Revision: 28376 Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py Log: More ootypesystem tests. Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_objectmodel.py (original) +++ pypy/dist/pypy/rpython/test/test_objectmodel.py Tue Jun 6 15:20:40 2006 @@ -1,17 +1,8 @@ import py from pypy.rpython.objectmodel import * from pypy.translator.translator import TranslationContext, graphof -from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -def test_we_are_translated(): - assert we_are_translated() == False - - def fn(): - return we_are_translated() - res = interpret(fn, []) - assert res is True - def strange_key_eq(key1, key2): return key1[0] == key2[0] # only the 1st character is relevant def strange_key_hash(key): @@ -70,28 +61,6 @@ assert d.keys() == [] return True # for the tests below -def test_cast_to_and_from_weakaddress(): - class A(object): - pass - class B(object): - pass - def f(): - a = A() - addr = cast_object_to_weakgcaddress(a) - return a is cast_weakgcaddress_to_object(addr, A) - assert f() - res = interpret(f, []) - assert res - a = A() - addr = cast_object_to_weakgcaddress(A) - py.test.raises(AssertionError, "cast_weakgcaddress_to_object(addr, B)") - assert isinstance(cast_weakgcaddress_to_int(addr), int) - def g(): - a = A() - addr = cast_object_to_weakgcaddress(a) - return cast_weakgcaddress_to_int(addr) - assert isinstance(interpret(f, []), int) - def test_recursive_r_dict_repr(): import operator @@ -146,7 +115,40 @@ assert a.binding(graph.getargs()[0]).knowntype == Strange_def assert a.binding(graph.getargs()[1]).knowntype == str + +def test_unboxed_value(): + class Base(object): + pass + class C(Base, UnboxedValue): + __slots__ = 'smallint' + + assert C(17).smallint == 17 + assert C(17).getvalue() == 17 + + class A(UnboxedValue): + __slots__ = ['value'] + + assert A(12098).value == 12098 + assert A(12098).getvalue() == 12098 + +def test_symbolic(): + py.test.skip("xxx no test here") + +def test_symbolic_raises(): + s1 = Symbolic() + s2 = Symbolic() + py.test.raises(TypeError, "s1 < s2") + py.test.raises(TypeError, "hash(s1)") + class BaseTestObjectModel(BaseRtypingTest): + + def test_we_are_translated(self): + assert we_are_translated() == False + + def fn(): + return we_are_translated() + res = self.interpret(fn, []) + assert res is True def test_rtype_r_dict(self): res = self.interpret(test_r_dict, []) @@ -249,53 +251,49 @@ res = self.interpret(g, [3]) assert res == 77 + def test_hint(self): + self._skip_oo('hint') + from pypy.rpython import objectmodel + def f(): + x = objectmodel.hint(5, hello="world") + return x + res = self.interpret(f, []) + assert res == 5 -def test_rtype_keepalive(): - from pypy.rpython import objectmodel - def f(): - x = [1] - y = ['b'] - objectmodel.keepalive_until_here(x,y) - return 1 - - res = interpret(f, []) - assert res == 1 - -def test_hint(): - from pypy.rpython import objectmodel - def f(): - x = objectmodel.hint(5, hello="world") - return x - res = interpret(f, []) - assert res == 5 - -def test_unboxed_value(): - class Base(object): - pass - class C(Base, UnboxedValue): - __slots__ = 'smallint' - - assert C(17).smallint == 17 - assert C(17).getvalue() == 17 - - class A(UnboxedValue): - __slots__ = ['value'] - - assert A(12098).value == 12098 - assert A(12098).getvalue() == 12098 - -def test_symbolic(): - py.test.skip("xxx no test here") +class TestLLtype(BaseTestObjectModel, LLRtypeMixin): + def test_cast_to_and_from_weakaddress(self): + class A(object): + pass + class B(object): + pass + def f(): + a = A() + addr = cast_object_to_weakgcaddress(a) + return a is cast_weakgcaddress_to_object(addr, A) + assert f() + res = self.interpret(f, []) + assert res + a = A() + addr = cast_object_to_weakgcaddress(A) + py.test.raises(AssertionError, "cast_weakgcaddress_to_object(addr, B)") + assert isinstance(cast_weakgcaddress_to_int(addr), int) + def g(): + a = A() + addr = cast_object_to_weakgcaddress(a) + return cast_weakgcaddress_to_int(addr) + assert isinstance(self.interpret(f, []), int) -def test_symbolic_raises(): - s1 = Symbolic() - s2 = Symbolic() - py.test.raises(TypeError, "s1 < s2") - py.test.raises(TypeError, "hash(s1)") + def test_rtype_keepalive(self): + from pypy.rpython import objectmodel + def f(): + x = [1] + y = ['b'] + objectmodel.keepalive_until_here(x,y) + return 1 + res = self.interpret(f, []) + assert res == 1 -class TestLLtype(BaseTestObjectModel, LLRtypeMixin): - pass class TestOOtype(BaseTestObjectModel, OORtypeMixin): pass From ericvrp at codespeak.net Tue Jun 6 15:34:57 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 6 Jun 2006 15:34:57 +0200 (CEST) Subject: [pypy-svn] r28377 - pypy/dist/pypy/translator/js2 Message-ID: <20060606133457.800DB10036@code0.codespeak.net> Author: ericvrp Date: Tue Jun 6 15:34:56 2006 New Revision: 28377 Added: pypy/dist/pypy/translator/js2/conftest.py (contents, props changed) Log: Added missing conftest to get test_dom.py to work. Fijal, if this does not resemble your actual conftest, please remove mine. Added: pypy/dist/pypy/translator/js2/conftest.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/conftest.py Tue Jun 6 15:34:56 2006 @@ -0,0 +1,8 @@ +import py + +Option = py.test.Config.Option + +option = py.test.Config.addoptions("pypy-js options", + Option('--browser', action="store_true",dest="browser", + default=False, help="run Javascript tests in your default browser"), + ) From fijal at codespeak.net Tue Jun 6 15:42:16 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 15:42:16 +0200 (CEST) Subject: [pypy-svn] r28378 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20060606134216.9444A10053@code0.codespeak.net> Author: fijal Date: Tue Jun 6 15:42:14 2006 New Revision: 28378 Modified: pypy/dist/pypy/rpython/ootypesystem/ll_str.py pypy/dist/pypy/rpython/ootypesystem/rstr.py Log: Added possible suggested_primitive optimizations Modified: pypy/dist/pypy/rpython/ootypesystem/ll_str.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ll_str.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ll_str.py Tue Jun 6 15:42:14 2006 @@ -5,6 +5,7 @@ def ll_int_str(repr, i): return ll_int2dec(i) +ll_int_str.suggested_primitive = True def ll_int2dec(i): return oostring(i, const(10)) Modified: pypy/dist/pypy/rpython/ootypesystem/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rstr.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rstr.py Tue Jun 6 15:42:14 2006 @@ -152,6 +152,7 @@ def ll_int(s, base): return ootype.ooparse_int(s, base) + ll_int.suggested_primitive = True def do_stringformat(cls, hop, sourcevarsrepr): InstanceRepr = hop.rtyper.type_system.rclass.InstanceRepr From fijal at codespeak.net Tue Jun 6 15:42:42 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 15:42:42 +0200 (CEST) Subject: [pypy-svn] r28379 - in pypy/dist/pypy/translator/js2: . modules test Message-ID: <20060606134242.A394310053@code0.codespeak.net> Author: fijal Date: Tue Jun 6 15:42:41 2006 New Revision: 28379 Modified: pypy/dist/pypy/translator/js2/metavm.py pypy/dist/pypy/translator/js2/modules/dom.py pypy/dist/pypy/translator/js2/opcodes.py pypy/dist/pypy/translator/js2/test/test_dom.py Log: DOM preliminary version now works, also with element getting/setting. Modified: pypy/dist/pypy/translator/js2/metavm.py ============================================================================== --- pypy/dist/pypy/translator/js2/metavm.py (original) +++ pypy/dist/pypy/translator/js2/metavm.py Tue Jun 6 15:42:41 2006 @@ -34,14 +34,10 @@ generator.load(func_arg) generator.call_external(builtin, args[1:]) - def _render_builtin_method(self, generator, builtin, args, is_property): - if not is_property: - for func_arg in args: - generator.load(func_arg) - generator.call_external_method(builtin, len(args)-1) - else: - generator.load(args[0]) - generator.get_field(None, builtin) + def _render_builtin_method(self, generator, builtin, args): + for func_arg in args: + generator.load(func_arg) + generator.call_external_method(builtin, len(args)-1) def _render_function(self, generator, graph, args): for func_arg in args[1:]: # push parameters @@ -71,6 +67,11 @@ 'll_js_jseval' : CallBuiltin('eval'), 'll_newlist' : lambda g,op: g.ilasm.load_const("[]"), 'll_alloc_and_set' : CallBuiltin('alloc_and_set'), + 'get_document' : lambda g,op: g.ilasm.load_const('document'), + 'setTimeout' : CallBuiltin('setTimeout'), + 'll_int_str' : lambda g,op: Call._render_builtin_method(g, 'toString' , [op.args[2]]), + 'll_strconcat' : InstructionList([PushAllArgs, '+']), + 'll_int' : CallBuiltin('parseInt'), } self.builtin_obj_map = { ootype.String.__class__: { @@ -134,9 +135,8 @@ class _GetBuiltinField(MicroInstruction): def render(self, generator, op): this = op.args[0] - field = op.args[1] - field_name = this.value.methods[field].name[1:] - self.run_it(generator, this, field_name) + field = op.args[1].value[1:] + self.run_it(generator, this, field) def run_it(self, generator, this, field_name): generator.load(this) @@ -147,10 +147,13 @@ class _SetBuiltinField(MicroInstruction): def render(self, generator, op): this = op.args[0] - field = op.args[1] - value = op.args[2] - field_name = this.value.methods[field].name[1:] - self.run_it(generator, this, field_name, value) + field = op.args[1].value + if not field.startswith('o'): + generator.load_void() + else: + value = op.args[2] + field_name = field[1:] + self.run_it(generator, this, field_name, value) def run_it(self, generator, this, field_name, value): generator.load(this) @@ -164,6 +167,16 @@ method = op.args[0] self._render_method(generator, method.value, op.args[1:]) +class _CallBuiltinObject(_Call): + def render(self, generator, op): + this = op.args[1].concretetype + method = op.args[0] + method_name = this._methods[method.value]._name[1:] + generator.load(op.args[1]) + self._render_builtin_method(generator, method_name, op.args[1:]) + +CallBuiltinObject = _CallBuiltinObject() + class _IsInstance(MicroInstruction): def render(self, generator, op): # FIXME: just temporary hack @@ -206,8 +219,8 @@ if getattr(func.value._callable, 'suggested_primitive', False): func_name = func.value._name.split("__")[0] log("Function name: %s suggested primitive" % func_name) - if Builtins.builtin_map.has_key(func_name): - return Builtins.builtin_map[func_name](generator, op) + #if Builtins.builtin_map.has_key(func_name): + return Builtins.builtin_map[func_name](generator, op) else: return Call.render(generator, op) Modified: pypy/dist/pypy/translator/js2/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js2/modules/dom.py (original) +++ pypy/dist/pypy/translator/js2/modules/dom.py Tue Jun 6 15:42:41 2006 @@ -9,21 +9,12 @@ import time class Style(object): + _rpython_hints = {'_suggested_external' : True} + def __init__(self, s_str): self.left = "0" self.top = "0" - - def setLeft(self, left): - self.left = left - - def getLeft(self): - return self.left - - def setTop(self, top): - self.top = top - - def getTop(self): - return self.top + class Node(object): _rpython_hints = {'_suggested_external' : True} @@ -35,18 +26,19 @@ def getElementById(self, id): return Node() - def setInnerHTML(self, data): - self.innerHTML = data - def setAttribute(self, name, style_str): if name == 'style': self.style = Style( style_str) - - def getStyle(self): - return self.style + +def get_document(): + return Node() + +get_document.suggested_primitive = True document = Node() def setTimeout(func, delay): # scheduler call, but we don't want to mess with threads right now return func + +setTimeout.suggested_primitive = True Modified: pypy/dist/pypy/translator/js2/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js2/opcodes.py (original) +++ pypy/dist/pypy/translator/js2/opcodes.py Tue Jun 6 15:42:41 2006 @@ -6,7 +6,8 @@ InstructionList, New, SetField, GetField, RuntimeNew, MicroInstruction from pypy.translator.js2.metavm import SameAs, IsInstance, Call, CallMethod, CopyName, CastString,\ - _Prefix, _CastFun, _NotImplemented, GetFieldDispatcher, SetFieldDispatcher, CallDispatcher, MethodDispatcher + _Prefix, _CastFun, _NotImplemented, GetFieldDispatcher, SetFieldDispatcher, CallDispatcher, MethodDispatcher,\ + CallBuiltin DoNothing = [PushAllArgs] @@ -105,6 +106,7 @@ 'oodowncast' : DoNothing, 'oononnull' : [PushAllArgs,_Prefix('!!')], 'oostring' : [CastString], + 'ooparse_int' : [CallBuiltin('parseInt')], 'oois' : '==', # FIXME: JS does not have real equal # when casting from bool we want that every truth value is casted # to 1: we can't simply DoNothing, because the CLI stack could Modified: pypy/dist/pypy/translator/js2/test/test_dom.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_dom.py (original) +++ pypy/dist/pypy/translator/js2/test/test_dom.py Tue Jun 6 15:42:41 2006 @@ -5,7 +5,7 @@ import py from pypy.translator.js2.test.runtest import compile_function -from pypy.translator.js2.modules.dom import document, setTimeout, Node +from pypy.translator.js2.modules.dom import document, setTimeout, Node, get_document from pypy.translator.js2 import conftest import time @@ -16,7 +16,7 @@ class TestDOM(object): def test_document_base(self): def f(): - return document.getElementById("dupa") + return get_document().getElementById("dupa") #document.getElementById("dupa").setInnerHTML("

Fire!

") #return document.getElementById("dupa") @@ -28,8 +28,8 @@ if dir < 0: dx = -dx dy = -dy - obj.getStyle().setLeft(str(int(obj.getStyle().getLeft()) + dx) + "px") - obj.getStyle().setTop(str(int(obj.getStyle().getTop()) + dy) + "px") + obj.style.left = str(int(obj.style.left) + dx) + "px" + obj.style.top = str(int(obj.style.top) + dy) + "px" def move_it(): move_it_by(get_document().getElementById("anim_img"), 3, 3, 1) From fijal at codespeak.net Tue Jun 6 15:45:56 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 15:45:56 +0200 (CEST) Subject: [pypy-svn] r28380 - pypy/dist/pypy/translator/js2 Message-ID: <20060606134556.58AB910077@code0.codespeak.net> Author: fijal Date: Tue Jun 6 15:45:55 2006 New Revision: 28380 Modified: pypy/dist/pypy/translator/js2/conftest.py Log: Modified conftest. Modified: pypy/dist/pypy/translator/js2/conftest.py ============================================================================== --- pypy/dist/pypy/translator/js2/conftest.py (original) +++ pypy/dist/pypy/translator/js2/conftest.py Tue Jun 6 15:45:55 2006 @@ -2,7 +2,7 @@ Option = py.test.Config.Option -option = py.test.Config.addoptions("pypy-js options", - Option('--browser', action="store_true",dest="browser", - default=False, help="run Javascript tests in your default browser"), +option = py.test.Config.addoptions("pypy-ojs options", + Option('--use-browser', action="store", dest="browser", type="string", + default="", help="run Javascript tests in your default browser") ) From antocuni at codespeak.net Tue Jun 6 15:52:35 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 15:52:35 +0200 (CEST) Subject: [pypy-svn] r28381 - pypy/dist/pypy/rpython/test Message-ID: <20060606135235.EB3A610076@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 15:52:35 2006 New Revision: 28381 Modified: pypy/dist/pypy/rpython/test/test_rspecialcase.py Log: More ootypesystem tests. Modified: pypy/dist/pypy/rpython/test/test_rspecialcase.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rspecialcase.py (original) +++ pypy/dist/pypy/rpython/test/test_rspecialcase.py Tue Jun 6 15:52:35 2006 @@ -1,20 +1,6 @@ from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.test.test_llinterp import interpret, gengraph - - -def test_override_ignore(): - def f(): - pass - f._annspecialcase_ = "override:ignore" - def g(i): - if i == 1: - return "ab" - else: - return f() - res = interpret(g, [0]) - assert not res - res = interpret(g, [1]) - assert ''.join(res.chars) == "ab" +from pypy.rpython.test.test_llinterp import gengraph +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin def test_ignore_breaking_transformations(): def f(): @@ -36,20 +22,43 @@ simplify.eliminate_empty_blocks(graph) #should not crash: checkgraph(graph) - -def test_meth_override_ignore(): - class X: - def f(self): + +class BaseTestRspecialcase(BaseRtypingTest): + + def test_override_ignore(self): + def f(): pass f._annspecialcase_ = "override:ignore" - def g(i): - x = X() - if i == 1: - return "ab" - else: - return x.f() + def g(i): + if i == 1: + return "ab" + else: + return f() + res = self.interpret(g, [0]) + assert not res + res = self.interpret(g, [1]) + assert self.ll_to_string(res) == "ab" + + def test_meth_override_ignore(self): + self._skip_oo('override:ignore') + class X: + def f(self): + pass + f._annspecialcase_ = "override:ignore" + def g(i): + x = X() + if i == 1: + return "ab" + else: + return x.f() + + res = self.interpret(g, [0]) + assert not res + res = self.interpret(g, [1]) + assert self.ll_to_string(res) == "ab" + +class TestLLtype(BaseTestRspecialcase, LLRtypeMixin): + pass - res = interpret(g, [0]) - assert not res - res = interpret(g, [1]) - assert ''.join(res.chars) == "ab" +class TestOOtype(BaseTestRspecialcase, OORtypeMixin): + pass From antocuni at codespeak.net Tue Jun 6 15:56:54 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 15:56:54 +0200 (CEST) Subject: [pypy-svn] r28382 - pypy/dist/pypy/rpython/test Message-ID: <20060606135654.1DFDA10036@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 15:56:53 2006 New Revision: 28382 Modified: pypy/dist/pypy/rpython/test/test_exception.py Log: Yet another ootypesystem test. Modified: pypy/dist/pypy/rpython/test/test_exception.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_exception.py (original) +++ pypy/dist/pypy/rpython/test/test_exception.py Tue Jun 6 15:56:53 2006 @@ -1,7 +1,6 @@ from pypy.translator.translator import TranslationContext from pypy.rpython.lltypesystem.lltype import * -from pypy.rpython.test.test_llinterp import interpret - +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin class MyException(Exception): pass @@ -55,14 +54,20 @@ strgerr_inst = excdata.fn_pyexcclass2exc(pyobjectptr(MyStrangeException)) assert strgerr_inst.typeptr == t.rtyper.class_reprs[None].getvtable() +class BaseTestException(BaseRtypingTest): + def test_exception_with_arg(self): + def g(n): + raise OSError(n, "?") + def f(n): + try: + g(n) + except OSError, e: + return e.errno + res = self.interpret(f, [42]) + assert res == 42 -def test_exception_with_arg(): - def g(n): - raise OSError(n, "?") - def f(n): - try: - g(n) - except OSError, e: - return e.errno - res = interpret(f, [42]) - assert res == 42 +class TestLLtype(BaseTestException, LLRtypeMixin): + pass + +class TestOOtype(BaseTestException, OORtypeMixin): + pass From antocuni at codespeak.net Tue Jun 6 16:02:14 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 16:02:14 +0200 (CEST) Subject: [pypy-svn] r28384 - pypy/dist/pypy/rpython/test Message-ID: <20060606140214.BF2D310076@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 16:02:14 2006 New Revision: 28384 Modified: pypy/dist/pypy/rpython/test/test_rbool.py Log: More ootypesystem tests (yes, I'm copying-and-pasting the very same message all the time :-)). Modified: pypy/dist/pypy/rpython/test/test_rbool.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbool.py (original) +++ pypy/dist/pypy/rpython/test/test_rbool.py Tue Jun 6 16:02:14 2006 @@ -2,8 +2,7 @@ from pypy.rpython.lltypesystem.lltype import pyobjectptr from pypy.annotation import model as annmodel from pypy.rpython.test import snippet -from pypy.rpython.test.test_llinterp import interpret - +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin class TestSnippet(object): @@ -35,14 +34,16 @@ for opname in annmodel.BINARY_OPERATIONS: print 'BINARY_OPERATIONS:', opname +class BaseTestRbool(BaseRtypingTest): + def test_bool2int(self): def f(n): if n: n = 2 return n - res = interpret(f, [False]) + res = self.interpret(f, [False]) assert res == 0 and res is not False # forced to int by static typing - res = interpret(f, [True]) + res = self.interpret(f, [True]) assert res == 2 def test_arithmetic_with_bool_inputs(self): @@ -51,7 +52,7 @@ a -= (a != n) > False return a + (-(n<0)) for i in [-1, 1, 2, 42]: - res = interpret(f, [i]) + res = self.interpret(f, [i]) assert res == f(i) def test_bool2str(self): @@ -62,15 +63,22 @@ return oct(n > 5) else: return str(n > 5) - res = interpret(f, [2, 0]) - assert ''.join(res.chars) in ('0', 'False') # unspecified so far - res = interpret(f, [9, 0]) - assert ''.join(res.chars) in ('1', 'True') # unspecified so far - res = interpret(f, [2, 1]) - assert ''.join(res.chars) == '0x0' - res = interpret(f, [9, 1]) - assert ''.join(res.chars) == '0x1' - res = interpret(f, [2, 2]) - assert ''.join(res.chars) == '0' - res = interpret(f, [9, 2]) - assert ''.join(res.chars) == '01' + res = self.interpret(f, [2, 0]) + assert self.ll_to_string(res) in ('0', 'False') # unspecified so far + res = self.interpret(f, [9, 0]) + assert self.ll_to_string(res) in ('1', 'True') # unspecified so far + res = self.interpret(f, [2, 1]) + assert self.ll_to_string(res) == '0x0' + res = self.interpret(f, [9, 1]) + assert self.ll_to_string(res) == '0x1' + res = self.interpret(f, [2, 2]) + assert self.ll_to_string(res) == '0' + res = self.interpret(f, [9, 2]) + assert self.ll_to_string(res) == '01' + + +class TestLLtype(BaseTestRbool, LLRtypeMixin): + pass + +class TestOOtype(BaseTestRbool, OORtypeMixin): + pass From antocuni at codespeak.net Tue Jun 6 16:03:59 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 16:03:59 +0200 (CEST) Subject: [pypy-svn] r28385 - pypy/dist/pypy/rpython/test Message-ID: <20060606140359.8948610077@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 16:03:58 2006 New Revision: 28385 Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py Log: The we_are_translated test here was redundant (see test_objectmodel.py). Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Tue Jun 6 16:03:58 2006 @@ -18,14 +18,6 @@ if op.opname == 'direct_call': yield op - - - -def test_we_are_translated(): - def f(): - return we_are_translated() - res = interpret(f, []) - assert res is True and f() is False def test_method_join(): # this is tuned to catch a specific bug: From antocuni at codespeak.net Tue Jun 6 16:09:00 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 16:09:00 +0200 (CEST) Subject: [pypy-svn] r28386 - pypy/dist/pypy/rpython/test Message-ID: <20060606140900.93EAC10077@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 16:09:00 2006 New Revision: 28386 Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py Log: More ootypesystem tests. Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Tue Jun 6 16:09:00 2006 @@ -1,5 +1,4 @@ from pypy.translator.translator import graphof -from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.test import test_llinterp from pypy.rpython.objectmodel import instantiate, we_are_translated from pypy.rpython.lltypesystem import lltype @@ -19,88 +18,62 @@ yield op -def test_method_join(): - # this is tuned to catch a specific bug: - # a wrong rtyper_makekey() for BuiltinMethodRepr - def f(): - lst1 = ['abc', 'def'] - s1 = ', '.join(lst1) - lst2 = ['1', '2', '3'] - s2 = ''.join(lst2) - return s1 + s2 - res = interpret(f, []) - assert ''.join(list(res.chars)) == 'abc, def123' - -def test_method_repr(): - def g(n): - if n >= 0: - return "egg" - else: - return "spam" - def f(n): - # this is designed for a specific bug: conversions between - # BuiltinMethodRepr. The append method of the list is passed - # around, and g(-1) below causes a reflowing at the beginning - # of the loop (but not inside the loop). This situation creates - # a newlist returning a SomeList() which '==' but 'is not' the - # SomeList() inside the loop. - x = len([ord(c) for c in g(1)]) - g(-1) - return x - res = interpret(f, [0]) - assert res == 3 - -def test_chr(): - def f(x=int): - try: - return chr(x) - except ValueError: - return '?' - res = interpret(f, [65]) - assert res == 'A' - res = interpret(f, [256]) - assert res == '?' - res = interpret(f, [-1]) - assert res == '?' +class BaseTestRbuiltin(BaseRtypingTest): + def test_method_join(self): + # this is tuned to catch a specific bug: + # a wrong rtyper_makekey() for BuiltinMethodRepr + def f(): + lst1 = ['abc', 'def'] + s1 = ', '.join(lst1) + lst2 = ['1', '2', '3'] + s2 = ''.join(lst2) + return s1 + s2 + res = self.interpret(f, []) + assert self.ll_to_string(res) == 'abc, def123' -def test_intmask(): - def f(x=r_uint): - try: - return intmask(x) - except ValueError: - return 0 - - res = interpret(f, [r_uint(5)]) - assert type(res) is int and res == 5 - -def test_cast_primitive(): - from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy - def llf(u): - return lltype.cast_primitive(lltype.Signed, u) - res = interpret(llf, [r_uint(-1)], policy=LowLevelAnnotatorPolicy()) - assert res == -1 - res = interpret(llf, ['x'], policy=LowLevelAnnotatorPolicy()) - assert res == ord('x') - def llf(v): - return lltype.cast_primitive(lltype.Unsigned, v) - res = interpret(llf, [-1], policy=LowLevelAnnotatorPolicy()) - assert res == r_uint(-1) - res = interpret(llf, [u'x'], policy=LowLevelAnnotatorPolicy()) - assert res == ord(u'x') - res = interpret(llf, [1.0], policy=LowLevelAnnotatorPolicy()) - assert res == r_uint(1) - def llf(v): - return lltype.cast_primitive(lltype.Char, v) - res = interpret(llf, [ord('x')], policy=LowLevelAnnotatorPolicy()) - assert res == 'x' - def llf(v): - return lltype.cast_primitive(lltype.UniChar, v) - res = interpret(llf, [ord('x')], policy=LowLevelAnnotatorPolicy()) - assert res == u'x' + def test_method_repr(self): + def g(n): + if n >= 0: + return "egg" + else: + return "spam" + def f(n): + # this is designed for a specific bug: conversions between + # BuiltinMethodRepr. The append method of the list is passed + # around, and g(-1) below causes a reflowing at the beginning + # of the loop (but not inside the loop). This situation creates + # a newlist returning a SomeList() which '==' but 'is not' the + # SomeList() inside the loop. + x = len([ord(c) for c in g(1)]) + g(-1) + return x + res = self.interpret(f, [0]) + assert res == 3 + def test_chr(self): + def f(x=int): + try: + return chr(x) + except ValueError: + return '?' + res = self.interpret(f, [65]) + assert res == 'A' + res = self.interpret(f, [256]) + assert res == '?' + res = self.interpret(f, [-1]) + assert res == '?' + + + def test_intmask(self): + def f(x=r_uint): + try: + return intmask(x) + except ValueError: + return 0 -class BaseTestExtfunc(BaseRtypingTest): + res = self.interpret(f, [r_uint(5)]) + assert type(res) is int and res == 5 def test_rbuiltin_list(self): def f(): @@ -297,7 +270,7 @@ res = self.interpret(f, [1]) assert res is False -class TestLLtype(BaseTestExtfunc, LLRtypeMixin): +class TestLLtype(BaseTestRbuiltin, LLRtypeMixin): from pypy.rpython.lltypesystem.module import ll_os def test_instantiate(self): @@ -348,6 +321,32 @@ assert res._obj.value == y # hmm, would like to test against PyObj, is this the wrong place/way? + def test_cast_primitive(self): + from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy + def llf(u): + return lltype.cast_primitive(lltype.Signed, u) + res = self.interpret(llf, [r_uint(-1)], policy=LowLevelAnnotatorPolicy()) + assert res == -1 + res = self.interpret(llf, ['x'], policy=LowLevelAnnotatorPolicy()) + assert res == ord('x') + def llf(v): + return lltype.cast_primitive(lltype.Unsigned, v) + res = self.interpret(llf, [-1], policy=LowLevelAnnotatorPolicy()) + assert res == r_uint(-1) + res = self.interpret(llf, [u'x'], policy=LowLevelAnnotatorPolicy()) + assert res == ord(u'x') + res = self.interpret(llf, [1.0], policy=LowLevelAnnotatorPolicy()) + assert res == r_uint(1) + def llf(v): + return lltype.cast_primitive(lltype.Char, v) + res = self.interpret(llf, [ord('x')], policy=LowLevelAnnotatorPolicy()) + assert res == 'x' + def llf(v): + return lltype.cast_primitive(lltype.UniChar, v) + res = self.interpret(llf, [ord('x')], policy=LowLevelAnnotatorPolicy()) + assert res == u'x' + + -class TestOOtype(BaseTestExtfunc, OORtypeMixin): +class TestOOtype(BaseTestRbuiltin, OORtypeMixin): from pypy.rpython.ootypesystem.module import ll_os From antocuni at codespeak.net Tue Jun 6 16:15:14 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 16:15:14 +0200 (CEST) Subject: [pypy-svn] r28387 - pypy/dist/pypy/rpython/test Message-ID: <20060606141514.8B75E10064@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 16:15:13 2006 New Revision: 28387 Modified: pypy/dist/pypy/rpython/test/test_rclass.py Log: More and more ootypesystem tests. Modified: pypy/dist/pypy/rpython/test/test_rclass.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rclass.py (original) +++ pypy/dist/pypy/rpython/test/test_rclass.py Tue Jun 6 16:15:13 2006 @@ -3,9 +3,9 @@ from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.ootypesystem import ootype -from pypy.rpython.test.test_llinterp import interpret, interpret_raises +#from pypy.rpython.test.test_llinterp import interpret, interpret_raises from pypy.rpython.rarithmetic import intmask - +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin class EmptyBase(object): pass @@ -29,7 +29,7 @@ class C(B): pass -class BaseTestRclass: +class BaseTestRclass(BaseRtypingTest): def test_instanceattr(self): def dummyfn(): @@ -37,16 +37,16 @@ x.a = 5 x.a += 1 return x.a - res = interpret(dummyfn, [], type_system=self.ts) + res = self.interpret(dummyfn, []) assert res == 6 def test_simple(self): def dummyfn(): x = EmptyBase() return x - res = interpret(dummyfn, [], type_system=self.ts) + res = self.interpret(dummyfn, []) T = typeOf(res) - if self.ts == "lltype": + if self.type_system == "lltype": assert isinstance(T, Ptr) and isinstance(T.TO, GcStruct) else: assert isinstance(T, ootype.Instance) @@ -56,7 +56,7 @@ def dummyfn(): x = Random() return x.xyzzy - res = interpret(dummyfn, [], type_system=self.ts) + res = self.interpret(dummyfn, []) assert res == 12 def test_classattr_both(self): @@ -74,9 +74,9 @@ C = pick(i) i = C() return C.a + i.a - res = interpret(dummyfn, [0], type_system=self.ts) + res = self.interpret(dummyfn, [0]) assert res == 2 - res = interpret(dummyfn, [1], type_system=self.ts) + res = self.interpret(dummyfn, [1]) assert res == 4 def test_classattr_both2(self): @@ -96,9 +96,9 @@ C = pick(i) i = C() return C.a + i.a - res = interpret(dummyfn, [0], type_system=self.ts) + res = self.interpret(dummyfn, [0]) assert res == 2 - res = interpret(dummyfn, [1], type_system=self.ts) + res = self.interpret(dummyfn, [1]) assert res == 4 def test_runtime_exception(self): @@ -110,15 +110,15 @@ def f(flag): ex = pick(flag) raise ex() - interpret_raises(TypeError, f, [True], type_system=self.ts) - interpret_raises(ValueError, f, [False], type_system=self.ts) + self.interpret_raises(TypeError, f, [True]) + self.interpret_raises(ValueError, f, [False]) def test_classattr_as_defaults(self): def dummyfn(): x = Random() x.xyzzy += 1 return x.xyzzy - res = interpret(dummyfn, [], type_system=self.ts) + res = self.interpret(dummyfn, []) assert res == 13 def test_prebuilt_instance(self): @@ -127,7 +127,7 @@ def dummyfn(): a.x += 1 return a.x - interpret(dummyfn, [], type_system=self.ts) + self.interpret(dummyfn, []) def test_recursive_prebuilt_instance(self): a = EmptyBase() @@ -138,7 +138,7 @@ b.peer = a def dummyfn(): return a.peer.peer.peer.x - res = interpret(dummyfn, [], type_system=self.ts) + res = self.interpret(dummyfn, []) assert res == 6 def test_prebuilt_instances_with_void(self): @@ -148,7 +148,7 @@ a.nothing_special = marker def dummyfn(): return a.nothing_special() - res = interpret(dummyfn, [], type_system=self.ts) + res = self.interpret(dummyfn, []) assert res == 42 def test_simple_method_call(self): @@ -158,9 +158,9 @@ else: a = B() return a.f() - res = interpret(f, [True], type_system=self.ts) + res = self.interpret(f, [True]) assert res == 42 - res = interpret(f, [False], type_system=self.ts) + res = self.interpret(f, [False]) assert res == 1 def test_isinstance(self): @@ -175,14 +175,14 @@ o = C() return 100*isinstance(o, A)+10*isinstance(o, B)+1*isinstance(o ,C) - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 100 - res = interpret(f, [2], type_system=self.ts) + res = self.interpret(f, [2]) assert res == 110 - res = interpret(f, [3], type_system=self.ts) + res = self.interpret(f, [3]) assert res == 111 - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 0 def test_method_used_in_subclasses_only(self): @@ -194,7 +194,7 @@ def f(): x = B() return x.meth() - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert res == 123 def test_method_both_A_and_B(self): @@ -207,7 +207,7 @@ a = A() b = B() return a.meth() + b.meth() - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert res == 246 def test_issubclass_type(self): @@ -223,8 +223,8 @@ else: c1 = B() return issubclass(type(c1), B) - assert interpret(f, [0], type_system=self.ts) == False - assert interpret(f, [1], type_system=self.ts) == True + assert self.interpret(f, [0]) == False + assert self.interpret(f, [1]) == True def g(i): if i == 0: @@ -232,8 +232,8 @@ else: c1 = B() return issubclass(type(c1), A) - assert interpret(g, [0], type_system=self.ts) == True - assert interpret(g, [1], type_system=self.ts) == True + assert self.interpret(g, [0]) == True + assert self.interpret(g, [1]) == True def test_staticmethod(self): class A(object): @@ -241,7 +241,7 @@ def f(): a = A() return a.f(6, 7) - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert res == 42 def test_is(self): @@ -264,13 +264,13 @@ 0x0008*(a is e) | 0x0010*(b is c) | 0x0020*(b is d) | 0x0040*(b is e) | 0x0080*(c is d) | 0x0100*(c is e) | 0x0200*(d is e)) - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 0x0004 - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 0x0020 - res = interpret(f, [2], type_system=self.ts) + res = self.interpret(f, [2]) assert res == 0x0100 - res = interpret(f, [3], type_system=self.ts) + res = self.interpret(f, [3]) assert res == 0x0200 def test_eq(self): @@ -293,13 +293,13 @@ 0x0008*(a == e) | 0x0010*(b == c) | 0x0020*(b == d) | 0x0040*(b == e) | 0x0080*(c == d) | 0x0100*(c == e) | 0x0200*(d == e)) - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 0x0004 - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 0x0020 - res = interpret(f, [2], type_system=self.ts) + res = self.interpret(f, [2]) assert res == 0x0100 - res = interpret(f, [3]) + res = self.interpret(f, [3]) assert res == 0x0200 def test_istrue(self): @@ -314,9 +314,9 @@ return 1 else: return 2 - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 1 - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 2 def test_ne(self): @@ -339,13 +339,13 @@ 0x0008*(a != e) | 0x0010*(b != c) | 0x0020*(b != d) | 0x0040*(b != e) | 0x0080*(c != d) | 0x0100*(c != e) | 0x0200*(d != e)) - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == ~0x0004 & 0x3ff - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == ~0x0020 & 0x3ff - res = interpret(f, [2], type_system=self.ts) + res = self.interpret(f, [2]) assert res == ~0x0100 & 0x3ff - res = interpret(f, [3], type_system=self.ts) + res = self.interpret(f, [3]) assert res == ~0x0200 & 0x3ff def test_hash_preservation(self): @@ -361,7 +361,7 @@ x = (hash(d2) & sys.maxint) == (id(d2) & sys.maxint) return x, hash(c)+hash(d) - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert res.item0 == True assert res.item1 == intmask(hash(c)+hash(d)) @@ -381,11 +381,11 @@ else: a = None return g(a) is A # should type(None) work? returns None for now - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res is True - res = interpret(f, [-1], type_system=self.ts) + res = self.interpret(f, [-1]) assert res is False - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res is False def test_void_fnptr(self): @@ -395,7 +395,7 @@ e = EmptyBase() e.attr = g return e.attr() - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert res == 42 def test_getattr_on_classes(self): @@ -418,9 +418,9 @@ x = C() x.value = 12 return meth(x) # calls A.meth or C.meth, completely ignores B.meth - res = interpret(f, [1], type_system=self.ts) + res = self.interpret(f, [1]) assert res == 54 - res = interpret(f, [0], type_system=self.ts) + res = self.interpret(f, [0]) assert res == 11 def test_constant_bound_method(self): @@ -431,7 +431,7 @@ meth = C().meth def f(): return meth() - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert res == 1 def test_mixin(self): @@ -462,7 +462,7 @@ v2 = c.m('y') return v0, v1, v2 - res = interpret(f, [], type_system=self.ts) + res = self.interpret(f, []) assert typeOf(res.item0) == Signed def test___class___attribute(self): @@ -485,14 +485,12 @@ cls1, cls2 = f(1) return cls1 is A, cls2 is B - res = interpret(g, [], type_system=self.ts) + res = self.interpret(g, []) assert res.item0 assert res.item1 -class TestLltype(BaseTestRclass): - - ts = "lltype" +class TestLltype(BaseTestRclass, LLRtypeMixin): def test__del__(self): class A(object): @@ -558,9 +556,7 @@ assert destrptra is not None assert destrptrb is not None -class TestOotype(BaseTestRclass): - - ts = "ootype" +class TestOOtype(BaseTestRclass, OORtypeMixin): def test__del__(self): class A(object): @@ -573,7 +569,7 @@ return a.a t = TranslationContext() t.buildannotator().build_types(f, []) - t.buildrtyper(type_system=self.ts).specialize() + t.buildrtyper(type_system=self.type_system).specialize() graph = graphof(t, f) TYPE = graph.startblock.operations[0].args[0].value _, meth = TYPE._lookup("o__del___variant0") @@ -605,7 +601,7 @@ assert res == 42 t = TranslationContext() t.buildannotator().build_types(f, []) - t.buildrtyper(type_system=self.ts).specialize() + t.buildrtyper(type_system=self.type_system).specialize() graph = graphof(t, f) TYPEA = graph.startblock.operations[0].args[0].value TYPEB = graph.startblock.operations[2].args[0].value From antocuni at codespeak.net Tue Jun 6 16:19:40 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 16:19:40 +0200 (CEST) Subject: [pypy-svn] r28388 - pypy/dist/pypy/rpython/test Message-ID: <20060606141940.A682210053@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 16:19:39 2006 New Revision: 28388 Modified: pypy/dist/pypy/rpython/test/test_rconstantdict.py Log: More ootypesystem tests. At the moment one is actually skipping because ootypesystem still misses support for r_dict constants. Modified: pypy/dist/pypy/rpython/test/test_rconstantdict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rconstantdict.py (original) +++ pypy/dist/pypy/rpython/test/test_rconstantdict.py Tue Jun 6 16:19:39 2006 @@ -1,60 +1,70 @@ import py -from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.objectmodel import r_dict +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -def test_constant_int_dict(): - d = {1: 2, 2: 3, 3: 4} - def func(i): - return d[i] - res = interpret(func, [3]) - assert res == 4 - -def test_constantdict_contains(): - d = {1: True, 4: True, 16: True} - def func(i): - return i in d - res = interpret(func, [15]) - assert res is False - res = interpret(func, [4]) - assert res is True - -def test_constantdict_get(): - d = {1: -11, 4: -44, 16: -66} - def func(i, j): - return d.get(i, j) - res = interpret(func, [15, 62]) - assert res == 62 - res = interpret(func, [4, 25]) - assert res == -44 - -def test_unichar_dict(): - d = {u'a': 5, u'b': 123, u'?': 321} - def func(i): - return d[unichr(i)] - res = interpret(func, [97]) - assert res == 5 - res = interpret(func, [98]) - assert res == 123 - res = interpret(func, [63]) - assert res == 321 - -def test_constant_r_dict(): - def strange_key_eq(key1, key2): - return key1[0] == key2[0] # only the 1st character is relevant - def strange_key_hash(key): - return ord(key[0]) - - d = r_dict(strange_key_eq, strange_key_hash) - d['hello'] = 42 - d['world'] = 43 - for x in range(65, 91): - d[chr(x)] = x*x - def func(i): - return d[chr(i)] - res = interpret(func, [ord('h')]) - assert res == 42 - res = interpret(func, [ord('w')]) - assert res == 43 - for x in range(65, 91): - res = interpret(func, [x]) - assert res == x*x +class BaseTestRconstantdict(BaseRtypingTest): + + def test_constant_int_dict(self): + d = {1: 2, 2: 3, 3: 4} + def func(i): + return d[i] + res = self.interpret(func, [3]) + assert res == 4 + + def test_constantdict_contains(self): + d = {1: True, 4: True, 16: True} + def func(i): + return i in d + res = self.interpret(func, [15]) + assert res is False + res = self.interpret(func, [4]) + assert res is True + + def test_constantdict_get(self): + d = {1: -11, 4: -44, 16: -66} + def func(i, j): + return d.get(i, j) + res = self.interpret(func, [15, 62]) + assert res == 62 + res = self.interpret(func, [4, 25]) + assert res == -44 + + def test_unichar_dict(self): + d = {u'a': 5, u'b': 123, u'?': 321} + def func(i): + return d[unichr(i)] + res = self.interpret(func, [97]) + assert res == 5 + res = self.interpret(func, [98]) + assert res == 123 + res = self.interpret(func, [63]) + assert res == 321 + + def test_constant_r_dict(self): + self._skip_oo('constant r_dict') + def strange_key_eq(key1, key2): + return key1[0] == key2[0] # only the 1st character is relevant + def strange_key_hash(key): + return ord(key[0]) + + d = r_dict(strange_key_eq, strange_key_hash) + d['hello'] = 42 + d['world'] = 43 + for x in range(65, 91): + d[chr(x)] = x*x + def func(i): + return d[chr(i)] + res = self.interpret(func, [ord('h')]) + assert res == 42 + res = self.interpret(func, [ord('w')]) + assert res == 43 + for x in range(65, 91): + res = self.interpret(func, [x]) + assert res == x*x + + +class TestLLtype(BaseTestRconstantdict, LLRtypeMixin): + pass + +class TestOOtype(BaseTestRconstantdict, OORtypeMixin): + pass From ale at codespeak.net Tue Jun 6 17:24:33 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 6 Jun 2006 17:24:33 +0200 (CEST) Subject: [pypy-svn] r28390 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060606152433.22B3010060@code0.codespeak.net> Author: ale Date: Tue Jun 6 17:24:33 2006 New Revision: 28390 Modified: pypy/extradoc/sprintinfo/ddorf2006/people.txt Log: Pruning my attendance Modified: pypy/extradoc/sprintinfo/ddorf2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/ddorf2006/people.txt (original) +++ pypy/extradoc/sprintinfo/ddorf2006/people.txt Tue Jun 6 17:24:33 2006 @@ -18,7 +18,7 @@ Samuele Pedroni 1st - 9th Hotel an der Uni Christian Tismer 1st - 9th Hotel an der Uni Antonio Cuni 1st - 9th cfbolz -Anders Lehmann 2nd - 9th Hotel an der Uni +Anders Lehmann 2nd - 8th Hotel an der Uni Niklaus Haldimann 2nd - 4th cfbolz (?) ==================== ============== ===================== From antocuni at codespeak.net Tue Jun 6 17:38:24 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 17:38:24 +0200 (CEST) Subject: [pypy-svn] r28392 - in pypy/dist/pypy: annotation rpython/ootypesystem rpython/test Message-ID: <20060606153824.676CD10050@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 17:38:23 2006 New Revision: 28392 Modified: pypy/dist/pypy/annotation/unaryop.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/rootype.py pypy/dist/pypy/rpython/test/test_remptydict.py Log: Make ootypesystem to work with SomeOOInstance with Void lowleveltype too. Some more ootypesystem tests. Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Tue Jun 6 17:38:23 2006 @@ -634,8 +634,9 @@ def setattr(r, s_attr, s_value): assert s_attr.is_constant(), "setattr on ref %r with non-constant field-name" % r.ootype v = annotation_to_lltype(s_value) - setattr(r.ootype._example(), s_attr.const, - v._example()) + example = r.ootype._example() + if example is not None: + setattr(r.ootype._example(), s_attr.const, v._example()) def is_true(p): return SomeBool() Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Tue Jun 6 17:38:23 2006 @@ -2,7 +2,7 @@ from pypy.annotation import model as annmodel from pypy.annotation import description from pypy.objspace.flow import model as flowmodel -from pypy.rpython.rmodel import inputconst, TyperError +from pypy.rpython.rmodel import inputconst, TyperError, warning from pypy.rpython.rmodel import mangle as pbcmangle from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \ getinstancerepr, getclassrepr, get_type_repr Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rootype.py Tue Jun 6 17:38:23 2006 @@ -51,6 +51,8 @@ resulttype = hop.r_result.lowleveltype) def rtype_setattr(self, hop): + if self.lowleveltype is Void: + return attr = hop.args_s[1].const self.lowleveltype._check_field(attr) vlist = hop.inputargs(self, Void, hop.args_r[2]) Modified: pypy/dist/pypy/rpython/test/test_remptydict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_remptydict.py (original) +++ pypy/dist/pypy/rpython/test/test_remptydict.py Tue Jun 6 17:38:23 2006 @@ -1,27 +1,34 @@ import py -from pypy.rpython.test.test_llinterp import interpret +from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -def test_empty_dict(): - class A: - pass - a = A() - a.d1 = {} - def func(): - a.d2 = {} - return bool(a.d1) or bool(a.d2) - res = interpret(func, []) - assert res is False +class BaseTestRemptydict(BaseRtypingTest): + def test_empty_dict(self): + class A: + pass + a = A() + a.d1 = {} + def func(): + a.d2 = {} + return bool(a.d1) or bool(a.d2) + res = self.interpret(func, []) + assert res is False -def test_iterate_over_empty_dict(): - def f(): - n = 0 - d = {} - for x in []: n += x - for y in d: n += y - for z in d.iterkeys(): n += z - for s in d.itervalues(): n += s - for t, u in d.items(): n += t * u - for t, u in d.iteritems(): n += t * u - return n - res = interpret(f, []) - assert res == 0 + def test_iterate_over_empty_dict(self): + def f(): + n = 0 + d = {} + for x in []: n += x + for y in d: n += y + for z in d.iterkeys(): n += z + for s in d.itervalues(): n += s + for t, u in d.items(): n += t * u + for t, u in d.iteritems(): n += t * u + return n + res = self.interpret(f, []) + assert res == 0 + +class TestLLtype(BaseTestRemptydict, LLRtypeMixin): + pass + +class TestOOtype(BaseTestRemptydict, OORtypeMixin): + pass From cfbolz at codespeak.net Tue Jun 6 17:39:51 2006 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 6 Jun 2006 17:39:51 +0200 (CEST) Subject: [pypy-svn] r28393 - in pypy/dist/pypy: doc lib/pyontology module/crypt module/crypt/test module/readline module/readline/test module/time2 module/time2/test objspace/std/test rpython/lltypesystem/module rpython/ootypesystem/module tool translator/cl/test translator/js2 translator/js2/modules translator/js2/test translator/oosupport Message-ID: <20060606153951.601D610060@code0.codespeak.net> Author: cfbolz Date: Tue Jun 6 17:39:48 2006 New Revision: 28393 Modified: pypy/dist/pypy/doc/pyontology.txt (props changed) pypy/dist/pypy/lib/pyontology/constraint_classes.py (props changed) pypy/dist/pypy/module/crypt/ (props changed) pypy/dist/pypy/module/crypt/test/ (props changed) pypy/dist/pypy/module/readline/ (props changed) pypy/dist/pypy/module/readline/test/ (props changed) pypy/dist/pypy/module/time2/ (props changed) pypy/dist/pypy/module/time2/test/ (props changed) pypy/dist/pypy/objspace/std/test/test_set.py (props changed) pypy/dist/pypy/rpython/lltypesystem/module/ (props changed) pypy/dist/pypy/rpython/ootypesystem/module/ (props changed) pypy/dist/pypy/tool/codespeak-gendoc.py (props changed) pypy/dist/pypy/translator/cl/test/test_tuple.py (props changed) pypy/dist/pypy/translator/js2/ (props changed) pypy/dist/pypy/translator/js2/__init__.py (props changed) pypy/dist/pypy/translator/js2/_class.py (props changed) pypy/dist/pypy/translator/js2/asmgen.py (props changed) pypy/dist/pypy/translator/js2/database.py (props changed) pypy/dist/pypy/translator/js2/function.py (props changed) pypy/dist/pypy/translator/js2/js.py (props changed) pypy/dist/pypy/translator/js2/jts.py (props changed) pypy/dist/pypy/translator/js2/log.py (props changed) pypy/dist/pypy/translator/js2/metavm.py (props changed) pypy/dist/pypy/translator/js2/modules/ (props changed) pypy/dist/pypy/translator/js2/modules/__init__.py (props changed) pypy/dist/pypy/translator/js2/modules/dom.py (props changed) pypy/dist/pypy/translator/js2/opcodes.py (props changed) pypy/dist/pypy/translator/js2/support.py (props changed) pypy/dist/pypy/translator/js2/test/ (props changed) pypy/dist/pypy/translator/js2/test/__init__.py (props changed) pypy/dist/pypy/translator/js2/test/browsertest.py (props changed) pypy/dist/pypy/translator/js2/test/runtest.py (props changed) pypy/dist/pypy/translator/js2/test/test_class.py (props changed) pypy/dist/pypy/translator/js2/test/test_dom.py (props changed) pypy/dist/pypy/translator/js2/test/test_exc_operation.py (props changed) pypy/dist/pypy/translator/js2/test/test_exception.py (props changed) pypy/dist/pypy/translator/js2/test/test_genllvm.py (props changed) pypy/dist/pypy/translator/js2/test/test_genllvm1.py (props changed) pypy/dist/pypy/translator/js2/test/test_jseval.py (props changed) pypy/dist/pypy/translator/js2/test/test_loops.py (props changed) pypy/dist/pypy/translator/js2/test/test_merge_if_blocks.py (props changed) pypy/dist/pypy/translator/js2/test/test_runtest.py (props changed) pypy/dist/pypy/translator/js2/test/test_seq.py (props changed) pypy/dist/pypy/translator/js2/test/test_snippet.py (props changed) pypy/dist/pypy/translator/js2/test/test_typed.py (props changed) pypy/dist/pypy/translator/oosupport/ (props changed) Log: FIXEOL From mwh at codespeak.net Tue Jun 6 17:40:39 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 6 Jun 2006 17:40:39 +0200 (CEST) Subject: [pypy-svn] r28394 - pypy/dist/pypy/translator/stackless Message-ID: <20060606154039.C760B10064@code0.codespeak.net> Author: mwh Date: Tue Jun 6 17:40:38 2006 New Revision: 28394 Modified: pypy/dist/pypy/translator/stackless/transform.py Log: move some frame typer hacking into a method on the frame typer. Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Tue Jun 6 17:40:38 2006 @@ -125,6 +125,15 @@ self.frametypes[key] = T return T, fieldnames + def ensure_frame_type_for_types(self, frame_type): + key, fieldnames = self._key_fieldnames_for_types( + [frame_type._flds[n] for n in frame_type._names[1:]]) + assert len(fieldnames) <= 1, "nasty field ordering issues need to be solved XXX mwh, pedronis" + if key in self.frametypes: + assert self.frametypes[key] is frame_type + self.frametypes[key] = frame_type + + class StacklessAnalyzer(graphanalyze.GraphAnalyzer): def __init__(self, translator, unwindtype, stackless_gc): graphanalyze.GraphAnalyzer.__init__(self, translator) @@ -331,12 +340,7 @@ label, len(self.masterarray1) + i) frame_type = restartinfo.frame_types[i] self.explicit_resume_point_data[label] = frame_type - key, fieldnames = self.frametyper._key_fieldnames_for_types( - [frame_type._flds[n] for n in frame_type._names[1:]]) - assert len(fieldnames) <= 1, "nasty field ordering issues need to be solved XXX mwh, pedronis" - if key in self.frametyper.frametypes: - assert self.frametyper.frametypes[key] is frame_type - self.frametyper.frametypes[key] = frame_type + self.frametyper.ensure_frame_type_for_types(frame_type) self.register_restart_info(restartinfo) def transform_all(self): From fijal at codespeak.net Tue Jun 6 17:48:08 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 17:48:08 +0200 (CEST) Subject: [pypy-svn] r28395 - pypy/dist/pypy/translator/oosupport Message-ID: <20060606154808.7B88A10064@code0.codespeak.net> Author: fijal Date: Tue Jun 6 17:48:07 2006 New Revision: 28395 Added: pypy/dist/pypy/translator/oosupport/__init__.py pypy/dist/pypy/translator/oosupport/metavm.py Removed: pypy/dist/pypy/translator/oosupport/README.txt Log: Added oosupport. Added: pypy/dist/pypy/translator/oosupport/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/oosupport/__init__.py Tue Jun 6 17:48:07 2006 @@ -0,0 +1,5 @@ + +""" +This module contains code and tests that can be shared between +the various ootypesystem based backends. +""" Added: pypy/dist/pypy/translator/oosupport/metavm.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/oosupport/metavm.py Tue Jun 6 17:48:07 2006 @@ -0,0 +1,143 @@ + +""" +Varius microopcodes for different ootypesystem based backends +""" + +from pypy.rpython.ootypesystem import ootype + +class Generator(object): + def function_signature(self, graph): + pass + + def emit(self, instr, *args): + pass + + def call(self, func_name): + pass + + def load(self, v): + pass + + def store(self, v): + pass + + +class InstructionList(list): + def render(self, generator, op): + for instr in self: + if isinstance(instr, MicroInstruction): + instr.render(generator, op) + else: + generator.emit(instr) + + def __call__(self, *args): + return self.render(*args) + + +class MicroInstruction(object): + def render(self, generator, op): + pass + + def __str__(self): + return self.__class__.__name__ + + def __call__(self, *args): + return self.render(*args) + +class PushArg(MicroInstruction): + def __init__(self, n): + self.n = n + + def render(self, generator, op): + generator.load(op.args[self.n]) + +class _PushAllArgs(MicroInstruction): + def render(self, generator, op): + for arg in op.args: + generator.load(arg) + +class _StoreResult(MicroInstruction): + def render(self, generator, op): + generator.store(op.result) + +class _SetField(MicroInstruction): + def render(self, generator, op): + this, field, value = op.args +## if field.value == 'meta': +## return # TODO + + generator.load(this) + generator.load(value) + generator.set_field(this.concretetype, field.value) + +class _GetField(MicroInstruction): + def render(self, generator, op): + this, field = op.args + generator.load(this) + generator.get_field(this.concretetype, field.value) + + +# There are three distinct possibilities where we need to map call differently: +# 1. Object is marked with rpython_hints as a builtin, so every attribut access +# and function call goes as builtin +# 2. Function called is a builtin, so it might be mapped to attribute access, builtin function call +# or even method call +# 3. Object on which method is called is primitive object and method is mapped to some +# method/function/attribute access +class _GeneralDispatcher(MicroInstruction): + def __init__(self, builtins, class_map): + self.builtins = builtins + self.class_map = class_map + + def render(self, generator, op): + raise NotImplementedError("pure virtual class") + + def check_builtin(self, this): + if not isinstance(this, ootype.Instance): + return False + return this._hints.get('_suggested_external') + +class _MethodDispatcher(_GeneralDispatcher): + def render(self, generator, op): + method = op.args[0].value + this = op.args[1].concretetype + if self.check_builtin(this): + return self.class_map['CallBuiltinObject'].render(generator, op) + try: + self.builtins.builtin_obj_map[this.__class__][method](generator, op) + except KeyError: + return self.class_map['CallMethod'].render(generator, op) + +class _CallDispatcher(_GeneralDispatcher): + def render(self, generator, op): + func = op.args[0] + if getattr(func.value._callable, 'suggested_primitive', False): + func_name = func.value._name.split("__")[0] + return self.builtins.builtin_map[func_name](generator, op) + else: + return self.class_map['Call'].render(generator, op) + +class _GetFieldDispatcher(_GeneralDispatcher): + def render(self, generator, op): + if self.check_builtin(op.args[0].concretetype): + return self.class_map['GetBuiltinField'].render(generator, op) + else: + return self.class_map['GetField'].render(generator, op) + +class _SetFieldDispatcher(_GeneralDispatcher): + def render(self, generator, op): + if self.check_builtin(op.args[0].concretetype): + return self.class_map['SetBuiltinField'].render(generator, op) + else: + return self.class_map['SetField'].render(generator, op) + +class _New(MicroInstruction): + def render(self, generator, op): + generator.new(op.args[0].value) + +New = _New() + +PushAllArgs = _PushAllArgs() +StoreResult = _StoreResult() +SetField = _SetField() +GetField = _GetField() From fijal at codespeak.net Tue Jun 6 17:51:23 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 17:51:23 +0200 (CEST) Subject: [pypy-svn] r28396 - pypy/dist/pypy/translator/cli Message-ID: <20060606155123.EB45A10070@code0.codespeak.net> Author: fijal Date: Tue Jun 6 17:51:23 2006 New Revision: 28396 Modified: pypy/dist/pypy/translator/cli/metavm.py pypy/dist/pypy/translator/cli/opcodes.py Log: Oosupport. Modified: pypy/dist/pypy/translator/cli/metavm.py ============================================================================== --- pypy/dist/pypy/translator/cli/metavm.py (original) +++ pypy/dist/pypy/translator/cli/metavm.py Tue Jun 6 17:51:23 2006 @@ -1,62 +1,5 @@ from pypy.translator.cli import oopspec - -class Generator(object): - def function_signature(self, graph): - pass - - def emit(self, instr, *args): - pass - - def call(self, func_name): - pass - - def load(self, v): - pass - - def store(self, v): - pass - - -class InstructionList(list): - def render(self, generator, op): - for instr in self: - if isinstance(instr, MicroInstruction): - instr.render(generator, op) - else: - generator.emit(instr) - - def __call__(self, *args): - return self.render(*args) - - -class MicroInstruction(object): - def render(self, generator, op): - pass - - def __str__(self): - return self.__class__.__name__ - - def __call__(self, *args): - return self.render(*args) - -class PushArg(MicroInstruction): - def __init__(self, n): - self.n = n - - def render(self, generator, op): - generator.load(op.args[self.n]) - - -class _PushAllArgs(MicroInstruction): - def render(self, generator, op): - for arg in op.args: - generator.load(arg) - - -class _StoreResult(MicroInstruction): - def render(self, generator, op): - generator.store(op.result) - +from pypy.translator.oosupport.metavm import Generator, InstructionList, MicroInstruction class _Call(MicroInstruction): def render(self, generator, op): @@ -85,25 +28,7 @@ method = op.args[0] self._render_method(generator, method.value, op.args[1:]) -class _New(MicroInstruction): - def render(self, generator, op): - generator.new(op.args[0].value) - -class _SetField(MicroInstruction): - def render(self, generator, op): - this, field, value = op.args -## if field.value == 'meta': -## return # TODO - - generator.load(this) - generator.load(value) - generator.set_field(this.concretetype, field.value) -class _GetField(MicroInstruction): - def render(self, generator, op): - this, field = op.args - generator.load(this) - generator.get_field(this.concretetype, field.value) class _RuntimeNew(MicroInstruction): def render(self, generator, op): @@ -111,11 +36,6 @@ generator.call_signature('object [pypylib]pypy.runtime.Utils::RuntimeNew(class [mscorlib]System.Type)') generator.cast_to(op.result.concretetype) -PushAllArgs = _PushAllArgs() -StoreResult = _StoreResult() Call = _Call() -New = _New() -SetField = _SetField() -GetField = _GetField() CallMethod = _CallMethod() RuntimeNew = _RuntimeNew() Modified: pypy/dist/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/cli/opcodes.py (original) +++ pypy/dist/pypy/translator/cli/opcodes.py Tue Jun 6 17:51:23 2006 @@ -1,5 +1,7 @@ -from pypy.translator.cli.metavm import PushArg, PushAllArgs, StoreResult, Call,\ - InstructionList, New, SetField, GetField, CallMethod, RuntimeNew +from pypy.translator.cli.metavm import Call, CallMethod, RuntimeNew + +from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\ + SetField, GetField, New # some useful instruction patterns Not = ['ldc.i4.0', 'ceq'] From fijal at codespeak.net Tue Jun 6 17:52:00 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 17:52:00 +0200 (CEST) Subject: [pypy-svn] r28397 - in pypy/dist/pypy/translator/js2: . modules test Message-ID: <20060606155200.82BC410077@code0.codespeak.net> Author: fijal Date: Tue Jun 6 17:51:59 2006 New Revision: 28397 Modified: pypy/dist/pypy/translator/js2/metavm.py pypy/dist/pypy/translator/js2/modules/dom.py pypy/dist/pypy/translator/js2/opcodes.py pypy/dist/pypy/translator/js2/test/test_dom.py Log: Added support for oosupport. Modified: pypy/dist/pypy/translator/js2/metavm.py ============================================================================== --- pypy/dist/pypy/translator/js2/metavm.py (original) +++ pypy/dist/pypy/translator/js2/metavm.py Tue Jun 6 17:51:59 2006 @@ -3,8 +3,8 @@ """ #from pypy.translator.js2.jsbuiltin import Builtins -from pypy.translator.cli.metavm import PushArg, PushAllArgs, StoreResult,\ - InstructionList, New, SetField, GetField, RuntimeNew, MicroInstruction +from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult,\ + InstructionList, New, SetField, GetField, MicroInstruction from pypy.translator.js2.log import log from pypy.rpython.ootypesystem import ootype @@ -59,42 +59,6 @@ def render(self, generator, op): self._render_builtin(generator, self.builtin, op.args) -class _Builtins(object): - def __init__(self): - list_resize = lambda g,op: SetBuiltinField.run_it(g, op.args[1], 'length', op.args[2]) - - self.builtin_map = { - 'll_js_jseval' : CallBuiltin('eval'), - 'll_newlist' : lambda g,op: g.ilasm.load_const("[]"), - 'll_alloc_and_set' : CallBuiltin('alloc_and_set'), - 'get_document' : lambda g,op: g.ilasm.load_const('document'), - 'setTimeout' : CallBuiltin('setTimeout'), - 'll_int_str' : lambda g,op: Call._render_builtin_method(g, 'toString' , [op.args[2]]), - 'll_strconcat' : InstructionList([PushAllArgs, '+']), - 'll_int' : CallBuiltin('parseInt'), - } - self.builtin_obj_map = { - ootype.String.__class__: { - 'll_strconcat' : InstructionList([PushAllArgs, '+']), - 'll_strlen' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'), - 'll_stritem_nonneg' : ListGetitem, - 'll_streq' : InstructionList([PushAllArgs, '==']), - 'll_strcmp' : CallBuiltin('strcmp'), - 'll_startswith' : CallBuiltin('startswith'), - 'll_endswith' : CallBuiltin('endswith'), - }, - ootype.List: { - 'll_setitem_fast' : ListSetitem, - 'll_getitem_fast' : ListGetitem, - '_ll_resize' : list_resize, - '_ll_resize_ge' : list_resize, - '_ll_resize_le' : list_resize, - 'll_length' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'), - } - } - -Builtins = _Builtins() - class _SameAs(MicroInstruction): def render(self, generator, op): generator.change_name(op.result, op.args[0]) @@ -184,64 +148,6 @@ generator.ilasm.load_const(op.args[1].value._name.replace('.', '_'))#[-1]) generator.cast_function("isinstanceof", 2) -# There are three distinct possibilities where we need to map call differently: -# 1. Object is marked with rpython_hints as a builtin, so every attribut access -# and function call goes as builtin -# 2. Function called is a builtin, so it might be mapped to attribute access, builtin function call -# or even method call -# 3. Object on which method is called is primitive object and method is mapped to some -# method/function/attribute access -class _GeneralDispatcher(MicroInstruction): - def render(self, generator, op): - raise NotImplementedError("pure virtual class") - - def check_builtin(self, this): - if not isinstance(this, ootype.Instance): - return False - return this._hints.get('_suggested_external') - -class _MethodDispatcher(_GeneralDispatcher): - def render(self, generator, op): - method = op.args[0].value - this = op.args[1].concretetype - if self.check_builtin(this): - return CallBuiltinObject.render(generator, op) - try: - Builtins.builtin_obj_map[this.__class__][method](generator, op) - log("%r.%r declared builtin" % (this, method)) - except KeyError: - log("%r.%r declared normal" % (this, method)) - CallMethod.render(generator, op) - -class _CallDispatcher(_GeneralDispatcher): - def render(self, generator, op): - func = op.args[0] - if getattr(func.value._callable, 'suggested_primitive', False): - func_name = func.value._name.split("__")[0] - log("Function name: %s suggested primitive" % func_name) - #if Builtins.builtin_map.has_key(func_name): - return Builtins.builtin_map[func_name](generator, op) - else: - return Call.render(generator, op) - -class _GetFieldDispatcher(_GeneralDispatcher): - def render(self, generator, op): - if self.check_builtin(op.args[0].concretetype): - return GetBuiltinField.render(generator, op) - else: - return GetField.render(generator, op) - -class _SetFieldDispatcher(_GeneralDispatcher): - def render(self, generator, op): - if self.check_builtin(op.args[0].concretetype): - return SetBuiltinField.render(generator, op) - else: - return SetField.render(generator, op) - -MethodDispatcher = _MethodDispatcher() -CallDispatcher = _CallDispatcher() -GetFieldDispatcher = _GetFieldDispatcher() -SetFieldDispatcher = _SetFieldDispatcher() IsInstance = _IsInstance() CallMethod = _CallMethod() CopyName = [PushAllArgs, _SameAs ()] Modified: pypy/dist/pypy/translator/js2/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js2/modules/dom.py (original) +++ pypy/dist/pypy/translator/js2/modules/dom.py Tue Jun 6 17:51:59 2006 @@ -39,6 +39,6 @@ def setTimeout(func, delay): # scheduler call, but we don't want to mess with threads right now - return func + func() setTimeout.suggested_primitive = True Modified: pypy/dist/pypy/translator/js2/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js2/opcodes.py (original) +++ pypy/dist/pypy/translator/js2/opcodes.py Tue Jun 6 17:51:59 2006 @@ -2,17 +2,31 @@ """ opcode definitions """ -from pypy.translator.cli.metavm import PushArg, PushAllArgs, StoreResult,\ - InstructionList, New, SetField, GetField, RuntimeNew, MicroInstruction +from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult,\ + InstructionList, New, SetField, GetField, MicroInstruction +from pypy.translator.oosupport.metavm import _GetFieldDispatcher, _SetFieldDispatcher, \ + _CallDispatcher, _MethodDispatcher + from pypy.translator.js2.metavm import SameAs, IsInstance, Call, CallMethod, CopyName, CastString,\ - _Prefix, _CastFun, _NotImplemented, GetFieldDispatcher, SetFieldDispatcher, CallDispatcher, MethodDispatcher,\ - CallBuiltin + _Prefix, _CastFun, _NotImplemented, CallBuiltin, CallBuiltinObject, GetBuiltinField, SetBuiltinField + +from pypy.translator.js2.jsbuiltin import Builtins DoNothing = [PushAllArgs] from pypy.translator.js2.log import log +class_map = { 'Call' : Call, + 'CallMethod' : CallMethod, + 'CallBuiltinObject' : CallBuiltinObject, + 'CallBuiltin' : CallBuiltin, + 'GetBuiltinField' : GetBuiltinField, + 'GetField' : GetField, + 'SetField' : SetField, + 'SetBuiltinField' : SetBuiltinField +} + opcodes = {'int_mul': '*', 'int_add': '+', 'int_sub': '-', @@ -89,7 +103,7 @@ 'uint_is_true': [PushAllArgs,_Prefix('!!')], 'float_is_true': [PushAllArgs,_Prefix('!!')], - 'direct_call' : [CallDispatcher], + 'direct_call' : [_CallDispatcher(Builtins, class_map)], 'indirect_call' : [_NotImplemented("Indirect call not implemented")], 'same_as' : SameAs, 'new' : [New], @@ -97,9 +111,9 @@ # objects - 'oosetfield' : [SetFieldDispatcher], - 'oogetfield' : [GetFieldDispatcher], - 'oosend' : [MethodDispatcher], + 'oosetfield' : [_SetFieldDispatcher(Builtins, class_map)], + 'oogetfield' : [_GetFieldDispatcher(Builtins, class_map)], + 'oosend' : [_MethodDispatcher(Builtins, class_map)], #'ooupcast' : [_NotImplemented("Inheritance not implemented (ooupcast)")], #'oodowncast' : [_NotImplemented("Inheritance not implemented (oodowncast)")], 'ooupcast' : DoNothing, Modified: pypy/dist/pypy/translator/js2/test/test_dom.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_dom.py (original) +++ pypy/dist/pypy/translator/js2/test/test_dom.py Tue Jun 6 17:51:59 2006 @@ -24,22 +24,32 @@ assert fn() == '[object HTMLHeadingElement]' def test_anim(self): - def move_it_by(obj, dx, dy, dir): - if dir < 0: - dx = -dx - dy = -dy - obj.style.left = str(int(obj.style.left) + dx) + "px" - obj.style.top = str(int(obj.style.top) + dy) + "px" + class Mover(object): + def __init__(self): + self.elem = get_document().getElementById("anim_img") + self.x = 0 + self.y = 0 + self.dir = 1 + + def move_it_by(self, obj, dx, dy): + if dir < 0: + dx = -dx + dy = -dy + self.x += dx + self.y += dy + obj.style.left = str(int(obj.style.left) + dx) + "px" + obj.style.top = str(int(obj.style.top) + dy) + "px" - def move_it(): - move_it_by(get_document().getElementById("anim_img"), 3, 3, 1) - setTimeout('move_it()', 100) + def move_it(self): + self.move_it_by(get_document().getElementById("anim_img"), 3, 3) + setTimeout(mov.move_it, 100) def anim_fun(): obj = get_document().getElementById("anim_img") obj.setAttribute('style', 'position: absolute; top: 0; left: 0;') - setTimeout('move_it()', 100) - move_it() + mov = Mover() + setTimeout(mov.move_it, 100) + mov.move_it() fn = compile_function(anim_fun, [], html = 'html/anim.html', is_interactive = True) assert fn() == 'ok' From fijal at codespeak.net Tue Jun 6 18:18:17 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 18:18:17 +0200 (CEST) Subject: [pypy-svn] r28398 - in pypy/dist/pypy/translator/js2: . test Message-ID: <20060606161817.BA16C10053@code0.codespeak.net> Author: fijal Date: Tue Jun 6 18:18:16 2006 New Revision: 28398 Modified: pypy/dist/pypy/translator/js2/jts.py pypy/dist/pypy/translator/js2/metavm.py pypy/dist/pypy/translator/js2/opcodes.py pypy/dist/pypy/translator/js2/test/test_genllvm.py Log: Indirect call support. Right now it does only support user-defined functions (you cannot access predefined functions that way) Modified: pypy/dist/pypy/translator/js2/jts.py ============================================================================== --- pypy/dist/pypy/translator/js2/jts.py (original) +++ pypy/dist/pypy/translator/js2/jts.py Tue Jun 6 18:18:16 2006 @@ -82,6 +82,7 @@ # FIXME: It's not ok to use always empty list val = "[]" elif isinstance(_type,StaticMethod): + self.db.pending_function(v.graph) val = v._name elif _type is UniChar or _type is Char: #log("Constant %r"%v) Modified: pypy/dist/pypy/translator/js2/metavm.py ============================================================================== --- pypy/dist/pypy/translator/js2/metavm.py (original) +++ pypy/dist/pypy/translator/js2/metavm.py Tue Jun 6 18:18:16 2006 @@ -148,6 +148,13 @@ generator.ilasm.load_const(op.args[1].value._name.replace('.', '_'))#[-1]) generator.cast_function("isinstanceof", 2) +class _IndirectCall(MicroInstruction): + def render(self, generator, op): + for func_arg in op.args[1:]: # push parameters + generator.load(func_arg) + generator.call_external(op.args[0].name, op.args[1:]) + +IndirectCall = _IndirectCall() IsInstance = _IsInstance() CallMethod = _CallMethod() CopyName = [PushAllArgs, _SameAs ()] Modified: pypy/dist/pypy/translator/js2/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js2/opcodes.py (original) +++ pypy/dist/pypy/translator/js2/opcodes.py Tue Jun 6 18:18:16 2006 @@ -9,7 +9,8 @@ _CallDispatcher, _MethodDispatcher from pypy.translator.js2.metavm import SameAs, IsInstance, Call, CallMethod, CopyName, CastString,\ - _Prefix, _CastFun, _NotImplemented, CallBuiltin, CallBuiltinObject, GetBuiltinField, SetBuiltinField + _Prefix, _CastFun, _NotImplemented, CallBuiltin, CallBuiltinObject, GetBuiltinField, SetBuiltinField,\ + IndirectCall from pypy.translator.js2.jsbuiltin import Builtins @@ -104,7 +105,7 @@ 'float_is_true': [PushAllArgs,_Prefix('!!')], 'direct_call' : [_CallDispatcher(Builtins, class_map)], - 'indirect_call' : [_NotImplemented("Indirect call not implemented")], + 'indirect_call' : [IndirectCall], 'same_as' : SameAs, 'new' : [New], 'instanceof' : [IsInstance], Modified: pypy/dist/pypy/translator/js2/test/test_genllvm.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_genllvm.py (original) +++ pypy/dist/pypy/translator/js2/test/test_genllvm.py Tue Jun 6 18:18:16 2006 @@ -7,7 +7,7 @@ from pypy.translator.js2.test.runtest import compile_function def test_simple_function_pointer(): - py.test.skip("ootypesystem problems with lists") + #py.test.skip("ootypesystem problems with lists") def f1(x): return x + 1 def f2(x): @@ -29,7 +29,7 @@ assert f() == 1 def test_invoke_function_pointer(): - py.test.skip("ootypesystem problems with lists") + #py.test.skip("ootypesystem problems with lists") def f1(x): return x + 1 def f2(x): From stephan at codespeak.net Tue Jun 6 19:06:43 2006 From: stephan at codespeak.net (stephan at codespeak.net) Date: Tue, 6 Jun 2006 19:06:43 +0200 (CEST) Subject: [pypy-svn] r28399 - pypy/dist/pypy/module/stackless/test Message-ID: <20060606170643.48AA310053@code0.codespeak.net> Author: stephan Date: Tue Jun 6 19:06:41 2006 New Revision: 28399 Modified: pypy/dist/pypy/module/stackless/test/stack2.py pypy/dist/pypy/module/stackless/test/stackless_.py Log: still not working :-( this is for christian to look at. Specifically, some house keeping after switch (or before) seems to be wrong. Modified: pypy/dist/pypy/module/stackless/test/stack2.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/stack2.py (original) +++ pypy/dist/pypy/module/stackless/test/stack2.py Tue Jun 6 19:06:41 2006 @@ -2,20 +2,38 @@ if hasattr(stackless,'coroutine'): import stackless_ as stackless +DEBUG = False + +def print_sched(prev, next): + try: + print 'before scheduling. prev: %s, next: %s' % (prev, next) + except Exception, e: + print 'Exception in print_sched', e + print '\tprev:', type(prev) + print '\tnext:', type(next) + print + +def print_chan(chan, task, sending, willblock): + print 'channel_action:', chan, task, 's:', sending, ' wb:', + print willblock + print + +if DEBUG: + stackless.set_schedule_callback(print_sched) + stackless.set_channel_callback(print_chan) + def f(outchan): for i in range(10): - #print 'f: outchan before:',str(outchan) print 'f: sending',i + print outchan.send(i) - #print 'f: outchan after:',str(outchan) outchan.send(-1) def g(inchan): while 1: - #print 'g: inchan before:',str(inchan) val = inchan.receive() print 'g: received',val - #print 'g: inchan after:',str(inchan) + print if val == -1: break @@ -23,4 +41,4 @@ t1 = stackless.tasklet(f)(ch) t2 = stackless.tasklet(g)(ch) -t1.run() +stackless.run() Modified: pypy/dist/pypy/module/stackless/test/stackless_.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/stackless_.py (original) +++ pypy/dist/pypy/module/stackless/test/stackless_.py Tue Jun 6 19:06:41 2006 @@ -4,8 +4,27 @@ Please refer to their documentation. """ +import sys + +#DEBUG = True DEBUG = True +switches = 0 + +def ASSERT_Q(task): + try: + if task is not None: + assert isinstance(task,(tasklet,TaskletProxy)) + if task.next is not None: + assert isinstance(task.next,(tasklet, TaskletProxy, Scheduler)) + if task.prev is not None: + assert isinstance(task.prev,(tasklet, TaskletProxy, Scheduler)) + except AssertionError: + if DEBUG: + print 'task to insert as _head is wrong' + print task + raise + try: from stackless import coroutine except ImportError: @@ -43,7 +62,7 @@ def __init__(self, coro): self.alive = False self.atomic = False - self.blocked = False + self.blocked = 0 self.frame = None self.ignore_nesting = False self.is_current = False @@ -164,12 +183,19 @@ sending and willblock are booleans. Pass None to switch monitoring off again. """ - pass + global channel_hook + + channel_hook = callable + +def _schedule_callback(prev, next): + # lot's of error checking missing + global _schedule_hook + return _schedule_hook(prev, next) note = """ should be implemented for debugging purposes. Low priority """ -def set_schedule_callback(callable): +def set_schedule_callback(func): """ set_schedule_callback(callable) -- install a callback for scheduling. Every explicit or implicit schedule will call the callback function @@ -181,7 +207,17 @@ When main starts up or after death, prev is None. Pass None to switch monitoring off again. """ - pass + global _schedule_fasthook + global _schedule_hook + global _schedule_callback + + if func is not None and not callable(func): + raise TypeError("schedule callback nust be callable") + _schedule_hook = func + if func is None: + _schedule_fasthook = None + else: + _schedule_fasthook = _schedule_callback # class tasklet: see below @@ -193,16 +229,17 @@ channel_hook = None schedlock = False _schedule_fasthook = None +_schedule_hook = None def __init(): global main_tasklet global main_coroutine global scheduler - scheduler = Scheduler() main_coroutine = c = coroutine.getcurrent() main_tasklet = TaskletProxy(c) main_tasklet.next = main_tasklet.prev = main_tasklet main_tasklet.is_main = True + scheduler = Scheduler() note = """ It is not needed to implement the watchdog feature right now. @@ -210,7 +247,7 @@ The runner is always main, which must be removed while running all the tasklets. The implementation below is wrong. """ -def run(): +def run(timeout=0): """ run_watchdog(timeout) -- run tasklets until they are all done, or timeout instructions have passed. Tasklets must @@ -221,7 +258,19 @@ tasklet that caused a timeout, if any. If an exception occours, it will be passed to the main tasklet. """ - schedule() + me = scheduler.current_remove() + if me is not main_tasklet: + raise RuntimeError("run() must be run from the main thread's \ + main tasklet") + try: + scheduler.schedule_task(me, scheduler._head, 1) + except Exception, exp: + b = curexc_to_bomb() + main = main_tasklet + main.tempval = b + scheduler.current_insert_after(main) + scheduler.schedule_task(me, main, 1) + def getcurrent(): """ @@ -244,7 +293,7 @@ tasklet as default. schedule_remove(retval=stackless.current) -- ditto, and remove self. """ - prev = getcurrent() + prev = scheduler._head next = prev.next return scheduler.schedule_task(prev, next, 0) """ @@ -305,7 +354,7 @@ New tasklets can be created with methods from the stackless module. """ - __slots__ = ['alive','atomic','blocked','frame', + __slots__ = ['alive','atomic','blocked','block_trap','frame', 'ignore_nesting','is_current','is_main', 'nesting_level','next','paused','prev','recursion_depth', 'restorable','scheduled','tempval','thread_id'] @@ -328,7 +377,8 @@ super(tasklet,self).__init__() self.alive = False self.atomic = False - self.blocked = False + self.blocked = 0 + self.block_trap = False self.frame = None self.ignore_nesting = False self.is_current = False @@ -351,7 +401,9 @@ return self def __str__(self): - return 'Tasklet-%s' % self.thread_id + next = (self.next and self.next.thread_id) or None + prev = (self.prev and self.prev.thread_id) or None + return 'Tasklet-%s(%s) n: %s; p: %s' % (self.thread_id, str(self.blocked), next, prev) def bind(self, func): """ @@ -469,7 +521,6 @@ coroutine.bind(self,self.tempval,*argl,**argd) self.tempval = None self.insert() - """ /*************************************************************************** @@ -496,6 +547,9 @@ """ +def channel_callback(chan, task, sending, willblock): + return channel_hook(chan, task, sending, willblock) + class channel(object): """ A channel object is used for communication between tasklets. @@ -512,10 +566,12 @@ self.balance = 0 self.closing = False self.preference = 0 - self.head = self.tail = None + self.next = self.prev = self + self.schedule_all = False + self.thread_id = -2 def __str__(self): - return 'channel(' + str(self.balance) + ' : ' + str(self.queue) + ')' + return 'channel(' + str(self.balance) + ')' def _get_closed(self): return self.closing and self.next is None @@ -525,16 +581,16 @@ def _channel_insert(self, task, d): self._ins(task) self.balance += d - task.blocked = dir + task.blocked = d def _queue(self): - if self.head is self: + if self.next is self: return None else: - return self.head + return self.next def _channel_remove(self, d): - ret = self.head + ret = self.next assert isinstance(ret,tasklet) self.balance -= d self._rem(ret) @@ -542,19 +598,22 @@ return ret - def channel_remove_specific(self, dir, task): + def channel_remove_specific(self, d, task): # note: we assume that the task is in the channel - self.balance -= dir + self.balance -= d self._rem(task) - task.blocked = False + task.blocked = 0 + return task def _ins(self, task): - assert task.next is None - assert task.prev is None + if DEBUG: + print '### channel._ins(%s)' % task + if (task.next is not None) or (task.prev is not None): + raise AssertionError('task.next and task.prev must be None') # insert at end - task.prev = self.head.prev - task.next = self.head + task.prev = self.prev + task.next = self self.prev.next = task self.prev = task @@ -565,58 +624,83 @@ task.next.prev = task.prev task.prev.next = task.next task.next = task.prev = None + if DEBUG: + print '### channel._rem(%s)' % task - def _notify(self, task, dir, cando, res): + def _notify(self, task, d, cando, res): global schedlock + global channel_hook if channel_hook is not None: if schedlock: raise RuntimeError('Recursive channel call due to callbacks!') schedlock = 1 - channel_callback(self, task, dir > 0, not cando) + channel_callback(self, task, d > 0, not cando) schedlock = 0 - def _channel_action(self, arg, dir, stackl): - source = getcurrent() - target = self.head - interthread = 0 # no interthreading at the moment - if dir > 0: - cando = self.balance < 0 - else: - cando = self.balance > 0 + def _channel_action(self, arg, d, stackl): + try: + #source = getcurrent() + source = scheduler._head + if DEBUG: + print '_channel_action -> source:', source + target = self.next + if DEBUG: + print '_channel_action -> target:', target + print + interthread = 0 # no interthreading at the moment + if d > 0: + cando = self.balance < 0 + else: + cando = self.balance > 0 - assert abs(dir) == 1 + assert abs(d) == 1 - source.tempval = arg - if not interthread: - self._notify(source, dir, cando, None) - if cando: - # communication 1): there is somebody waiting - target = self._channel_remove(-dir) - source.tempval, target.tempval = target.tempval, source.tempval - if interthread: - raise Exception('no interthreading: I can not be reached...') - else: - if self.schedule_all: - scheduler.current_insert(target) - target = source.next - elif self.preference == -dir: - scheduler.current = source.next - scheduler.current_insert(target) - scheduler.current = source + source.tempval = arg + if not interthread: + self._notify(source, d, cando, None) + if DEBUG: + print '_channel_action(',arg, ',', d, ')' + print 'cando:',cando + print + if cando: + # communication 1): there is somebody waiting + target = self._channel_remove(-d) + source.tempval, target.tempval = target.tempval, source.tempval + if interthread: + raise Exception('no interthreading: I can not be reached...') else: - scheduler.current_insert(target) - target = source - else: - if source.block_trap: - raise RuntimeError("this tasklet does not like to be blocked") - if self.closing: - raise StopIteration() - scheduler.current_remove() - self._channel_insert(source, dir) - target = getcurrent() - retval = scheduler.schedule_task(source, target, stackl) + if self.schedule_all: + scheduler.current_insert(target) + target = source.next + elif self.preference == -d: + scheduler._head = source.next + scheduler.current_insert(target) + scheduler._head = source + else: + scheduler.current_insert(target) + target = source + else: + if source.block_trap: + raise RuntimeError("this tasklet does not like to be blocked") + if self.closing: + raise StopIteration() + scheduler.current_remove() + self._channel_insert(source, d) + target = scheduler._head + except Exception, exp: + if DEBUG: + print 'Exception in channel_action', exp, '\n\n' + raise + try: + print '# channel action: calling schedule with', source, target + retval = scheduler.schedule_task(source, target, stackl) + except Exception, exp: + print 'schedule_task raised', exp + print sys.exc_info() + print retval + raise if interthread: - self._notify(source, dir, cando, None) + self._notify(source, d, cando, None) return retval ## note: needed @@ -730,8 +814,12 @@ class Scheduler(object): def __init__(self): - self.chain = None - self.current = None + self._head = getcurrent() + #self.chain = None + #self.current = getcurrent() + + def _set_head(self, task): + self._head = task def reset(self): self.__init__() @@ -742,8 +830,8 @@ def _content(self): visited = set() items = [] - if self.chain: - next = self.chain + next = self._head + if next is not self: while next is not None and next not in visited: items.append(next) visited.add(next) @@ -752,7 +840,10 @@ def __str__(self): parts = ['%s' % x.thread_id for x in self._content()] - currid = (self.current and self.current.thread_id) or -1 + if self._head is not self: + currid = self._head.thread_id + else: + currid = -1 return '===== Scheduler ====\nchain:' + \ ' -> '.join(parts) + '\ncurrent: %s' % currid + \ '\n====================' @@ -760,47 +851,45 @@ def _chain_insert(self, task): assert task.next is None assert task.prev is None - if self.chain is None: + if self._head is None: task.next = task.prev = task - self.chain = task + self._set_head(task) else: - r = self.chain + r = self._head l = r.prev l.next = r.prev = task task.prev = l task.next = r def _chain_remove(self): - if self.chain is None: + if self._head is None: return None - task = self.chain + task = self._head l = task.prev r = task.next l.next = r r.prev = l - self.chain = r + self._set_head(r) if r == task: - self.chain = None + self._set_head(None) task.prev = task.next = None return task def current_insert(self, task): - self.chain = self.current or getcurrent() self._chain_insert(task) - self.current = None def current_insert_after(self, task): - curr = self.current or getcurrent() - self.chain = curr.next - self._chain_insert(task) - self.chain = curr - self.current = None + if self._head is not None: + curr = self._head + self._set_head(curr.next) + self._chain_insert(task) + self._set_head(curr) + else: + self.current_insert(task) def current_remove(self): - self.chain = self.current or getcurrent() - self.current = None return self._chain_remove() def channel_remove_slow(self, task): @@ -810,16 +899,16 @@ chan = prev assert chan.balance if chan.balance > 0: - dir = 1 + d = 1 else: - dir = -1 - return chan.channel_remove_specific(dir, task) + d = -1 + return chan.channel_remove_specific(d, task) def bomb_explode(self, task): thisbomb = task.tempval assert isinstance(thisbomb, bomb) task.tempval = None - bomb._explode() + thisbomb._explode() def _notify_schedule(self, prev, next, errflag): if _schedule_fasthook is not None: @@ -845,30 +934,55 @@ return self.schedule_task(prev, prev, stackl) def schedule_task(self, prev, next, stackl): - if next is None: - return self.schedule_task_block(prev, stackl) - if next.blocked: - self.channel_remove_slow(next) - self.current_insert(next) - elif next.next is None: - self.current_insert(next) - if prev is next: - retval = prev.tempval - if isinstance(retval, bomb): - self.bomb_explode(retval) - retval._explode() - return retval - self._notify_schedule(prev, next, None) + try: + global switches + switches += 1 + myswitch = switches + print '\nschedule_task(%s)' % myswitch, prev, next + if next is None: + return self.schedule_task_block(prev, stackl) + if next.blocked: + self.channel_remove_slow(next) + self.current_insert(next) + elif next.next is None: + self.current_insert(next) + if prev is next: + retval = prev.tempval + if isinstance(retval, bomb): + self.bomb_explode(prev) + return retval + self._notify_schedule(prev, next, None) + except Exception, exp: + print '### Exception BEFORE switch', exp + raise # lots of soft-/ hard switching stuff in C source next.switch() - retval = next.tempval - if isinstance(retval, bomb): - self.bomb_explode(next) + try: + if DEBUG: + print 'after switch(%s) ->' % myswitch ,next + print + #self._set_head(next) + self._head = next - return retval + retval = next.tempval + if isinstance(retval, bomb): + print '!!!!! exploding !!!!!!' + self.bomb_explode(next) + + return retval + except Exception, exp: + print '### Exception AFTER switch', exp + raise + + def schedule_callback(self, prev, next): + ret = _schedule_hook(prev, next) + if ret: + return 0 + else: + return -1 From fijal at codespeak.net Tue Jun 6 19:10:08 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 19:10:08 +0200 (CEST) Subject: [pypy-svn] r28400 - in pypy/dist/pypy/translator/js2: . test Message-ID: <20060606171008.4A00A10053@code0.codespeak.net> Author: fijal Date: Tue Jun 6 19:10:07 2006 New Revision: 28400 Modified: pypy/dist/pypy/translator/js2/metavm.py pypy/dist/pypy/translator/js2/test/test_dom.py Log: First javascript animation working. Modified: pypy/dist/pypy/translator/js2/metavm.py ============================================================================== --- pypy/dist/pypy/translator/js2/metavm.py (original) +++ pypy/dist/pypy/translator/js2/metavm.py Tue Jun 6 19:10:07 2006 @@ -154,6 +154,21 @@ generator.load(func_arg) generator.call_external(op.args[0].name, op.args[1:]) +class _SetTimeout(MicroInstruction): + # FIXME: Dirty hack for javascript callback stuff + def render(self, generator, op): + val = op.args[1].value + if isinstance(val, ootype.StaticMethod): + real_name = val._name + generator.db.pending_function(val.graph) + else: + real_name = val.concretize().value._name + generator.db.pending_function(val.concretize().value.graph) + generator.load_str("'%s()'" % real_name) + generator.load(op.args[2]) + generator.call_external('setTimeout',[0]*2) + +SetTimeout = _SetTimeout() IndirectCall = _IndirectCall() IsInstance = _IsInstance() CallMethod = _CallMethod() Modified: pypy/dist/pypy/translator/js2/test/test_dom.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_dom.py (original) +++ pypy/dist/pypy/translator/js2/test/test_dom.py Tue Jun 6 19:10:07 2006 @@ -5,7 +5,7 @@ import py from pypy.translator.js2.test.runtest import compile_function -from pypy.translator.js2.modules.dom import document, setTimeout, Node, get_document +from pypy.translator.js2.modules.dom import document, Node, get_document, setTimeout from pypy.translator.js2 import conftest import time @@ -13,43 +13,48 @@ if not conftest.option.browser: py.test.skip("Works only in browser (right now?)") -class TestDOM(object): - def test_document_base(self): - def f(): - return get_document().getElementById("dupa") - #document.getElementById("dupa").setInnerHTML("

Fire!

") - #return document.getElementById("dupa") - - fn = compile_function(f, [], html = 'html/test.html') - assert fn() == '[object HTMLHeadingElement]' - - def test_anim(self): - class Mover(object): - def __init__(self): - self.elem = get_document().getElementById("anim_img") - self.x = 0 - self.y = 0 - self.dir = 1 - - def move_it_by(self, obj, dx, dy): - if dir < 0: - dx = -dx - dy = -dy - self.x += dx - self.y += dy - obj.style.left = str(int(obj.style.left) + dx) + "px" - obj.style.top = str(int(obj.style.top) + dy) + "px" - - def move_it(self): - self.move_it_by(get_document().getElementById("anim_img"), 3, 3) - setTimeout(mov.move_it, 100) - - def anim_fun(): - obj = get_document().getElementById("anim_img") - obj.setAttribute('style', 'position: absolute; top: 0; left: 0;') - mov = Mover() - setTimeout(mov.move_it, 100) - mov.move_it() - - fn = compile_function(anim_fun, [], html = 'html/anim.html', is_interactive = True) - assert fn() == 'ok' +def test_document_base(): + def f(): + return get_document().getElementById("dupa") + #document.getElementById("dupa").setInnerHTML("

Fire!

") + #return document.getElementById("dupa") + + fn = compile_function(f, [], html = 'html/test.html') + assert fn() == '[object HTMLHeadingElement]' + +class Mover(object): + def __init__(self): + self.x = 0 + self.y = 0 + self.dir = 1 + + def move_it_by(self, obj, dx, dy): + if self.dir < 0: + dx = -dx + dy = -dy + self.x += dx + self.y += dy + if self.x > 100: + self.dir = -1 + if self.x < 0: + self.dir = 1 + obj.style.left = str(int(obj.style.left) + dx) + "px" + obj.style.top = str(int(obj.style.top) + dy) + "px" + + def move_it(self): + self.move_it_by(get_document().getElementById("anim_img"), 3, 3) + +movers = [Mover(), Mover()] + +def move_it(): + movers[0].move_it() + setTimeout(move_it, 10) + +def test_anim_f(): + def anim_fun(): + obj = get_document().getElementById("anim_img") + obj.setAttribute('style', 'position: absolute; top: 0; left: 0;') + setTimeout(move_it, 10) + + fn = compile_function(anim_fun, [], html = 'html/anim.html', is_interactive = True) + assert fn() == 'ok' From antocuni at codespeak.net Tue Jun 6 19:13:09 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 19:13:09 +0200 (CEST) Subject: [pypy-svn] r28401 - pypy/dist/pypy/rpython Message-ID: <20060606171309.F000810053@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 19:13:09 2006 New Revision: 28401 Modified: pypy/dist/pypy/rpython/llinterp.py Log: Don't re-wrap LLExceptions. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Tue Jun 6 19:13:09 2006 @@ -384,6 +384,8 @@ obj = self.llinterpreter.typer.type_system.deref(fptr) try: return obj._callable(*args) + except LLException, e: + raise except Exception: self.make_llexception() From antocuni at codespeak.net Tue Jun 6 19:14:13 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 19:14:13 +0200 (CEST) Subject: [pypy-svn] r28402 - pypy/dist/pypy/rpython/test Message-ID: <20060606171413.3486710053@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 19:14:12 2006 New Revision: 28402 Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py Log: Don't skip two tests that now pass. Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_objectmodel.py (original) +++ pypy/dist/pypy/rpython/test/test_objectmodel.py Tue Jun 6 19:14:12 2006 @@ -176,7 +176,6 @@ assert res == 2 def test_rtype_r_dict_exceptions(self): - self._skip_oo('r_dict exception handling') def raising_hash(obj): if obj.startswith("bla"): raise TypeError @@ -234,7 +233,6 @@ assert res == 6 def test_access_in_try_set(self): - self._skip_oo('r_dict exception handling') h = lambda x: 1 eq = lambda x,y: x==y def f(d): @@ -261,6 +259,7 @@ assert res == 5 class TestLLtype(BaseTestObjectModel, LLRtypeMixin): + def test_cast_to_and_from_weakaddress(self): class A(object): pass From antocuni at codespeak.net Tue Jun 6 19:15:22 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 19:15:22 +0200 (CEST) Subject: [pypy-svn] r28403 - in pypy/dist/pypy/rpython: . ootypesystem test Message-ID: <20060606171522.2512C10053@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 19:15:21 2006 New Revision: 28403 Modified: pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/rpython/ootypesystem/rdict.py pypy/dist/pypy/rpython/test/test_rconstantdict.py Log: Fixed a bug during construction of r_dict constants in ootypesystem. Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Tue Jun 6 19:15:21 2006 @@ -261,3 +261,10 @@ def __repr__(self): return repr(self.key) + +class _r_dictkey_with_hash(_r_dictkey): + def __init__(self, dic, key, hash): + self.dic = dic + self.key = key + self.hash = hash + Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rdict.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rdict.py Tue Jun 6 19:15:21 2006 @@ -181,12 +181,17 @@ r_key = self.key_repr r_value = self.value_repr - for dictkey, dictvalue in dictobj.items(): - llkey = r_key.convert_const(dictkey) - llvalue = r_value.convert_const(dictvalue) - if self.custom_eq_hash: - l_dict._dict._dict[llkey] = llvalue # XXX: am I cheating? - else: + if self.custom_eq_hash: + for dictkeycont, dictvalue in dictobj._dict.items(): + llkey = r_key.convert_const(dictkeycont.key) + llvalue = r_value.convert_const(dictvalue) + llhash = dictkeycont.hash + l_dictkeycont = objectmodel._r_dictkey_with_hash(l_dict._dict, llkey, llhash) + l_dict._dict._dict[l_dictkeycont] = llvalue + else: + for dictkey, dictvalue in dictobj.items(): + llkey = r_key.convert_const(dictkey) + llvalue = r_value.convert_const(dictvalue) l_dict.ll_set(llkey, llvalue) return l_dict @@ -209,11 +214,6 @@ def rtype_setitem((r_dict, r_key), hop): v_dict, v_key, v_value = hop.inputargs(r_dict, r_dict.key_repr, r_dict.value_repr) - if r_dict.custom_eq_hash: - hop.exception_is_here() -## else: -## hop.exception_cannot_occur() -## hop.exception_is_here() return r_dict.send_message(hop, 'll_set', can_raise=r_dict.custom_eq_hash) def rtype_contains((r_dict, r_key), hop): Modified: pypy/dist/pypy/rpython/test/test_rconstantdict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rconstantdict.py (original) +++ pypy/dist/pypy/rpython/test/test_rconstantdict.py Tue Jun 6 19:15:21 2006 @@ -41,7 +41,6 @@ assert res == 321 def test_constant_r_dict(self): - self._skip_oo('constant r_dict') def strange_key_eq(key1, key2): return key1[0] == key2[0] # only the 1st character is relevant def strange_key_hash(key): From fijal at codespeak.net Tue Jun 6 19:18:37 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 19:18:37 +0200 (CEST) Subject: [pypy-svn] r28404 - pypy/dist/pypy/translator/js2 Message-ID: <20060606171837.C9C0D10053@code0.codespeak.net> Author: fijal Date: Tue Jun 6 19:18:37 2006 New Revision: 28404 Added: pypy/dist/pypy/translator/js2/jsbuiltin.py Log: Added necessary file. Added: pypy/dist/pypy/translator/js2/jsbuiltin.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/jsbuiltin.py Tue Jun 6 19:18:37 2006 @@ -0,0 +1,45 @@ + +""" JavaScript builtin mappings +""" + +from pypy.translator.oosupport.metavm import InstructionList, PushAllArgs +from pypy.translator.js2.metavm import SetBuiltinField, ListGetitem, ListSetitem, \ + GetBuiltinField, CallBuiltin, Call, SetTimeout + +from pypy.rpython.ootypesystem import ootype + +class _Builtins(object): + def __init__(self): + list_resize = lambda g,op: SetBuiltinField.run_it(g, op.args[1], 'length', op.args[2]) + + self.builtin_map = { + 'll_js_jseval' : CallBuiltin('eval'), + 'll_newlist' : lambda g,op: g.ilasm.load_const("[]"), + 'll_alloc_and_set' : CallBuiltin('alloc_and_set'), + 'get_document' : lambda g,op: g.ilasm.load_const('document'), + 'setTimeout' : SetTimeout, + 'll_int_str' : lambda g,op: Call._render_builtin_method(g, 'toString' , [op.args[2]]), + 'll_strconcat' : InstructionList([PushAllArgs, '+']), + 'll_int' : CallBuiltin('parseInt'), + } + self.builtin_obj_map = { + ootype.String.__class__: { + 'll_strconcat' : InstructionList([PushAllArgs, '+']), + 'll_strlen' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'), + 'll_stritem_nonneg' : ListGetitem, + 'll_streq' : InstructionList([PushAllArgs, '==']), + 'll_strcmp' : CallBuiltin('strcmp'), + 'll_startswith' : CallBuiltin('startswith'), + 'll_endswith' : CallBuiltin('endswith'), + }, + ootype.List: { + 'll_setitem_fast' : ListSetitem, + 'll_getitem_fast' : ListGetitem, + '_ll_resize' : list_resize, + '_ll_resize_ge' : list_resize, + '_ll_resize_le' : list_resize, + 'll_length' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'), + } + } + +Builtins = _Builtins() From antocuni at codespeak.net Tue Jun 6 19:19:02 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 19:19:02 +0200 (CEST) Subject: [pypy-svn] r28405 - pypy/dist/pypy/rpython/test Message-ID: <20060606171902.BF01910064@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 19:19:02 2006 New Revision: 28405 Modified: pypy/dist/pypy/rpython/test/test_rfloat.py Log: Two more tests ported to ootypesystem. Modified: pypy/dist/pypy/rpython/test/test_rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rfloat.py (original) +++ pypy/dist/pypy/rpython/test/test_rfloat.py Tue Jun 6 19:19:02 2006 @@ -33,22 +33,6 @@ for opname in annmodel.BINARY_OPERATIONS: print 'BINARY_OPERATIONS:', opname -def test_int_conversion(): - def fn(f): - return int(f) - - res = interpret(fn, [1.0]) - assert res == 1 - assert type(res) is int - res = interpret(fn, [2.34]) - assert res == fn(2.34) - -def test_hash(): - def fn(f): - return hash(f) - res = interpret(fn, [1.5]) - assert res == hash(1.5) - class BaseTestRfloat(BaseRtypingTest): def test_float2str(self): @@ -65,8 +49,25 @@ res = self.interpret(fn, [1.5]) assert float(self.ll_to_string(res)) == 1.5 + def test_int_conversion(self): + def fn(f): + return int(f) + + res = self.interpret(fn, [1.0]) + assert res == 1 + assert type(res) is int + res = self.interpret(fn, [2.34]) + assert res == fn(2.34) + + class TestLLtype(BaseTestRfloat, LLRtypeMixin): - pass + + def test_hash(self): + def fn(f): + return hash(f) + res = self.interpret(fn, [1.5]) + assert res == hash(1.5) + class TestOOtype(BaseTestRfloat, OORtypeMixin): pass From antocuni at codespeak.net Tue Jun 6 19:22:23 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 19:22:23 +0200 (CEST) Subject: [pypy-svn] r28406 - pypy/dist/pypy/rpython/test Message-ID: <20060606172223.5FC5610053@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 19:22:22 2006 New Revision: 28406 Modified: pypy/dist/pypy/rpython/test/test_rint.py Log: More ootypesystem tests. Modified: pypy/dist/pypy/rpython/test/test_rint.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rint.py (original) +++ pypy/dist/pypy/rpython/test/test_rint.py Tue Jun 6 19:22:22 2006 @@ -37,91 +37,6 @@ print 'BINARY_OPERATIONS:', opname -def test_unsigned(): - def dummy(i): - i = r_uint(i) - j = r_uint(12) - return i < j - - res = interpret(dummy,[0]) - assert res is True - - res = interpret(dummy, [-1]) - assert res is False # -1 ==> 0xffffffff - -def test_specializing_int_functions(): - def f(i): - return i + 1 - f._annspecialcase_ = "specialize:argtype(0)" - def g(n): - if n > 0: - return f(r_longlong(0)) - else: - return f(0) - res = interpret(g, [0]) - assert res == 1 - - res = interpret(g, [1]) - assert res == 1 - -def test_downcast_int(): - def f(i): - return int(i) - res = interpret(f, [r_longlong(0)]) - assert res == 0 - -def test_isinstance_vs_int_types(): - class FakeSpace(object): - def wrap(self, x): - if x is None: - return [None] - if isinstance(x, str): - return x - if isinstance(x, r_longlong): - return int(x) - return "XXX" - wrap._annspecialcase_ = 'specialize:argtype(0)' - - space = FakeSpace() - def wrap(x): - return space.wrap(x) - res = interpret(wrap, [r_longlong(0)]) - assert res == 0 - -def test_truediv(): - import operator - def f(n, m): - return operator.truediv(n, m) - res = interpret(f, [20, 4]) - assert type(res) is float - assert res == 5.0 - - -def test_rarithmetic(): - inttypes = [int, r_uint, r_longlong, r_ulonglong] - for inttype in inttypes: - c = inttype() - def f(): - return c - res = interpret(f, []) - assert res == f() - assert type(res) == inttype - - for inttype in inttypes: - def f(): - return inttype(0) - res = interpret(f, []) - assert res == f() - assert type(res) == inttype - - for inttype in inttypes: - def f(x): - return x - res = interpret(f, [inttype(0)]) - assert res == f(inttype(0)) - assert type(res) == inttype - - class BaseTestRint(BaseRtypingTest): def test_char_constant(self): @@ -176,6 +91,89 @@ res = self.interpret(dummy, [-123]) assert self.ll_to_string(res) == '-0173' + def test_unsigned(self): + def dummy(i): + i = r_uint(i) + j = r_uint(12) + return i < j + + res = self.interpret(dummy,[0]) + assert res is True + + res = self.interpret(dummy, [-1]) + assert res is False # -1 ==> 0xffffffff + + def test_specializing_int_functions(self): + def f(i): + return i + 1 + f._annspecialcase_ = "specialize:argtype(0)" + def g(n): + if n > 0: + return f(r_longlong(0)) + else: + return f(0) + res = self.interpret(g, [0]) + assert res == 1 + + res = self.interpret(g, [1]) + assert res == 1 + + def test_downcast_int(self): + def f(i): + return int(i) + res = self.interpret(f, [r_longlong(0)]) + assert res == 0 + + def test_isinstance_vs_int_types(self): + class FakeSpace(object): + def wrap(self, x): + if x is None: + return [None] + if isinstance(x, str): + return x + if isinstance(x, r_longlong): + return int(x) + return "XXX" + wrap._annspecialcase_ = 'specialize:argtype(0)' + + space = FakeSpace() + def wrap(x): + return space.wrap(x) + res = self.interpret(wrap, [r_longlong(0)]) + assert res == 0 + + def test_truediv(self): + import operator + def f(n, m): + return operator.truediv(n, m) + res = self.interpret(f, [20, 4]) + assert type(res) is float + assert res == 5.0 + + + def test_rarithmetic(self): + inttypes = [int, r_uint, r_longlong, r_ulonglong] + for inttype in inttypes: + c = inttype() + def f(): + return c + res = self.interpret(f, []) + assert res == f() + assert type(res) == inttype + + for inttype in inttypes: + def f(): + return inttype(0) + res = self.interpret(f, []) + assert res == f() + assert type(res) == inttype + + for inttype in inttypes: + def f(x): + return x + res = self.interpret(f, [inttype(0)]) + assert res == f(inttype(0)) + assert type(res) == inttype class TestLLtype(BaseTestRint, LLRtypeMixin): pass From antocuni at codespeak.net Tue Jun 6 19:27:19 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 19:27:19 +0200 (CEST) Subject: [pypy-svn] r28407 - pypy/dist/pypy/rpython/test Message-ID: <20060606172719.0123210060@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 19:27:18 2006 New Revision: 28407 Modified: pypy/dist/pypy/rpython/test/test_rlist.py Log: One more ootypesystem test. Modified: pypy/dist/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rlist.py (original) +++ pypy/dist/pypy/rpython/test/test_rlist.py Tue Jun 6 19:27:18 2006 @@ -449,8 +449,7 @@ res = self.interpret(dummyfn, (6,)) assert res == 1 - interpret_raises(ValueError, dummyfn, [42]) - + self.interpret_raises(ValueError, dummyfn, [42]) def test_insert_pop(self): def dummyfn(): From arigo at codespeak.net Tue Jun 6 19:29:01 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 6 Jun 2006 19:29:01 +0200 (CEST) Subject: [pypy-svn] r28408 - pypy/dist/pypy/translator/goal Message-ID: <20060606172901.C18A810069@code0.codespeak.net> Author: arigo Date: Tue Jun 6 19:29:00 2006 New Revision: 28408 Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: Trying to make PyPy translatable again. (step 1) Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Tue Jun 6 19:29:00 2006 @@ -25,35 +25,42 @@ # __________ Entry point __________ -def entry_point(argv): - debug("entry point starting") - for arg in argv: - debug(" argv -> " + arg) - try: - try: - space.call_function(w_run_toplevel, w_call_startup) - w_executable = space.wrap(argv[0]) - w_argv = space.newlist([space.wrap(s) for s in argv[1:]]) - w_exitcode = space.call_function(w_entry_point, w_executable, w_argv) - exitcode = space.int_w(w_exitcode) - # try to pull it all in - ## from pypy.interpreter import main, interactive, error - ## con = interactive.PyPyConsole(space) - ## con.interact() - except OperationError, e: - debug("OperationError:") - debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) - return 1 - finally: +def create_entry_point(space, w_dict): + w_entry_point = space.getitem(w_dict, space.wrap('entry_point')) + w_run_toplevel = space.getitem(w_dict, space.wrap('run_toplevel')) + w_call_finish_gateway = space.wrap(gateway.interp2app(call_finish)) + w_call_startup_gateway = space.wrap(gateway.interp2app(call_startup)) + + def entry_point(argv): + debug("entry point starting") + for arg in argv: + debug(" argv -> " + arg) try: - space.call_function(w_run_toplevel, w_call_finish) - except OperationError, e: - debug("OperationError:") - debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) - return 1 - return exitcode + try: + space.call_function(w_run_toplevel, w_call_startup_gateway) + w_executable = space.wrap(argv[0]) + w_argv = space.newlist([space.wrap(s) for s in argv[1:]]) + w_exitcode = space.call_function(w_entry_point, w_executable, w_argv) + exitcode = space.int_w(w_exitcode) + # try to pull it all in + ## from pypy.interpreter import main, interactive, error + ## con = interactive.PyPyConsole(space) + ## con.interact() + except OperationError, e: + debug("OperationError:") + debug(" operror-type: " + e.w_type.getname(space, '?')) + debug(" operror-value: " + space.str_w(space.str(e.w_value))) + return 1 + finally: + try: + space.call_function(w_run_toplevel, w_call_finish_gateway) + except OperationError, e: + debug("OperationError:") + debug(" operror-type: " + e.w_type.getname(space, '?')) + debug(" operror-value: " + space.str_w(space.str(e.w_value))) + return 1 + return exitcode + return entry_point # _____ Define and setup target ___ @@ -78,14 +85,9 @@ def call_finish(space): space.finish() -w_call_finish = gateway.interp2app(call_finish) - def call_startup(space): space.startup() -w_call_startup = gateway.interp2app(call_startup) - - def target(driver, args): driver.exe_name = 'pypy-%(backend)s' @@ -95,7 +97,8 @@ translate.log_options(tgt_options, "target PyPy options in effect") - global space, w_entry_point, w_run_toplevel + # expose the following variables to ease debugging + global space, entry_point geninterp = not getattr(options, 'lowmem', False) @@ -125,8 +128,7 @@ filename = os.path.join(this_dir, 'app_main.py') w_dict = space.newdict([]) space.exec_(open(filename).read(), w_dict, w_dict) - w_entry_point = space.getitem(w_dict, space.wrap('entry_point')) - w_run_toplevel = space.getitem(w_dict, space.wrap('run_toplevel')) + entry_point = create_entry_point(space, w_dict) # sanity-check: call the entry point res = entry_point(["pypy", "app_basic_example.py"]) From antocuni at codespeak.net Tue Jun 6 19:36:06 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 19:36:06 +0200 (CEST) Subject: [pypy-svn] r28409 - pypy/dist/pypy/rpython/test Message-ID: <20060606173606.ADC5310060@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 19:36:05 2006 New Revision: 28409 Modified: pypy/dist/pypy/rpython/test/test_rpbc.py Log: Two more ootypesystem tests. Modified: pypy/dist/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rpbc.py (original) +++ pypy/dist/pypy/rpython/test/test_rpbc.py Tue Jun 6 19:36:05 2006 @@ -1293,7 +1293,7 @@ return value + AorB(n).meth(x) for i in [1, 3, 5]: - res = interpret(f, [i]) + res = self.interpret(f, [i]) assert res == f(i) def test_function_as_frozen_pbc(self): @@ -1311,21 +1311,18 @@ res = self.interpret(f, [2]) assert res == False - -def test_call_from_list(): - # Don't test with ootype, since it doesn't support lists in a - # coherent way yet. - def f0(n): return n+200 - def f1(n): return n+192 - def f2(n): return n+46 - def f3(n): return n+2987 - def f4(n): return n+217 - lst = [f0, f1, f2, f3, f4] - def f(i, n): - return lst[i](n) - for i in range(5): - res = interpret(f, [i, 1000]) - assert res == f(i, 1000) + def test_call_from_list(self): + def f0(n): return n+200 + def f1(n): return n+192 + def f2(n): return n+46 + def f3(n): return n+2987 + def f4(n): return n+217 + lst = [f0, f1, f2, f3, f4] + def f(i, n): + return lst[i](n) + for i in range(5): + res = self.interpret(f, [i, 1000]) + assert res == f(i, 1000) # We don't care about the following test_hlinvoke tests working on From fijal at codespeak.net Tue Jun 6 19:37:05 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Jun 2006 19:37:05 +0200 (CEST) Subject: [pypy-svn] r28410 - pypy/dist/pypy/translator/js2 Message-ID: <20060606173705.2C8E910060@code0.codespeak.net> Author: fijal Date: Tue Jun 6 19:37:04 2006 New Revision: 28410 Modified: pypy/dist/pypy/translator/js2/jts.py Log: Compatibility issue with sets on python2.3. Modified: pypy/dist/pypy/translator/js2/jts.py ============================================================================== --- pypy/dist/pypy/translator/js2/jts.py (original) +++ pypy/dist/pypy/translator/js2/jts.py Tue Jun 6 19:37:04 2006 @@ -13,6 +13,11 @@ from pypy.translator.js2.log import log +try: + set +except NameError: + from sets import Set as set + class JTS(object): """ Class implementing JavaScript type system calls with mapping similiar to cts From mwh at codespeak.net Tue Jun 6 19:42:09 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 6 Jun 2006 19:42:09 +0200 (CEST) Subject: [pypy-svn] r28411 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060606174209.9C8271006F@code0.codespeak.net> Author: mwh Date: Tue Jun 6 19:42:08 2006 New Revision: 28411 Added: pypy/extradoc/sprintinfo/ddorf2006/report1.txt (contents, props changed) Log: draft version of a sprint report, we need to upload a photo before we send this out. Added: pypy/extradoc/sprintinfo/ddorf2006/report1.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/ddorf2006/report1.txt Tue Jun 6 19:42:08 2006 @@ -0,0 +1,151 @@ +Duesseldorf Sprint Report Days 1-4 +================================== + +So we're sitting in the geography^Wcomputer science department of +Heinrich-Heine-Universitaet Duesseldorf, the alleged employers of +Armin and Michael, and (also alleged) educator of Carl. We've been +doing the usual sprinty things of drinking beer, getting up late, +going to bed even later (and so still not really getting much sleep) +and hacking. + +An early task was finishing off the mostly complete weakref support. +After drawing an extremely confusing diagram: + + http://XXX + +Carl and Arre realized that there were a few strange cases that our +model cannot support (in the case of a object and a +weakref-with-callback to the same object both being in the same trash +cycle, it is unclear whether the callback will be called). We plan to +deal with this by calling anyone who claims to care insane. They then +looked at getting CPython's test_weakref to run (something that's been +on the "that would be nice" list for a looong time). This uncovered +an amusing problem, a result of three facts: + +1. the conservative Boehm collector cannot distinguish between a + pointer and an integer that happens to have the same bit pattern as + the pointer (this is what is meant by "conservative"). + +2. the hash of a weakref object is the hash of the referenced object. + +3. the default hash of a Python instance is it's id, which is usually + the memory address cast to an int. + +This made weakref.WeakKeyDictionary rather poorly named. This was +fixed by changing the id when using Boehm; the pointer is cast to an +integer and then bitwise complemented. Accidentally, this means that +that this: + + bool(id(object()) & 1) + +is now a check for pypy-c linked with the Boehm GC (use this fact with +care). + +After solving the weak-keys-are-strong problem and adding a few calls +to gc.collect() to CPython's test_weakref (to give Boehm a hurry up), +test_weakref now passes. + +This leads on to the work that Anders and Holger did during the first +day of the sprint: improving PyPy's "compliance score": + + http://codespeak.net/~hpk/pypy-testresult/ + +After a couple of months of relative neglect, this measure of how +accurately we implement CPython's behaviour had slipped to around 80%. +After fixing a few problems with the new interp-level implementation +of the complex type and the above weakref work, we are back well over +95%. + +Michael helped Samuele remember exactly what he was thinking of in a +branch that previously had only been the subject of hacking in the +small hours of the night before his vacation. The goal of the +nocturnal head bashing was to introduce the concept of an "explicit +resume point" in an RPython program: a named, arbitrary location in +the code and a way of transferring control to that point together with +values for all live local variables. For example: + + def f(x, y, z): + r = x + y + rstack.resume_point("rp_f", r, z) + return r + z + +defines a resume point called "rp_f" and records that the values of r +and z must be supplied when the state is jumped to, like so: + + state = rstack.resume_state_create(None, "rp_f", 3, 4) + result = rstack.resume_state_invoke(state) + +Something like this is a necessary piece in the puzzle that is +implementing tasklet pickling, or more properly tasklet unpickling. +This was a nice illustration of the "build one to throw away" concept: +we were able to see that what Samuele had implemented as one operation +really needed to be implemented as two (resume_state_create and +resume_state_invoke in the above examples), and the rest of the coding +only required moderate amounts of head bashing. By this morning, they +had written a test that manually copied a (interp-level) coroutine, +which validates the approach to at least some extent. + +You can also use explicit resume points to write some extremely +confusing programs (as we discovered by mistake when debugging). + +The other major pieces of the tasklet pickling puzzle are being able +to pickle and unpickle the core interpreter types such as frames, +generators, tracebacks, ..., placing enough explicit resume points in +the source of the Standard Interpreter to be able to resume a pickled +tasklet and integration of the various pieces. Christian and Eric +(working remotely; he arrives in Duesseldorf today) worked on the +pickling and unpickling of interpreter types and have now implemented +this for enough types that we now have no real option but to face the +scary task of making something useful. + +For the last couple of days, the attention of Holger, Armin (still +recovering from the 'flu, that's why we haven't mentioned him yet), +Arre and a bit of Carl have been focussed on the elusive +"ext-compiler": a tool designed to take an RPython module in a form +suitable for making an "extension" for PyPy and translating it into an +efficient extension module for CPython. This would clearly already be +useful for purely algorithmic code, but the new-ish rctypes package of +PyPy allows it to be used for modules that wrap an external library. + +While most of the basic technology is present for this, the tool is +still far too rough to be unleashed even on unsuspecting Summer of +Code students, never mind mere humans. Holger and Arre fleshed out +ideas for how to build a more usable interface and wrote some +documentation explaining this interface (who said open source projects +are rubbish at documentation?). Armin began implementing support for +typedefs, i.e. exposing custom types in the module interface, but ran +into a small army of confusing levels of abstraction, which shift +around as soon as you aren't staring at them. We're sure they're no +match for Armin's planet-sized [#]_ brain though :) + +.. _[#]: http://mail.python.org/pipermail/python-dev/2003-January/032600.html + +While some of the above work involved much discussion and occasional +voluminous cursing, two or three people have been sitting in the +corner muttering about strange things like "ootypes" and "dot-net" and +"javaskript", as well as producing a stream of high quality checkins +(most of them have the log message "More ootypesystem tests", though). +PyPy semi-regular Nik and newcomers and Summer of Code participants +Antonio and Maciej worked on the ootypesystem backends, fixing many +bugs and implementing new features, to the point that the richards and +rpystone benchmarks can be run using the llinterpreter (now +increasingly badly named; rinterpreter would prooooobably be better, +but would have other unhelpful connotations). + +They couldn't run these benchmarks without a small modification: +removing the print at the end that tells you how fast they ran +(running things on the llinterpreter is so horrendously slow that this +doesn't defeat the point of the excercise as you might at first +think). The problem with printing is that it involves calling an +external function, something that was not at all supported in the +ootypesystem's world. So they decided to fix that :) And they did. + +Maciej also worked on the newer, ootype-using version of Javascript +backend, and can now write python programs which bounce bub-n-bros +characters around a browser window. This was a good way of getting +Armin's attention :) + +Pozdrawiam, +mwh & Carl Friedrich + + From antocuni at codespeak.net Tue Jun 6 19:42:50 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Jun 2006 19:42:50 +0200 (CEST) Subject: [pypy-svn] r28412 - pypy/dist/pypy/rpython/test Message-ID: <20060606174250.468111006F@code0.codespeak.net> Author: antocuni Date: Tue Jun 6 19:42:48 2006 New Revision: 28412 Modified: pypy/dist/pypy/rpython/test/test_rclass.py pypy/dist/pypy/rpython/test/test_rdict.py pypy/dist/pypy/rpython/test/test_rfloat.py pypy/dist/pypy/rpython/test/test_rint.py pypy/dist/pypy/rpython/test/test_rlist.py pypy/dist/pypy/rpython/test/test_rpbc.py pypy/dist/pypy/rpython/test/test_rtuple.py Log: Removed some unused imports. Now we are confident the ootypesystem is complete, for some definitions of 'confident' and 'complete'. :-) Modified: pypy/dist/pypy/rpython/test/test_rclass.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rclass.py (original) +++ pypy/dist/pypy/rpython/test/test_rclass.py Tue Jun 6 19:42:48 2006 @@ -3,7 +3,6 @@ from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.ootypesystem import ootype -#from pypy.rpython.test.test_llinterp import interpret, interpret_raises from pypy.rpython.rarithmetic import intmask from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin Modified: pypy/dist/pypy/rpython/test/test_rdict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rdict.py (original) +++ pypy/dist/pypy/rpython/test/test_rdict.py Tue Jun 6 19:42:48 2006 @@ -1,6 +1,5 @@ from pypy.translator.translator import TranslationContext from pypy.rpython.lltypesystem import lltype -from pypy.rpython.test.test_llinterp import interpret, interpret_raises from pypy.rpython import rint from pypy.rpython.lltypesystem import rdict, rstr from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin Modified: pypy/dist/pypy/rpython/test/test_rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rfloat.py (original) +++ pypy/dist/pypy/rpython/test/test_rfloat.py Tue Jun 6 19:42:48 2006 @@ -1,6 +1,5 @@ from pypy.translator.translator import TranslationContext from pypy.rpython.test import snippet -from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin class TestSnippet(object): Modified: pypy/dist/pypy/rpython/test/test_rint.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rint.py (original) +++ pypy/dist/pypy/rpython/test/test_rint.py Tue Jun 6 19:42:48 2006 @@ -2,7 +2,6 @@ from pypy.translator.translator import TranslationContext from pypy.annotation import model as annmodel from pypy.rpython.test import snippet -from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.rarithmetic import r_uint, r_longlong, r_ulonglong from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin Modified: pypy/dist/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rlist.py (original) +++ pypy/dist/pypy/rpython/test/test_rlist.py Tue Jun 6 19:42:48 2006 @@ -8,8 +8,6 @@ from pypy.rpython.ootypesystem import rlist as oo_rlist from pypy.rpython.lltypesystem.rslice import ll_newslice from pypy.rpython.rint import signed_repr -from pypy.rpython.test.test_llinterp import interpret -from pypy.rpython.test.test_llinterp import interpret_raises from pypy.translator.translator import TranslationContext from pypy.objspace.flow.model import Constant, Variable from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin Modified: pypy/dist/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rpbc.py (original) +++ pypy/dist/pypy/rpython/test/test_rpbc.py Tue Jun 6 19:42:48 2006 @@ -1,6 +1,5 @@ from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.rtyper import RPythonTyper -from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.ootypesystem import ootype from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin Modified: pypy/dist/pypy/rpython/test/test_rtuple.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rtuple.py (original) +++ pypy/dist/pypy/rpython/test/test_rtuple.py Tue Jun 6 19:42:48 2006 @@ -3,7 +3,6 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.rint import signed_repr from pypy.rpython.rbool import bool_repr -from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin import py From arigo at codespeak.net Tue Jun 6 20:32:23 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 6 Jun 2006 20:32:23 +0200 (CEST) Subject: [pypy-svn] r28413 - pypy/dist/pypy/interpreter Message-ID: <20060606183223.E836C10060@code0.codespeak.net> Author: arigo Date: Tue Jun 6 20:32:23 2006 New Revision: 28413 Modified: pypy/dist/pypy/interpreter/pyframe.py Log: Make PyPy translatable again (step 2/2). Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Tue Jun 6 20:32:23 2006 @@ -78,7 +78,7 @@ nt = space.newtuple if isinstance(self, PyNestedScopeFrame): - w_cells = w([w(cell) for cell in self.cells]) + w_cells = space.newlist([w(cell) for cell in self.cells]) else: w_cells = space.w_None @@ -127,7 +127,6 @@ w_f_back, w_builtin, w_pycode, w_valuestack, w_blockstack, w_last_exception,\ w_globals, w_last_instr, w_next_instr, w_f_lineno, w_fastlocals, w_f_locals, \ w_f_trace, w_instr_lb, w_instr_ub, w_instr_prev, w_cells = args_w - w = space.wrap #new_frame = PyFrame(space, pycode, w(globals), None) # let the code object create the right kind of frame @@ -436,32 +435,6 @@ ### Frame Blocks ### -block_classes = {} - -def setup_block_classes(): - "NOT_RPYTHON" - import types - for cls in globals().values(): - if isinstance(cls, (types.ClassType,type)): - if issubclass(cls, FrameBlock) and hasattr(cls, '_opname'): - block_classes[cls._opname] = cls - -def get_block_class(opname): - # select the appropriate kind of block - if not block_classes: - setup_block_classes() # lazily - return block_classes[opname] - -def unpickle_block(space, w_tup): - w_opname, w_handlerposition, w_valuestackdepth = space.unpackiterable(w_tup) - opname = space.str_w(w_opname) - handlerposition = space.int_w(w_handlerposition) - valuestackdepth = space.int_w(w_valuestackdepth) - blk = instantiate(get_block_class(opname)) - blk.handlerposition = handlerposition - blk.valuestackdepth = valuestackdepth - return blk - class FrameBlock: """Abstract base class for frame blocks from the blockstack, @@ -681,3 +654,29 @@ class BytecodeCorruption(ValueError): """Detected bytecode corruption. Never caught; it's an error.""" + +# ____________________________________________________________ + +def setup_block_classes(): + "NOT_RPYTHON" + import types + for cls in globals().values(): + if isinstance(cls, (types.ClassType,type)): + if issubclass(cls, FrameBlock) and hasattr(cls, '_opname'): + block_classes[cls._opname] = cls +block_classes = {} +setup_block_classes() + +def get_block_class(opname): + # select the appropriate kind of block + return block_classes[opname] + +def unpickle_block(space, w_tup): + w_opname, w_handlerposition, w_valuestackdepth = space.unpackiterable(w_tup) + opname = space.str_w(w_opname) + handlerposition = space.int_w(w_handlerposition) + valuestackdepth = space.int_w(w_valuestackdepth) + blk = instantiate(get_block_class(opname)) + blk.handlerposition = handlerposition + blk.valuestackdepth = valuestackdepth + return blk From arigo at codespeak.net Tue Jun 6 20:37:48 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 6 Jun 2006 20:37:48 +0200 (CEST) Subject: [pypy-svn] r28414 - in pypy/branch/pypy-malloc-nz: . annotation rpython rpython/lltypesystem rpython/memory translator/c translator/c/src Message-ID: <20060606183748.B283310060@code0.codespeak.net> Author: arigo Date: Tue Jun 6 20:37:46 2006 New Revision: 28414 Added: pypy/branch/pypy-malloc-nz/ - copied from r28413, pypy/dist/pypy/ Modified: pypy/branch/pypy-malloc-nz/annotation/builtin.py pypy/branch/pypy-malloc-nz/rpython/llinterp.py pypy/branch/pypy-malloc-nz/rpython/lltypesystem/llheap.py pypy/branch/pypy-malloc-nz/rpython/lltypesystem/llmemory.py pypy/branch/pypy-malloc-nz/rpython/lltypesystem/lloperation.py pypy/branch/pypy-malloc-nz/rpython/lltypesystem/lltype.py pypy/branch/pypy-malloc-nz/rpython/memory/gc.py pypy/branch/pypy-malloc-nz/rpython/memory/gclltype.py pypy/branch/pypy-malloc-nz/rpython/memory/gctransform.py pypy/branch/pypy-malloc-nz/rpython/memory/lladdress.py pypy/branch/pypy-malloc-nz/rpython/memory/simulator.py pypy/branch/pypy-malloc-nz/rpython/rbuiltin.py pypy/branch/pypy-malloc-nz/translator/c/funcgen.py pypy/branch/pypy-malloc-nz/translator/c/src/mem.h Log: A branch to experiment with a raw_malloc_nz operation that doesn't zero out memory. Modified: pypy/branch/pypy-malloc-nz/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/branch/pypy-malloc-nz/annotation/builtin.py Tue Jun 6 20:37:46 2006 @@ -543,7 +543,7 @@ from pypy.rpython.memory import lladdress -def raw_malloc(s_size): +def raw_malloc(s_size, s_clear=None): assert isinstance(s_size, SomeInteger) #XXX add noneg...? return SomeAddress() Modified: pypy/branch/pypy-malloc-nz/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/llinterp.py Tue Jun 6 20:37:46 2006 @@ -798,9 +798,9 @@ # __________________________________________________________ # operations on addresses - def op_raw_malloc(self, size): + def op_raw_malloc_nz(self, size): assert lltype.typeOf(size) == lltype.Signed - return self.heap.raw_malloc(size) + return self.heap.raw_malloc(size, clear=False) def op_raw_malloc_usage(self, size): assert lltype.typeOf(size) == lltype.Signed @@ -815,6 +815,10 @@ assert checkadr(toaddr) self.heap.raw_memcopy(fromaddr, toaddr, size) + def op_raw_memclear(self, addr, size): + assert checkadr(addr) + self.heap.raw_memclear(addr, size) + def op_raw_load(self, addr, typ, offset): assert checkadr(addr) value = getattr(addr, str(typ).lower())[offset] Modified: pypy/branch/pypy-malloc-nz/rpython/lltypesystem/llheap.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/llheap.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/lltypesystem/llheap.py Tue Jun 6 20:37:46 2006 @@ -2,5 +2,5 @@ from pypy.rpython.lltypesystem.lltype import pyobjectptr, malloc, free from pypy.rpython.lltypesystem.llmemory import raw_malloc, raw_free -from pypy.rpython.lltypesystem.llmemory import raw_memcopy +from pypy.rpython.lltypesystem.llmemory import raw_memcopy, raw_memclear from pypy.rpython.lltypesystem.llmemory import raw_malloc_usage Modified: pypy/branch/pypy-malloc-nz/rpython/lltypesystem/llmemory.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/llmemory.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/lltypesystem/llmemory.py Tue Jun 6 20:37:46 2006 @@ -527,7 +527,7 @@ # ____________________________________________________________ -def raw_malloc(size): +def raw_malloc(size, clear=True): if not isinstance(size, AddressOffset): raise NotImplementedError(size) return size.raw_malloc([]) @@ -552,6 +552,9 @@ from pypy.rpython.rctypes.rmodel import reccopy reccopy(source, dest) +def raw_memclear(adr, size): + pass # XXX + # ____________________________________________________________ class _arena(object): Modified: pypy/branch/pypy-malloc-nz/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/lltypesystem/lloperation.py Tue Jun 6 20:37:46 2006 @@ -292,10 +292,11 @@ # __________ address operations __________ - 'raw_malloc': LLOp(canraise=(MemoryError,)), + 'raw_malloc_nz': LLOp(canraise=(MemoryError,)), 'raw_malloc_usage': LLOp(sideeffects=False), 'raw_free': LLOp(), 'raw_memcopy': LLOp(), + 'raw_memclear': LLOp(), 'raw_load': LLOp(sideeffects=False), 'raw_store': LLOp(), 'adr_add': LLOp(canfold=True), Modified: pypy/branch/pypy-malloc-nz/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/lltypesystem/lltype.py Tue Jun 6 20:37:46 2006 @@ -437,12 +437,6 @@ def _inline_is_varsize(self, last): raise TypeError, "%r cannot be inlined in structure" % self -class PyObjectType(ContainerType): - __name__ = 'PyObject' - def __str__(self): - return "PyObject" -PyObject = PyObjectType() - class ForwardReference(ContainerType): def become(self, realcontainertype): if not isinstance(realcontainertype, ContainerType): @@ -462,9 +456,6 @@ self.__class__ = realcontainertype.__class__ self.__dict__ = realcontainertype.__dict__ -GC_CONTAINER = (GcStruct, GcArray, PyObjectType, GcForwardReference, - GcOpaqueType) - class Primitive(LowLevelType): def __init__(self, name, default): @@ -521,6 +512,21 @@ UniChar = Primitive("UniChar", u'\x00') +class PyObjectType(ContainerType): + def __init__(self, DATA=Void): + self.DATA = DATA + if DATA is Void: + self.__name__ = 'PyObject' + else: + self.__name__ = 'PyObjectType(%s)' % (DATA,) + def __str__(self): + return self.__name__ +PyObject = PyObjectType() + +GC_CONTAINER = (GcStruct, GcArray, PyObjectType, GcForwardReference, + GcOpaqueType) + + class Ptr(LowLevelType): __name__ = property(lambda self: '%sPtr' % self.TO.__name__) Modified: pypy/branch/pypy-malloc-nz/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/memory/gc.py Tue Jun 6 20:37:46 2006 @@ -1,5 +1,6 @@ from pypy.rpython.memory.lladdress import raw_malloc, raw_free, raw_memcopy from pypy.rpython.memory.lladdress import NULL, _address, raw_malloc_usage +from pypy.rpython.memory.lladdress import raw_memclear from pypy.rpython.memory.support import get_address_linked_list from pypy.rpython.memory.gcheader import GCHeaderBuilder from pypy.rpython.memory import lltypesimulation @@ -109,7 +110,7 @@ return init_gc_object_immortal = init_gc_object -DEBUG_PRINT = True +DEBUG_PRINT = False class MarkSweepGC(GCBase): _alloc_flavor_ = "raw" @@ -162,17 +163,20 @@ offset_to_length = self.varsize_offset_to_length(typeid) ref = self.malloc_varsize(typeid, length, size, itemsize, offset_to_length, True) + addr = llmemory.cast_ptr_to_adr(ref) else: ref = self.malloc_fixedsize(typeid, size, True) + addr = llmemory.cast_ptr_to_adr(ref) + raw_memclear(addr, size) # XXX lots of cast and reverse-cast around, but this malloc() # should eventually be killed - return llmemory.cast_ptr_to_adr(ref) + return addr def malloc_fixedsize(self, typeid, size, can_collect): if can_collect and self.bytes_malloced > self.bytes_malloced_threshold: self.collect() size_gc_header = self.gcheaderbuilder.size_gc_header - result = raw_malloc(size_gc_header + size) + result = raw_malloc(size_gc_header + size, clear=False) hdr = llmemory.cast_adr_to_ptr(result, self.HDRPTR) hdr.typeid = typeid << 1 if not self.getfinalizer(typeid): Modified: pypy/branch/pypy-malloc-nz/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/memory/gclltype.py Tue Jun 6 20:37:46 2006 @@ -4,6 +4,7 @@ from pypy.rpython.memory.lltypesimulation import malloc, functionptr, nullptr from pypy.rpython.memory.lltypesimulation import pyobjectptr from pypy.rpython.memory.lladdress import raw_malloc, raw_free, raw_memcopy +from pypy.rpython.memory.lladdress import raw_memclear def raw_malloc_usage(sz): return sz Modified: pypy/branch/pypy-malloc-nz/rpython/memory/gctransform.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/memory/gctransform.py Tue Jun 6 20:37:46 2006 @@ -18,6 +18,7 @@ from pypy.rpython.memory.gcheader import GCHeaderBuilder from pypy.rpython.annlowlevel import MixLevelHelperAnnotator from pypy.rpython.extregistry import ExtRegistryEntry +from pypy.rpython.rtyper import LowLevelOpList import sets, os def var_ispyobj(var): @@ -1194,6 +1195,10 @@ ops, index = self.protect_roots(newop, livevars, block, block.operations.index(op)) ops.append(SpaceOperation("cast_opaque_ptr", [v], op.result)) + if not op.opname.endswith('_varsize'): + llops = LowLevelOpList(None) + gen_zero_gc_pointers(TYPE, op.result, llops) + ops.extend(llops) return ops replace_malloc_varsize = replace_malloc @@ -1297,6 +1302,20 @@ offsets.append(0) return offsets +def gen_zero_gc_pointers(TYPE, v, llops): + assert isinstance(TYPE, lltype.Struct) + for name in TYPE._names: + FIELD = getattr(TYPE, name) + if isinstance(FIELD, lltype.Ptr) and FIELD._needsgc(): + c_name = Constant(name, lltype.Void) + c_null = Constant(lltype.nullptr(FIELD.TO), FIELD) + llops.genop('bare_setfield', [v, c_name, c_null]) + elif isinstance(FIELD, lltype.Struct): + c_name = Constant(name, lltype.Void) + v1 = llops.genop('getsubstruct', [v, c_name], + resulttype = lltype.Ptr(FIELD)) + gen_zero_gc_pointers(FIELD, v1, llops) + # ____________________________________________________________ Modified: pypy/branch/pypy-malloc-nz/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/memory/lladdress.py Tue Jun 6 20:37:46 2006 @@ -118,7 +118,7 @@ simulator = MemorySimulator() -def raw_malloc(size): +def raw_malloc(size, clear=True): return _address(simulator.malloc(size)) def raw_malloc_usage(size): @@ -131,6 +131,9 @@ def raw_memcopy(addr1, addr2, size): simulator.memcopy(addr1.intaddress, addr2.intaddress, size) +def raw_memclear(addr, size): + simulator.memclear(addr.intaddress, size) + def get_address_of_object(obj): return _address(simulator.get_address_of_object(obj)) Modified: pypy/branch/pypy-malloc-nz/rpython/memory/simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/simulator.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/memory/simulator.py Tue Jun 6 20:37:46 2006 @@ -58,6 +58,9 @@ other.memory[offset2:offset2+size] = self.memory[offset1:offset1+size] other.status[offset2:offset2+size] = self.status[offset1:offset1+size] + def memclear(self, offset, size): + self.setbytes(offset, "\x00" * size) + # block which stores functions and PyObects class ObjectBlock(object): Modified: pypy/branch/pypy-malloc-nz/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/branch/pypy-malloc-nz/rpython/rbuiltin.py Tue Jun 6 20:37:46 2006 @@ -494,9 +494,18 @@ from pypy.rpython.memory import lladdress from pypy.rpython.lltypesystem import llmemory -def rtype_raw_malloc(hop): - v_size, = hop.inputargs(lltype.Signed) - return hop.genop('raw_malloc', [v_size], resulttype=llmemory.Address) +def rtype_raw_malloc(hop, i_clear=None): + v_size = hop.inputarg(lltype.Signed, 0) + if i_clear is not None: + v_clear = hop.inputarg(lltype.Bool, i_clear) + assert isinstance(v_clear, Constant) + clear = v_clear.value + else: + clear = True + res = hop.genop('raw_malloc_nz', [v_size], resulttype=llmemory.Address) + if clear: + hop.genop('raw_memclear', [res, v_size]) + return res def rtype_raw_malloc_usage(hop): v_size, = hop.inputargs(lltype.Signed) Modified: pypy/branch/pypy-malloc-nz/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/branch/pypy-malloc-nz/translator/c/funcgen.py Tue Jun 6 20:37:46 2006 @@ -559,7 +559,7 @@ if flavor == "raw": return "OP_RAW_MALLOC(%s, %s);" % (esize, eresult) elif flavor == "stack": - return "OP_STACK_MALLOC(%s, %s);" % (esize, eresult) + return "OP_STACK_MALLOC(%s, %s);" % (esize, eresult) else: raise NotImplementedError Modified: pypy/branch/pypy-malloc-nz/translator/c/src/mem.h ============================================================================== --- pypy/dist/pypy/translator/c/src/mem.h (original) +++ pypy/branch/pypy-malloc-nz/translator/c/src/mem.h Tue Jun 6 20:37:46 2006 @@ -15,7 +15,8 @@ if (r == NULL) FAIL_EXCEPTION(PyExc_MemoryError, "out of memory");\ #define OP_RAW_FREE(x,r) OP_FREE(x) -#define OP_RAW_MEMCOPY(x,y,size,r) memcpy(y,x,size); +#define OP_RAW_MEMCOPY(x,y,size,r) memcpy(y,x,size) +#define OP_RAW_MEMCLEAR(x,size,r) memset(x,0,size) /************************************************************/ @@ -44,6 +45,13 @@ COUNT_MALLOC; \ } \ } +#define OP_RAW_MALLOC_NZ(size, r) { \ + r = (void*) PyObject_Malloc(size); \ + if (r == NULL) {FAIL_EXCEPTION(PyExc_MemoryError, "out of memory"); } \ + else { \ + COUNT_MALLOC; \ + } \ + } #define OP_FREE(p) { PyObject_Free(p); COUNT_FREE; } From antocuni at codespeak.net Wed Jun 7 10:40:05 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 10:40:05 +0200 (CEST) Subject: [pypy-svn] r28417 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20060607084005.49A2810060@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 10:40:04 2006 New Revision: 28417 Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py Log: Fixed a bug in ootypesystem rdict. Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rdict.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rdict.py Wed Jun 7 10:40:04 2006 @@ -214,6 +214,8 @@ def rtype_setitem((r_dict, r_key), hop): v_dict, v_key, v_value = hop.inputargs(r_dict, r_dict.key_repr, r_dict.value_repr) + if not r_dict.custom_eq_hash: + hop.exception_cannot_occur() # XXX: maybe should we move this inside send_message? return r_dict.send_message(hop, 'll_set', can_raise=r_dict.custom_eq_hash) def rtype_contains((r_dict, r_key), hop): From fijal at codespeak.net Wed Jun 7 10:59:54 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 7 Jun 2006 10:59:54 +0200 (CEST) Subject: [pypy-svn] r28418 - pypy/dist/pypy/translator/js2/test/html Message-ID: <20060607085954.C9FC410060@code0.codespeak.net> Author: fijal Date: Wed Jun 7 10:59:53 2006 New Revision: 28418 Added: pypy/dist/pypy/translator/js2/test/html/anim.html Log: Added test-base html file. Added: pypy/dist/pypy/translator/js2/test/html/anim.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/test/html/anim.html Wed Jun 7 10:59:53 2006 @@ -0,0 +1,36 @@ + + + + + + + +
+ + + + + From fijal at codespeak.net Wed Jun 7 11:04:40 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 7 Jun 2006 11:04:40 +0200 (CEST) Subject: [pypy-svn] r28419 - pypy/dist/pypy/translator/js2/test Message-ID: <20060607090440.56F9110060@code0.codespeak.net> Author: fijal Date: Wed Jun 7 11:04:39 2006 New Revision: 28419 Modified: pypy/dist/pypy/translator/js2/test/browsertest.py Log: Added html base file check. Modified: pypy/dist/pypy/translator/js2/test/browsertest.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/browsertest.py (original) +++ pypy/dist/pypy/translator/js2/test/browsertest.py Wed Jun 7 11:04:39 2006 @@ -93,7 +93,12 @@ isinteractive = '' else: isinteractive = 'resultform.submit();' - html_page = open(self.server.html_page).read() % locals() + try: + html_page = open(self.server.html_page).read() % locals() + except IOError: + log("HTML FILE WAS NOT FOUND!!!!") + self.send_error(404, "File not found") + return else: html_page = config.html_page % locals() From hpk at codespeak.net Wed Jun 7 11:16:31 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 7 Jun 2006 11:16:31 +0200 (CEST) Subject: [pypy-svn] r28420 - pypy/dist/pypy/doc Message-ID: <20060607091631.4BB7610060@code0.codespeak.net> Author: hpk Date: Wed Jun 7 11:16:30 2006 New Revision: 28420 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/extcompiler.txt pypy/dist/pypy/doc/getting-started.txt Log: fixing extcompiler ReST, adding and updating references Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Wed Jun 7 11:16:30 2006 @@ -28,10 +28,13 @@ .. _`lib/test2/`: .. _`pypy/lib/test2`: ../../pypy/lib/test2 .. _`module/`: -.. _`pypy/module`: ../../pypy/module +.. _`pypy/module`: +.. _`pypy/module/`: ../../pypy/module .. _`module/__builtin__/`: ../../pypy/module/__builtin__ .. _`pypy/module/__builtin__/__init__.py`: ../../pypy/module/__builtin__/__init__.py .. _`module/_sre/`: ../../pypy/module/_sre +.. _`pypy/module/readline`: ../../pypy/module/readline +.. _`pypy/module/readline/test/test_readline.py`: ../../pypy/module/readline/test/test_readline.py .. _`module/recparser/`: ../../pypy/module/recparser .. _`module/sys/`: ../../pypy/module/sys .. _`objspace/`: Modified: pypy/dist/pypy/doc/extcompiler.txt ============================================================================== --- pypy/dist/pypy/doc/extcompiler.txt (original) +++ pypy/dist/pypy/doc/extcompiler.txt Wed Jun 7 11:16:30 2006 @@ -32,6 +32,8 @@ XXX describe directory structure here +.. _`pypy checkout`: getting-started.html#gettingpypy + testing a module ++++++++++++++++++++++++ @@ -103,3 +105,4 @@ otherwise it will complain with "unable to open this file with RTLD_LOCAL" when trying to load the C library. +.. include:: _ref.txt Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Wed Jun 7 11:16:30 2006 @@ -25,6 +25,8 @@ Just the facts ============== +.. _gettingpypy: + Downloading & running the PyPy 0.8 release ------------------------------------------- From hpk at codespeak.net Wed Jun 7 12:07:15 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 7 Jun 2006 12:07:15 +0200 (CEST) Subject: [pypy-svn] r28422 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060607100715.7376510064@code0.codespeak.net> Author: hpk Date: Wed Jun 7 12:07:14 2006 New Revision: 28422 Modified: pypy/extradoc/sprintinfo/ddorf2006/report1.txt Log: fix footnote (thanks michael) Modified: pypy/extradoc/sprintinfo/ddorf2006/report1.txt ============================================================================== --- pypy/extradoc/sprintinfo/ddorf2006/report1.txt (original) +++ pypy/extradoc/sprintinfo/ddorf2006/report1.txt Wed Jun 7 12:07:14 2006 @@ -118,7 +118,7 @@ around as soon as you aren't staring at them. We're sure they're no match for Armin's planet-sized [#]_ brain though :) -.. _[#]: http://mail.python.org/pipermail/python-dev/2003-January/032600.html +.. [#] http://mail.python.org/pipermail/python-dev/2003-January/032600.html While some of the above work involved much discussion and occasional voluminous cursing, two or three people have been sitting in the From ac at codespeak.net Wed Jun 7 12:20:31 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 7 Jun 2006 12:20:31 +0200 (CEST) Subject: [pypy-svn] r28423 - pypy/extradoc/sprintinfo/leysin-summer-2006 Message-ID: <20060607102031.75BB21006F@code0.codespeak.net> Author: ac Date: Wed Jun 7 12:20:30 2006 New Revision: 28423 Added: pypy/extradoc/sprintinfo/leysin-summer-2006/ pypy/extradoc/sprintinfo/leysin-summer-2006/people.txt (contents, props changed) Log: Initial europycon pre-sprint information. Added: pypy/extradoc/sprintinfo/leysin-summer-2006/people.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/leysin-summer-2006/people.txt Wed Jun 7 12:20:30 2006 @@ -0,0 +1,46 @@ + +People coming to the Leysin sprint Winter 2006 +================================================== + +People who have a ``?`` in their arrive/depart or accomodation +column are known to be coming but there are no details +available yet from them. + +Use ``Accomodation = Ermina`` for the group booking at the Chalets. + +==================== ============== ===================== + Name Arrive/Depart Accomodation +==================== ============== ===================== +Anders Chrigstroem 27/6 - 2/7 Ermina +Samuele Pedroni 27/6 - 2/7 Ermina +Armin Rigo -- private +==================== ============== ===================== + +People on the following list were present at previous sprints: + +==================== ============== ===================== + Name Arrive/Depart Accomodation +==================== ============== ===================== +Holger Krekel ? ? +Lene Wagner ? ? +Amaury Forgeot d'Arc ? ? +Valentino Volonghi ? ? +Boris Feigin ? ? +Andrew Thompson ? ? +Bert Freudenberg ? ? +Laura Creighton ? ? +Beatrice Duering ? ? +Eric van Riet Paap ? ? +Carl Friedrich Bolz ? ? +Richard Emslie ? ? +Johan Hahn ? ? +Christian Tismer ? ? +Michael Hudson ? ? +Anders Lehmann ? ? +Jacob Hallen ? ? +Niklaus Haldimann ? ? +Aurelien Campeas ? ? +Alexandre Fayolle ? ? +Maciej Fijalkowski ? ? +Antonio Cuni ? ? +==================== ============== ===================== From ac at codespeak.net Wed Jun 7 12:22:49 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 7 Jun 2006 12:22:49 +0200 (CEST) Subject: [pypy-svn] r28424 - pypy/extradoc/sprintinfo/europython-2006 Message-ID: <20060607102249.80EA810060@code0.codespeak.net> Author: ac Date: Wed Jun 7 12:22:48 2006 New Revision: 28424 Modified: pypy/extradoc/sprintinfo/europython-2006/people.txt Log: My and Samueles details. Modified: pypy/extradoc/sprintinfo/europython-2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/europython-2006/people.txt (original) +++ pypy/extradoc/sprintinfo/europython-2006/people.txt Wed Jun 7 12:22:48 2006 @@ -8,6 +8,8 @@ ==================== ============== ===================== Name Arrive/Depart Accomodation ==================== ============== ===================== +Anders Chrigstroem 2/7 - 10/7 NH Geneva Airport +Samuele Pedroni 2/7 - 10/7 NH Geneva Airport ==================== ============== ===================== People on the following list were present at previous sprints: @@ -21,8 +23,6 @@ Carl Friedrich Bolz ? ? Eric van Riet Paap ? ? Maciej Fijalkowski ? ? -Anders Chrigstroem ? ? -Samuele Pedroni ? ? Christian Tismer ? ? Antonio Cuni ? ? Anders Lehmann ? ? From hpk at codespeak.net Wed Jun 7 12:25:52 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 7 Jun 2006 12:25:52 +0200 (CEST) Subject: [pypy-svn] r28425 - pypy/extradoc/sprintinfo/post-ep2006 Message-ID: <20060607102552.061C710069@code0.codespeak.net> Author: hpk Date: Wed Jun 7 12:25:50 2006 New Revision: 28425 Added: pypy/extradoc/sprintinfo/post-ep2006/ pypy/extradoc/sprintinfo/post-ep2006/announce.txt (contents, props changed) pypy/extradoc/sprintinfo/post-ep2006/people.txt (contents, props changed) Log: draft announcement + people Added: pypy/extradoc/sprintinfo/post-ep2006/announce.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/post-ep2006/announce.txt Wed Jun 7 12:25:50 2006 @@ -0,0 +1,59 @@ +Geneva/CERN Post-EuroPython PyPy sprint 6-9th July +==================================================== + +The next PyPy sprint will be held at CERN/Geneva right after +the EuroPython conference. We specifically invite newcomers +and people interested to get to know and get into PyPy development. +We are going to work on a variety of topics and will give +introductions to various aspects of PyPy (on the 6th morning). + +Some foreseen focus will be on the following topics: + +* The extension module compiler. Using it for implementing + extension modules both for PyPy and CPython from the same + source code. (for example if you have a Need for Speed :) + +* work and experiment with our to-be-relased 0.9 stackless features + +* work on high level backends: .NET, Javascript etc. + +* optimization of core Python data types, making full + use of PyPy's flexible architecture and python-implemented + (and then translated) type system. + +* You may even dare to dive into ongoing work on the JIT compiler + +* experimenting with novel security systems for Python, + enabled by PyPy + +* and so on :) + +Registration +---------------------- + +If you'd like to come, please subscribe to the `pypy-sprint mailing list`_ +and drop a note about your interests and post any questions. More +organisational information will be send to that list. We'll keep +a list of `people`_ which we'll update (which you can do so yourself +if you have codespeak commit rights). + +Special note to Students! +---------------------------- + +We have already four people working on a "Summer of Code" proposal, +three of which we could get through the Google/PSF process. + +However, we are working to enable 4-6 more students to get +travel + accomodation funding and provide mentoring from our side. +This we call "Summer of PyPy". The idea is that you can suggest +a PyPy related proposal to us ("pypy-tb at codespeak.net") and we will +then get back to you. If we agree to it, then you can get expenses +funding. + +As we still need to figure out budget/money issues, for now we +can only promise for now that we can fund this Post-EP2006 sprint +for such students. But don't hesitate to come to our irc channel, +ask around and produce such proposals! + +.. _`pypy-sprint mailing list`: http://codespeak.net/mailman/listinfo/pypy-sprint +.. _`people`: people.html Added: pypy/extradoc/sprintinfo/post-ep2006/people.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/post-ep2006/people.txt Wed Jun 7 12:25:50 2006 @@ -0,0 +1,43 @@ +People coming to the Post EuroPython Sprint (Geneva) 2006 +============================================================= + +People who have a ``?`` in their arrive/depart or accomodation +column are known to be coming but there are no details +available yet from them. + +==================== ============== ===================== + Name Arrive/Depart Accomodation +==================== ============== ===================== +Michael Hudson 6-9th ? +Armin Rigo ? private +Carl Friedrich Bolz 6-9th CERN hostel +Guido Wesdorp 6-9th CERN hostel +Holger Krekel 6-? CERN hostel +Maciej Fijalkowski ? ? +Anders Chrigstroem ? ? +Samuele Pedroni ? ? +Christian Tismer ? ? +Antonio Cuni ? ? +Anders Lehmann ? ? +==================== ============== ===================== + +People on the following list were present at previous sprints: + +==================== ============== ===================== + Name Arrive/Depart Accomodation +==================== ============== ===================== +Christian Tismer ? ? +Jacob Hallen ? ? +Aurelien Campeas ? ? +Alexandre Fayolle ? ? +Lene Wagner ? ? +Amaury Forgeot d'Arc ? ? +Valentino Volonghi ? ? +Boris Feigin ? ? +Andrew Thompson ? ? +Bert Freudenberg ? ? +Laura Creighton ? ? +Beatrice Duering ? ? +Richard Emslie ? ? +Johan Hahn ? ? +==================== ============== ===================== From pedronis at codespeak.net Wed Jun 7 12:35:03 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 7 Jun 2006 12:35:03 +0200 (CEST) Subject: [pypy-svn] r28426 - pypy/extradoc/sprintinfo/post-ep2006 Message-ID: <20060607103503.3A2B810074@code0.codespeak.net> Author: pedronis Date: Wed Jun 7 12:35:02 2006 New Revision: 28426 Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt Log: arre's and my information Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/post-ep2006/people.txt (original) +++ pypy/extradoc/sprintinfo/post-ep2006/people.txt Wed Jun 7 12:35:02 2006 @@ -14,8 +14,8 @@ Guido Wesdorp 6-9th CERN hostel Holger Krekel 6-? CERN hostel Maciej Fijalkowski ? ? -Anders Chrigstroem ? ? -Samuele Pedroni ? ? +Anders Chrigstroem 2/7 - 10/7 NH Geneva Airport +Samuele Pedroni 2/7 - 10/7 NH Geneva Airport Christian Tismer ? ? Antonio Cuni ? ? Anders Lehmann ? ? From pedronis at codespeak.net Wed Jun 7 12:35:48 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 7 Jun 2006 12:35:48 +0200 (CEST) Subject: [pypy-svn] r28427 - pypy/extradoc/sprintinfo/europython-2006 Message-ID: <20060607103548.0F89F10064@code0.codespeak.net> Author: pedronis Date: Wed Jun 7 12:35:47 2006 New Revision: 28427 Removed: pypy/extradoc/sprintinfo/europython-2006/ Log: replaced by post-ep2006 From ale at codespeak.net Wed Jun 7 12:40:17 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 7 Jun 2006 12:40:17 +0200 (CEST) Subject: [pypy-svn] r28429 - in pypy/dist/pypy/lib/pyontology: . test Message-ID: <20060607104017.4A55610064@code0.codespeak.net> Author: ale Date: Wed Jun 7 12:40:16 2006 New Revision: 28429 Modified: pypy/dist/pypy/lib/pyontology/constraint_classes.py pypy/dist/pypy/lib/pyontology/pyontology.py pypy/dist/pypy/lib/pyontology/test/test_ontology.py Log: Added a class to implement the semantic of individuals. Changed and fixed the tests Modified: pypy/dist/pypy/lib/pyontology/constraint_classes.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/constraint_classes.py (original) +++ pypy/dist/pypy/lib/pyontology/constraint_classes.py Wed Jun 7 12:40:16 2006 @@ -26,8 +26,8 @@ import py from pypy.tool.ansi_print import ansi_log -log = py.log.Producer("CardinalityConstraint") -py.log.setconsumer("CardinalityConstraint", ansi_log) +log = py.log.Producer("Constraint") +py.log.setconsumer("Constraint", ansi_log) class CardinalityConstraint(AbstractConstraint): @@ -101,18 +101,29 @@ Thing_uri = URIRef(u'http://www.w3.org/2002/07/owl#Thing') +class MemberConstraint(AbstractConstraint): + + def __init__(self, variable, cls_or_restriction): + AbstractConstraint.__init__(self, [ cls_or_restriction]) + self.object = cls_or_restriction + self.variable = variable + + def narrow(self, domains): + x_vals = domains[self.object].getValues() + if self.variable not in x_vals: + raise ConsistencyFailure("%s not in %s"% (self.variable, self.object)) + class ComplementOfConstraint(SubClassConstraint): def narrow(self, domains): vals = domains[self.variable].getValues() x_vals = domains[self.object].getValues() - for v in x_vals: - if v in vals: - raise ConsistencyFailure("%s cannot have the value %s and be \ - complementOf %s" % (v, self.object, self.variable)) - for v in domains['owl_Thing'].getValues(): - if not v in vals: - domains[self.variable].addValue(v) + remove = [] + for v in vals: + if v in x_vals: + remove.append(v) + log("Complementof %r %r"%([x.name for x in remove], [x.name for x in x_vals])) + domains[self.variable].removeValues(remove) class RangeConstraint(SubClassConstraint): @@ -133,10 +144,6 @@ res = newrange propdom.range = res propdom.setValues([(None,i) for i in res]) - #prop = Linkeddict(propdom.getValues()) - #for pval in sum(prop.values(),[]): - # if pval not in range: - # raise ConsistencyFailure("Value %r not in range %r for Var %s"%(pval,range, self.variable)) class DomainConstraint(SubClassConstraint): @@ -298,10 +305,8 @@ val = Linkeddict(vals) if self.variable in val.keys() and not self.object in val.keys(): vals +=[dom.addValue(self.object,v) for v in val[self.variable]] - #dom.setValues(vals) elif not self.variable in val.keys() and self.object in val.keys(): vals +=[dom.addValue(self.variable,v) for v in val[self.object]] - #dom.setValues(vals) elif self.variable in val.keys() and self.object in val.keys(): if not val[self.object] == val[self.variable]: raise ConsistencyFailure("Sameas failure: The two individuals (%s, %s) \ Modified: pypy/dist/pypy/lib/pyontology/pyontology.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/pyontology.py (original) +++ pypy/dist/pypy/lib/pyontology/pyontology.py Wed Jun 7 12:40:16 2006 @@ -4,9 +4,8 @@ from logilab.constraint.propagation import AbstractDomain, AbstractConstraint, ConsistencyFailure from constraint_classes import * import sys, py -from pypy.tool.ansi_print import ansi_log import time - +from pypy.tool.ansi_print import ansi_log log = py.log.Producer("Pyontology") py.log.setconsumer("Pyontology", ansi_log) @@ -57,9 +56,10 @@ # Properties of a class is in the dictionary "properties" # The bases of a class is in the list "bases" - def __init__(self, name='', values=[], bases = []): + def __init__(self, name='', uri=None, values = [], bases = []): AbstractDomain.__init__(self) self.name = name + self.uri = uri self.values = {} self.setValues(values) self.property = None @@ -67,16 +67,21 @@ self.un_constraint = [] self.in_constraint = [] self.domains = {} - self._bases = [] #bases #+[name] + self.bases = [] self.finished = False + self.value = None def finish(self, variables, glob_constraints): # The finish method constructs the constraints if not self.finished: log("FINISH %s" % self.name) # Try to initialise constraints for this class + prop = getattr(self, 'property') + val = getattr(self, 'value') + if prop: + prop = variables[prop] for constraint in self.un_constraint: - dom, constraints = constraint(self.name, variables[self.property], self.value) + dom, constraints = constraint(self.name, prop, val) if dom: self.domains.update(dom) self.in_constraint.extend(constraints) @@ -84,6 +89,8 @@ for cls in self.bases: cls = variables[cls] dom,constraint = cls.finish(variables, glob_constraints) + + log("DOM %r "%dom) # if the base class is a Restriction we shouldnt add the constraints to the store if not isinstance(cls, Restriction): self.domains.update(dom) @@ -97,7 +104,8 @@ self.finished = True log("RESULT of finish %r, %r" %(self.domains,self.in_constraint)) # update the store - if 'owl_Thing' in variables.keys() and isinstance(self, ClassDomain): + if ('owl_Thing' in variables.keys() and isinstance(self, ClassDomain) + and self.getValues() == []): variables[self.name].setValues(variables['owl_Thing'].getValues()) variables.update(self.domains) glob_constraints.extend(self.in_constraint) @@ -115,7 +123,7 @@ def removeValues(self, values): for val in values: - self.values.pop(val) #(self.values.index(val)) + self.values.pop(val) def getBases(self): return self._bases @@ -124,7 +132,6 @@ log(">>>>>>>>>>>>>>>>>>>>>>> %r" %self.name) assert self.name != 'owl_Class' self._bases = bases - bases = property(getBases, setBases) def addValue(self, value): self.values[value] = True @@ -141,11 +148,32 @@ class Thing(ClassDomain): pass +class Individual: + def __init__(self, name, uri=None, values=[], bases=[]): + self.name = name + self.uri = uri + self.sameas = [] + self.differentfrom = [] + + def __hash__(self): + return hash(self.uri) + def __eq__(self, other): + log("CMP %r,%r"%(self,other)) + if ((hasattr(other,'uri') and self.uri == other.uri) or + (not hasattr(other,'uri') and self.uri == other) or + other in self.sameas): + return True + if other in self.differentfrom: + return False + else: + return None + + cmp = __eq__ + class List(ClassDomain): def __init__(self, name='', values=[], bases = []): ClassDomain.__init__(self, name, values, bases) -# self.constraint = ListConstraint(name) class Property(fd): # Property contains the relationship between a class instance and a value @@ -162,6 +190,7 @@ self.constraint = [] self.un_constraint = [] self.in_constraint = [] + self.bases = [] def finish(self, var, constraints): return var, constraints @@ -293,6 +322,7 @@ ClassDomain.__init__(self, name, values, bases) self.property = None + builtin_voc = { getUriref('owl', 'Thing') : Thing, getUriref('owl', 'Class') : ClassDomain, @@ -344,16 +374,16 @@ self.graph.load(f, format=format) def attach_fd(self): - while len(list(self.graph.triples((None,)*3))) != len(self.seen.keys()): - for (s, p, o) in (self.graph.triples((None,)*3)): - self.consider_triple((s, p, o)) - log("%s %s" %(s,p)) - #assert len([x for x in self.variables.values() if isinstance(x, fd)])==0 + #while len(list(self.graph.triples((None,)*3))) != len(self.seen.keys()): + for (s, p, o) in (self.graph.triples((None,)*3)): + self.consider_triple((s, p, o)) + log("%s %s" %(s,p)) log("=============================") assert len(list(self.graph.triples((None,)*3))) == len(self.seen.keys()) def finish(self): for key in list(self.variables.keys()): + log("FINISHING %s,%r" % (key,self.variables[key].bases)) self.variables[key].finish(self.variables, self.constraints) def consider_triple(self,(s, p, o)): @@ -379,7 +409,7 @@ sub = self.make_var(Thing, s) obj = self.make_var(Thing, o) propdom = self.variables[avar] - res = propdom.addValue(s, o) + res = propdom.addValue(Individual(sub,s),Individual(obj,o)) def resolve_item(self, item): item_as_subject = self.graph.triples((item, None, None)) @@ -436,6 +466,7 @@ return Solver().solve(rep, verbose) def consistency(self, verbose=0): + log("BEFORE FINISH %r" % self.variables) self.finish() log("DOMAINS %r"% self.variables) self.rep = Repository(self.variables.keys(), self.variables, self.constraints) @@ -478,21 +509,22 @@ if not var in builtin_voc : # var is not one of the builtin classes -> it is a Thing self.type(s, Thing_uri) - svar = self.make_var(self.variables[avar].__class__, s) - self.variables[avar].addValue(s) + svar = self.make_var(None,s) + self.constraints.append(MemberConstraint(Individual(svar,s), avar)) else: # var is a builtin class cls = builtin_voc[var] if cls == List: return - else: - svar = self.make_var(None, s) svar = self.make_var(cls, s) cls = self.variables[svar] if cls.constraint: self.constraints.extend(cls.constraint) if not isinstance(self.variables[avar], Property): - self.variables[avar].addValue(s) + if isinstance(self.variables[avar], Thing): + self.variables[avar].addValue(Individual(svar, s)) + else: + self.variables[avar].addValue(s) def first(self, s, var): pass @@ -501,7 +533,6 @@ pass def onProperty(self, s, var): -# self.resolve_predicate(var) log("%r onProperty %r "%(s, var)) svar =self.make_var(Restriction, s) avar =self.make_var(Property, var) @@ -545,23 +576,13 @@ self.resolve_item(var) avar = self.make_var(ClassDomain, var) svar = self.make_var(ClassDomain, s) - vals = self.variables[avar].getValues() - x_vals = self.variables[svar].getValues() - for v in x_vals: - if v in vals: - raise ConsistencyFailure("%s cannot have the value %s and be \ - complementOf %s" % (s, v, var)) - for v in self.variables[self.make_var(None,Thing_uri)].getValues(): - if not v in vals: - self.variables[svar].addValue(v) self.constraints.append(ComplementOfConstraint(svar, avar)) def oneOf(self, s, var): var = self.flatten_rdf_list(var) - #avar = self.make_var(List, var) svar = self.make_var(ClassDomain, s) res = self.variables[var].getValues() - self.variables[svar].setValues(res) + self.variables[svar].setValues([Individual(self.make_var(None,x),x) for x in res]) def unionOf(self,s, var): var = self.flatten_rdf_list(var) @@ -683,21 +704,37 @@ """ The hasValue restriction defines a class having as an extension all Individuals that have a property with the value of var. To make an assertion we need to know for which class the restriction applies""" - def Hasvalue(cls ,prop, val): - #The Domain of the cls should be Thing var = "%s_%s_hasvalue" %(cls, prop.name) dom = {var : fd(prop.getValues( ))} - cons = Expression([cls, var], "%s == %s[1] and %s == %s[0]" %(val, var, cls, var)) + cons = Expression([cls, var], " %s[1].cmp(%s) and %s.cmp( %s[0])" %( var, val, cls, var)) + log("HASVALUE %r %r"%(prop.getValues(),dom)) return dom, [cons] self.value_helper(s, var, Hasvalue) def allValuesFrom(self, s, var): - self.value_helper(s, var, AllValueConstraint) + def allvalue(cls ,prop, val): + # This creates a temporary domain to be able to help find the classes that only has values + # from val + var = "%s_%s_allvalue" %(cls, prop.name) + dom = {var : fd([(x,tuple(y)) for (x,y) in prop.getValuesPrKey( )])} + # The condition should return true if + cons = Expression([cls, var], "%s == %s[1] and %s == %s[0]" %(val, var, cls, var)) + return dom, [cons] + self.value_helper(s, var, allvalue) def someValuesFrom(self, s, var): - self.value_helper(s, var, SomeValueConstraint) + #Maybe just add hasvalue + def somevalue(cls ,prop, val): + # This creates a temporary domain to be able to help find the classes that only has values + # from val + var = "%s_%s_allvalue" %(cls, prop.name) + dom = {var : fd(prop.getValues( ))} + # The condition should return true if + cons = Expression([cls, var], " %s[1] in %s and %s == %s[0]" %(var, val, cls, var)) + return dom, [cons] + self.value_helper(s, var, somevalue) # ----------------- ---------------- Modified: pypy/dist/pypy/lib/pyontology/test/test_ontology.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/test/test_ontology.py (original) +++ pypy/dist/pypy/lib/pyontology/test/test_ontology.py Wed Jun 7 12:40:16 2006 @@ -597,25 +597,27 @@ b_cls = URIRef('b') O.type(a_cls, URIRef(namespaces['owl']+'#Class')) O.type(b_cls, URIRef(namespaces['owl']+'#Class')) - for i in ['i1', 'i2', 'i3', 'i4']: - O.type(URIRef(i), a_cls) + O.oneOf(a_cls, [URIRef('i1'), URIRef('i2'), URIRef('i3'), URIRef('i4')]) + for i in ['i1', 'i2', 'i3', 'i4']: O.type(URIRef(i), URIRef(namespaces['owl']+'#Thing')) O.type(URIRef('i5'), URIRef(namespaces['owl']+'#Thing')) O.complementOf(b_cls, a_cls) + O.consistency() assert O.variables[O.make_var(None, b_cls)].getValues() == ['i5'] -def test_complementof(): +def test_complementof_raise(): O = Ontology() a_cls = URIRef('a') b_cls = URIRef('b') O.type(a_cls, URIRef(namespaces['owl']+'#Class')) O.type(b_cls, URIRef(namespaces['owl']+'#Class')) - for i in ['i1', 'i2', 'i3', 'i4']: - O.type(URIRef(i), a_cls) + O.oneOf(a_cls, [URIRef('i1'), URIRef('i2'), URIRef('i3'), URIRef('i4')]) + for i in ['i1', 'i2', 'i3', 'i4']: O.type(URIRef(i), URIRef(namespaces['owl']+'#Thing')) O.type(URIRef('i5'), URIRef(namespaces['owl']+'#Thing')) O.type(URIRef('i4'), b_cls) - raises(ConsistencyFailure, O.complementOf, b_cls, a_cls) + O.complementOf(b_cls, a_cls) + raises(ConsistencyFailure, O.consistency) def test_class_promotion(): O = Ontology() @@ -649,3 +651,11 @@ O.type(a_cls, URIRef(namespaces['rdf']+'#Property')) assert isinstance(O.variables['a_'], ObjectProperty) + +def test_individual(): + # test comparison (unknown, equal, different) + O = Ontology() + first = URIRef('first') + second = URIRef('second') + O.type(first, URIRef(namespaces['owl']+'#Thing')) + assert isinstance((O.variables['owl_Thing'].getValues()[0]), Individual) From ac at codespeak.net Wed Jun 7 12:44:01 2006 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 7 Jun 2006 12:44:01 +0200 (CEST) Subject: [pypy-svn] r28430 - pypy/extradoc/sprintinfo/leysin-summer-2006 Message-ID: <20060607104401.7D87610076@code0.codespeak.net> Author: ac Date: Wed Jun 7 12:44:00 2006 New Revision: 28430 Modified: pypy/extradoc/sprintinfo/leysin-summer-2006/people.txt Log: Fix a cut-n-paste error. Modified: pypy/extradoc/sprintinfo/leysin-summer-2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/leysin-summer-2006/people.txt (original) +++ pypy/extradoc/sprintinfo/leysin-summer-2006/people.txt Wed Jun 7 12:44:00 2006 @@ -1,5 +1,5 @@ -People coming to the Leysin sprint Winter 2006 +People coming to the Leysin sprint Summer 2006 ================================================== People who have a ``?`` in their arrive/depart or accomodation From ericvrp at codespeak.net Wed Jun 7 12:46:45 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 7 Jun 2006 12:46:45 +0200 (CEST) Subject: [pypy-svn] r28431 - pypy/extradoc/sprintinfo/post-ep2006 Message-ID: <20060607104645.4DDC010076@code0.codespeak.net> Author: ericvrp Date: Wed Jun 7 12:46:44 2006 New Revision: 28431 Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt Log: I will come to the post europython 2006 Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/post-ep2006/people.txt (original) +++ pypy/extradoc/sprintinfo/post-ep2006/people.txt Wed Jun 7 12:46:44 2006 @@ -19,6 +19,7 @@ Christian Tismer ? ? Antonio Cuni ? ? Anders Lehmann ? ? +Eric van Riet Paap ? ? ==================== ============== ===================== People on the following list were present at previous sprints: From mwh at codespeak.net Wed Jun 7 12:48:59 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 7 Jun 2006 12:48:59 +0200 (CEST) Subject: [pypy-svn] r28432 - pypy/extradoc/sprintinfo/ddorf2006 Message-ID: <20060607104859.92F4A10069@code0.codespeak.net> Author: mwh Date: Wed Jun 7 12:48:58 2006 New Revision: 28432 Modified: pypy/extradoc/sprintinfo/ddorf2006/report1.txt Log: add a link to the photo. Modified: pypy/extradoc/sprintinfo/ddorf2006/report1.txt ============================================================================== --- pypy/extradoc/sprintinfo/ddorf2006/report1.txt (original) +++ pypy/extradoc/sprintinfo/ddorf2006/report1.txt Wed Jun 7 12:48:58 2006 @@ -11,7 +11,7 @@ An early task was finishing off the mostly complete weakref support. After drawing an extremely confusing diagram: - http://XXX + http://codespeak.net/~mwh/blackboard.jpg Carl and Arre realized that there were a few strange cases that our model cannot support (in the case of a object and a From mwh at codespeak.net Wed Jun 7 13:01:55 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 7 Jun 2006 13:01:55 +0200 (CEST) Subject: [pypy-svn] r28434 - pypy/extradoc/sprintinfo/post-ep2006 Message-ID: <20060607110155.1197A10036@code0.codespeak.net> Author: mwh Date: Wed Jun 7 13:01:54 2006 New Revision: 28434 Modified: pypy/extradoc/sprintinfo/post-ep2006/announce.txt Log: reword the summer of pypy section. should we be more precise about the sprint location? Modified: pypy/extradoc/sprintinfo/post-ep2006/announce.txt ============================================================================== --- pypy/extradoc/sprintinfo/post-ep2006/announce.txt (original) +++ pypy/extradoc/sprintinfo/post-ep2006/announce.txt Wed Jun 7 13:01:54 2006 @@ -40,20 +40,22 @@ Special note to Students! ---------------------------- -We have already four people working on a "Summer of Code" proposal, -three of which we could get through the Google/PSF process. +As you might know, there are three students in Google's Summer of Code +program who are working on projects related to PyPy. -However, we are working to enable 4-6 more students to get -travel + accomodation funding and provide mentoring from our side. -This we call "Summer of PyPy". The idea is that you can suggest -a PyPy related proposal to us ("pypy-tb at codespeak.net") and we will -then get back to you. If we agree to it, then you can get expenses -funding. +In addition we are planning our own "Summer of PyPy": we can cover the +expenses of attending some of our sprints and provide mentorship. -As we still need to figure out budget/money issues, for now we -can only promise for now that we can fund this Post-EP2006 sprint -for such students. But don't hesitate to come to our irc channel, -ask around and produce such proposals! +In this vein, if you have an interesting idea for a project relating +to PyPy you should send us ("pypy-tb at codespeak.net") a proposal. We +will consider it get back to you on whether we can fund your travel +and accomodation. We expect to able to fund between 4 and 6 students +in this way. + +As we still need to figure out budget/money issues, for now we can +only promise for now that we can fund this Post-EP2006 sprint for such +students. But don't hesitate to come to our irc channel, ask around +and produce proposals! .. _`pypy-sprint mailing list`: http://codespeak.net/mailman/listinfo/pypy-sprint .. _`people`: people.html From hpk at codespeak.net Wed Jun 7 13:14:05 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 7 Jun 2006 13:14:05 +0200 (CEST) Subject: [pypy-svn] r28435 - pypy/extradoc/sprintinfo/post-ep2006 Message-ID: <20060607111405.D8AED10070@code0.codespeak.net> Author: hpk Date: Wed Jun 7 13:14:04 2006 New Revision: 28435 Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt Log: added some infos from people which are sitting next to me Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/post-ep2006/people.txt (original) +++ pypy/extradoc/sprintinfo/post-ep2006/people.txt Wed Jun 7 13:14:04 2006 @@ -16,8 +16,8 @@ Maciej Fijalkowski ? ? Anders Chrigstroem 2/7 - 10/7 NH Geneva Airport Samuele Pedroni 2/7 - 10/7 NH Geneva Airport -Christian Tismer ? ? -Antonio Cuni ? ? +Christian Tismer 6-9th ? +Antonio Cuni 6-9th CERN Hostel Anders Lehmann ? ? Eric van Riet Paap ? ? ==================== ============== ===================== From antocuni at codespeak.net Wed Jun 7 13:18:46 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 13:18:46 +0200 (CEST) Subject: [pypy-svn] r28436 - in pypy/dist/pypy/translator/cli: . test Message-ID: <20060607111846.16A5410060@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 13:18:44 2006 New Revision: 28436 Modified: pypy/dist/pypy/translator/cli/cts.py pypy/dist/pypy/translator/cli/database.py pypy/dist/pypy/translator/cli/gencli.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/test/test_oo.py Log: (antocuni, arigo) Added support for indirect_call. Modified: pypy/dist/pypy/translator/cli/cts.py ============================================================================== --- pypy/dist/pypy/translator/cli/cts.py (original) +++ pypy/dist/pypy/translator/cli/cts.py Wed Jun 7 13:18:44 2006 @@ -76,7 +76,8 @@ name = self.db.pending_record(t) return self.__class(name, include_class) elif isinstance(t, ootype.StaticMethod): - return 'void' # TODO: is it correct to ignore StaticMethod? + #return 'void' # TODO: is it correct to ignore StaticMethod? + return self.db.record_delegate_type(t) elif isinstance(t, ootype.List): item_type = self.lltype_to_cts(t._ITEMTYPE) if item_type == 'void': # special case: CLI doesn't allow List of void; use int instead @@ -115,21 +116,25 @@ return '%s %s(%s)' % (ret_type, func_name, arg_list) - def method_signature(self, obj, name): + def method_signature(self, TYPE, name): # TODO: use callvirt only when strictly necessary - if isinstance(obj, ootype.Instance): - owner, meth = obj._lookup(name) - class_name = obj._name + if isinstance(TYPE, ootype.Instance): + owner, meth = TYPE._lookup(name) + class_name = TYPE._name full_name = 'class %s::%s' % (class_name, name) return self.graph_to_signature(meth.graph, True, full_name), True - elif isinstance(obj, ootype.BuiltinType): - meth = oopspec.get_method(obj, name) - class_name = self.lltype_to_cts(obj) - ret_type = self.lltype_to_cts(meth.RESULT) - arg_types = [self.lltype_to_cts(arg) for arg in meth.ARGS] + elif isinstance(TYPE, (ootype.BuiltinType, ootype.StaticMethod)): + if isinstance(TYPE, ootype.StaticMethod): + METH = TYPE + else: + METH = oopspec.get_method(TYPE, name) + class_name = self.lltype_to_cts(TYPE) + ret_type = self.lltype_to_cts(METH.RESULT) + arg_types = [self.lltype_to_cts(arg) for arg in METH.ARGS] arg_list = ', '.join(arg_types) return '%s %s::%s(%s)' % (ret_type, class_name, name, arg_list), False + else: assert False Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Wed Jun 7 13:18:44 2006 @@ -21,10 +21,12 @@ self._rendered_nodes = set() self.function_class = function_class self.type_system_class = type_system_class + self.cts = type_system_class(self) self.classes = {} # classdef --> class_name self.functions = {} # graph --> function_name self.methods = {} # graph --> method_name self.consts = {} # value --> const_name + self.delegates = {} # StaticMethod --> type_name self.const_names = set() def pending_function(self, graph): @@ -50,6 +52,7 @@ self.classes[classdef] = name def graph_name(self, graph): + # XXX: graph name are not guaranteed to be unique return self.functions.get(graph, None) def class_name(self, classdef): @@ -68,6 +71,38 @@ return '%s.%s::%s' % (CONST_NAMESPACE, CONST_CLASS, name) + def record_delegate_type(self, TYPE): + try: + return self.delegates[TYPE] + except KeyError: + name = 'StaticMethod__%d' % len(self.delegates) + # record we know about result and argument types + self.cts.lltype_to_cts(TYPE.RESULT) + for ARG in TYPE.ARGS: + self.cts.lltype_to_cts(ARG) + self.delegates[TYPE] = name + return name + + def gen_delegate_types(self, ilasm): + for TYPE, name in self.delegates.iteritems(): + ilasm.begin_class(name, '[mscorlib]System.MulticastDelegate') + 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] + ilasm.begin_function('Invoke', arglist, resulttype, False, + 'virtual', 'hidebysig', 'instance', 'default', + runtime=True) + ilasm.end_function() + ilasm.end_class() + + def gen_constants(self, ilasm): ilasm.begin_namespace(CONST_NAMESPACE) ilasm.begin_class(CONST_CLASS) @@ -132,6 +167,8 @@ return ListConst(db, const) elif isinstance(const, ootype._string): return StringConst(db, const) + elif isinstance(const, ootype._static_meth): + return StaticMethodConst(db, const) else: assert False, 'Unknown constant: %s' % const make = staticmethod(make) @@ -214,6 +251,33 @@ AbstractConst.load(self.db, FIELD_TYPE, value, ilasm) ilasm.set_field((f_type, class_name, f_name)) +class StaticMethodConst(AbstractConst): + def __init__(self, db, sm): + self.db = db + self.cts = CTS(db) + self.sm = sm + + def __hash__(self): + return hash(self.sm) + + def __eq__(self, other): + return self.sm == other.sm + + def get_name(self): + return 'Delegate' + + def get_type(self, include_class=True): + return self.cts.lltype_to_cts(self.sm._TYPE, include_class) + + def init(self, ilasm): + self.db.pending_function(self.sm.graph) + signature = self.cts.graph_to_signature(self.sm.graph) + delegate_type = self.db.record_delegate_type(self.sm._TYPE) + ilasm.opcode('ldnull') + ilasm.opcode('ldftn', signature) + ilasm.new('instance void class %s::.ctor(object, native int)' % delegate_type) + + class ListConst(AbstractConst): def __init__(self, db, list_): self.db = db Modified: pypy/dist/pypy/translator/cli/gencli.py ============================================================================== --- pypy/dist/pypy/translator/cli/gencli.py (original) +++ pypy/dist/pypy/translator/cli/gencli.py Wed Jun 7 13:18:44 2006 @@ -57,6 +57,7 @@ self.gen_entrypoint() self.gen_pendings() self.db.gen_constants(self.ilasm) + self.db.gen_delegate_types(self.ilasm) self.gen_pendings() out.close() return self.tmpfile.strpath Modified: pypy/dist/pypy/translator/cli/ilgenerator.py ============================================================================== --- pypy/dist/pypy/translator/cli/ilgenerator.py (original) +++ pypy/dist/pypy/translator/cli/ilgenerator.py Wed Jun 7 13:18:44 2006 @@ -71,13 +71,18 @@ self.code.writeline('.field public %s %s %s' % (s, type_, name)) - def begin_function(self, name, arglist, returntype, is_entrypoint = False, *args): + def begin_function(self, name, arglist, returntype, is_entrypoint = False, *args, **kwds): # TODO: .maxstack + runtime = kwds.get('runtime', False) + if runtime: + method_type = 'runtime' + else: + method_type = 'il' attributes = ' '.join(args) arglist = ', '.join(['%s %s' % arg for arg in arglist]) - self.code.writeline('.method public %s %s %s(%s) il managed' %\ - (attributes, returntype, name, arglist)) + self.code.writeline('.method public %s %s %s(%s) %s managed' %\ + (attributes, returntype, name, arglist, method_type)) self.code.openblock() if is_entrypoint: Modified: pypy/dist/pypy/translator/cli/metavm.py ============================================================================== --- pypy/dist/pypy/translator/cli/metavm.py (original) +++ pypy/dist/pypy/translator/cli/metavm.py Wed Jun 7 13:18:44 2006 @@ -29,6 +29,10 @@ self._render_method(generator, method.value, op.args[1:]) +class _IndirectCall(_Call): + def render(self, generator, op): + # discard the last argument because it's used only for analysis + self._render_method(generator, 'Invoke', op.args[:-1]) class _RuntimeNew(MicroInstruction): def render(self, generator, op): @@ -38,4 +42,5 @@ Call = _Call() CallMethod = _CallMethod() +IndirectCall = _IndirectCall() RuntimeNew = _RuntimeNew() Modified: pypy/dist/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/cli/opcodes.py (original) +++ pypy/dist/pypy/translator/cli/opcodes.py Wed Jun 7 13:18:44 2006 @@ -1,4 +1,4 @@ -from pypy.translator.cli.metavm import Call, CallMethod, RuntimeNew +from pypy.translator.cli.metavm import Call, CallMethod, RuntimeNew, IndirectCall from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\ SetField, GetField, New @@ -51,7 +51,7 @@ 'same_as': DoNothing, # TODO: does same_as really do nothing else than renaming? 'direct_call': [Call], - 'indirect_call': None, # when is it generated? + 'indirect_call': [IndirectCall], # __________ numeric operations __________ Modified: pypy/dist/pypy/translator/cli/test/test_oo.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_oo.py (original) +++ pypy/dist/pypy/translator/cli/test/test_oo.py Wed Jun 7 13:18:44 2006 @@ -1,4 +1,5 @@ from pypy.translator.cli.test.runtest import check +from pypy.translator.cli.test.runtest import CliTest def test_oo(): for name, func in globals().iteritems(): @@ -7,6 +8,20 @@ yield check, func, [int, int], (42, 13) +class TestOO(CliTest): + def test_indirect_call(self): + def f(): + return 1 + def g(): + return 2 + def fn(flag): + if flag: + x = f + else: + x = g + return x() + assert self.interpret(fn, [True]) == 1 + assert self.interpret(fn, [False]) == 2 class MyClass: INCREMENT = 1 From fijal at codespeak.net Wed Jun 7 13:37:42 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 7 Jun 2006 13:37:42 +0200 (CEST) Subject: [pypy-svn] r28437 - in pypy/dist/pypy/translator/js2: . modules test Message-ID: <20060607113742.42EA710069@code0.codespeak.net> Author: fijal Date: Wed Jun 7 13:37:41 2006 New Revision: 28437 Modified: pypy/dist/pypy/translator/js2/metavm.py pypy/dist/pypy/translator/js2/modules/dom.py pypy/dist/pypy/translator/js2/test/test_dom.py Log: Improved dom tests. Really strange hacks around setTimeout Modified: pypy/dist/pypy/translator/js2/metavm.py ============================================================================== --- pypy/dist/pypy/translator/js2/metavm.py (original) +++ pypy/dist/pypy/translator/js2/metavm.py Wed Jun 7 13:37:41 2006 @@ -158,12 +158,15 @@ # FIXME: Dirty hack for javascript callback stuff def render(self, generator, op): val = op.args[1].value - if isinstance(val, ootype.StaticMethod): - real_name = val._name - generator.db.pending_function(val.graph) - else: - real_name = val.concretize().value._name - generator.db.pending_function(val.concretize().value.graph) + assert(isinstance(val, ootype._static_meth)) + #if isinstance(val, ootype.StaticMethod): + real_name = val._name + generator.db.pending_function(val.graph) + #generator.db.pending_function(val.graph) + #else: + # concrete = val.concretize() + # real_name = concrete.value._name + # generator.db.pending_function(concrete.value.graph) generator.load_str("'%s()'" % real_name) generator.load(op.args[2]) generator.call_external('setTimeout',[0]*2) Modified: pypy/dist/pypy/translator/js2/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js2/modules/dom.py (original) +++ pypy/dist/pypy/translator/js2/modules/dom.py Wed Jun 7 13:37:41 2006 @@ -8,6 +8,8 @@ import time +from pypy.translator.stackless.test.test_transform import one + class Style(object): _rpython_hints = {'_suggested_external' : True} @@ -22,9 +24,14 @@ def __init__(self): self.innerHTML = "" self.style = None + self.subnodes = {} def getElementById(self, id): - return Node() + try: + return self.subnodes[id] + except KeyError: + self.subnodes[id] = Node() + return self.subnodes[id] def setAttribute(self, name, style_str): if name == 'style': @@ -37,8 +44,15 @@ document = Node() +def some_fun(): + pass + def setTimeout(func, delay): # scheduler call, but we don't want to mess with threads right now - func() + if one(): + setTimeout(some_fun, delay) + else: + func() + #pass setTimeout.suggested_primitive = True Modified: pypy/dist/pypy/translator/js2/test/test_dom.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/test_dom.py (original) +++ pypy/dist/pypy/translator/js2/test/test_dom.py Wed Jun 7 13:37:41 2006 @@ -23,10 +23,11 @@ assert fn() == '[object HTMLHeadingElement]' class Mover(object): - def __init__(self): + def __init__(self, elem): self.x = 0 self.y = 0 self.dir = 1 + self.elem = elem#get_document().getElementById(elem) def move_it_by(self, obj, dx, dy): if self.dir < 0: @@ -42,19 +43,24 @@ obj.style.top = str(int(obj.style.top) + dy) + "px" def move_it(self): - self.move_it_by(get_document().getElementById("anim_img"), 3, 3) + #self.move_it_by(self.elem, 3, 3) + self.move_it_by(get_document().getElementById(self.elem), 3, 3) -movers = [Mover(), Mover()] +movers = [Mover("anim_img"), Mover("anim_img2")] +movers[1].x = 20 def move_it(): movers[0].move_it() - setTimeout(move_it, 10) + movers[1].move_it() -def test_anim_f(): +def test_anim_f(): def anim_fun(): obj = get_document().getElementById("anim_img") obj.setAttribute('style', 'position: absolute; top: 0; left: 0;') - setTimeout(move_it, 10) + obj2 = get_document().getElementById("anim_img2") + obj2.setAttribute('style', 'position: absolute; top: 50; left: 0;') + move_it() + return get_document().getElementById("anim_img").style.left - fn = compile_function(anim_fun, [], html = 'html/anim.html', is_interactive = True) - assert fn() == 'ok' + fn = compile_function(anim_fun, [], html = 'html/anim.html') + assert fn() == '3px' From antocuni at codespeak.net Wed Jun 7 15:08:24 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 15:08:24 +0200 (CEST) Subject: [pypy-svn] r28447 - in pypy/dist/pypy/translator/cli: . test Message-ID: <20060607130824.7A11310074@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 15:08:23 2006 New Revision: 28447 Modified: pypy/dist/pypy/translator/cli/conftest.py pypy/dist/pypy/translator/cli/test/runtest.py Log: Added an option to let .NET exception flowing out of the entry point. Modified: pypy/dist/pypy/translator/cli/conftest.py ============================================================================== --- pypy/dist/pypy/translator/cli/conftest.py (original) +++ pypy/dist/pypy/translator/cli/conftest.py Wed Jun 7 15:08:23 2006 @@ -15,6 +15,9 @@ help="print the generated IL code to stdout, too"), Option('--nostop', action="store_true", dest="nostop", default=False, - help="don't stop on warning. The generated IL code could not compile") + help="don't stop on warning. The generated IL code could not compile"), + + Option('--nowrap', action="store_true", dest="nowrap", default=False, + help="don't wrap exceptions but let them to flow out of the entry point") ) Modified: pypy/dist/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/runtest.py (original) +++ pypy/dist/pypy/translator/cli/test/runtest.py Wed Jun 7 15:08:23 2006 @@ -79,9 +79,12 @@ for exc in ('[mscorlib]System.Exception', 'exceptions.Exception'): ilasm.begin_catch(exc) - ilasm.call('string class [pypylib]pypy.test.Result::FormatException(object)') - ilasm.call('void class [mscorlib]System.Console::WriteLine(string)') - ilasm.leave('return') + if getoption('nowrap'): + ilasm.opcode('throw') + else: + ilasm.call('string class [pypylib]pypy.test.Result::FormatException(object)') + ilasm.call('void class [mscorlib]System.Console::WriteLine(string)') + ilasm.leave('return') ilasm.end_catch() # write the result to stdout @@ -210,12 +213,17 @@ def __init__(self, class_name): self.class_name = class_name + def __repr__(self): + return 'ExceptionWrapper(%s)' % repr(self.class_name) class CliTest(BaseRtypingTest, OORtypeMixin): def interpret(self, fn, args): ann = [lltype_to_annotation(typeOf(x)) for x in args] f = compile_function(fn, ann) - return f(*args) + res = f(*args) + if isinstance(res, ExceptionWrapper): + raise ExceptionWrapper + return res def interpret_raises(self, exception, fn, args): import exceptions # needed by eval From antocuni at codespeak.net Wed Jun 7 15:11:21 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 15:11:21 +0200 (CEST) Subject: [pypy-svn] r28448 - in pypy/dist/pypy/translator/cli: . test Message-ID: <20060607131121.6CF1E10076@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 15:11:20 2006 New Revision: 28448 Modified: pypy/dist/pypy/translator/cli/database.py pypy/dist/pypy/translator/cli/test/test_oo.py Log: - Added support for constants of type ootype.Class. - Completed support for constants of type ootype.Instance. - As a bonus, a failing test now passes. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Wed Jun 7 15:11:20 2006 @@ -169,6 +169,8 @@ return StringConst(db, const) elif isinstance(const, ootype._static_meth): return StaticMethodConst(db, const) + elif isinstance(const, ootype._class): + return ClassConst(db, const) else: assert False, 'Unknown constant: %s' % const make = staticmethod(make) @@ -277,6 +279,29 @@ ilasm.opcode('ldftn', signature) ilasm.new('instance void class %s::.ctor(object, native int)' % delegate_type) +class ClassConst(AbstractConst): + def __init__(self, db, class_): + self.db = db + self.cts = CTS(db) + self.class_ = class_ + + def __hash__(self): + return hash(self.class_) + + def __eq__(self, other): + return self.class_ == other.class_ + + def get_name(self): + return 'Class' + + def get_type(self, include_class=True): + return self.cts.lltype_to_cts(self.class_._TYPE, include_class) + + def init(self, ilasm): + self.cts.lltype_to_cts(self.class_._INSTANCE) # force scheduling class generation + classname = self.class_._INSTANCE._name + ilasm.opcode('ldtoken', classname) + ilasm.call('class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)') class ListConst(AbstractConst): def __init__(self, db, list_): @@ -323,6 +348,7 @@ class InstanceConst(AbstractConst): def __init__(self, db, obj, static_type): + self.db = db self.cts = CTS(db) self.obj = obj if static_type is None: @@ -347,16 +373,10 @@ classdef = self.obj._TYPE ilasm.new('instance void class %s::.ctor()' % classdef._name) while classdef is not None: - for name, (type_, default) in classdef._fields.iteritems(): - if isinstance(type_, ootype.StaticMethod): - continue - elif type_ is ootype.Class: - value = getattr(self.obj, name) - self.cts.lltype_to_cts(value._INSTANCE) # force scheduling class generation - classname = value._INSTANCE._name - ilasm.opcode('dup') - ilasm.opcode('ldtoken', classname) - ilasm.call('class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)') - ilasm.opcode('stfld class [mscorlib]System.Type %s::%s' % (classdef._name, name)) + for name, (TYPE, default) in classdef._fields.iteritems(): + value = getattr(self.obj, name) + type_ = self.cts.lltype_to_cts(TYPE) + ilasm.opcode('dup') + AbstractConst.load(self.db, TYPE, value, ilasm) + ilasm.opcode('stfld %s %s::%s' % (type_, classdef._name, name)) classdef = classdef._superclass - Modified: pypy/dist/pypy/translator/cli/test/test_oo.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_oo.py (original) +++ pypy/dist/pypy/translator/cli/test/test_oo.py Wed Jun 7 15:11:20 2006 @@ -8,21 +8,6 @@ yield check, func, [int, int], (42, 13) -class TestOO(CliTest): - def test_indirect_call(self): - def f(): - return 1 - def g(): - return 2 - def fn(flag): - if flag: - x = f - else: - x = g - return x() - assert self.interpret(fn, [True]) == 1 - assert self.interpret(fn, [False]) == 2 - class MyClass: INCREMENT = 1 @@ -52,6 +37,35 @@ def compute(self): return self.x - self.y + +class TestOO(CliTest): + def test_indirect_call(self): + def f(): + return 1 + def g(): + return 2 + def fn(flag): + if flag: + x = f + else: + x = g + return x() + assert self.interpret(fn, [True]) == 1 + assert self.interpret(fn, [False]) == 2 + + def test_indirect_call_arguments(self): + def f(x): + return x+1 + def g(x): + return x+2 + def fn(flag, n): + if flag: + x = f + else: + x = g + return x(n) + assert self.interpret(fn, [True, 42]) == 43 + # helper functions def call_method(obj): return obj.compute() From antocuni at codespeak.net Wed Jun 7 16:05:12 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 16:05:12 +0200 (CEST) Subject: [pypy-svn] r28454 - pypy/dist/pypy/translator/cli/test Message-ID: <20060607140512.467C910064@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 16:05:11 2006 New Revision: 28454 Modified: pypy/dist/pypy/translator/cli/test/runtest.py Log: bugfix Modified: pypy/dist/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/runtest.py (original) +++ pypy/dist/pypy/translator/cli/test/runtest.py Wed Jun 7 16:05:11 2006 @@ -222,7 +222,7 @@ f = compile_function(fn, ann) res = f(*args) if isinstance(res, ExceptionWrapper): - raise ExceptionWrapper + raise res return res def interpret_raises(self, exception, fn, args): From antocuni at codespeak.net Wed Jun 7 16:10:44 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 16:10:44 +0200 (CEST) Subject: [pypy-svn] r28455 - in pypy/dist/pypy/translator/cli: . src Message-ID: <20060607141044.73E8510079@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 16:10:43 2006 New Revision: 28455 Modified: pypy/dist/pypy/translator/cli/cts.py pypy/dist/pypy/translator/cli/database.py pypy/dist/pypy/translator/cli/oopspec.py pypy/dist/pypy/translator/cli/src/pypylib.cs Log: (antocuni, arigo) Handle List of Void correctly. The problem is that .NET don't allow us to use the void type as a real type, so we have to workaround this. The solution for List(Void) is to have a special-cased class whose methods don't take care of parameters of ITEMTYPE type, then we special-cased some place for taking care of this. Probably in the future we will need a similar solution for Dict with Void keys or values, and so on. Modified: pypy/dist/pypy/translator/cli/cts.py ============================================================================== --- pypy/dist/pypy/translator/cli/cts.py (original) +++ pypy/dist/pypy/translator/cli/cts.py Wed Jun 7 16:10:43 2006 @@ -15,6 +15,7 @@ py.log.setconsumer("cli", ansi_log) PYPY_LIST = '[pypylib]pypy.runtime.List`1<%s>' +PYPY_LIST_OF_VOID = '[pypylib]pypy.runtime.ListOfVoid' PYPY_DICT = '[pypylib]pypy.runtime.Dict`2<%s, %s>' PYPY_DICT_ITEMS_ITERATOR = '[pypylib]pypy.runtime.DictItemsIterator`2<%s, %s>' @@ -76,12 +77,11 @@ name = self.db.pending_record(t) return self.__class(name, include_class) elif isinstance(t, ootype.StaticMethod): - #return 'void' # TODO: is it correct to ignore StaticMethod? return self.db.record_delegate_type(t) elif isinstance(t, ootype.List): item_type = self.lltype_to_cts(t._ITEMTYPE) - if item_type == 'void': # special case: CLI doesn't allow List of void; use int instead - item_type = 'int32' + if item_type == 'void': # special case: List of Void + return PYPY_LIST_OF_VOID return self.__class(PYPY_LIST % item_type, include_class) elif isinstance(t, ootype.Dict): key_type = self.lltype_to_cts(t._KEYTYPE) @@ -131,7 +131,7 @@ METH = oopspec.get_method(TYPE, name) class_name = self.lltype_to_cts(TYPE) ret_type = self.lltype_to_cts(METH.RESULT) - arg_types = [self.lltype_to_cts(arg) for arg in METH.ARGS] + arg_types = [self.lltype_to_cts(arg) for arg in METH.ARGS if arg is not ootype.Void] arg_list = ', '.join(arg_types) return '%s %s::%s(%s)' % (ret_type, class_name, name, arg_list), False Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Wed Jun 7 16:10:43 2006 @@ -1,4 +1,4 @@ -from pypy.translator.cli.cts import CTS +from pypy.translator.cli.cts import CTS, PYPY_LIST_OF_VOID from pypy.translator.cli.function import Function from pypy.translator.cli.class_ import Class from pypy.translator.cli.record import Record @@ -336,7 +336,7 @@ if ITEMTYPE is ootype.Void: ilasm.opcode('dup') AbstractConst.load(self.db, ootype.Signed, len(self.list._list), ilasm) - meth = 'void class [pypylib]pypy.runtime.List`1::_ll_resize(int32)' + meth = 'void class %s::_ll_resize(int32)' % PYPY_LIST_OF_VOID ilasm.call_method(meth, False) return Modified: pypy/dist/pypy/translator/cli/oopspec.py ============================================================================== --- pypy/dist/pypy/translator/cli/oopspec.py (original) +++ pypy/dist/pypy/translator/cli/oopspec.py Wed Jun 7 16:10:43 2006 @@ -1,4 +1,4 @@ -from pypy.rpython.ootypesystem.ootype import List, Meth, Void +from pypy.rpython.ootypesystem import ootype def get_method_name(graph, op): try: @@ -29,19 +29,24 @@ else: return None # explicit is better than implicit :-) -def get_method(obj, name): +def get_method(TYPE, name): try: - return obj._GENERIC_METHODS[name] + # special case: when having List of Void, look at the concrete + # methods, not the generic ones + if isinstance(TYPE, ootype.List) and TYPE._ITEMTYPE is ootype.Void: + return TYPE._METHODS[name] + else: + return TYPE._GENERIC_METHODS[name] except KeyError: - t = type(obj) + t = type(TYPE) return BUILTIN_METHODS[t][name] BUILTIN_TYPES = { - 'list': List + 'list': ootype.List } BUILTIN_METHODS = { - List : { - 'Add': Meth([List.ITEMTYPE_T], Void) + ootype.List : { + 'Add': ootype.Meth([ootype.List.ITEMTYPE_T], ootype.Void) } } Modified: pypy/dist/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/dist/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/dist/pypy/translator/cli/src/pypylib.cs Wed Jun 7 16:10:43 2006 @@ -94,28 +94,28 @@ this.RemoveRange(length, diff); } } + } - /* - public void append(T item) - { - this.Add(item); - } - - public void extend(List other) - { - this.AddRange(other); - } - - public void remove_range(int start, int count) - { - this.RemoveRange(start, count); - } + public class ListOfVoid + { + int Count = 0; - public int index(T item) + public override string ToString() { - return this.IndexOf(item); - } - */ + // TODO: use StringBuilder instead + string res = "["; + for(int i=0; i: System.Collections.Generic.Dictionary From antocuni at codespeak.net Wed Jun 7 16:17:59 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 16:17:59 +0200 (CEST) Subject: [pypy-svn] r28456 - pypy/dist/pypy/translator/cli/test Message-ID: <20060607141759.B55AF1007B@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 16:17:59 2006 New Revision: 28456 Modified: pypy/dist/pypy/translator/cli/test/runtest.py Log: bugfix for the previous bugfix. Modified: pypy/dist/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/runtest.py (original) +++ pypy/dist/pypy/translator/cli/test/runtest.py Wed Jun 7 16:17:59 2006 @@ -227,9 +227,12 @@ def interpret_raises(self, exception, fn, args): import exceptions # needed by eval - res = self.interpret(fn, args) - assert isinstance(res, ExceptionWrapper) - assert issubclass(eval(res.class_name), exception) + try: + self.interpret(fn, args) + except ExceptionWrapper, ex: + assert issubclass(eval(ex.class_name), exception) + else: + assert False, 'function did raise no exception at all' def ll_to_string(self, s): return s From antocuni at codespeak.net Wed Jun 7 16:25:14 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 16:25:14 +0200 (CEST) Subject: [pypy-svn] r28457 - pypy/dist/pypy/translator/cli Message-ID: <20060607142514.2794F1007B@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 16:25:13 2006 New Revision: 28457 Modified: pypy/dist/pypy/translator/cli/database.py Log: Added support for null instances as field of constant instances. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Wed Jun 7 16:25:13 2006 @@ -370,6 +370,10 @@ return self.cts.lltype_to_cts(self.static_type) def init(self, ilasm): + if not self.obj: + ilasm.opcode('ldnull') + return + classdef = self.obj._TYPE ilasm.new('instance void class %s::.ctor()' % classdef._name) while classdef is not None: From rhymes at codespeak.net Wed Jun 7 16:42:36 2006 From: rhymes at codespeak.net (rhymes at codespeak.net) Date: Wed, 7 Jun 2006 16:42:36 +0200 (CEST) Subject: [pypy-svn] r28458 - pypy/extradoc/sprintinfo/post-ep2006 Message-ID: <20060607144236.28E9B10070@code0.codespeak.net> Author: rhymes Date: Wed Jun 7 16:42:34 2006 New Revision: 28458 Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt Log: adding myself Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/post-ep2006/people.txt (original) +++ pypy/extradoc/sprintinfo/post-ep2006/people.txt Wed Jun 7 16:42:34 2006 @@ -20,6 +20,7 @@ Antonio Cuni 6-9th CERN Hostel Anders Lehmann ? ? Eric van Riet Paap ? ? +Lawrence Oluyede 6-9th CERN Hostel ==================== ============== ===================== People on the following list were present at previous sprints: From tismer at codespeak.net Wed Jun 7 17:00:18 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 7 Jun 2006 17:00:18 +0200 (CEST) Subject: [pypy-svn] r28459 - in pypy/dist/pypy: interpreter module/stackless module/stackless/test Message-ID: <20060607150018.98B8510076@code0.codespeak.net> Author: tismer Date: Wed Jun 7 17:00:17 2006 New Revision: 28459 Modified: pypy/dist/pypy/interpreter/executioncontext.py pypy/dist/pypy/module/stackless/coroutine.py pypy/dist/pypy/module/stackless/test/test_coroutine.py Log: initial coroutine pickling. We just cannot test the real functionality without compiling the resume point stuff into a binary ;-) Modified: pypy/dist/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/dist/pypy/interpreter/executioncontext.py (original) +++ pypy/dist/pypy/interpreter/executioncontext.py Wed Jun 7 17:00:17 2006 @@ -58,7 +58,25 @@ current.is_tracing = self.is_tracing # coroutine: I think this is all, folks! - + + # well, not quite: we need an interface for pickling + def subcontext_getstate(coobj): + # we just save the framestack + space = coobj.space + items = [space.wrap(item) for item in coobj.framestack.items] + return space.newtuple(items) + subcontext_getstate = staticmethod(subcontext_getstate) + + def subcontext_setstate(coobj, w_state): + from pypy.interpreter.pyframe import PyFrame + space = coobj.space + items = [space.interp_w(PyFrame, item) + for item in space.unpackiterable(w_state)] + coobj.framestack.items = items + subcontext_setstate = staticmethod(subcontext_setstate) + + # coroutine: now I really I think this is all, folks! + def get_builtin(self): try: return self.framestack.top().builtin Modified: pypy/dist/pypy/module/stackless/coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/coroutine.py (original) +++ pypy/dist/pypy/module/stackless/coroutine.py Wed Jun 7 17:00:17 2006 @@ -102,6 +102,38 @@ return space.wrap(AppCoroutine._get_state(space).current) w_getcurrent = staticmethod(w_getcurrent) + # pickling interface + def descr__reduce__(self, space): + # this is trying to be simplistic at the moment. + # we neither allow to pickle main (which can become a mess + # since it has some deep anchestor frames) + # nor we allowto pickle the current coroutine. + # rule: switch before pickling. + # you cannot construct the tree that you are climbing. + + from pypy.interpreter.mixedmodule import MixedModule + w_mod = space.getbuiltinmodule('stackless') + mod = space.interp_w(MixedModule, w_mod) + new_inst = mod.get('coroutine') + w = space.wrap + nt = space.newtuple + ec = self.space.getexecutioncontext() + + tup_base = [ + ] + tup_state = [ + w(self.flags), + ec.subcontext_getstate(self), + ] + + return nt([new_inst, nt(tup_base), nt(tup_state)]) + + def descr__setstate__(self, space, w_args): + args_w = space.unpackiterable(w_args) + w_flags, w_state = args_w + self.flags = space.int_w(w_flags) + ec = self.space.getexecutioncontext() + ec.subcontext_setstate(self, w_state) # _mixin_ did not work for methname in StacklessFlags.__dict__: @@ -140,6 +172,11 @@ kill = interp2app(AppCoroutine.w_kill), is_zombie = GetSetProperty(AppCoroutine.w_get_is_zombie, doc=AppCoroutine.get_is_zombie.__doc__), getcurrent = interp2app(AppCoroutine.w_getcurrent), + __reduce__ = interp2app(AppCoroutine.descr__reduce__, + unwrap_spec=['self', ObjSpace]), + __setstate__ = interp2app(AppCoroutine.descr__setstate__, + unwrap_spec=['self', ObjSpace, W_Root]), + __module__ = 'stackless', ) class AppCoState(BaseCoState): Modified: pypy/dist/pypy/module/stackless/test/test_coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/test_coroutine.py (original) +++ pypy/dist/pypy/module/stackless/test/test_coroutine.py Wed Jun 7 17:00:17 2006 @@ -13,3 +13,15 @@ print stackless.__file__ co = stackless.coroutine() print co + # not much we can do here without compiling. + # well, we can pickle, at least: + + def test_pickle_coroutine(self): + # this test is limited to basic pickling. + # real stacks can only tested with a stackless pypy build. + import stackless + co = stackless.coroutine() + import pickle + pckl = pickle.dumps(co) + co2 = pickle.loads(pckl) + \ No newline at end of file From antocuni at codespeak.net Wed Jun 7 17:02:33 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 17:02:33 +0200 (CEST) Subject: [pypy-svn] r28460 - pypy/dist/pypy/rpython/test Message-ID: <20060607150233.BA0851007A@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 17:02:33 2006 New Revision: 28460 Modified: pypy/dist/pypy/rpython/test/test_rclass.py pypy/dist/pypy/rpython/test/tool.py Log: A bit of refactoring for reuse the test in the backends. Modified: pypy/dist/pypy/rpython/test/test_rclass.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rclass.py (original) +++ pypy/dist/pypy/rpython/test/test_rclass.py Wed Jun 7 17:02:33 2006 @@ -44,12 +44,7 @@ x = EmptyBase() return x res = self.interpret(dummyfn, []) - T = typeOf(res) - if self.type_system == "lltype": - assert isinstance(T, Ptr) and isinstance(T.TO, GcStruct) - else: - assert isinstance(T, ootype.Instance) - + assert self.is_of_instance_type(res) def test_classattr(self): def dummyfn(): Modified: pypy/dist/pypy/rpython/test/tool.py ============================================================================== --- pypy/dist/pypy/rpython/test/tool.py (original) +++ pypy/dist/pypy/rpython/test/tool.py Wed Jun 7 17:02:33 2006 @@ -1,5 +1,6 @@ import py from pypy.rpython.ootypesystem import ootype +from pypy.rpython.lltypesystem import lltype from pypy.rpython.test.test_llinterp import interpret, interpret_raises class BaseRtypingTest(object): @@ -43,6 +44,10 @@ return attr raise AttributeError() + def is_of_instance_type(self, val): + T = lltype.typeOf(val) + return isinstance(T, lltype.Ptr) and isinstance(T.TO, lltype.GcStruct) + class OORtypeMixin(object): type_system = 'ootype' @@ -66,3 +71,7 @@ def read_attr(self, value, attr): value = ootype.oodowncast(ootype.dynamicType(value), value) return getattr(value, "o" + attr) + + def is_of_instance_type(self, val): + T = lltype.typeOf(val) + return isinstance(T, ootype.Instance) From antocuni at codespeak.net Wed Jun 7 17:05:33 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 17:05:33 +0200 (CEST) Subject: [pypy-svn] r28461 - pypy/dist/pypy/translator/cli/test Message-ID: <20060607150533.E18641007A@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 17:05:33 2006 New Revision: 28461 Added: pypy/dist/pypy/translator/cli/test/test_class.py (contents, props changed) Modified: pypy/dist/pypy/translator/cli/test/runtest.py Log: Some more gencli tests. Some of them don't pass, yet. Modified: pypy/dist/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/runtest.py (original) +++ pypy/dist/pypy/translator/cli/test/runtest.py Wed Jun 7 17:05:33 2006 @@ -242,3 +242,6 @@ def class_name(self, value): return value.class_name.split(".")[-1] + + def is_of_instance_type(self, val): + return isinstance(val, InstanceWrapper) Added: pypy/dist/pypy/translator/cli/test/test_class.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/cli/test/test_class.py Wed Jun 7 17:05:33 2006 @@ -0,0 +1,6 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_rclass import BaseTestRclass + +class TestCliClass(CliTest, BaseTestRclass): + pass From antocuni at codespeak.net Wed Jun 7 17:22:35 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 17:22:35 +0200 (CEST) Subject: [pypy-svn] r28464 - pypy/dist/pypy/translator/js2 Message-ID: <20060607152235.CDDCF10064@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 17:22:35 2006 New Revision: 28464 Modified: pypy/dist/pypy/translator/js2/database.py Log: Compatibility with gencli. Modified: pypy/dist/pypy/translator/js2/database.py ============================================================================== --- pypy/dist/pypy/translator/js2/database.py (original) +++ pypy/dist/pypy/translator/js2/database.py Wed Jun 7 17:22:35 2006 @@ -159,6 +159,8 @@ const.init_fields(ilasm, self.const_var, name) #ilasm.field(name, const.get_type(), static=True) + def gen_delegate_types(self, ilasm): + pass def load_const(self, type_, value, ilasm): if self.is_primitive(type_): From ale at codespeak.net Wed Jun 7 17:25:28 2006 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 7 Jun 2006 17:25:28 +0200 (CEST) Subject: [pypy-svn] r28465 - pypy/extradoc/sprintinfo/post-ep2006 Message-ID: <20060607152528.E5F0510074@code0.codespeak.net> Author: ale Date: Wed Jun 7 17:25:27 2006 New Revision: 28465 Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt Log: My details Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/post-ep2006/people.txt (original) +++ pypy/extradoc/sprintinfo/post-ep2006/people.txt Wed Jun 7 17:25:27 2006 @@ -18,7 +18,7 @@ Samuele Pedroni 2/7 - 10/7 NH Geneva Airport Christian Tismer 6-9th ? Antonio Cuni 6-9th CERN Hostel -Anders Lehmann ? ? +Anders Lehmann 6-9th ? Eric van Riet Paap ? ? Lawrence Oluyede 6-9th CERN Hostel ==================== ============== ===================== From antocuni at codespeak.net Wed Jun 7 17:26:59 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 17:26:59 +0200 (CEST) Subject: [pypy-svn] r28466 - pypy/dist/pypy/translator/cli Message-ID: <20060607152659.9A52010074@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 17:26:58 2006 New Revision: 28466 Modified: pypy/dist/pypy/translator/cli/database.py pypy/dist/pypy/translator/cli/metavm.py pypy/dist/pypy/translator/cli/opcodes.py Log: Fixed a bug related to class fields with Void type. For doing that I needed to move _GetField from oosupport to gencli: need to be refactored. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Wed Jun 7 17:26:58 2006 @@ -378,6 +378,8 @@ ilasm.new('instance void class %s::.ctor()' % classdef._name) while classdef is not None: for name, (TYPE, default) in classdef._fields.iteritems(): + if TYPE is ootype.Void: + continue value = getattr(self.obj, name) type_ = self.cts.lltype_to_cts(TYPE) ilasm.opcode('dup') Modified: pypy/dist/pypy/translator/cli/metavm.py ============================================================================== --- pypy/dist/pypy/translator/cli/metavm.py (original) +++ pypy/dist/pypy/translator/cli/metavm.py Wed Jun 7 17:26:58 2006 @@ -1,4 +1,5 @@ from pypy.translator.cli import oopspec +from pypy.rpython.ootypesystem import ootype from pypy.translator.oosupport.metavm import Generator, InstructionList, MicroInstruction class _Call(MicroInstruction): @@ -40,7 +41,16 @@ generator.call_signature('object [pypylib]pypy.runtime.Utils::RuntimeNew(class [mscorlib]System.Type)') generator.cast_to(op.result.concretetype) +class _GetField(MicroInstruction): + def render(self, generator, op): + if op.result.concretetype is ootype.Void: + return + this, field = op.args + generator.load(this) + generator.get_field(this.concretetype, field.value) + Call = _Call() CallMethod = _CallMethod() IndirectCall = _IndirectCall() RuntimeNew = _RuntimeNew() +GetField = _GetField() Modified: pypy/dist/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/cli/opcodes.py (original) +++ pypy/dist/pypy/translator/cli/opcodes.py Wed Jun 7 17:26:58 2006 @@ -1,7 +1,6 @@ -from pypy.translator.cli.metavm import Call, CallMethod, RuntimeNew, IndirectCall - +from pypy.translator.cli.metavm import Call, CallMethod, RuntimeNew, IndirectCall, GetField from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\ - SetField, GetField, New + SetField, New # some useful instruction patterns Not = ['ldc.i4.0', 'ceq'] From fijal at codespeak.net Wed Jun 7 17:37:12 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 7 Jun 2006 17:37:12 +0200 (CEST) Subject: [pypy-svn] r28467 - pypy/dist/pypy/translator/oosupport Message-ID: <20060607153712.6253510074@code0.codespeak.net> Author: fijal Date: Wed Jun 7 17:37:11 2006 New Revision: 28467 Added: pypy/dist/pypy/translator/oosupport/genoo.py Log: Added generic ootypesystem backend behaviour. Added: pypy/dist/pypy/translator/oosupport/genoo.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/oosupport/genoo.py Wed Jun 7 17:37:11 2006 @@ -0,0 +1,79 @@ + +""" basic oogenerator +""" + +class Tee(object): + def __init__(self, *args): + self.outfiles = args + + def write(self, s): + for outfile in self.outfiles: + outfile.write(s) + + def close(self): + for outfile in self.outfiles: + if outfile is not sys.stdout: + outfile.close() + +class GenOO(object): + def __init__(self, tmpdir, translator, entrypoint=None, backend_mapping=None, pending_graphs = [],\ + stdout = False): + + self.stdout = stdout + self.backend_mapping = backend_mapping + #def __init__(self, tmpdir, translator, entrypoint=None, type_system_class=CTS, + # opcode_dict=opcodes, name_suffix='.il', function_class=Function, + # database_class = LowLevelDatabase, pending_graphs=()): + self.tmpdir = tmpdir + self.translator = translator + self.entrypoint = entrypoint + self.db = self.backend_mapping['database_class'](self.backend_mapping) + + for graph in pending_graphs: + self.db.pending_function(graph) + + if entrypoint is None: + self.assembly_name = self.translator.graphs[0].name + else: + self.assembly_name = entrypoint.get_name() + + self.tmpfile = tmpdir.join(self.assembly_name + self.backend_mapping['name_suffix']) + + def generate_source(self): + out = self.tmpfile.open('w') + if self.stdout: + out = Tee(sys.stdout, out) + + self.ilasm = self.backend_mapping['asm_class'](out, self.assembly_name ) + + # TODO: instance methods that are also called as unbound + # methods are rendered twice, once within the class and once + # as an external function. Fix this. + self.fix_names() + self.gen_entrypoint() + self.gen_pendings() + self.db.gen_constants(self.ilasm) + self.gen_pendings() + out.close() + return self.tmpfile.strpath + + def gen_entrypoint(self): + if self.entrypoint: + self.entrypoint.db = self.db + self.db.pending_node(self.entrypoint) + else: + self.db.pending_function(self.translator.graphs[0]) + + def gen_pendings(self): + while self.db._pending_nodes: + node = self.db._pending_nodes.pop() + node.render(self.ilasm) + + def fix_names(self): + # it could happen that two distinct graph have the same name; + # here we assign an unique name to each graph. + names = set() + for graph in self.translator.graphs: + while graph.name in names: + graph.name += '_' + names.add(graph.name) From fijal at codespeak.net Wed Jun 7 17:37:34 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 7 Jun 2006 17:37:34 +0200 (CEST) Subject: [pypy-svn] r28468 - in pypy/dist/pypy/translator/js2: . modules Message-ID: <20060607153734.4E6F410076@code0.codespeak.net> Author: fijal Date: Wed Jun 7 17:37:33 2006 New Revision: 28468 Modified: pypy/dist/pypy/translator/js2/database.py pypy/dist/pypy/translator/js2/js.py pypy/dist/pypy/translator/js2/modules/dom.py Log: Added generic ootypesystem backend usage. Modified: pypy/dist/pypy/translator/js2/database.py ============================================================================== --- pypy/dist/pypy/translator/js2/database.py (original) +++ pypy/dist/pypy/translator/js2/database.py Wed Jun 7 17:37:33 2006 @@ -24,12 +24,12 @@ from sets import Set as set class LowLevelDatabase(object): - def __init__(self, type_system_class = JTS, opcode_dict = opcodes, function_class = Function): + def __init__(self, backend_mapping = None): self._pending_nodes = set() - self.opcode_dict = opcode_dict + self.opcode_dict = backend_mapping['opcode_dict'] self._rendered_nodes = set() - self.function_class = function_class - self.type_system_class = type_system_class + self.function_class = backend_mapping['function_class'] + self.type_system_class = backend_mapping['type_system_class'] self.classes = {} # classdef --> class_name self.functions = {} # graph --> function_name self.function_names = {} # graph --> real_name @@ -39,7 +39,8 @@ self.const_var = Variable("__consts") self.name_manager = JavascriptNameManager(self) self.pending_consts = [] - self.cts = type_system_class(self) + self.backend_mapping = backend_mapping + self.cts = self.type_system_class(self) self.prepare_builtins() def prepare_builtins(self): @@ -159,9 +160,6 @@ const.init_fields(ilasm, self.const_var, name) #ilasm.field(name, const.get_type(), static=True) - def gen_delegate_types(self, ilasm): - pass - def load_const(self, type_, value, ilasm): if self.is_primitive(type_): ilasm.load_const(self.cts.primitive_repr(type_, value)) Modified: pypy/dist/pypy/translator/js2/js.py ============================================================================== --- pypy/dist/pypy/translator/js2/js.py (original) +++ pypy/dist/pypy/translator/js2/js.py Wed Jun 7 17:37:33 2006 @@ -23,7 +23,7 @@ from pypy.translator.js2.function import Function from pypy.translator.js2.database import LowLevelDatabase -from pypy.translator.cli.gencli import GenCli +from pypy.translator.oosupport.genoo import GenOO from heapq import heappush, heappop @@ -33,10 +33,17 @@ path = os.path.join(path, p) return path -class JS(GenCli): +class JS(GenOO): def __init__(self, translator, functions=[], stackless=False, compress=False, logging=False): - GenCli.__init__(self, udir, translator, type_system_class = JTS, opcode_dict = opcodes,\ - name_suffix = '.js', function_class = Function, database_class = LowLevelDatabase) + backend_mapping = { + 'type_system_class' : JTS, + 'opcode_dict' : opcodes, + 'name_suffix' : '.js', + 'function_class' : Function, + 'database_class' : LowLevelDatabase, + 'asm_class' : AsmGen, + } + GenOO.__init__(self, udir, translator, backend_mapping = backend_mapping, pending_graphs = ()) self.translator = translator def gen_pendings(self): @@ -60,7 +67,7 @@ # not be used as inlined, rather another script to load # this is just workaround - self.generate_source(AsmGen) + self.generate_source() data = self.tmpfile.open().read() src_filename = _path_join(os.path.dirname(__file__), 'jssrc', 'misc.js') Modified: pypy/dist/pypy/translator/js2/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js2/modules/dom.py (original) +++ pypy/dist/pypy/translator/js2/modules/dom.py Wed Jun 7 17:37:33 2006 @@ -21,10 +21,11 @@ class Node(object): _rpython_hints = {'_suggested_external' : True} - def __init__(self): + def __init__(self, parent = None): self.innerHTML = "" self.style = None self.subnodes = {} + self.parent = parent def getElementById(self, id): try: @@ -33,12 +34,28 @@ self.subnodes[id] = Node() return self.subnodes[id] + def createElement(self, type): + return Node() + def setAttribute(self, name, style_str): if name == 'style': self.style = Style( style_str) + elif name == 'id': + self.id = style_str + elif name == 'src': + self.src = style_str + + def appendChild(self, elem): + self.subnodes[elem.id] = elem + +class Document(Node): + def __init__(self): + Node.__init__(self) + self.body = Node() + def get_document(): - return Node() + return Document() get_document.suggested_primitive = True @@ -56,3 +73,4 @@ #pass setTimeout.suggested_primitive = True + From antocuni at codespeak.net Wed Jun 7 17:57:04 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 17:57:04 +0200 (CEST) Subject: [pypy-svn] r28469 - pypy/dist/pypy/translator/cli Message-ID: <20060607155704.60CBC10074@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 17:57:03 2006 New Revision: 28469 Modified: pypy/dist/pypy/translator/cli/class_.py Log: Constructors now set the default value for class fields. Modified: pypy/dist/pypy/translator/cli/class_.py ============================================================================== --- pypy/dist/pypy/translator/cli/class_.py (original) +++ pypy/dist/pypy/translator/cli/class_.py Wed Jun 7 17:57:03 2006 @@ -48,7 +48,6 @@ if cts_type != 'void': ilasm.field(f_name, cts_type) - # TODO: should the .ctor set the default values? self._ctor() self._toString() @@ -65,11 +64,19 @@ self.db.record_class(self.classdef, self.name) - def _ctor(self): + from pypy.translator.cli.database import AbstractConst 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()) + # set default values for fields + for f_name, (F_TYPE, f_default) in self.classdef._fields.iteritems(): + cts_type = self.cts.lltype_to_cts(F_TYPE) + if cts_type != 'void': + self.ilasm.opcode('ldarg.0') + AbstractConst.load(self.db, F_TYPE, f_default, self.ilasm) + self.ilasm.set_field((cts_type, self.classdef._name, f_name)) + self.ilasm.opcode('ret') self.ilasm.end_function() From antocuni at codespeak.net Wed Jun 7 17:57:46 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 17:57:46 +0200 (CEST) Subject: [pypy-svn] r28470 - pypy/dist/pypy/translator/cli Message-ID: <20060607155746.114D11007A@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 17:57:45 2006 New Revision: 28470 Modified: pypy/dist/pypy/translator/cli/database.py Log: Added support for nullruntimeclass. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Wed Jun 7 17:57:45 2006 @@ -298,10 +298,13 @@ return self.cts.lltype_to_cts(self.class_._TYPE, include_class) def init(self, ilasm): - self.cts.lltype_to_cts(self.class_._INSTANCE) # force scheduling class generation - classname = self.class_._INSTANCE._name - ilasm.opcode('ldtoken', classname) - ilasm.call('class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)') + INSTANCE = self.class_._INSTANCE + if INSTANCE is None: + ilasm.opcode('ldnull') + else: + self.cts.lltype_to_cts(INSTANCE) # force scheduling class generation + ilasm.opcode('ldtoken', INSTANCE._name) + ilasm.call('class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)') class ListConst(AbstractConst): def __init__(self, db, list_): From antocuni at codespeak.net Wed Jun 7 18:21:46 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 18:21:46 +0200 (CEST) Subject: [pypy-svn] r28471 - pypy/dist/pypy/translator/cli/test Message-ID: <20060607162146.98A8910074@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 18:21:46 2006 New Revision: 28471 Modified: pypy/dist/pypy/translator/cli/test/test_class.py Log: Skip a failing test. Modified: pypy/dist/pypy/translator/cli/test/test_class.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_class.py (original) +++ pypy/dist/pypy/translator/cli/test/test_class.py Wed Jun 7 18:21:46 2006 @@ -3,4 +3,5 @@ from pypy.rpython.test.test_rclass import BaseTestRclass class TestCliClass(CliTest, BaseTestRclass): - pass + def test_recursive_prebuilt_instance(self): + py.test.skip("gencli doesn't support this, yet'") From antocuni at codespeak.net Wed Jun 7 18:35:00 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 18:35:00 +0200 (CEST) Subject: [pypy-svn] r28472 - pypy/dist/pypy/translator/cli Message-ID: <20060607163500.4E93810070@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 18:34:59 2006 New Revision: 28472 Modified: pypy/dist/pypy/translator/cli/function.py pypy/dist/pypy/translator/cli/metavm.py pypy/dist/pypy/translator/cli/opcodes.py Log: Added support for 'instanceof'. Modified: pypy/dist/pypy/translator/cli/function.py ============================================================================== --- pypy/dist/pypy/translator/cli/function.py (original) +++ pypy/dist/pypy/translator/cli/function.py Wed Jun 7 18:34:59 2006 @@ -307,3 +307,6 @@ self.ilasm.opcode('stloc', repr(v.name)) else: assert False + + def isinstance(self, class_name): + self.ilasm.opcode('isinst', class_name) Modified: pypy/dist/pypy/translator/cli/metavm.py ============================================================================== --- pypy/dist/pypy/translator/cli/metavm.py (original) +++ pypy/dist/pypy/translator/cli/metavm.py Wed Jun 7 18:34:59 2006 @@ -49,8 +49,14 @@ generator.load(this) generator.get_field(this.concretetype, field.value) +class _CastTo(MicroInstruction): + def render(self, generator, op): + generator.load(op.args[0]) + generator.isinstance(op.args[1].value._name) + Call = _Call() CallMethod = _CallMethod() IndirectCall = _IndirectCall() RuntimeNew = _RuntimeNew() GetField = _GetField() +CastTo = _CastTo() Modified: pypy/dist/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/cli/opcodes.py (original) +++ pypy/dist/pypy/translator/cli/opcodes.py Wed Jun 7 18:34:59 2006 @@ -1,4 +1,4 @@ -from pypy.translator.cli.metavm import Call, CallMethod, RuntimeNew, IndirectCall, GetField +from pypy.translator.cli.metavm import Call, CallMethod, RuntimeNew, IndirectCall, GetField, CastTo from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\ SetField, New @@ -47,6 +47,7 @@ 'oodowncast': DoNothing, # TODO: is it really safe? 'oois': 'ceq', 'oononnull': [PushAllArgs, 'ldnull', 'ceq']+Not, + 'instanceof': [CastTo, 'ldnull', 'cgt.un'], 'same_as': DoNothing, # TODO: does same_as really do nothing else than renaming? 'direct_call': [Call], From antocuni at codespeak.net Wed Jun 7 18:52:28 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 18:52:28 +0200 (CEST) Subject: [pypy-svn] r28473 - in pypy/dist/pypy/translator/cli: . src Message-ID: <20060607165228.A8D6010070@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 18:52:27 2006 New Revision: 28473 Modified: pypy/dist/pypy/translator/cli/opcodes.py pypy/dist/pypy/translator/cli/src/pypylib.cs Log: Added support for 'subclassof' Modified: pypy/dist/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/cli/opcodes.py (original) +++ pypy/dist/pypy/translator/cli/opcodes.py Wed Jun 7 18:52:27 2006 @@ -48,6 +48,7 @@ 'oois': 'ceq', 'oononnull': [PushAllArgs, 'ldnull', 'ceq']+Not, 'instanceof': [CastTo, 'ldnull', 'cgt.un'], + 'subclassof': [PushAllArgs, 'call bool [pypylib]pypy.runtime.Utils::SubclassOf(class [mscorlib]System.Type, class[mscorlib]System.Type)'], 'same_as': DoNothing, # TODO: does same_as really do nothing else than renaming? 'direct_call': [Call], Modified: pypy/dist/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/dist/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/dist/pypy/translator/cli/src/pypylib.cs Wed Jun 7 18:52:27 2006 @@ -35,6 +35,11 @@ { return t.GetConstructor(new Type[0]).Invoke(new object[0]); } + + public static bool SubclassOf(Type a, Type b) + { + return (a == b || a.IsSubclassOf(b)); + } } //The public interface List must implement is defined in From antocuni at codespeak.net Wed Jun 7 19:18:39 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 19:18:39 +0200 (CEST) Subject: [pypy-svn] r28474 - pypy/dist/pypy/translator/cli Message-ID: <20060607171839.69A5410075@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 19:18:38 2006 New Revision: 28474 Modified: pypy/dist/pypy/translator/cli/opcodes.py Log: Added support for 'ooidentityhash'. Modified: pypy/dist/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/cli/opcodes.py (original) +++ pypy/dist/pypy/translator/cli/opcodes.py Wed Jun 7 19:18:38 2006 @@ -49,6 +49,8 @@ 'oononnull': [PushAllArgs, 'ldnull', 'ceq']+Not, 'instanceof': [CastTo, 'ldnull', 'cgt.un'], 'subclassof': [PushAllArgs, 'call bool [pypylib]pypy.runtime.Utils::SubclassOf(class [mscorlib]System.Type, class[mscorlib]System.Type)'], + 'ooidentityhash': [PushAllArgs, 'callvirt instance int32 object::GetHashCode()'], + 'same_as': DoNothing, # TODO: does same_as really do nothing else than renaming? 'direct_call': [Call], From antocuni at codespeak.net Wed Jun 7 19:18:48 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 19:18:48 +0200 (CEST) Subject: [pypy-svn] r28475 - pypy/dist/pypy/translator/cli Message-ID: <20060607171848.518CB10078@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 19:18:47 2006 New Revision: 28475 Modified: pypy/dist/pypy/translator/cli/database.py Log: bugfix. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Wed Jun 7 19:18:47 2006 @@ -28,6 +28,11 @@ self.consts = {} # value --> const_name self.delegates = {} # StaticMethod --> type_name self.const_names = set() + self.name_count = 0 + + def next_count(self): + self.name_count += 1 + return self.name_count def pending_function(self, graph): self.pending_node(self.function_class(self, graph)) @@ -65,7 +70,7 @@ except KeyError: name = const.get_name() if name in self.const_names: - name += '__%d' % len(self.consts) + name += '__%d' % self.next_count() self.consts[const] = name self.const_names.add(name) From antocuni at codespeak.net Wed Jun 7 19:25:06 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 19:25:06 +0200 (CEST) Subject: [pypy-svn] r28476 - pypy/dist/pypy/translator/cli Message-ID: <20060607172506.E763010068@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 19:25:06 2006 New Revision: 28476 Modified: pypy/dist/pypy/translator/cli/metavm.py pypy/dist/pypy/translator/cli/opcodes.py Log: bugfix related to class field with Void type. Modified: pypy/dist/pypy/translator/cli/metavm.py ============================================================================== --- pypy/dist/pypy/translator/cli/metavm.py (original) +++ pypy/dist/pypy/translator/cli/metavm.py Wed Jun 7 19:25:06 2006 @@ -49,6 +49,16 @@ generator.load(this) generator.get_field(this.concretetype, field.value) +class _SetField(MicroInstruction): + def render(self, generator, op): + this, field, value = op.args + if value.concretetype is ootype.Void: + return + generator.load(this) + generator.load(value) + generator.set_field(this.concretetype, field.value) + + class _CastTo(MicroInstruction): def render(self, generator, op): generator.load(op.args[0]) @@ -59,4 +69,5 @@ IndirectCall = _IndirectCall() RuntimeNew = _RuntimeNew() GetField = _GetField() +SetField = _SetField() CastTo = _CastTo() Modified: pypy/dist/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/cli/opcodes.py (original) +++ pypy/dist/pypy/translator/cli/opcodes.py Wed Jun 7 19:25:06 2006 @@ -1,6 +1,7 @@ -from pypy.translator.cli.metavm import Call, CallMethod, RuntimeNew, IndirectCall, GetField, CastTo +from pypy.translator.cli.metavm import Call, CallMethod, RuntimeNew, \ + IndirectCall, GetField, SetField, CastTo from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\ - SetField, New + New # some useful instruction patterns Not = ['ldc.i4.0', 'ceq'] From antocuni at codespeak.net Wed Jun 7 19:43:17 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Jun 2006 19:43:17 +0200 (CEST) Subject: [pypy-svn] r28477 - pypy/dist/pypy/translator/cli Message-ID: <20060607174317.3235210068@code0.codespeak.net> Author: antocuni Date: Wed Jun 7 19:43:16 2006 New Revision: 28477 Modified: pypy/dist/pypy/translator/cli/database.py Log: Added support for null static methods. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Wed Jun 7 19:43:16 2006 @@ -277,6 +277,9 @@ return self.cts.lltype_to_cts(self.sm._TYPE, include_class) def init(self, ilasm): + if self.sm is ootype.null(self.sm._TYPE): + ilasm.opcode('ldnull') + return self.db.pending_function(self.sm.graph) signature = self.cts.graph_to_signature(self.sm.graph) delegate_type = self.db.record_delegate_type(self.sm._TYPE) From ericvrp at codespeak.net Wed Jun 7 19:57:10 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 7 Jun 2006 19:57:10 +0200 (CEST) Subject: [pypy-svn] r28478 - in pypy/dist/pypy/translator/js2/proxy: . testme testme.egg-info testme/sqlobject-history testme/static testme/static/css testme/static/images testme/static/javascript testme/templates Message-ID: <20060607175710.E644C10068@code0.codespeak.net> Author: ericvrp Date: Wed Jun 7 19:57:09 2006 New Revision: 28478 Added: pypy/dist/pypy/translator/js2/proxy/ pypy/dist/pypy/translator/js2/proxy/README.txt (contents, props changed) pypy/dist/pypy/translator/js2/proxy/dev.cfg pypy/dist/pypy/translator/js2/proxy/prod.cfg pypy/dist/pypy/translator/js2/proxy/setup.py (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme/ pypy/dist/pypy/translator/js2/proxy/testme-start.py (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme.egg-info/ pypy/dist/pypy/translator/js2/proxy/testme.egg-info/PKG-INFO pypy/dist/pypy/translator/js2/proxy/testme.egg-info/SOURCES.txt (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme.egg-info/not-zip-safe pypy/dist/pypy/translator/js2/proxy/testme.egg-info/requires.txt (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme.egg-info/sqlobject.txt (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme.egg-info/top_level.txt (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme/__init__.py (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme/controllers.py (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme/model.py (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme/msgstruct.py (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme/sqlobject-history/ pypy/dist/pypy/translator/js2/proxy/testme/static/ pypy/dist/pypy/translator/js2/proxy/testme/static/css/ pypy/dist/pypy/translator/js2/proxy/testme/static/images/ pypy/dist/pypy/translator/js2/proxy/testme/static/javascript/ pypy/dist/pypy/translator/js2/proxy/testme/templates/ pypy/dist/pypy/translator/js2/proxy/testme/templates/__init__.py (contents, props changed) pypy/dist/pypy/translator/js2/proxy/testme/templates/master.kid pypy/dist/pypy/translator/js2/proxy/testme/templates/welcome.kid Log: Temporary location for proxy-kind-of-code that will allow javascript to connect (over http) to a socket server (of a not yet to be disclosed piece of entertainment software) Added: pypy/dist/pypy/translator/js2/proxy/README.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/README.txt Wed Jun 7 19:57:09 2006 @@ -0,0 +1,4 @@ +testme + +This is a TurboGears (http://www.turbogears.org) project. It can be +started by running the start-testme.py script. \ No newline at end of file Added: pypy/dist/pypy/translator/js2/proxy/dev.cfg ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/dev.cfg Wed Jun 7 19:57:09 2006 @@ -0,0 +1,43 @@ +# This is where all of your settings go for your development environment + +[global] + +# DATABASE + +# pick the form for your database +# sqlobject.dburi="postgres://username at hostname/databasename" +# sqlobject.dburi="mysql://username:password at hostname:port/databasename" +# sqlobject.dburi="sqlite:///file_name_and_path" + +# for Windows users, sqlite URIs look like: +# sqlobject.dburi="sqlite:///drive_letter|/path/to/file" + + +# VIEW + +# kid.outputformat="html" + +# The sitetemplate is used for overall styling of a site that +# includes multiple TurboGears applications +# tg.sitetemplate="" + + +# SERVER + +# Some server parameters that you may want to tweak +# server.socketPort=8080 + +# Disable the debug output at the end on pages. +# logDebugInfoFilter.on = False + +server.environment="production" #"development" +autoreload.package="testme" +autoreload.on = False + +sessionFilter.on = True +sessionFilter.storageType = "Ram" +sessionFilter.cookieName = "BnB" + +[/static] +staticFilter.on = True +staticFilter.dir = "static" Added: pypy/dist/pypy/translator/js2/proxy/prod.cfg ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/prod.cfg Wed Jun 7 19:57:09 2006 @@ -0,0 +1,40 @@ +# This is where all of your settings go for your development environment + +[global] + +# DATABASE + +# pick the form for your database +# sqlobject.dburi="postgres://username at hostname/databasename" +# sqlobject.dburi="mysql://username:password at hostname:port/databasename" +# sqlobject.dburi="sqlite:///file_name_and_path" + +# for Windows users, sqlite URIs look like: +# sqlobject.dburi="sqlite:///drive_letter|/path/to/file" + + +# VIEW + +# kid.outputformat="html" + +# The sitetemplate is used for overall styling of a site that +# includes multiple TurboGears applications +# tg.sitetemplate="" + + +# SERVER + +# Some server parameters that you may want to tweak +# server.socketPort=8080 + +server.environment="production" +server.logFile="server.log" +server.logToScreen=False + +# if this is part of a larger site, you can set the path +# to the TurboGears instance here +# server.webpath="" + +[/static] +staticFilter.on = True +staticFilter.dir = "static" Added: pypy/dist/pypy/translator/js2/proxy/setup.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/setup.py Wed Jun 7 19:57:09 2006 @@ -0,0 +1,18 @@ +from setuptools import setup, find_packages +from turbogears.finddata import find_package_data + +setup( + name="testme", + version="1.0", + #description="", + #author="", + #author_email="", + #url="", + install_requires = ["TurboGears >= 0.8.9"], + scripts = ["testme-start.py"], + zip_safe=False, + packages=find_packages(), + package_data = find_package_data(where='testme', + package='testme'), + ) + Added: pypy/dist/pypy/translator/js2/proxy/testme-start.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme-start.py Wed Jun 7 19:57:09 2006 @@ -0,0 +1,23 @@ +#!/usr/bin/python +import pkg_resources +pkg_resources.require("TurboGears") + +import cherrypy +from os.path import * +import sys + +# first look on the command line for a desired config file, +# if it's not on the command line, then +# look for setup.py in this directory. If it's not there, this script is +# probably installed +if len(sys.argv) > 1: + cherrypy.config.update(file=sys.argv[1]) +elif exists(join(dirname(__file__), "setup.py")): + cherrypy.config.update(file="dev.cfg") +else: + cherrypy.config.update(file="prod.cfg") + +from testme.controllers import Root + +cherrypy.root = Root() +cherrypy.server.start() Added: pypy/dist/pypy/translator/js2/proxy/testme.egg-info/PKG-INFO ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme.egg-info/PKG-INFO Wed Jun 7 19:57:09 2006 @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: testme +Version: 1.0 +Summary: UNKNOWN +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN Added: pypy/dist/pypy/translator/js2/proxy/testme.egg-info/SOURCES.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme.egg-info/SOURCES.txt Wed Jun 7 19:57:09 2006 @@ -0,0 +1,13 @@ +README.txt +setup.py +testme-start.py +testme/__init__.py +testme/controllers.py +testme/model.py +testme.egg-info/PKG-INFO +testme.egg-info/SOURCES.txt +testme.egg-info/not-zip-safe +testme.egg-info/requires.txt +testme.egg-info/sqlobject.txt +testme.egg-info/top_level.txt +testme/templates/__init__.py Added: pypy/dist/pypy/translator/js2/proxy/testme.egg-info/not-zip-safe ============================================================================== Added: pypy/dist/pypy/translator/js2/proxy/testme.egg-info/requires.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme.egg-info/requires.txt Wed Jun 7 19:57:09 2006 @@ -0,0 +1 @@ +TurboGears >= 0.8.9 \ No newline at end of file Added: pypy/dist/pypy/translator/js2/proxy/testme.egg-info/sqlobject.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme.egg-info/sqlobject.txt Wed Jun 7 19:57:09 2006 @@ -0,0 +1,2 @@ +db_module=testme.model +history_dir=$base/testme/sqlobject-history Added: pypy/dist/pypy/translator/js2/proxy/testme.egg-info/top_level.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme.egg-info/top_level.txt Wed Jun 7 19:57:09 2006 @@ -0,0 +1 @@ +testme Added: pypy/dist/pypy/translator/js2/proxy/testme/__init__.py ============================================================================== Added: pypy/dist/pypy/translator/js2/proxy/testme/controllers.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme/controllers.py Wed Jun 7 19:57:09 2006 @@ -0,0 +1,129 @@ +import turbogears +from turbogears import controllers +import cherrypy +from msgstruct import * +import PIL.Image +import zlib +import socket + + +class SessionData: + + def broadcast_port(self, *values): + print 'MESSAGE (IGNORE):broadcast_port', values + + def ping(self): + print 'MESSAGE:ping' + + def def_playfield(self, width, height, backcolor, FnDesc): + print 'MESSAGE:def_playfield width=%s, height=%s, backcolor=%s, FnDesc=%s' %\ + (width, height, backcolor, FnDesc) + + def def_bitmap(self, code, data, *rest): + print 'MESSAGE:def_bitmap code=%s, data=%d bytes, colorkey=%s' %\ + (code, len(data), rest) + bitmap_filename = 'testme/static/images/bitmap%d.ppm' % code + f = open(bitmap_filename, 'wb') + f.write(zlib.decompress(data)) + f.close() + + #TODO: use in memory (don't save ppm first) + bitmap = PIL.Image.open(bitmap_filename) + gif_bitmap_filename = 'testme/static/images/bitmap%d.gif' % code + bitmap.save(gif_bitmap_filename) + + def def_icon(self, bitmap_code, code, x,y,w,h, *rest): + print 'MESSAGE:def_icon bitmap_code=%s, code=%s, x=%s, y=%s, w=%s, h=%s, alpha=%s' %\ + (bitmap_code, code, x,y,w,h, rest) + + #TODO: use in memory (don't save ppm first) + bitmap_filename = 'testme/static/images/bitmap%d.gif' % bitmap_code + icon_filename = 'testme/static/images/icon%d.gif' % code + icon = PIL.Image.open(bitmap_filename) + box = (x, y, x+w, y+h) + region = icon.crop(box) + region.save(icon_filename) + print 'SAVED:', icon_filename + + MESSAGES = { + MSG_BROADCAST_PORT : broadcast_port, + MSG_PING : ping, + MSG_DEF_PLAYFIELD : def_playfield, + MSG_DEF_BITMAP : def_bitmap, + MSG_DEF_ICON : def_icon, + } + + def __init__(self): + self.socket = None + self.data = '' + + def handleServerMessage(self, *values): + #print 'RECEIVED MESSAGE:%s(%d)' % (values[0], len(values[1:])) + fn = self.MESSAGES.get(values[0]) + if fn: + fn(self, *values[1:]) + else: + print "UNKNOWN MESSAGE:", values + + +class Root(controllers.Root): + + host = 'localhost' + port = 32819 #XXX automate this + size = 1024 + + #data + _sessionData = {} + n_header_lines = 2 + + def sessionData(self): + session = cherrypy.session + sessionid = session['_id'] + if sessionid not in self._sessionData: + self._sessionData[sessionid] = SessionData() + return self._sessionData[sessionid] + + def sessionSocket(self, close=False): + d = self.sessionData() + if d.socket is None: + d.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + d.socket.connect((self.host, self.port)) + #XXX todo: session.socket.close() after a timeout + return d.socket + + @turbogears.expose() + def send(self, data=message(CMSG_PING)): + self.sessionSocket().send(data) + print 'SENT:' + repr(data) + return self.recv() + + @turbogears.expose() + def recv(self): + #XXX hangs if not first sending a ping! + d = self.sessionData() + data = d.data + self.sessionSocket().recv(self.size) + while self.n_header_lines > 0 and '\n' in data: + self.n_header_lines -= 1 + header_line, data = data.split('\n',1) + print 'RECEIVED HEADER LINE: %s' % header_line + + #print 'RECEIVED DATA CONTAINS %d BYTES' % len(data) + while data: + values, data = decodemessage(data) + if not values: + break # incomplete message + d.handleServerMessage(*values) + d.data = data + #print 'RECEIVED DATA REMAINING CONTAINS %d BYTES' % len(data) + + return dict(data=data) + + @turbogears.expose() + def close(self): + session = cherrypy.session + sessionid = session['_id'] + d = self.sessionData() + if d.socket is not None: + d.socket.close() + del self._sessionData[sessionid] + Added: pypy/dist/pypy/translator/js2/proxy/testme/model.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme/model.py Wed Jun 7 19:57:09 2006 @@ -0,0 +1,8 @@ +from sqlobject import * +from turbogears.database import PackageHub + +hub = PackageHub("testme") +__connection__ = hub + +# class YourDataClass(SQLObject): +# pass Added: pypy/dist/pypy/translator/js2/proxy/testme/msgstruct.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme/msgstruct.py Wed Jun 7 19:57:09 2006 @@ -0,0 +1,75 @@ +from struct import pack, unpack, calcsize + +try: + from localmsg import PORTS +except ImportError: + PORTS = {} +try: + from localmsg import HOSTNAME +except ImportError: + from socket import gethostname + HOSTNAME = gethostname() + + +MSG_WELCOME = "Welcome to gamesrv.py(3) !\n" +MSG_BROADCAST_PORT= "*" +MSG_DEF_PLAYFIELD = "p" +MSG_DEF_KEY = "k" +MSG_DEF_ICON = "r" +MSG_DEF_BITMAP = "m" +MSG_DEF_SAMPLE = "w" +MSG_DEF_MUSIC = "z" +MSG_PLAY_MUSIC = "Z" +MSG_FADEOUT = "f" +MSG_PLAYER_JOIN = "+" +MSG_PLAYER_KILL = "-" +MSG_PLAYER_ICON = "i" +MSG_PING = "g" +MSG_PONG = "G" +MSG_INLINE_FRAME = "\\" +MSG_PATCH_FILE = MSG_DEF_MUSIC +MSG_ZPATCH_FILE = "P" +MSG_MD5_FILE = "M" +MSG_RECORDED = "\x00" + +CMSG_PROTO_VERSION= "v" +CMSG_KEY = "k" +CMSG_ADD_PLAYER = "+" +CMSG_REMOVE_PLAYER= "-" +CMSG_UDP_PORT = "<" +CMSG_ENABLE_SOUND = "s" +CMSG_ENABLE_MUSIC = "m" +CMSG_PING = "g" +CMSG_PONG = "G" +CMSG_DATA_REQUEST = "M" +CMSG_PLAYER_NAME = "n" + +BROADCAST_MESSAGE = "game!" # less than 6 bytes + + +def message(tp, *values): + strtype = type('') + typecodes = [''] + for v in values: + if type(v) is strtype: + typecodes.append('%ds' % len(v)) + elif 0 <= v < 256: + typecodes.append('B') + else: + typecodes.append('l') + typecodes = ''.join(typecodes) + assert len(typecodes) < 256 + return pack(("!B%dsc" % len(typecodes)) + typecodes, + len(typecodes), typecodes, tp, *values) + +def decodemessage(data): + if data: + limit = ord(data[0]) + 1 + if len(data) >= limit: + typecodes = "!c" + data[1:limit] + end = limit + calcsize(typecodes) + if len(data) >= end: + return unpack(typecodes, data[limit:end]), data[end:] + elif end > 1000000: + raise OverflowError + return None, data Added: pypy/dist/pypy/translator/js2/proxy/testme/templates/__init__.py ============================================================================== Added: pypy/dist/pypy/translator/js2/proxy/testme/templates/master.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme/templates/master.kid Wed Jun 7 19:57:09 2006 @@ -0,0 +1,17 @@ + + + + + + + Your title goes here + + + + + +
+ +
+ + Added: pypy/dist/pypy/translator/js2/proxy/testme/templates/welcome.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme/templates/welcome.kid Wed Jun 7 19:57:09 2006 @@ -0,0 +1,13 @@ + + + + + + BnB + + + +

sessionid: ${sessionid}

+ + From tismer at codespeak.net Wed Jun 7 20:09:59 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 7 Jun 2006 20:09:59 +0200 (CEST) Subject: [pypy-svn] r28479 - in pypy/dist/pypy: interpreter module/stackless module/stackless/test Message-ID: <20060607180959.49D0C10070@code0.codespeak.net> Author: tismer Date: Wed Jun 7 20:09:58 2006 New Revision: 28479 Added: pypy/dist/pypy/module/stackless/test/slp_test_pickle.py Modified: pypy/dist/pypy/interpreter/eval.py pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/pyopcode.py pypy/dist/pypy/module/stackless/coroutine.py Log: we possibly have some coroutine pickling ready, given that this mess compiles:-) Modified: pypy/dist/pypy/interpreter/eval.py ============================================================================== --- pypy/dist/pypy/interpreter/eval.py (original) +++ pypy/dist/pypy/interpreter/eval.py Wed Jun 7 20:09:58 2006 @@ -4,6 +4,7 @@ """ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import Wrappable +from pypy.rpython import rstack # for resume points class Code(Wrappable): @@ -156,6 +157,7 @@ executioncontext.enter(self) try: result = self.eval(executioncontext) + rstack.resume_point("evalframe", self, executioncontext, returns=result) finally: executioncontext.leave(self) return result Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Wed Jun 7 20:09:58 2006 @@ -8,6 +8,7 @@ from pypy.rpython.rarithmetic import r_uint, intmask import opcode from pypy.rpython.objectmodel import we_are_translated, instantiate +from pypy.rpython import rstack # for resume points # Define some opcodes used @@ -198,6 +199,7 @@ try: if we_are_translated(): self.dispatch_translated(executioncontext) + rstack.resume_point("eval", self) else: self.dispatch(executioncontext) # catch asynchronous exceptions and turn them Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Wed Jun 7 20:09:58 2006 @@ -15,6 +15,7 @@ from pypy.rpython.objectmodel import we_are_translated from pypy.rpython.rarithmetic import intmask from pypy.tool import stdlib_opcode as pythonopcode +from pypy.rpython import rstack # for resume points def unaryoperation(operationname): """NOT_RPYTHON""" @@ -675,6 +676,7 @@ args = Arguments(f.space, arguments, keywords, w_star, w_starstar) w_function = f.valuestack.pop() w_result = f.space.call_args(w_function, args) + rstack.resume_point("call_function", f, returns=w_result) f.valuestack.push(w_result) def CALL_FUNCTION(f, oparg): @@ -685,6 +687,7 @@ w_function = f.valuestack.top(nargs) try: w_result = f.space.call_valuestack(w_function, nargs, f.valuestack) + rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result) finally: f.valuestack.drop(nargs + 1) f.valuestack.push(w_result) @@ -825,12 +828,14 @@ ''' % (pythonopcode.HAVE_ARGUMENT, pythonopcode.EXTENDED_ARG, pythonopcode.HAVE_ARGUMENT) - for opname,i in pythonopcode.opmap.iteritems(): + for opname, i in pythonopcode.opmap.iteritems(): if i == pythonopcode.EXTENDED_ARG or i < pythonopcode.HAVE_ARGUMENT: continue opname = opname.replace('+', '_') dispatch_code += ' elif opcode == %d:\n' % i dispatch_code += ' self.%s(oparg)\n' % opname + if opname == 'CALL_FUNCTION': + dispatch_code += ' rstack.resume_point("dispatch_call", self, code, ec)\n' dispatch_code += ' else:\n' dispatch_code += ' self.MISSING_OPCODE_W_ARG(oparg)\n' dispatch_code += ' break\n' Modified: pypy/dist/pypy/module/stackless/coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/coroutine.py (original) +++ pypy/dist/pypy/module/stackless/coroutine.py Wed Jun 7 20:09:58 2006 @@ -26,6 +26,9 @@ from pypy.module.stackless.stackless_flags import StacklessFlags from pypy.module.stackless.interp_coroutine import Coroutine, BaseCoState, AbstractThunk +from pypy.rpython import rstack # for resume points +from pypy.tool import stdlib_opcode as pythonopcode + class _AppThunk(AbstractThunk): def __init__(self, space, costate, w_obj, args): @@ -40,7 +43,10 @@ self.args = args def call(self): - self.costate.w_tempval = self.space.call_args(self.w_func, self.args) + costate = self.costate + w_result = self.space.call_args(self.w_func, self.args) + rstack.resume_point("appthunk", costate, returns=w_result) + costate.w_tempval = w_result class AppCoroutine(Coroutine): # XXX, StacklessFlags): @@ -77,6 +83,7 @@ raise OperationError(space.w_ValueError, space.wrap( "cannot switch to an unbound Coroutine")) self.switch() + rstack.resume_point("w_switch", self, space) state = self.costate w_ret, state.w_tempval = state.w_tempval, space.w_None return w_ret @@ -110,7 +117,7 @@ # nor we allowto pickle the current coroutine. # rule: switch before pickling. # you cannot construct the tree that you are climbing. - + # XXX missing checks! from pypy.interpreter.mixedmodule import MixedModule w_mod = space.getbuiltinmodule('stackless') mod = space.interp_w(MixedModule, w_mod) @@ -134,6 +141,54 @@ self.flags = space.int_w(w_flags) ec = self.space.getexecutioncontext() ec.subcontext_setstate(self, w_state) + self.reconstruct_framechain() + + def reconstruct_framechain(self): + from pypy.interpreter.pyframe import PyFrame + from pypy.rpython.rstack import resume_state_create + if self.framestack.empty(): + self.frame = None + return + + space = self.space + ec = space.getexecutioncontext() + costate = self.costate + # now the big fun of recreating tiny things... + bottom = resume_state_create(None, "yield_current_frame_to_caller_1") + # resume_point("coroutine__bind", self, state) + _bind_frame = resume_state_create(bottom, "coroutine__bind", self, costate) + # rstack.resume_point("appthunk", costate, returns=w_result) + appthunk_frame = resume_state_create(_bind_frame, "appthunk", costate) + chain = appthunk_frame + for frame in self.framestack.items: + assert isinstance(frame, PyFrame) + # rstack.resume_point("evalframe", self, executioncontext, returns=result) + evalframe_frame = resume_state_create(chain, "evalframe", frame, ec) + # rstack.resume_point("eval", self) + eval_frame = resume_state_create(evalframe_frame, "eval", frame) + # rstack.resume_point("dispatch_call", self, code, ec) + code = frame.getcode().co_code + dispatch_call_frame = resume_state_create(eval_frame, "dispatch_call", frame, code, ec) + instr = frame.last_instr + opcode = ord(code[instr]) + assert opcode == pythonopcode.opmap['CALL_FUNCTION'] + instr += 1 + oparg = ord(code[instr]) | ord(code[instr + 1]) << 8 + if (oparg >> 8) & 0xff == 0: + # Only positional arguments + nargs = oparg & 0xff + # case1: rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result) + call_frame = resume_state_create(dispatch_call_frame, 'CALL_FUNCTION', frame, nargs) + else: + # case2: rstack.resume_point("call_function", f, returns=w_result) + call_frame = resume_state_create(dispatch_call_frame, 'call_function', frame) + chain = call_frame + + # rstack.resume_point("w_switch", self, space) + w_switch_frame = resume_state_create(chain, 'w_switch', self, space) + # resume_point("coroutine_switch", self, state, returns=incoming_frame) + switch_frame = resume_state_create(w_switch_frame, "coroutine_switch", self, costate) + self.frame = switch_frame # _mixin_ did not work for methname in StacklessFlags.__dict__: Added: pypy/dist/pypy/module/stackless/test/slp_test_pickle.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/stackless/test/slp_test_pickle.py Wed Jun 7 20:09:58 2006 @@ -0,0 +1,29 @@ +# app-level testing of coroutine pickling +import stackless + +class TestPickle: + + def test_simple_ish(self): + + output = [] + def f(coro, n, x): + if n == 0: + coro.switch() + return + f(coro, n-1, 2*x) + output.append(x) + + def example(): + main_coro = stackless.coroutine.getcurrent() + sub_coro = stackless.coroutine() + sub_coro.bind(f, main_coro, 5, 1) + sub_coro.switch() + + import pickle + pckl = pickle.dumps(sub_coro) + new_coro = pickle.loads(pckl) + + new_coro.switch() + + example() + assert output == [16, 8, 4, 2, 1] From mwh at codespeak.net Wed Jun 7 20:11:18 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 7 Jun 2006 20:11:18 +0200 (CEST) Subject: [pypy-svn] r28481 - pypy/dist/pypy/translator/stackless Message-ID: <20060607181118.9F2F110070@code0.codespeak.net> Author: mwh Date: Wed Jun 7 20:11:17 2006 New Revision: 28481 Modified: pypy/dist/pypy/translator/stackless/transform.py Log: fix (he says optimistically) various field naming/ordering issues to do with the fields used and stored to by the stackless transform. Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Wed Jun 7 20:11:17 2006 @@ -83,56 +83,56 @@ def __init__(self): self.frametypes = {} - def _key_fieldnames_for_types(self, types): - fieldnames = [] + def _key_for_types(self, types): counts = {} for tt in types: + if tt is lltype.Void: + continue t = storage_type(tt) - if t is lltype.Void: - fieldnames.append(None) - else: - n = counts.get(t, 0) - fieldnames.append('state_%s_%d' % (STORAGE_FIELDS[t], n)) - counts[t] = n + 1 + counts[t] = counts.get(t, 0) + 1 key = lltype.frozendict(counts) - return key, fieldnames - + return key def frame_type_for_vars(self, vars): - key, fieldnames = self._key_fieldnames_for_types([v.concretetype for v in vars]) - if key in self.frametypes: - T = self.frametypes[key] - it = iter(T._names[1:]) - rfieldnames = [] - for name in fieldnames: - if name is None: - rfieldnames.append(None) - else: - rfieldnames.append(it.next()) - try: - it.next() - except StopIteration: - pass - else: - assert False, "field name count mismatch" - return T, rfieldnames - else: + key = self._key_for_types([v.concretetype for v in vars]) + if key not in self.frametypes: fields = [] + fieldsbytype = {} for t in STORAGE_TYPES: for j in range(key.get(t, 0)): - fields.append(('state_%s_%d' % (STORAGE_FIELDS[t], j), t)) - T = frame.make_state_header_type("FrameState", *fields) - self.frametypes[key] = T + fname = 'state_%s_%d' % (STORAGE_FIELDS[t], j) + fields.append((fname, t)) + fieldsbytype.setdefault(t, []).append(fname) + self.frametypes[key] = (frame.make_state_header_type("FrameState", *fields), + fieldsbytype) + T, fieldsbytype = self.frametypes[key] + data = {} + for (k, fs) in fieldsbytype.iteritems(): + data[k] = fs[:] + fieldnames = [] + for v in vars: + if v.concretetype is lltype.Void: + fieldnames.append(None) + else: + t = storage_type(v.concretetype) + fieldnames.append(data[t].pop(0)) + assert max([0] + [len(v) for v in data.itervalues()]) == 0 return T, fieldnames def ensure_frame_type_for_types(self, frame_type): - key, fieldnames = self._key_fieldnames_for_types( - [frame_type._flds[n] for n in frame_type._names[1:]]) - assert len(fieldnames) <= 1, "nasty field ordering issues need to be solved XXX mwh, pedronis" + assert len(frame_type._names[1:]) <= 1, "too lazy" + if len(frame_type._names[1:]) == 1: + fname, = frame_type._names[1:] + t = frame_type._flds[fname] + fieldsbytype = {t:[fname]} + key = self._key_for_types([t]) + else: + key = self._key_for_types([]) + fieldsbytype = {} if key in self.frametypes: - assert self.frametypes[key] is frame_type - self.frametypes[key] = frame_type - + assert self.frametypes[key][0] is frame_type + self.frametypes[key] = (frame_type, fieldsbytype) + class StacklessAnalyzer(graphanalyze.GraphAnalyzer): def __init__(self, translator, unwindtype, stackless_gc): From tismer at codespeak.net Wed Jun 7 20:19:07 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 7 Jun 2006 20:19:07 +0200 (CEST) Subject: [pypy-svn] r28482 - pypy/dist/pypy/translator/goal Message-ID: <20060607181907.9087310070@code0.codespeak.net> Author: tismer Date: Wed Jun 7 20:19:06 2006 New Revision: 28482 Modified: pypy/dist/pypy/translator/goal/compile_stackless.bat Log: change batch file to use new-stackless Modified: pypy/dist/pypy/translator/goal/compile_stackless.bat ============================================================================== --- pypy/dist/pypy/translator/goal/compile_stackless.bat (original) +++ pypy/dist/pypy/translator/goal/compile_stackless.bat Wed Jun 7 20:19:06 2006 @@ -1,3 +1,3 @@ python -c "import time; print time.ctime(), 'compile start'" >> compile.log -translate.py --batch --stackless +translate.py --batch --new-stackless python -c "import time; print time.ctime(), 'compile stop'" >> compile.log From arigo at codespeak.net Wed Jun 7 20:27:01 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Jun 2006 20:27:01 +0200 (CEST) Subject: [pypy-svn] r28483 - pypy/dist/pypy/module/stackless/test Message-ID: <20060607182701.1E46B10070@code0.codespeak.net> Author: arigo Date: Wed Jun 7 20:27:00 2006 New Revision: 28483 Modified: pypy/dist/pypy/module/stackless/test/test_scheduling.py Log: Uh, is this really meant to be executed with py.test? It should not be called test_*.py if not... Modified: pypy/dist/pypy/module/stackless/test/test_scheduling.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/test_scheduling.py (original) +++ pypy/dist/pypy/module/stackless/test/test_scheduling.py Wed Jun 7 20:27:00 2006 @@ -1,3 +1,4 @@ +import py; py.test.skip("doesn't run with py.test") from stackless_ import scheduler class task_mock(object): From arigo at codespeak.net Wed Jun 7 20:31:53 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Jun 2006 20:31:53 +0200 (CEST) Subject: [pypy-svn] r28484 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/lltypesystem/test rpython/memory translator/c translator/tool Message-ID: <20060607183153.80A2010074@code0.codespeak.net> Author: arigo Date: Wed Jun 7 20:31:51 2006 New Revision: 28484 Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py pypy/dist/pypy/rpython/memory/gcheader.py pypy/dist/pypy/rpython/rgc.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/tool/lltracker.py Log: (arre, arigo) Introduced PyStructs, which are a Struct with PyObject-like memory management. Streamlined the various _gcstatus() flags to a single _gckind string that is either 'raw', 'gc' or 'cpy'. The PyStructs represent custom extensions of PyObject with new fields, for the ext compiler. Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/llmemory.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py Wed Jun 7 20:31:51 2006 @@ -52,7 +52,7 @@ def raw_malloc(self, rest): assert not rest if (isinstance(self.TYPE, lltype.ContainerType) - and self.TYPE._gcstatus()): + and self.TYPE._gckind == 'gc'): assert self.repeat == 1 p = lltype.malloc(self.TYPE) return cast_ptr_to_adr(p) @@ -148,7 +148,7 @@ if self.TYPE._hints.get('isrpystring'): count -= 1 # because malloc() will give us the extra char for free p = lltype.malloc(parenttype or self.TYPE, count, - immortal = not self.TYPE._gcstatus()) + immortal = self.TYPE._gckind == 'raw') return cast_ptr_to_adr(p) Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Wed Jun 7 20:31:51 2006 @@ -136,9 +136,6 @@ class ContainerType(LowLevelType): _adtmeths = {} - def _gcstatus(self): - return isinstance(self, GC_CONTAINER) - def _inline_is_varsize(self, last): raise TypeError, "%r cannot be inlined in structure" % self @@ -160,6 +157,8 @@ class Struct(ContainerType): + _gckind = 'raw' + def __init__(self, name, *fields, **kwds): self._name = self.__name__ = name flds = {} @@ -173,12 +172,12 @@ if name in flds: raise TypeError("%s: repeated field name" % self._name) flds[name] = typ - if isinstance(typ, GC_CONTAINER): - if name == fields[0][0] and isinstance(self, GC_CONTAINER): - pass # can inline a GC_CONTAINER as 1st field of GcStruct + if isinstance(typ, ContainerType) and typ._gckind != 'raw': + if name == fields[0][0] and typ._gckind == self._gckind: + pass # can inline a XxContainer as 1st field of XxStruct else: - raise TypeError("%s: cannot inline GC container %r" % ( - self._name, typ)) + raise TypeError("%s: cannot inline %s container %r" % ( + self._name, typ._gckind, typ)) # look if we have an inlined variable-sized array as the last field if fields: @@ -197,7 +196,8 @@ if self._names: first = self._names[0] FIRSTTYPE = self._flds[first] - if isinstance(FIRSTTYPE, Struct) and self._gcstatus() == FIRSTTYPE._gcstatus(): + if (isinstance(FIRSTTYPE, (Struct, PyObjectType)) and + self._gckind == FIRSTTYPE._gckind): return first, FIRSTTYPE return None, None @@ -263,6 +263,7 @@ return _struct(self, n) class GcStruct(Struct): + _gckind = 'gc' _runtime_type_info = None def _attach_runtime_type_info_funcptr(self, funcptr, destrptr): @@ -288,9 +289,18 @@ raise TypeError("expected a destructor function " "implementation, got: %s" % destrptr) self._runtime_type_info.destructor_funcptr = destrptr - + +class PyStruct(Struct): + _gckind = 'cpy' + + def __init__(self, name, *fields, **kwds): + Struct.__init__(self, name, *fields, **kwds) + if self._first_struct() == (None, None): + raise TypeError("a PyStruct must have another PyStruct or " + "PyObject as first field") class Array(ContainerType): + _gckind = 'raw' __name__ = 'array' _anonym_struct = False @@ -300,8 +310,9 @@ else: self.OF = Struct("", *fields) self._anonym_struct = True - if isinstance(self.OF, GC_CONTAINER): - raise TypeError("cannot have a GC container as array item type") + if isinstance(self.OF, ContainerType) and self.OF._gckind != 'raw': + raise TypeError("cannot have a %s container as array item type" + % (self.OF._gckind,)) self.OF._inline_is_varsize(False) self._install_extras(**kwds) @@ -342,6 +353,7 @@ return _array(self, 1) class GcArray(Array): + _gckind = 'gc' def _inline_is_varsize(self, last): raise TypeError("cannot inline a GC array inside a structure") @@ -356,8 +368,9 @@ **kwds) self.OF = OF self.length = length - if isinstance(self.OF, GC_CONTAINER): - raise TypeError("cannot have a GC container as array item type") + if isinstance(self.OF, ContainerType) and self.OF._gckind != 'raw': + raise TypeError("cannot have a %s container as array item type" + % (self.OF._gckind,)) self.OF._inline_is_varsize(False) def _str_fields(self): @@ -377,6 +390,7 @@ class FuncType(ContainerType): + _gckind = 'raw' __name__ = 'func' def __init__(self, args, result): for arg in args: @@ -410,6 +424,7 @@ class OpaqueType(ContainerType): + _gckind = 'raw' def __init__(self, tag): self.tag = tag @@ -430,6 +445,7 @@ RuntimeTypeInfo = OpaqueType("RuntimeTypeInfo") class GcOpaqueType(OpaqueType): + _gckind = 'gc' def __str__(self): return "%s (gcopaque)" % self.tag @@ -438,16 +454,23 @@ raise TypeError, "%r cannot be inlined in structure" % self class PyObjectType(ContainerType): + _gckind = 'cpy' __name__ = 'PyObject' def __str__(self): return "PyObject" + def _inline_is_varsize(self, last): + return False PyObject = PyObjectType() class ForwardReference(ContainerType): + _gckind = 'raw' def become(self, realcontainertype): if not isinstance(realcontainertype, ContainerType): raise TypeError("ForwardReference can only be to a container, " "not %r" % (realcontainertype,)) + if realcontainertype._gckind != self._gckind: + raise TypeError("become() gives conflicting gckind, use the " + "correct XxForwardReference") self.__class__ = realcontainertype.__class__ self.__dict__ = realcontainertype.__dict__ @@ -455,15 +478,7 @@ raise TypeError("%r object is not hashable" % self.__class__.__name__) class GcForwardReference(ForwardReference): - def become(self, realcontainertype): - if not isinstance(realcontainertype, GC_CONTAINER): - raise TypeError("GcForwardReference can only be to GcStruct or " - "GcArray, not %r" % (realcontainertype,)) - self.__class__ = realcontainertype.__class__ - self.__dict__ = realcontainertype.__dict__ - -GC_CONTAINER = (GcStruct, GcArray, PyObjectType, GcForwardReference, - GcOpaqueType) + _gckind = 'gc' class Primitive(LowLevelType): @@ -531,7 +546,8 @@ self.TO = TO def _needsgc(self): - return self.TO._gcstatus() + # XXX deprecated interface + return self.TO._gckind != 'raw' def __str__(self): return '* %s' % (self.TO, ) @@ -540,7 +556,7 @@ return 'Ptr %s' % (self.TO._short_name(), ) def _is_atomic(self): - return not self.TO._gcstatus() + return self.TO._gckind == 'raw' def _defl(self, parent=None, parentindex=None): return _ptr(self, None) @@ -641,7 +657,7 @@ OUTSIDE = getattr(OUTSIDE, first) def castable(PTRTYPE, CURTYPE): - if CURTYPE._needsgc() != PTRTYPE._needsgc(): + if CURTYPE.TO._gckind != PTRTYPE.TO._gckind: raise TypeError("cast_pointer() cannot change the gc status: %s to %s" % (CURTYPE, PTRTYPE)) if CURTYPE == PTRTYPE: @@ -669,7 +685,7 @@ CURTYPE = typeOf(ptr) if not isinstance(CURTYPE, Ptr) or not isinstance(PTRTYPE, Ptr): raise TypeError, "can only cast pointers to other pointers" - if CURTYPE._needsgc() != PTRTYPE._needsgc(): + if CURTYPE.TO._gckind != PTRTYPE.TO._gckind: raise TypeError("cast_opaque_ptr() cannot change the gc status: " "%s to %s" % (CURTYPE, PTRTYPE)) if (isinstance(CURTYPE.TO, OpaqueType) @@ -813,7 +829,11 @@ def _set_obj0(self, obj): _ptr._obj0.__set__(self, obj) + def _togckind(self): + return self._T._gckind + def _needsgc(self): + # XXX deprecated interface return self._TYPE._needsgc() # xxx other rules? def __init__(self, TYPE, pointing_to, solid=False): @@ -855,7 +875,8 @@ def _setobj(self, pointing_to, solid=False): if pointing_to is None: obj0 = None - elif solid or isinstance(self._T, (GC_CONTAINER, FuncType)): + elif (solid or self._T._gckind != 'raw' or + isinstance(self._T, FuncType)): obj0 = pointing_to else: self._set_weak(True) @@ -1091,7 +1112,7 @@ self._parent_index = parentindex if (isinstance(self._parent_type, Struct) and parentindex == self._parent_type._names[0] - and self._TYPE._gcstatus() == typeOf(parent)._gcstatus()): + and self._TYPE._gckind == typeOf(parent)._gckind): # keep strong reference to parent, we share the same allocation self._keepparent = parent @@ -1439,7 +1460,7 @@ o = _array(T, n) else: raise TypeError, "malloc for Structs and Arrays only" - if not isinstance(T, GC_CONTAINER) and not immortal and flavor.startswith('gc'): + if T._gckind != 'gc' and not immortal and flavor.startswith('gc'): raise TypeError, "gc flavor malloc of a non-GC non-immortal structure" solid = immortal or not flavor.startswith('gc') # immortal or non-gc case return _ptr(Ptr(T), o, solid) @@ -1448,7 +1469,7 @@ if flavor.startswith('gc'): raise TypeError, "gc flavor free" T = typeOf(p) - if not isinstance(T, Ptr) or p._needsgc(): + if not isinstance(T, Ptr) or p._togckind() != 'raw': raise TypeError, "free(): only for pointers to non-gc containers" def functionptr(TYPE, name, **attrs): Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py Wed Jun 7 20:31:51 2006 @@ -693,3 +693,12 @@ import gc gc.collect() repr(s) + +def test_pyobject(): + p = pyobjectptr({42: 84}) + assert typeOf(p) == Ptr(PyObject) + S1 = PyStruct('S1', ('head', PyObject), ('x', Signed)) + # cannot really instantiate S1 so far + py.test.raises(TypeError, PyStruct, 'S2', ('y', Signed)) + py.test.raises(TypeError, PyStruct, 'S2', ('x', Struct('X'))) + py.test.raises(TypeError, PyStruct, 'S2', ('x', GcStruct('X'))) Modified: pypy/dist/pypy/rpython/memory/gcheader.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcheader.py (original) +++ pypy/dist/pypy/rpython/memory/gcheader.py Wed Jun 7 20:31:51 2006 @@ -27,7 +27,7 @@ gcobj = gcptr._as_obj() assert gcobj not in self.obj2header # sanity checks - assert isinstance(gcobj._TYPE, lltype.GC_CONTAINER) + assert gcobj._TYPE._gckind == 'gc' assert not isinstance(gcobj._TYPE, lltype.GcOpaqueType) assert not gcobj._parentstructure() headerptr = lltype.malloc(self.HDR, immortal=True) Modified: pypy/dist/pypy/rpython/rgc.py ============================================================================== --- pypy/dist/pypy/rpython/rgc.py (original) +++ pypy/dist/pypy/rpython/rgc.py Wed Jun 7 20:31:51 2006 @@ -63,7 +63,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory, rtuple r_gcobject = hop.args_r[0] if (not isinstance(r_gcobject.lowleveltype, lltype.Ptr) or - not isinstance(r_gcobject.lowleveltype.TO, lltype.GC_CONTAINER)): + r_gcobject.lowleveltype.TO._gckind != 'gc'): raise TyperError("gc_clone() can only clone a dynamically " "allocated object;\ngot %r" % (r_gcobject,)) from pypy.annotation import model as annmodel Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Wed Jun 7 20:31:51 2006 @@ -106,7 +106,7 @@ # zero malloc impl def zero_malloc(self, TYPE, esize, eresult): - assert TYPE._gcstatus() # we don't really support this + assert TYPE._gckind == 'gc' # we don't really support this return 'OP_ZERO_MALLOC(%s, %s);' % (esize, eresult) @@ -186,7 +186,7 @@ def zero_malloc(self, TYPE, esize, eresult): gcinfo = self.db.gettypedefnode(TYPE).gcinfo - assert TYPE._gcstatus() # _is_atomic() depends on this! + assert TYPE._gckind == 'gc' # _is_atomic() depends on this! is_atomic = TYPE._is_atomic() is_varsize = TYPE._is_varsize() result = 'OP_BOEHM_ZERO_MALLOC(%s, %s, %d, %d);' % (esize, @@ -320,7 +320,7 @@ gcinfo = defnode.gcinfo if gcinfo: if not gcinfo.malloc_exact: - assert TYPE._gcstatus() # _is_atomic() depends on this! + assert TYPE._gckind == 'gc' # _is_atomic() depends on this! is_atomic = TYPE._is_atomic() is_varsize = TYPE._is_varsize() result = 'OP_BOEHM_ZERO_MALLOC(%s, %s, %d, %d);' % ( @@ -393,7 +393,7 @@ return defnode.db.gctransformer.gc_field_values_for(o) def zero_malloc(self, TYPE, esize, eresult): - assert TYPE._gcstatus() # we don't really support this + assert TYPE._gckind == 'gc' # we don't really support this return 'OP_ZERO_MALLOC(%s, %s);' % (esize, eresult) Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Wed Jun 7 20:31:51 2006 @@ -1,7 +1,7 @@ from __future__ import generators from pypy.rpython.lltypesystem.lltype import \ Struct, Array, FixedSizeArray, FuncType, PyObjectType, typeOf, \ - GcStruct, GcArray, GC_CONTAINER, ContainerType, \ + GcStruct, GcArray, ContainerType, \ parentlink, Ptr, PyObject, Void, OpaqueType, Float, \ RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray from pypy.translator.c.funcgen import FunctionCodeGenerator @@ -13,10 +13,12 @@ def needs_gcheader(T): - if not isinstance(T, GC_CONTAINER): + if not isinstance(T, ContainerType): + return False + if T._gckind == 'raw': return False if isinstance(T, GcStruct): - if T._names and isinstance(T._flds[T._names[0]], GC_CONTAINER): + if T._first_struct() != (None, None): return False # gcheader already in the first field return True Modified: pypy/dist/pypy/translator/tool/lltracker.py ============================================================================== --- pypy/dist/pypy/translator/tool/lltracker.py (original) +++ pypy/dist/pypy/translator/tool/lltracker.py Wed Jun 7 20:31:51 2006 @@ -56,7 +56,7 @@ # XXX clean up T = lltype.typeOf(o) if (self.size_gc_header is not None and with_header - and isinstance(T, lltype.GC_CONTAINER)): + and isinstance(T, lltype.ContainerType) and T._gckind == 'gc'): adr = llmemory.cast_ptr_to_adr(o._as_ptr()) adr -= self.size_gc_header o = adr.get()._obj From rxe at codespeak.net Thu Jun 8 00:38:35 2006 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 8 Jun 2006 00:38:35 +0200 (CEST) Subject: [pypy-svn] r28490 - pypy/dist/pypy/translator/c Message-ID: <20060607223835.4966710070@code0.codespeak.net> Author: rxe Date: Thu Jun 8 00:38:32 2006 New Revision: 28490 Modified: pypy/dist/pypy/translator/c/pyobj.py Log: Tyop Modified: pypy/dist/pypy/translator/c/pyobj.py ============================================================================== --- pypy/dist/pypy/translator/c/pyobj.py (original) +++ pypy/dist/pypy/translator/c/pyobj.py Thu Jun 8 00:38:32 2006 @@ -570,7 +570,7 @@ if isinstance(value, FunctionType): func = value fname = '%s.%s' % (cls.__name__, func.__name__) - if not should_expose_method(func): + if not should_expose(func): log.REMARK('method %s hidden from wrapper' % fname) continue if func.__name__ == '__init__': From antocuni at codespeak.net Thu Jun 8 11:08:12 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 11:08:12 +0200 (CEST) Subject: [pypy-svn] r28502 - pypy/dist/pypy/translator/cli Message-ID: <20060608090812.0073210076@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 11:08:12 2006 New Revision: 28502 Modified: pypy/dist/pypy/translator/cli/database.py Log: A bit of refactoring. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Thu Jun 8 11:08:12 2006 @@ -25,7 +25,8 @@ self.classes = {} # classdef --> class_name self.functions = {} # graph --> function_name self.methods = {} # graph --> method_name - self.consts = {} # value --> const_name + self.consts = {} # value --> AbstractConst, const_name + self.pending_consts = {} # value --> AbstractConst, const_name self.delegates = {} # StaticMethod --> type_name self.const_names = set() self.name_count = 0 @@ -64,14 +65,16 @@ return self.classes.get(classdef, None) def record_const(self, value): - const = AbstractConst.make(self, value) - try: - name = self.consts[const] - except KeyError: + if value in self.consts: + const, name = self.consts[value] + elif value in self.pending_consts: + const, name = self.pending_consts[value] + else: + const = AbstractConst.make(self, value) name = const.get_name() if name in self.const_names: name += '__%d' % self.next_count() - self.consts[const] = name + self.pending_consts[value] = const, name self.const_names.add(name) return '%s.%s::%s' % (CONST_NAMESPACE, CONST_CLASS, name) @@ -122,16 +125,17 @@ # the last step0. step = 0 - while self.consts: - consts = self.consts - self.consts = {} + while self.pending_consts: + pending_consts = self.pending_consts + self.consts.update(pending_consts) + self.pending_consts = {} # render field definitions - for const, name in consts.iteritems(): + for const, name in pending_consts.itervalues(): ilasm.field(name, const.get_type(), static=True) ilasm.begin_function('step%d' % step, [], 'void', False, 'static') - for const, name in consts.iteritems(): + for const, name in pending_consts.itervalues(): const.init(ilasm) type_ = const.get_type() ilasm.set_static_field (type_, CONST_NAMESPACE, CONST_CLASS, name) From antocuni at codespeak.net Thu Jun 8 12:13:26 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 12:13:26 +0200 (CEST) Subject: [pypy-svn] r28504 - pypy/dist/pypy/translator/cli Message-ID: <20060608101326.0AE5010079@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 12:13:23 2006 New Revision: 28504 Modified: pypy/dist/pypy/translator/cli/database.py Log: More refactoring around database.py. Now AbstractConsts stores their names themselves, instead of having LowLevelDatabase storing them. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Thu Jun 8 12:13:23 2006 @@ -25,8 +25,8 @@ self.classes = {} # classdef --> class_name self.functions = {} # graph --> function_name self.methods = {} # graph --> method_name - self.consts = {} # value --> AbstractConst, const_name - self.pending_consts = {} # value --> AbstractConst, const_name + self.consts = {} # value --> AbstractConst + self.pending_consts = {} # value --> AbstractConst self.delegates = {} # StaticMethod --> type_name self.const_names = set() self.name_count = 0 @@ -66,18 +66,14 @@ def record_const(self, value): if value in self.consts: - const, name = self.consts[value] + const = self.consts[value] elif value in self.pending_consts: - const, name = self.pending_consts[value] + const = self.pending_consts[value] else: - const = AbstractConst.make(self, value) - name = const.get_name() - if name in self.const_names: - name += '__%d' % self.next_count() - self.pending_consts[value] = const, name - self.const_names.add(name) + const = AbstractConst.make(self, value, self.next_count()) + self.pending_consts[value] = const - return '%s.%s::%s' % (CONST_NAMESPACE, CONST_CLASS, name) + return '%s.%s::%s' % (CONST_NAMESPACE, CONST_CLASS, const.name) def record_delegate_type(self, TYPE): try: @@ -131,14 +127,14 @@ self.pending_consts = {} # render field definitions - for const, name in pending_consts.itervalues(): - ilasm.field(name, const.get_type(), static=True) + for const in pending_consts.itervalues(): + ilasm.field(const.name, const.get_type(), static=True) ilasm.begin_function('step%d' % step, [], 'void', False, 'static') - for const, name in pending_consts.itervalues(): + for const in pending_consts.itervalues(): const.init(ilasm) type_ = const.get_type() - ilasm.set_static_field (type_, CONST_NAMESPACE, CONST_CLASS, name) + ilasm.set_static_field (type_, CONST_NAMESPACE, CONST_CLASS, const.name) ilasm.ret() ilasm.end_function() @@ -161,25 +157,25 @@ class AbstractConst(object): - def make(db, const): - if isinstance(const, ootype._view): - static_type = const._TYPE - const = const._inst + def make(db, value, count): + if isinstance(value, ootype._view): + static_type = value._TYPE + value = value._inst else: static_type = None - if isinstance(const, ootype._instance): - return InstanceConst(db, const, static_type) - elif isinstance(const, ootype._record): - return RecordConst(db, const) - elif isinstance(const, ootype._list): - return ListConst(db, const) - elif isinstance(const, ootype._string): - return StringConst(db, const) - elif isinstance(const, ootype._static_meth): - return StaticMethodConst(db, const) - elif isinstance(const, ootype._class): - return ClassConst(db, const) + if isinstance(value, ootype._instance): + return InstanceConst(db, value, static_type, count) + elif isinstance(value, ootype._record): + return RecordConst(db, value, count) + elif isinstance(value, ootype._list): + return ListConst(db, value, count) + elif isinstance(value, ootype._string): + return StringConst(db, value, count) + elif isinstance(value, ootype._static_meth): + return StaticMethodConst(db, value, count) + elif isinstance(value, ootype._class): + return ClassConst(db, value, count) else: assert False, 'Unknown constant: %s' % const make = staticmethod(make) @@ -214,10 +210,11 @@ pass class StringConst(AbstractConst): - def __init__(self, db, string): + def __init__(self, db, string, count): self.db = db self.cts = CTS(db) self.string = string + self.name = 'STRING_LITERAL__%d' % count def __hash__(self): return hash(self.string) @@ -225,9 +222,6 @@ def __eq__(self, other): return self.string == other.string - def get_name(self): - return 'string_literal' - def get_type(self, include_class=True): return self.cts.lltype_to_cts(ootype.String, include_class) @@ -235,10 +229,11 @@ ilasm.opcode('ldstr', '"%s"' % self.string._str) class RecordConst(AbstractConst): - def __init__(self, db, record): + def __init__(self, db, record, count): self.db = db self.cts = CTS(db) self.record = record + self.name = 'RECORD__%d' % count def __hash__(self): return hash(self.record) @@ -246,9 +241,6 @@ def __eq__(self, other): return self.record == other.record - def get_name(self): - return 'Record' - def get_type(self, include_class=True): return self.cts.lltype_to_cts(self.record._TYPE, include_class) @@ -263,10 +255,11 @@ ilasm.set_field((f_type, class_name, f_name)) class StaticMethodConst(AbstractConst): - def __init__(self, db, sm): + def __init__(self, db, sm, count): self.db = db self.cts = CTS(db) self.sm = sm + self.name = 'DELEGATE__%d' % count def __hash__(self): return hash(self.sm) @@ -274,9 +267,6 @@ def __eq__(self, other): return self.sm == other.sm - def get_name(self): - return 'Delegate' - def get_type(self, include_class=True): return self.cts.lltype_to_cts(self.sm._TYPE, include_class) @@ -292,10 +282,11 @@ ilasm.new('instance void class %s::.ctor(object, native int)' % delegate_type) class ClassConst(AbstractConst): - def __init__(self, db, class_): + def __init__(self, db, class_, count): self.db = db self.cts = CTS(db) self.class_ = class_ + self.name = 'CLASS__%d' % count def __hash__(self): return hash(self.class_) @@ -303,9 +294,6 @@ def __eq__(self, other): return self.class_ == other.class_ - def get_name(self): - return 'Class' - def get_type(self, include_class=True): return self.cts.lltype_to_cts(self.class_._TYPE, include_class) @@ -319,10 +307,11 @@ ilasm.call('class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)') class ListConst(AbstractConst): - def __init__(self, db, list_): + def __init__(self, db, list_, count): self.db = db self.cts = CTS(db) self.list = list_ + self.name = 'LIST__%d' % count def __hash__(self): return hash(self.list) @@ -330,9 +319,6 @@ def __eq__(self, other): return self.list == other.list - def get_name(self): - return 'List' - def get_type(self, include_class=True): return self.cts.lltype_to_cts(self.list._TYPE, include_class) @@ -361,8 +347,9 @@ meth = 'void class [pypylib]pypy.runtime.List`1<%s>::Add(%s)' % (itemtype, itemtype_T) ilasm.call_method(meth, False) + class InstanceConst(AbstractConst): - def __init__(self, db, obj, static_type): + def __init__(self, db, obj, static_type, count): self.db = db self.cts = CTS(db) self.obj = obj @@ -371,6 +358,8 @@ else: self.static_type = static_type self.cts.lltype_to_cts(obj._TYPE) # force scheduling of obj's class + class_name = obj._TYPE._name.replace('.', '_') + self.name = '%s__%d' % (class_name, count) def __hash__(self): return hash(self.obj) @@ -378,9 +367,6 @@ def __eq__(self, other): return self.obj == other.obj - def get_name(self): - return self.obj._TYPE._name.replace('.', '_') - def get_type(self): return self.cts.lltype_to_cts(self.static_type) @@ -401,3 +387,4 @@ AbstractConst.load(self.db, TYPE, value, ilasm) ilasm.opcode('stfld %s %s::%s' % (type_, classdef._name, name)) classdef = classdef._superclass + From mwh at codespeak.net Thu Jun 8 12:29:01 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Jun 2006 12:29:01 +0200 (CEST) Subject: [pypy-svn] r28506 - in pypy/dist/pypy/translator/stackless: . test Message-ID: <20060608102901.376B61007F@code0.codespeak.net> Author: mwh Date: Thu Jun 8 12:29:00 2006 New Revision: 28506 Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/transform.py Log: (mwh, pedronis) GAR! fix the bug in insert_unwind_handling again, in handle_resume_point. also, an exploding skipped test. Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Thu Jun 8 12:29:00 2006 @@ -222,3 +222,41 @@ res = run_stackless_function(example) assert res == 141 + +def test_finally(): + def f(x): + rstack.resume_point("rp1", x) + return 1/x + def in_finally(x): + rstack.resume_point("rp1.5", x) + return 2/x + def g(x): + r = y = 0 + r += f(x) + try: + y = f(x) + rstack.resume_point("rp0", x, r, returns=y) + finally: + r += in_finally(x) + return r + y + def example(): + return g(one()) + transform_stackless_function(example) + +def test_except(): + py.test.skip('in-progress') + def f(x): + rstack.resume_point("rp1", x) + return 1/x + def g(x): + r = y = 0 + r += f(x) + try: + y = f(x) + rstack.resume_point("rp0", x, r, returns=y) + except ZeroDivisionError: + r += f(x) + return r + y + def example(): + return g(one()) + transform_stackless_function(example) Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Thu Jun 8 12:29:00 2006 @@ -504,9 +504,11 @@ op = block.operations[i] if i == len(block.operations) - 1: link = block.exits[0] + nextblock = None else: link = support.split_block_with_keepalive(block, i+1) i = 0 + nextblock = link.target parms = op.args[1:] if not isinstance(parms[0], model.Variable): assert parms[0].value is None @@ -547,7 +549,7 @@ symb = SymbolicRestartNumber(label, restart_number) self.symbolic_restart_numbers[label] = symb - return link.target, i + return nextblock def handle_resume_state_create(self, block, i): op = block.operations[i] @@ -724,9 +726,13 @@ if (op.opname in ('direct_call', 'indirect_call') or self.analyzer.operation_is_true(op)): if op.opname == 'resume_point': - block, i = self.handle_resume_point(block, i) - continue - + block = self.handle_resume_point(block, i) + if block is None: + return + else: + i = 0 + continue + # trap calls to stackless-related suggested primitives if op.opname == 'direct_call': func = getattr(op.args[0].value._obj, '_callable', None) From mwh at codespeak.net Thu Jun 8 13:25:04 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Jun 2006 13:25:04 +0200 (CEST) Subject: [pypy-svn] r28507 - in pypy/dist/pypy: annotation rpython translator/c translator/c/test Message-ID: <20060608112504.9DF121007E@code0.codespeak.net> Author: mwh Date: Thu Jun 8 13:25:01 2006 New Revision: 28507 Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/rpython/raddress.py pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/primitive.py pypy/dist/pypy/translator/c/test/test_lladdresses.py Log: (mwh, pedronis) Support for non trivial constant weak addresses. Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Thu Jun 8 13:25:01 2006 @@ -368,7 +368,6 @@ elif isinstance(x, llmemory.fakeaddress): result = SomeAddress(is_null=not x) elif isinstance(x, llmemory.fakeweakaddress): - assert x.ref is None # only WEAKNULL allowed result = SomeWeakGcAddress() elif isinstance(x, ootype._static_meth): result = SomeOOStaticMeth(ootype.typeOf(x)) Modified: pypy/dist/pypy/rpython/raddress.py ============================================================================== --- pypy/dist/pypy/rpython/raddress.py (original) +++ pypy/dist/pypy/rpython/raddress.py Thu Jun 8 13:25:01 2006 @@ -17,7 +17,7 @@ class __extend__(annmodel.SomeWeakGcAddress): def rtyper_makerepr(self, rtyper): - return weakgcaddress_repr + return WeakGcAddressRepr(rtyper) def rtyper_makekey(self): return self.__class__, @@ -140,4 +140,20 @@ class WeakGcAddressRepr(Repr): lowleveltype = WeakGcAddress -weakgcaddress_repr = WeakGcAddressRepr() + def __init__(self, rtyper): + self.rtyper = rtyper + + def convert_const(self, value): + from pypy.rpython.lltypesystem import llmemory + from pypy.rpython.objectmodel import cast_object_to_weakgcaddress + from pypy.objspace.flow.model import Constant + assert isinstance(value, llmemory.fakeweakaddress) + if value.ref is None: + return value + ob = value.ref() + assert ob is not None + repr = self.rtyper.bindingrepr(Constant(ob)) + newob = repr.convert_const(ob) + return cast_object_to_weakgcaddress(newob) + +#weakgcaddress_repr = WeakGcAddressRepr() Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Thu Jun 8 13:25:01 2006 @@ -36,8 +36,11 @@ self.containerstats = {} self.externalfuncs = {} self.helper2ptr = {} - - self.infs = [] + + # late_initializations is for when the value you want to + # assign to a constant object is something C doesn't think is + # constant + self.late_initializations = [] self.namespace = CNameManager() if not standalone: self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator) Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Thu Jun 8 13:25:01 2006 @@ -527,7 +527,7 @@ # put float infinities in global constants, we should not have so many of them for now to make # a table+loop preferable - for dest, value in database.infs: + for dest, value in database.late_initializations: print >> f, "\t%s = %s;" % (dest, value) firsttime = True Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Thu Jun 8 13:25:01 2006 @@ -4,6 +4,7 @@ GcStruct, GcArray, ContainerType, \ parentlink, Ptr, PyObject, Void, OpaqueType, Float, \ RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray +from pypy.rpython.lltypesystem.llmemory import WeakGcAddress from pypy.translator.c.funcgen import FunctionCodeGenerator from pypy.translator.c.external import CExternalFunctionCodeGenerator from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring @@ -524,9 +525,12 @@ expr = 'NULL /*%s*/' % node.name node.where_to_copy_me.append('&%s' % access_expr) elif typeOf(value) == Float and isinf(value): - db.infs.append(('%s' % access_expr, db.get(value))) + db.late_initializations.append(('%s' % access_expr, db.get(value))) expr = '0.0 /* patched later by %sinfinity */' % ( '-+'[value > 0]) + elif typeOf(value) == WeakGcAddress and value.ref is not None: + db.late_initializations.append(('%s' % access_expr, db.get(value))) + expr = 'HIDE_POINTER(NULL) /* patched later */' else: expr = db.get(value) if typeOf(value) is Void: Modified: pypy/dist/pypy/translator/c/primitive.py ============================================================================== --- pypy/dist/pypy/translator/c/primitive.py (original) +++ pypy/dist/pypy/translator/c/primitive.py Thu Jun 8 13:25:01 2006 @@ -115,8 +115,12 @@ def name_weakgcaddress(value, db): assert isinstance(value, fakeweakaddress) - assert value.ref is None # only weak NULL supported - return 'HIDE_POINTER(NULL)' + if value.ref is None: + return 'HIDE_POINTER(NULL)' + else: + ob = value.ref() + assert ob is not None + return 'HIDE_POINTER(%s)'%db.get(ob) PrimitiveName = { Modified: pypy/dist/pypy/translator/c/test/test_lladdresses.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_lladdresses.py (original) +++ pypy/dist/pypy/translator/c/test/test_lladdresses.py Thu Jun 8 13:25:01 2006 @@ -137,3 +137,27 @@ return len(l1) == len(l2) fn = compile(func, [int]) assert fn(10) + +def test_constant_weakaddress(): + from pypy.rpython.objectmodel import cast_object_to_weakgcaddress + from pypy.rpython.objectmodel import cast_weakgcaddress_to_object + from pypy.rpython.lltypesystem.lloperation import llop + class A(object): + pass + constant_a = A() + constant_weak_a = cast_object_to_weakgcaddress(constant_a) + l = [constant_weak_a] + def func(i): + l1 = [] + l2 = [] + l3 = [] + l4 = [] + for i in range(i): + a = A() + l1.append(a) + l2.append(cast_object_to_weakgcaddress(a)) + l3.append(constant_a) + l4.extend(l) + return len(l1) == len(l2) == len(l3) == len(l4) + fn = compile(func, [int]) + assert fn(10) From ericvrp at codespeak.net Thu Jun 8 14:01:31 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 8 Jun 2006 14:01:31 +0200 (CEST) Subject: [pypy-svn] r28508 - pypy/dist/pypy/translator/js2/test Message-ID: <20060608120131.315901007D@code0.codespeak.net> Author: ericvrp Date: Thu Jun 8 14:01:30 2006 New Revision: 28508 Modified: pypy/dist/pypy/translator/js2/test/browsertest.py Log: some more detailed error messages Modified: pypy/dist/pypy/translator/js2/test/browsertest.py ============================================================================== --- pypy/dist/pypy/translator/js2/test/browsertest.py (original) +++ pypy/dist/pypy/translator/js2/test/browsertest.py Thu Jun 8 14:01:30 2006 @@ -83,7 +83,7 @@ def do_GET(self): global do_status if self.path != "/test.html": - self.send_error(404, "File not found") + self.send_error(404, "File /test.html not found") return jsfilename = jstest.jsfilename jstestcase = jstest.jstestcase @@ -97,7 +97,7 @@ html_page = open(self.server.html_page).read() % locals() except IOError: log("HTML FILE WAS NOT FOUND!!!!") - self.send_error(404, "File not found") + self.send_error(404, "File %s not found" % self.server.html_page) return else: html_page = config.html_page % locals() @@ -109,7 +109,7 @@ def do_POST(self): global do_status if self.path != "/test.html": - self.send_error(404, "File not found") + self.send_error(404, "File /test.html not found") return form = parse_qs(self.rfile.read(int(self.headers['content-length']))) if self.server.is_interactive: From antocuni at codespeak.net Thu Jun 8 15:04:28 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 15:04:28 +0200 (CEST) Subject: [pypy-svn] r28514 - in pypy/dist/pypy/translator/cli: . test Message-ID: <20060608130428.0A6A61008D@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 15:04:26 2006 New Revision: 28514 Modified: pypy/dist/pypy/translator/cli/class_.py pypy/dist/pypy/translator/cli/test/runtest.py pypy/dist/pypy/translator/cli/test/test_runtest.py Log: bugfix. Modified: pypy/dist/pypy/translator/cli/class_.py ============================================================================== --- pypy/dist/pypy/translator/cli/class_.py (original) +++ pypy/dist/pypy/translator/cli/class_.py Thu Jun 8 15:04:26 2006 @@ -83,7 +83,7 @@ def _toString(self): self.ilasm.begin_function('ToString', [], 'string', False, 'virtual', 'instance', 'default') self.ilasm.opcode('ldarg.0') - self.ilasm.call('string class [pypylib]pypy.test.Result::ToPython(object)') + self.ilasm.call('string class [pypylib]pypy.test.Result::InstanceToPython(object)') self.ilasm.ret() self.ilasm.end_function() Modified: pypy/dist/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/runtest.py (original) +++ pypy/dist/pypy/translator/cli/test/runtest.py Thu Jun 8 15:04:26 2006 @@ -34,12 +34,13 @@ assert res1 == res2 def format_object(TYPE, ilasm): - if isinstance(TYPE, (ootype.BuiltinType, ootype.Instance)) and TYPE is not ootype.String: - ilasm.call_method('string object::ToString()', virtual=True) - elif TYPE is ootype.Void: + if TYPE is ootype.Void: ilasm.opcode('ldstr "None"') else: - type_ = cts.lltype_to_cts(TYPE) + if isinstance(TYPE, (ootype.BuiltinType, ootype.Instance)) and TYPE is not ootype.String: + type_ = 'object' + else: + type_ = cts.lltype_to_cts(TYPE) ilasm.call('string class [pypylib]pypy.test.Result::ToPython(%s)' % type_) @@ -245,3 +246,6 @@ def is_of_instance_type(self, val): return isinstance(val, InstanceWrapper) + + def read_attr(self, obj, name): + py.test.skip('read_attr not supported on gencli tests') Modified: pypy/dist/pypy/translator/cli/test/test_runtest.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_runtest.py (original) +++ pypy/dist/pypy/translator/cli/test/test_runtest.py Thu Jun 8 15:04:26 2006 @@ -46,3 +46,11 @@ def fn(): raise IndexError self.interpret_raises(LookupError, fn, []) + + def test_object_or_none(self): + def fn(flag): + if flag: + return "hello"; + else: + return None + assert self.interpret(fn, [False]) is None From arigo at codespeak.net Thu Jun 8 15:24:51 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Jun 2006 15:24:51 +0200 (CEST) Subject: [pypy-svn] r28515 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/lltypesystem/test rpython/memory rpython/ootypesystem rpython/test translator/c Message-ID: <20060608132451.561D910078@code0.codespeak.net> Author: arigo Date: Thu Jun 8 15:24:47 2006 New Revision: 28515 Added: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py (contents, props changed) pypy/dist/pypy/rpython/rcpy.py (contents, props changed) Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/lltypesystem/rclass.py pypy/dist/pypy/rpython/memory/gctransform.py pypy/dist/pypy/rpython/memory/lltypelayout.py pypy/dist/pypy/rpython/normalizecalls.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rclass.py pypy/dist/pypy/rpython/rmodel.py pypy/dist/pypy/rpython/test/test_llinterp.py pypy/dist/pypy/rpython/test/test_nongc.py pypy/dist/pypy/rpython/test/test_rtyper.py pypy/dist/pypy/translator/c/funcgen.py Log: (arre, arigo) Added support for the 'cpy' gc flavor in rclass.py. This is used via the rcpy module for now; see test_rcpyclass.py. Includes a whole bunch of renaming of True/False flags into gckind-style flags. Note that now the check 'TYPE == Ptr(PyObject)' should mostly not be used any more! You need instead to check for TYPE._gckind == 'cpy'. Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Thu Jun 8 15:24:47 2006 @@ -299,6 +299,10 @@ raise TypeError("a PyStruct must have another PyStruct or " "PyObject as first field") +STRUCT_BY_FLAVOR = {'raw': Struct, + 'gc': GcStruct, + 'cpy': PyStruct} + class Array(ContainerType): _gckind = 'raw' __name__ = 'array' @@ -480,6 +484,13 @@ class GcForwardReference(ForwardReference): _gckind = 'gc' +class PyForwardReference(ForwardReference): + _gckind = 'cpy' + +FORWARDREF_BY_FLAVOR = {'raw': ForwardReference, + 'gc': GcForwardReference, + 'cpy': PyForwardReference} + class Primitive(LowLevelType): def __init__(self, name, default): Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Thu Jun 8 15:24:47 2006 @@ -10,12 +10,12 @@ getclassrepr, getinstancerepr,\ get_type_repr, rtype_new_instance from pypy.rpython.lltypesystem.lltype import \ - ForwardReference, GcForwardReference, \ Ptr, Struct, GcStruct, malloc, \ cast_pointer, castable, nullptr, \ RuntimeTypeInfo, getRuntimeTypeInfo, typeOf, \ Array, Char, Void, attachRuntimeTypeInfo, \ FuncType, Bool, Signed, functionptr, FuncType, PyObject +from pypy.rpython.lltypesystem import lltype from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.extregistry import ExtRegistryEntry from pypy.annotation import model as annmodel @@ -55,7 +55,7 @@ # # there's also a nongcobject -OBJECT_VTABLE = ForwardReference() +OBJECT_VTABLE = lltype.ForwardReference() CLASSTYPE = Ptr(OBJECT_VTABLE) OBJECT = GcStruct('object', ('typeptr', CLASSTYPE)) OBJECTPTR = Ptr(OBJECT) @@ -71,6 +71,16 @@ NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE)) NONGCOBJECTPTR = Ptr(OBJECT) +# cpy case (XXX try to merge the typeptr with the ob_type) +CPYOBJECT = lltype.PyStruct('cpyobject', ('head', PyObject), + ('typeptr', CLASSTYPE)) +CPYOBJECTPTR = Ptr(CPYOBJECT) + +OBJECT_BY_FLAVOR = {'gc': OBJECT, + 'raw': NONGCOBJECT, + 'cpy': CPYOBJECT} + + def cast_vtable_to_typeptr(vtable): while typeOf(vtable).TO != OBJECT_VTABLE: vtable = vtable.super @@ -84,7 +94,7 @@ # 'object' root type self.vtable_type = OBJECT_VTABLE else: - self.vtable_type = ForwardReference() + self.vtable_type = lltype.ForwardReference() self.lowleveltype = Ptr(self.vtable_type) def _setup_repr(self): @@ -173,7 +183,7 @@ vtable.subclassrange_max = sys.maxint rinstance = getinstancerepr(self.rtyper, rsubcls.classdef) rinstance.setup() - if rinstance.needsgc: # only gc-case + if rinstance.gcflavor == 'gc': # only gc-case vtable.rtti = getRuntimeTypeInfo(rinstance.object_type) if rsubcls.classdef is None: name = 'object' @@ -285,22 +295,17 @@ class InstanceRepr(AbstractInstanceRepr): - def __init__(self, rtyper, classdef, does_need_gc=True): + def __init__(self, rtyper, classdef, gcflavor='gc'): AbstractInstanceRepr.__init__(self, rtyper, classdef) if classdef is None: - if does_need_gc: - self.object_type = OBJECT - else: - self.object_type = NONGCOBJECT + self.object_type = OBJECT_BY_FLAVOR[gcflavor] else: - if does_need_gc: - self.object_type = GcForwardReference() - else: - self.object_type = ForwardReference() + ForwardRef = lltype.FORWARDREF_BY_FLAVOR[gcflavor] + self.object_type = ForwardRef() self.prebuiltinstances = {} # { id(x): (x, _ptr) } self.lowleveltype = Ptr(self.object_type) - self.needsgc = does_need_gc + self.gcflavor = gcflavor def _setup_repr(self): # NOTE: don't store mutable objects like the dicts below on 'self' @@ -330,7 +335,8 @@ fields['_hash_cache_'] = 'hash_cache', rint.signed_repr llfields.append(('hash_cache', Signed)) - self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, not self.needsgc) + self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, + self.gcflavor) self.rbase.setup() # # PyObject wrapper support @@ -338,11 +344,7 @@ fields['_wrapper_'] = 'wrapper', pyobj_repr llfields.append(('wrapper', Ptr(PyObject))) - if self.needsgc: - MkStruct = GcStruct - else: - MkStruct = Struct - + MkStruct = lltype.STRUCT_BY_FLAVOR[self.gcflavor] object_type = MkStruct(self.classdef.name, ('super', self.rbase.object_type), *llfields) @@ -351,11 +353,11 @@ allinstancefields.update(fields) self.fields = fields self.allinstancefields = allinstancefields - if self.needsgc: # only gc-case + if self.gcflavor == 'gc': # only gc-case attachRuntimeTypeInfo(self.object_type) def _setup_repr_final(self): - if self.needsgc: # only gc-case + if self.gcflavor == 'gc': # only gc-case if (self.classdef is not None and self.classdef.classdesc.lookup('__del__') is not None): s_func = self.classdef.classdesc.s_read_attribute('__del__') @@ -375,10 +377,7 @@ ll_runtime_type_info, OBJECT, destrptr) def common_repr(self): # -> object or nongcobject reprs - return getinstancerepr(self.rtyper, None, nogc=not self.needsgc) - - def getflavor(self): - return self.classdef.classdesc.read_attribute('_alloc_flavor_', Constant('gc')).value + return getinstancerepr(self.rtyper, None, self.gcflavor) def null_instance(self): return nullptr(self.object_type) @@ -387,7 +386,7 @@ return cast_pointer(self.lowleveltype, result) def create_instance(self): - return malloc(self.object_type, flavor=self.getflavor()) # pick flavor + return malloc(self.object_type, flavor=self.gcflavor) def has_wrapper(self): return self.classdef is not None and ( @@ -481,12 +480,16 @@ ctype = inputconst(Void, self.object_type) vlist = [ctype] if self.classdef is not None: - flavor = self.getflavor() - if flavor != 'gc': # not defalut flavor + flavor = self.gcflavor + if flavor != 'gc': # not default flavor mallocop = 'flavored_malloc' - vlist = [inputconst(Void, flavor)] + vlist + vlist.insert(0, inputconst(Void, flavor)) + if flavor == 'cpy': + cpytype = self.classdef._cpy_exported_type_ + c = inputconst(Ptr(PyObject), lltype.pyobjectptr(cpytype)) + vlist.append(c) vptr = llops.genop(mallocop, vlist, - resulttype = Ptr(self.object_type)) # xxx flavor + resulttype = Ptr(self.object_type)) ctypeptr = inputconst(CLASSTYPE, self.rclass.getvtable()) self.setfield(vptr, '__class__', ctypeptr, llops) # initialize instance attributes from their defaults from the class @@ -575,7 +578,7 @@ return hop.gendirectcall(ll_isinstance, v_obj, v_cls) -def buildinstancerepr(rtyper, classdef, does_need_gc=True): +def buildinstancerepr(rtyper, classdef, gcflavor='gc'): if classdef is None: unboxed = [] else: @@ -583,14 +586,14 @@ if subdef.classdesc.pyobj is not None and issubclass(subdef.classdesc.pyobj, UnboxedValue)] if len(unboxed) == 0: - return InstanceRepr(rtyper, classdef, does_need_gc) + return InstanceRepr(rtyper, classdef, gcflavor) else: # the UnboxedValue class and its parent classes need a # special repr for their instances if len(unboxed) != 1: raise TyperError("%r has several UnboxedValue subclasses" % ( classdef,)) - assert does_need_gc + assert gcflavor == 'gc' from pypy.rpython.lltypesystem import rtagged return rtagged.TaggedInstanceRepr(rtyper, classdef, unboxed[0]) @@ -618,16 +621,15 @@ return NotImplemented def rtype_is_((r_ins1, r_ins2), hop): - if r_ins1.needsgc != r_ins2.needsgc: + if r_ins1.gcflavor != r_ins2.gcflavor: # obscure logic, the is can be true only if both are None v_ins1, v_ins2 = hop.inputargs(r_ins1.common_repr(), r_ins2.common_repr()) return hop.gendirectcall(ll_both_none, v_ins1, v_ins2) - nogc = not (r_ins1.needsgc and r_ins2.needsgc) if r_ins1.classdef is None or r_ins2.classdef is None: basedef = None else: basedef = r_ins1.classdef.commonbase(r_ins2.classdef) - r_ins = getinstancerepr(r_ins1.rtyper, basedef, nogc=nogc) + r_ins = getinstancerepr(r_ins1.rtyper, basedef, r_ins1.gcflavor) return pairtype(Repr, Repr).rtype_is_(pair(r_ins, r_ins), hop) rtype_eq = rtype_is_ Added: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py Thu Jun 8 15:24:47 2006 @@ -0,0 +1,24 @@ +from pypy.translator.c.test.test_genc import compile +from pypy.rpython.rcpy import cpy_export + + +class W_MyTest(object): + + def __init__(self, x): + self.x = x + + def double(self): + return self.x * 2 + + +def test_cpy_export(): + class mytest(object): + pass + + def f(): + w = W_MyTest(21) + return cpy_export(w, mytest) + + fn = compile(f, []) + res = fn() + assert type(res).__name__.endswith('mytest') Modified: pypy/dist/pypy/rpython/memory/gctransform.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform.py (original) +++ pypy/dist/pypy/rpython/memory/gctransform.py Thu Jun 8 15:24:47 2006 @@ -23,13 +23,15 @@ def var_ispyobj(var): if hasattr(var, 'concretetype'): if isinstance(var.concretetype, lltype.Ptr): - return var.concretetype.TO is lltype.PyObject + return var.concretetype.TO._gckind == 'cpy' else: return False else: # assume PyObjPtr return True - + +PyObjPtr = lltype.Ptr(lltype.PyObject) + class GCTransformer(object): finished_helpers = False @@ -154,8 +156,9 @@ op = ops[index] if var_needsgc(op.result): if var_ispyobj(op.result): - assert op.opname != 'cast_pointer', 'casting to a PyObject*??' - if op.opname in ('getfield', 'getarrayitem', 'same_as'): + if op.opname in ('getfield', 'getarrayitem', 'same_as', + 'cast_pointer', 'getsubstruct'): + # XXX more operations? lst = list(self.push_alive(op.result)) newops.extend(lst) elif op.opname not in ('direct_call', 'indirect_call'): @@ -211,7 +214,13 @@ def push_alive_pyobj(self, var): result = varoftype(lltype.Void) - return [SpaceOperation("gc_push_alive_pyobj", [var], result)] + lst = [] + if hasattr(var, 'concretetype') and var.concretetype != PyObjPtr: + res = varoftype(PyObjPtr) + lst.append(SpaceOperation("cast_pointer", [var], res)) + var = res + lst.append(SpaceOperation("gc_push_alive_pyobj", [var], result)) + return lst def pop_alive(self, var): if var_ispyobj(var): @@ -225,7 +234,13 @@ def pop_alive_pyobj(self, var): result = varoftype(lltype.Void) - return [SpaceOperation("gc_pop_alive_pyobj", [var], result)] + lst = [] + if hasattr(var, 'concretetype') and var.concretetype != PyObjPtr: + res = varoftype(PyObjPtr) + lst.append(SpaceOperation("cast_pointer", [var], res)) + var = res + lst.append(SpaceOperation("gc_pop_alive_pyobj", [var], result)) + return lst def replace_gc_protect(self, op, livevars, block): """ protect this object from gc (make it immortal). the specific @@ -653,7 +668,7 @@ if type_contains_pyobjs(TYPE._flds[name]): return True return False - elif isinstance(TYPE, lltype.Ptr) and TYPE.TO == lltype.PyObject: + elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'cpy': return True else: return False @@ -722,7 +737,7 @@ t = lltype.typeOf(v) if isinstance(t, lltype.Struct): for n, t2 in t._flds.iteritems(): - if isinstance(t2, lltype.Ptr) and t2._needsgc() and t2.TO != lltype.PyObject: + if isinstance(t2, lltype.Ptr) and t2.TO._gckind == 'gc': yield adr + llmemory.offsetof(t, n) elif isinstance(t2, (lltype.Array, lltype.Struct)): for a in gc_pointers_inside(getattr(v, n), adr + llmemory.offsetof(t, n)): @@ -1068,7 +1083,7 @@ adr = llmemory.cast_ptr_to_adr(hdr) self.gcdata.gc.init_gc_object(adr, typeid) - if TYPE != lltype.PyObject and find_gc_ptrs_in_type(TYPE): + if find_gc_ptrs_in_type(TYPE): adr = llmemory.cast_ptr_to_adr(value._as_ptr()) if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)): self.static_gc_roots.append(adr) @@ -1292,8 +1307,7 @@ #adr = llmemory.cast_ptr_to_adr(ex) #for off in offsets: # (adr + off) - elif (isinstance(TYPE, lltype.Ptr) and TYPE._needsgc() and - TYPE.TO is not lltype.PyObject): + elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc': offsets.append(0) return offsets Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypelayout.py (original) +++ pypy/dist/pypy/rpython/memory/lltypelayout.py Thu Jun 8 15:24:47 2006 @@ -115,8 +115,7 @@ offsets = [] for name in TYPE._names: FIELD = getattr(TYPE, name) - if (isinstance(FIELD, lltype.Ptr) and FIELD._needsgc() and - FIELD.TO is not lltype.PyObject): + if isinstance(FIELD, lltype.Ptr) and FIELD.TO._gckind == 'gc': offsets.append(llmemory.offsetof(TYPE, name)) elif isinstance(FIELD, lltype.Struct): suboffsets = offsets_to_gc_pointers(FIELD) Modified: pypy/dist/pypy/rpython/normalizecalls.py ============================================================================== --- pypy/dist/pypy/rpython/normalizecalls.py (original) +++ pypy/dist/pypy/rpython/normalizecalls.py Thu Jun 8 15:24:47 2006 @@ -8,7 +8,7 @@ from pypy.tool.sourcetools import has_varargs, valid_identifier from pypy.tool.sourcetools import func_with_new_name from pypy.rpython.error import TyperError -from pypy.rpython.rmodel import needsgc +from pypy.rpython.rmodel import getgcflavor from pypy.rpython.objectmodel import instantiate, ComputedIntSymbolic def normalize_call_familes(annotator): @@ -246,7 +246,7 @@ needs_generic_instantiate = annotator.bookkeeper.needs_generic_instantiate for classdef in needs_generic_instantiate: - assert needsgc(classdef) # only gc-case + assert getgcflavor(classdef) == 'gc' # only gc-case create_instantiate_function(annotator, classdef) def create_instantiate_function(annotator, classdef): Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Thu Jun 8 15:24:47 2006 @@ -148,7 +148,7 @@ return mangled[1:] class InstanceRepr(AbstractInstanceRepr): - def __init__(self, rtyper, classdef, does_need_gc=True): + def __init__(self, rtyper, classdef, gcflavor='ignored'): AbstractInstanceRepr.__init__(self, rtyper, classdef) self.baserepr = None @@ -237,7 +237,7 @@ ootype.addFields(self.lowleveltype, fields) - self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, True) + self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef) self.rbase.setup() methods = {} Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Thu Jun 8 15:24:47 2006 @@ -539,7 +539,7 @@ def rtype_free_non_gc_object(hop): vinst, = hop.inputargs(hop.args_r[0]) - flavor = hop.args_r[0].getflavor() + flavor = hop.args_r[0].gcflavor assert not flavor.startswith('gc') cflavor = hop.inputconst(lltype.Void, flavor) return hop.genop('flavored_free', [cflavor, vinst]) Modified: pypy/dist/pypy/rpython/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/rclass.py (original) +++ pypy/dist/pypy/rpython/rclass.py Thu Jun 8 15:24:47 2006 @@ -3,7 +3,7 @@ #from pypy.annotation.classdef import isclassdef from pypy.annotation import description from pypy.rpython.error import TyperError -from pypy.rpython.rmodel import Repr, needsgc +from pypy.rpython.rmodel import Repr, getgcflavor def getclassrepr(rtyper, classdef): try: @@ -24,19 +24,18 @@ rtyper.add_pendingsetup(result) return result -def getinstancerepr(rtyper, classdef, nogc=False): - does_need_gc = needsgc(classdef, nogc) +def getinstancerepr(rtyper, classdef, default_flavor='gc'): + if classdef is None: + flavor = default_flavor + else: + flavor = getgcflavor(classdef) try: - result = rtyper.instance_reprs[classdef, does_need_gc] + result = rtyper.instance_reprs[classdef, flavor] except KeyError: - #if classdef and classdef.cls is Exception: - # # see getclassrepr() - # result = getinstancerepr(rtyper, None, nogc=False) - #else: result = rtyper.type_system.rclass.buildinstancerepr( - rtyper, classdef, does_need_gc=does_need_gc) + rtyper, classdef, gcflavor=flavor) - rtyper.instance_reprs[classdef, does_need_gc] = result + rtyper.instance_reprs[classdef, flavor] = result rtyper.add_pendingsetup(result) return result Added: pypy/dist/pypy/rpython/rcpy.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/rcpy.py Thu Jun 8 15:24:47 2006 @@ -0,0 +1,30 @@ +from pypy.rpython.extregistry import ExtRegistryEntry + + +def cpy_export(obj, cpytype): + raise NotImplementedError("only works in translated versions") + + +class Entry(ExtRegistryEntry): + _about_ = cpy_export + + def compute_result_annotation(self, s_obj, s_cpytype): + from pypy.annotation.model import SomeObject + from pypy.annotation.model import SomeInstance + assert isinstance(s_obj, SomeInstance) + assert s_cpytype.is_constant() + cpytype = s_cpytype.const + if hasattr(s_obj.classdef, '_cpy_exported_type_'): + assert s_obj.classdef._cpy_exported_type_ == cpytype + else: + s_obj.classdef._cpy_exported_type_ = cpytype + s = SomeObject() + s.knowntype = cpytype + return s + + def specialize_call(self, hop): + from pypy.rpython.lltypesystem import lltype + r_inst = hop.args_r[0] + v_inst = hop.inputarg(r_inst, arg=0) + return hop.genop('cast_pointer', [v_inst], + resulttype = lltype.Ptr(lltype.PyObject)) Modified: pypy/dist/pypy/rpython/rmodel.py ============================================================================== --- pypy/dist/pypy/rpython/rmodel.py (original) +++ pypy/dist/pypy/rpython/rmodel.py Thu Jun 8 15:24:47 2006 @@ -421,14 +421,14 @@ # __________ utilities __________ PyObjPtr = Ptr(PyObject) -def needsgc(classdef, nogc=False): - if classdef is None: - return not nogc +def getgcflavor(classdef): + if hasattr(classdef, '_cpy_exported_type_'): + return 'cpy' else: classdesc = classdef.classdesc alloc_flavor = classdesc.read_attribute('_alloc_flavor_', Constant('gc')).value - return alloc_flavor.startswith('gc') + return alloc_flavor def externalvsinternal(rtyper, item_repr): # -> external_item_repr, (internal_)item_repr from pypy.rpython import rclass Modified: pypy/dist/pypy/rpython/test/test_llinterp.py ============================================================================== Modified: pypy/dist/pypy/rpython/test/test_nongc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_nongc.py (original) +++ pypy/dist/pypy/rpython/test/test_nongc.py Thu Jun 8 15:24:47 2006 @@ -39,8 +39,8 @@ assert s.knowntype == Adef rtyper = RPythonTyper(a) rtyper.specialize() - assert (Adef, False) in rtyper.instance_reprs - assert (Adef, True) not in rtyper.instance_reprs + assert (Adef, 'raw') in rtyper.instance_reprs + assert (Adef, 'gc') not in rtyper.instance_reprs def test_alloc_flavor_subclassing(): class A: @@ -58,10 +58,10 @@ assert s.knowntype == Bdef rtyper = RPythonTyper(a) rtyper.specialize() - assert (Adef, False) in rtyper.instance_reprs - assert (Adef, True) not in rtyper.instance_reprs - assert (Bdef, False) in rtyper.instance_reprs - assert (Bdef, True) not in rtyper.instance_reprs + assert (Adef, 'raw') in rtyper.instance_reprs + assert (Adef, 'gc') not in rtyper.instance_reprs + assert (Bdef, 'raw') in rtyper.instance_reprs + assert (Bdef, 'gc') not in rtyper.instance_reprs def test_unsupported(): class A: Modified: pypy/dist/pypy/rpython/test/test_rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rtyper.py (original) +++ pypy/dist/pypy/rpython/test/test_rtyper.py Thu Jun 8 15:24:47 2006 @@ -113,13 +113,13 @@ assert [vT.concretetype for vT in vTs] == [Void] * 3 -def test_needsgc(): +def test_getgcflavor(): class A: pass class B: _alloc_flavor_ = "gc" class R: - _alloc_flavor_ = "nongc" + _alloc_flavor_ = "raw" NDF = object() @@ -137,16 +137,9 @@ else: return default - assert rmodel.needsgc(DummyClsDescDef(A)) - assert rmodel.needsgc(DummyClsDescDef(A), nogc=True) - assert rmodel.needsgc(DummyClsDescDef(B)) - assert rmodel.needsgc(DummyClsDescDef(B), nogc=True) - assert not rmodel.needsgc(DummyClsDescDef(R)) - assert not rmodel.needsgc(DummyClsDescDef(R), nogc=False) - assert rmodel.needsgc(None) - assert rmodel.needsgc(None, nogc=False) - assert not rmodel.needsgc(None, nogc=True) - - - - + assert rmodel.getgcflavor(DummyClsDescDef(A)) == 'gc' + assert rmodel.getgcflavor(DummyClsDescDef(B)) == 'gc' + assert rmodel.getgcflavor(DummyClsDescDef(R)) == 'raw' + cdef = DummyClsDescDef(A) + cdef._cpy_exported_type_ = type(Ellipsis) + assert rmodel.getgcflavor(cdef) == 'cpy' Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Thu Jun 8 15:24:47 2006 @@ -559,7 +559,11 @@ if flavor == "raw": return "OP_RAW_MALLOC(%s, %s);" % (esize, eresult) elif flavor == "stack": - return "OP_STACK_MALLOC(%s, %s);" % (esize, eresult) + return "OP_STACK_MALLOC(%s, %s);" % (esize, eresult) + elif flavor == "cpy": + cpytype = self.expr(op.args[2]) + return "%s = PyObject_New(%s, (PyTypeObject *)%s);" % ( + eresult, cdecl(typename, ''), cpytype) else: raise NotImplementedError @@ -593,7 +597,6 @@ result.append('%s = (%s)%s;' % (self.expr(op.result), cdecl(typename, ''), self.expr(op.args[0]))) - assert TYPE != PyObjPtr return '\t'.join(result) OP_CAST_PTR_TO_ADR = OP_CAST_POINTER From mwh at codespeak.net Thu Jun 8 15:28:13 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Jun 2006 15:28:13 +0200 (CEST) Subject: [pypy-svn] r28516 - pypy/dist/pypy/interpreter Message-ID: <20060608132813.596CE10078@code0.codespeak.net> Author: mwh Date: Thu Jun 8 15:28:12 2006 New Revision: 28516 Modified: pypy/dist/pypy/interpreter/pyframe.py Log: (mwh, pedronis) dispatch_translated always exits via an exception, so put the resume_point just after it inside a finally clause Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Thu Jun 8 15:28:12 2006 @@ -198,8 +198,10 @@ try: try: if we_are_translated(): - self.dispatch_translated(executioncontext) - rstack.resume_point("eval", self) + try: + self.dispatch_translated(executioncontext) + finally: + rstack.resume_point("eval", self) else: self.dispatch(executioncontext) # catch asynchronous exceptions and turn them From mwh at codespeak.net Thu Jun 8 15:34:15 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Jun 2006 15:34:15 +0200 (CEST) Subject: [pypy-svn] r28518 - in pypy/dist/pypy: interpreter objspace/std tool Message-ID: <20060608133415.58AF910078@code0.codespeak.net> Author: mwh Date: Thu Jun 8 15:34:13 2006 New Revision: 28518 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/stdtypedef.py pypy/dist/pypy/objspace/std/typeobject.py pypy/dist/pypy/objspace/std/typetype.py pypy/dist/pypy/tool/cache.py Log: (mwh, pedronis) issue204 in-progress implement __subclasses__(). required a small extension of tool/cache, and a way of building a very simple weakref that has a chance of working "early". W_TypeObjects now need to have their .ready() called "at some point" -- apart from during space setup, just after __init__ will do. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Thu Jun 8 15:34:13 2006 @@ -111,6 +111,15 @@ return self.build(key) finally: self.space.leave_cache_building_mode(val) + def _ready(self, result): + val = self.space.enter_cache_building_mode() + try: + return self.ready(result) + finally: + self.space.leave_cache_building_mode(val) + def ready(self, result): + pass + class ObjSpaceOptions: def _freeze_(self): Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Thu Jun 8 15:34:13 2006 @@ -211,6 +211,7 @@ if not bases: bases = [space.w_object] res = W_TypeObject(space, name, bases, dic) + res.ready() return res try: # note that we hide the real call method by an instance variable! Modified: pypy/dist/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/dist/pypy/objspace/std/stdtypedef.py (original) +++ pypy/dist/pypy/objspace/std/stdtypedef.py Thu Jun 8 15:34:13 2006 @@ -91,6 +91,9 @@ w_type.lazyloaders = lazyloaders return w_type + def ready(self, w_type): + w_type.ready() + def hack_out_multimethods(ns): "NOT_RPYTHON: initialization-time only." result = [] Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Thu Jun 8 15:34:13 2006 @@ -53,6 +53,7 @@ w_self.nslots = 0 w_self.needsdel = False w_self.w_bestbase = None + w_self.weak_subclasses_w = [] # make sure there is a __doc__ in dict_w if '__doc__' not in dict_w: @@ -207,6 +208,12 @@ return w_self.mro_w = w_self.compute_mro() + def ready(w_self): + for w_base in w_self.bases_w: + if not isinstance(w_base, W_TypeObject): + continue + w_base.add_subclass(w_self) + # compute the most parent class with the same layout as us def get_layout(w_self): w_bestbase = w_self.w_bestbase @@ -315,6 +322,20 @@ else: return space.wrap('__builtin__') + def add_subclass(w_self, w_subclass): + space = w_self.space + from pypy.module._weakref.interp__weakref import basic_weakref + w_newref = basic_weakref(space, w_subclass) + + for i in range(len(w_self.weak_subclasses_w)): + w_ref = w_self.weak_subclasses_w[i] + ob = space.call_function(w_ref) + if space.is_w(ob, space.w_None): + w_self.weak_subclasses_w[i] = w_newref + return + else: + w_self.weak_subclasses_w.append(w_newref) + # for now, weakref support for W_TypeObject is hard to get automatically _lifeline_ = None def getweakref(self): Modified: pypy/dist/pypy/objspace/std/typetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/typetype.py (original) +++ pypy/dist/pypy/objspace/std/typetype.py Thu Jun 8 15:34:13 2006 @@ -44,6 +44,7 @@ w_type = space.allocate_instance(W_TypeObject, w_typetype) W_TypeObject.__init__(w_type, space, name, bases_w or [space.w_object], dict_w) + w_type.ready() return w_type def _precheck_for_new(space, w_type): @@ -138,6 +139,15 @@ w_type.name)) w_type.dict_w['__module__'] = w_value +def descr___subclasses__(space, w_type): + w_type = _check(space, w_type) + subclasses_w = [] + for w_ref in w_type.weak_subclasses_w: + w_ob = space.call_function(w_ref) + if not space.is_w(w_ob, space.w_None): + subclasses_w.append(w_ob) + return space.newlist(subclasses_w) + # ____________________________________________________________ type_typedef = StdTypeDef("type", @@ -151,5 +161,6 @@ mro = gateway.interp2app(descr_mro), __flags__ = GetSetProperty(descr__flags), __module__ = GetSetProperty(descr_get__module, descr_set__module), + __subclasses__ = gateway.interp2app(descr___subclasses__), __weakref__ = weakref_descr, ) Modified: pypy/dist/pypy/tool/cache.py ============================================================================== --- pypy/dist/pypy/tool/cache.py (original) +++ pypy/dist/pypy/tool/cache.py Thu Jun 8 15:34:13 2006 @@ -36,9 +36,13 @@ except KeyError: result = self._build(key) self.content[key] = result + self._ready(result) return result getorbuild._annspecialcase_ = "specialize:memo" + def _ready(self, result): + pass + def _freeze_(self): # needs to be SomePBC, but otherwise we can't really freeze the # cache because more getorbuild() calls might be discovered later From antocuni at codespeak.net Thu Jun 8 15:36:51 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 15:36:51 +0200 (CEST) Subject: [pypy-svn] r28520 - pypy/dist/pypy/translator/cli Message-ID: <20060608133651.7E7A110097@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 15:36:49 2006 New Revision: 28520 Modified: pypy/dist/pypy/translator/cli/database.py Log: bugfix. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Thu Jun 8 15:36:49 2006 @@ -226,7 +226,10 @@ return self.cts.lltype_to_cts(ootype.String, include_class) def init(self, ilasm): - ilasm.opcode('ldstr', '"%s"' % self.string._str) + if self.string._str is None: + ilasm.opcode('ldnull') + else: + ilasm.opcode('ldstr', '"%s"' % self.string._str) class RecordConst(AbstractConst): def __init__(self, db, record, count): From antocuni at codespeak.net Thu Jun 8 15:37:26 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 15:37:26 +0200 (CEST) Subject: [pypy-svn] r28521 - pypy/dist/pypy/translator/cli Message-ID: <20060608133726.11C5910097@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 15:37:26 2006 New Revision: 28521 Modified: pypy/dist/pypy/translator/cli/cts.py pypy/dist/pypy/translator/cli/function.py Log: bugfix. Modified: pypy/dist/pypy/translator/cli/cts.py ============================================================================== --- pypy/dist/pypy/translator/cli/cts.py (original) +++ pypy/dist/pypy/translator/cli/cts.py Thu Jun 8 15:37:26 2006 @@ -60,6 +60,8 @@ assert False, error class CTS(object): + ILASM_KEYWORDS = ['call'] + def __init__(self, db): self.db = db @@ -69,6 +71,13 @@ else: return result + def escape_name(self, name): + """Mangle then name if it's a ilasm reserved word""" + if name in self.ILASM_KEYWORDS: + return name + '__MANGLED' # XXX: it could not be unique + else: + return name + def lltype_to_cts(self, t, include_class=True): if isinstance(t, ootype.Instance): self.db.pending_class(t) @@ -106,6 +115,7 @@ def graph_to_signature(self, graph, is_method = False, func_name = None): ret_type, ret_var = self.llvar_to_cts(graph.getreturnvar()) func_name = func_name or graph.name + func_name = self.escape_name(func_name) args = [arg for arg in graph.getargs() if arg.concretetype is not ootype.Void] if is_method: Modified: pypy/dist/pypy/translator/cli/function.py ============================================================================== --- pypy/dist/pypy/translator/cli/function.py (original) +++ pypy/dist/pypy/translator/cli/function.py Thu Jun 8 15:37:26 2006 @@ -24,7 +24,7 @@ self.db = db self.cts = CTS(db) self.graph = graph - self.name = name or graph.name + self.name = self.cts.escape_name(name or graph.name) self.is_method = is_method self.is_entrypoint = is_entrypoint self.blocknum = {} From antocuni at codespeak.net Thu Jun 8 15:46:35 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 15:46:35 +0200 (CEST) Subject: [pypy-svn] r28522 - pypy/dist/pypy/translator/cli Message-ID: <20060608134635.96EDB1009C@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 15:46:34 2006 New Revision: 28522 Modified: pypy/dist/pypy/translator/cli/class_.py pypy/dist/pypy/translator/cli/cts.py pypy/dist/pypy/translator/cli/function.py Log: Escape field names, too. Modified: pypy/dist/pypy/translator/cli/class_.py ============================================================================== --- pypy/dist/pypy/translator/cli/class_.py (original) +++ pypy/dist/pypy/translator/cli/class_.py Thu Jun 8 15:46:34 2006 @@ -45,6 +45,7 @@ ilasm.begin_class(self.name, self.get_base_class()) for f_name, (f_type, f_default) in self.classdef._fields.iteritems(): cts_type = self.cts.lltype_to_cts(f_type) + f_name = self.cts.escape_name(f_name) if cts_type != 'void': ilasm.field(f_name, cts_type) @@ -72,6 +73,7 @@ # set default values for fields for f_name, (F_TYPE, f_default) in self.classdef._fields.iteritems(): cts_type = self.cts.lltype_to_cts(F_TYPE) + f_name = self.cts.escape_name(f_name) if cts_type != 'void': self.ilasm.opcode('ldarg.0') AbstractConst.load(self.db, F_TYPE, f_default, self.ilasm) Modified: pypy/dist/pypy/translator/cli/cts.py ============================================================================== --- pypy/dist/pypy/translator/cli/cts.py (original) +++ pypy/dist/pypy/translator/cli/cts.py Thu Jun 8 15:46:34 2006 @@ -60,7 +60,7 @@ assert False, error class CTS(object): - ILASM_KEYWORDS = ['call'] + ILASM_KEYWORDS = ['call', 'on'] def __init__(self, db): self.db = db Modified: pypy/dist/pypy/translator/cli/function.py ============================================================================== --- pypy/dist/pypy/translator/cli/function.py (original) +++ pypy/dist/pypy/translator/cli/function.py Thu Jun 8 15:46:34 2006 @@ -242,6 +242,7 @@ class_name = self.class_name(class_) field_type = self.cts.lltype_to_cts(type_) + field = self.cts.escape_name(field) return '%s %s::%s' % (field_type, class_name, field) # following methods belongs to the Generator interface From mwh at codespeak.net Thu Jun 8 15:46:51 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Jun 2006 15:46:51 +0200 (CEST) Subject: [pypy-svn] r28523 - pypy/dist/pypy/rpython Message-ID: <20060608134651.952F91009C@code0.codespeak.net> Author: mwh Date: Thu Jun 8 15:46:50 2006 New Revision: 28523 Modified: pypy/dist/pypy/rpython/objectmodel.py Log: (mwh, pedronis) *cough*cough*cough* fix references to raddress.weakgcadress_repr Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Thu Jun 8 15:46:50 2006 @@ -105,7 +105,7 @@ def specialize_call(self, hop): from pypy.rpython import raddress assert isinstance(hop.args_r[0], raddress.WeakGcAddressRepr) - vlist = [hop.inputarg(raddress.weakgcaddress_repr, arg=0)] + vlist = [hop.inputarg(hop.args_r[0], arg=0)] return hop.genop('cast_weakadr_to_ptr', vlist, resulttype = hop.r_result.lowleveltype) @@ -126,7 +126,7 @@ def specialize_call(self, hop): from pypy.rpython import raddress assert isinstance(hop.args_r[0], raddress.WeakGcAddressRepr) - vlist = [hop.inputarg(raddress.weakgcaddress_repr, arg=0)] + vlist = [hop.inputarg(hop.args_r[0], arg=0)] return hop.genop('cast_weakadr_to_int', vlist, resulttype = hop.r_result.lowleveltype) From mwh at codespeak.net Thu Jun 8 15:48:54 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Jun 2006 15:48:54 +0200 (CEST) Subject: [pypy-svn] r28524 - pypy/dist/pypy/module/_weakref Message-ID: <20060608134854.92F14100A2@code0.codespeak.net> Author: mwh Date: Thu Jun 8 15:48:53 2006 New Revision: 28524 Modified: pypy/dist/pypy/module/_weakref/interp__weakref.py Log: this was supposed to be part of r28518 Modified: pypy/dist/pypy/module/_weakref/interp__weakref.py ============================================================================== --- pypy/dist/pypy/module/_weakref/interp__weakref.py (original) +++ pypy/dist/pypy/module/_weakref/interp__weakref.py Thu Jun 8 15:48:53 2006 @@ -248,3 +248,20 @@ **callable_proxy_typedef_dict) W_CallableProxy.typedef.acceptable_as_base_class = False +def basic_weakref(space, w_obj): + """this is a bit like the app-level weakref.ref(), but with no + fancy options like supporting subclasses of _weakref.ref and + callbacks.""" + lifeline = w_obj.getweakref() + if lifeline is None: + lifeline = WeakrefLifeline() + w_obj.setweakref(space, lifeline) + if lifeline.cached_weakref_index >= 0: + cached_weakref_address = lifeline.addr_refs[lifeline.cached_weakref_index] + return cast_weakgcaddress_to_object(cached_weakref_address, W_Weakref) + index = len(lifeline.addr_refs) + w_ref = W_Weakref(space, lifeline, index, w_obj, space.w_None) + lifeline.addr_refs.append(cast_object_to_weakgcaddress(w_ref)) + lifeline.cached_weakref_index = index + return w_ref + From antocuni at codespeak.net Thu Jun 8 15:52:40 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 15:52:40 +0200 (CEST) Subject: [pypy-svn] r28525 - in pypy/dist/pypy/translator/cli: src test Message-ID: <20060608135240.11393100A5@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 15:52:39 2006 New Revision: 28525 Added: pypy/dist/pypy/translator/cli/test/test_pbc.py (contents, props changed) Modified: pypy/dist/pypy/translator/cli/src/pypylib.cs pypy/dist/pypy/translator/cli/test/test_class.py Log: More gencli tests. Modified: pypy/dist/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/dist/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/dist/pypy/translator/cli/src/pypylib.cs Thu Jun 8 15:52:39 2006 @@ -7,15 +7,27 @@ { public static string ToPython(int x) { return x.ToString(); } public static string ToPython(bool x) { return x.ToString(); } - public static string ToPython(double x) { return x.ToString(); } + public static string ToPython(double x) { return x.ToString("F"); } public static string ToPython(char x) { return string.Format("'{0}'", x); } public static string ToPython(uint x) { return x.ToString(); } public static string ToPython(long x) { return x.ToString(); } public static string ToPython(ulong x) { return x.ToString(); } // XXX: it does not support strings containing "'". - public static string ToPython(string x) { return string.Format("'{0}'", x); } + public static string ToPython(string x) { + if (x == null) + return "None"; + else + return string.Format("'{0}'", x); + } + + public static string ToPython(object x) { + if (x == null) + return "None"; + else + return x.ToString(); + } - public static string ToPython(object obj) + public static string InstanceToPython(object obj) { return string.Format("InstanceWrapper('{0}')", obj.GetType().FullName); } Modified: pypy/dist/pypy/translator/cli/test/test_class.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_class.py (original) +++ pypy/dist/pypy/translator/cli/test/test_class.py Thu Jun 8 15:52:39 2006 @@ -4,4 +4,4 @@ class TestCliClass(CliTest, BaseTestRclass): def test_recursive_prebuilt_instance(self): - py.test.skip("gencli doesn't support this, yet'") + py.test.skip("gencli doesn't support recursive constants, yet") Added: pypy/dist/pypy/translator/cli/test/test_pbc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/cli/test/test_pbc.py Thu Jun 8 15:52:39 2006 @@ -0,0 +1,16 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_rpbc import BaseTestRPBC + +class TestCliPBC(CliTest, BaseTestRPBC): + def test_call_memoized_cache(self): + py.test.skip("gencli doesn't support recursive constants, yet") + + def test_multiple_specialized_functions(self): + py.test.skip("CLI doesn't support string, yet") + + def test_specialized_method_of_frozen(self): + py.test.skip("CLI doesn't support string, yet") + + def test_specialized_method(self): + py.test.skip("CLI doesn't support string, yet") From fijal at codespeak.net Thu Jun 8 16:09:00 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 8 Jun 2006 16:09:00 +0200 (CEST) Subject: [pypy-svn] r28528 - in pypy/dist/pypy: annotation rpython/ootypesystem rpython/ootypesystem/test Message-ID: <20060608140900.669B4100AC@code0.codespeak.net> Author: fijal Date: Thu Jun 8 16:08:59 2006 New Revision: 28528 Added: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py Modified: pypy/dist/pypy/annotation/annrpython.py Log: Added first version of external objects support. Modified: pypy/dist/pypy/annotation/annrpython.py ============================================================================== --- pypy/dist/pypy/annotation/annrpython.py (original) +++ pypy/dist/pypy/annotation/annrpython.py Thu Jun 8 16:08:59 2006 @@ -23,6 +23,7 @@ def __init__(self, translator=None, policy=None, bookkeeper=None): import pypy.rpython.ootypesystem.ooregistry # has side effects + import pypy.rpython.ootypesystem.bltregistry # has side effects if translator is None: # interface for tests Added: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Thu Jun 8 16:08:59 2006 @@ -0,0 +1,90 @@ + +""" External objects registry, defining two types of object: +1. Those who need to be flown normally, but needs different representation in the backend +2. Those who does not need to be flown +""" + +from pypy.annotation import model as annmodel +from pypy.objspace.flow.model import Variable, Constant +from pypy.rpython.ootypesystem import ootype + +class BasicMetaExternal(type): + pass + +class BasicExternal(object): + __metaclass__ = BasicMetaExternal + + _fields = {} + _methods = {} + +from pypy.rpython.extregistry import ExtRegistryEntry +from pypy.rpython.rmodel import Repr + + +class ExternalType(ootype.Instance): + class_dict = {} + + def __init__(self, _class): + # FIXME: We want to support inheritance at some point + self._class_ = _class + _methods = dict([(i,ootype._meth(ootype.Meth(*val))) for i,val in _class._methods.iteritems()]) + ootype.Instance.__init__(self, str(_class), None, _class._fields, _methods, True) + +## def _example(self): +## return ootype._instance(self) + + def get(class_): + try: + return ExternalType.class_dict[class_] + except KeyError: + next = ExternalType(class_) + ExternalType.class_dict[class_] = next + return next + + get = staticmethod(get) + +## def _init_instance(self, inst): +## for i,val in self._fields.iteritems(): +## inst.__dict__[i] = val +## +## def _lookup(self, name): +## return self, None +## +## def _lookup_field(self, name): +## return self, self.fields.get(name) +## +## def _has_field(self, name): +## return self._fields.get(name) is not None +## +## def _field_type(self, name): +## return self._fields[name] +## +## def _check_field(self, name): +## return True +## +## def __repr__(self): +## return "" % self._class +## +## def __str__(self): +## return "ExternalType(%s)" % self._class + +##class ExternalInstance(ootype.OOType): +## pass +## +##ExternalInstanceSingleton = ExternalInstance() + +class Entry_basicexternal(ExtRegistryEntry): + _type_ = BasicExternal.__metaclass__ + + #def compute_annotation(self, *args): + # return annmodel.SomeOOInstance(ootype=BasicExternal) + def compute_result_annotation(self): + return annmodel.SomeOOInstance(ootype=ExternalType.get(self.instance)) + + def specialize_call(self, hop): + #assert isinstance(hop.args_s[0], annmodel.SomeOOInstance)\ + # and hop.args_s[0].ootype is Externaltype + #import pdb; pdb.set_trace() + _class = hop.r_result.lowleveltype._class_ + return hop.genop('new', [Constant(ExternalType.get(_class), concretetype=ootype.Void)], \ + resulttype = ExternalType.get(_class)) Added: pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py Thu Jun 8 16:08:59 2006 @@ -0,0 +1,55 @@ + +""" Builtin annotation test +""" + +from pypy.annotation import model as annmodel +from pypy.objspace.flow import FlowObjSpace +from pypy.annotation.annrpython import RPythonAnnotator +import exceptions +from pypy.rpython.ootypesystem.bltregistry import BasicExternal, ExternalType +from pypy.rpython.ootypesystem.ootype import Signed + +class C(BasicExternal): + pass + +def test_new_bltn(): + def new(): + return C() + + a = RPythonAnnotator() + s = a.build_types(new, []) + assert isinstance(s.ootype, ExternalType) + assert s.ootype._class_ is C + +class A(BasicExternal): + _fields = { + 'b' : Signed, + } + +def test_bltn_attrs(): + def access_attr(): + a = A() + a.b = 3 + return a.b + + a = RPythonAnnotator() + s = a.build_types(access_attr, []) + assert s.knowntype is int + +class B(BasicExternal): + _fields = { + 'a' : Signed, + } + + _methods = { + 'm' : ([Signed],Signed), + } + +def test_bltn_method(): + def access_meth(): + a = B() + return a.m() + + a = RPythonAnnotator() + s = a.build_types(access_meth, []) + assert s.knowntype is int From antocuni at codespeak.net Thu Jun 8 17:09:00 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 17:09:00 +0200 (CEST) Subject: [pypy-svn] r28532 - in pypy/dist/pypy/translator/cli: . test Message-ID: <20060608150900.B7A43100A9@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 17:08:59 2006 New Revision: 28532 Added: pypy/dist/pypy/translator/cli/test/test_exception.py (contents, props changed) Modified: pypy/dist/pypy/translator/cli/function.py Log: Fixed a bug in exception handling; added the corresponding test. Modified: pypy/dist/pypy/translator/cli/function.py ============================================================================== --- pypy/dist/pypy/translator/cli/function.py (original) +++ pypy/dist/pypy/translator/cli/function.py Thu Jun 8 17:08:59 2006 @@ -115,8 +115,8 @@ assert len(target.inputargs) == 2 self.store(link.target.inputargs[1]) else: - # pop the unused exception value - self.ilasm.opcode('pop') + # the exception value is on the stack, store it in the proper place + self.store(link.last_exc_value) self._setup_link(link) target_label = self._get_block_name(target) Added: pypy/dist/pypy/translator/cli/test/test_exception.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/cli/test/test_exception.py Thu Jun 8 17:08:59 2006 @@ -0,0 +1,6 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_exception import BaseTestException + +class TestCliException(CliTest, BaseTestException): + pass From antocuni at codespeak.net Thu Jun 8 17:14:17 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 17:14:17 +0200 (CEST) Subject: [pypy-svn] r28534 - pypy/dist/pypy/translator/cli/test Message-ID: <20060608151417.2253F100AC@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 17:14:16 2006 New Revision: 28534 Added: pypy/dist/pypy/translator/cli/test/test_rpython.py (contents, props changed) Removed: pypy/dist/pypy/translator/cli/test/test_class.py pypy/dist/pypy/translator/cli/test/test_exception.py pypy/dist/pypy/translator/cli/test/test_list.py pypy/dist/pypy/translator/cli/test/test_pbc.py Log: Some files merged. Added: pypy/dist/pypy/translator/cli/test/test_rpython.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/cli/test/test_rpython.py Thu Jun 8 17:14:16 2006 @@ -0,0 +1,45 @@ +import py +from pypy.translator.cli.test.runtest import CliTest +from pypy.rpython.test.test_exception import BaseTestException +from pypy.rpython.test.test_rclass import BaseTestRclass +from pypy.rpython.test.test_rlist import BaseTestRlist +from pypy.rpython.test.test_rpbc import BaseTestRPBC + +class TestCliException(CliTest, BaseTestException): + pass + + +class TestCliClass(CliTest, BaseTestRclass): + def test_recursive_prebuilt_instance(self): + py.test.skip("gencli doesn't support recursive constants, yet") + + +class TestCliPBC(CliTest, BaseTestRPBC): + def test_call_memoized_cache(self): + py.test.skip("gencli doesn't support recursive constants, yet") + + def test_multiple_specialized_functions(self): + py.test.skip("CLI doesn't support string, yet") + + def test_specialized_method_of_frozen(self): + py.test.skip("CLI doesn't support string, yet") + + def test_specialized_method(self): + py.test.skip("CLI doesn't support string, yet") + + +class TestCliList(CliTest, BaseTestRlist): + def test_recursive(self): + py.test.skip("CLI doesn't support recursive lists") + + def test_list_comparestr(self): + py.test.skip("CLI doesn't support string, yet") + + def test_not_a_char_list_after_all(self): + py.test.skip("CLI doesn't support string, yet") + + def test_list_str(self): + py.test.skip("CLI doesn't support string, yet") + + def test_inst_list(self): + py.test.skip("CLI doesn't support string, yet") From arigo at codespeak.net Thu Jun 8 17:27:16 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Jun 2006 17:27:16 +0200 (CEST) Subject: [pypy-svn] r28537 - pypy/extradoc/talk/ep2004-pypy Message-ID: <20060608152716.2D386100B0@code0.codespeak.net> Author: arigo Date: Thu Jun 8 17:27:15 2006 New Revision: 28537 Added: pypy/extradoc/talk/ep2004-pypy/ - copied from r28536, user/arigo/hack/pypy-hack/ep2004-pypy/ Log: Copied this old talk from my part of the repository. From arigo at codespeak.net Thu Jun 8 17:27:30 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Jun 2006 17:27:30 +0200 (CEST) Subject: [pypy-svn] r28538 - in pypy/dist/pypy/rpython/lltypesystem: . test Message-ID: <20060608152730.AA2D5100AC@code0.codespeak.net> Author: arigo Date: Thu Jun 8 17:27:29 2006 New Revision: 28538 Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py Log: Support for instantiating PyStructs. Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Thu Jun 8 17:27:29 2006 @@ -252,8 +252,8 @@ def _short_name(self): return "%s %s" % (self.__class__.__name__, self._name) - def _defl(self, parent=None, parentindex=None): - return _struct(self, parent=parent, parentindex=parentindex) + def _defl(self, parent=None, parentindex=None, **kwds): + return _struct(self, parent=parent, parentindex=parentindex, **kwds) def _container_example(self): if self._arrayfld is None: @@ -443,8 +443,8 @@ def _container_example(self): return _opaque(self) - def _defl(self, parent=None, parentindex=None): - return _opaque(self, parent=parent, parentindex=parentindex) + def _defl(self, parent=None, parentindex=None, **kwds): + return _opaque(self, parent=parent, parentindex=parentindex, **kwds) RuntimeTypeInfo = OpaqueType("RuntimeTypeInfo") @@ -464,6 +464,13 @@ return "PyObject" def _inline_is_varsize(self, last): return False + def _defl(self, parent=None, parentindex=None, extra_args=()): + if not extra_args: + raise NotImplementedError("PyObjectType._defl()") + else: + ob_type = extra_args[0] + return _pyobjheader(ob_type, parent, parentindex) + PyObject = PyObjectType() class ForwardReference(ContainerType): @@ -658,14 +665,15 @@ if OUTSIDE == INSIDE: return 0 dwn = 0 - while True: + while isinstance(OUTSIDE, Struct): first, FIRSTTYPE = OUTSIDE._first_struct() if first is None: - return -1 + break dwn += 1 if FIRSTTYPE == INSIDE: return dwn OUTSIDE = getattr(OUTSIDE, first) + return -1 def castable(PTRTYPE, CURTYPE): if CURTYPE.TO._gckind != PTRTYPE.TO._gckind: @@ -673,8 +681,8 @@ % (CURTYPE, PTRTYPE)) if CURTYPE == PTRTYPE: return 0 - if (not isinstance(CURTYPE.TO, Struct) or - not isinstance(PTRTYPE.TO, Struct)): + if (not isinstance(CURTYPE.TO, (Struct, PyObjectType)) or + not isinstance(PTRTYPE.TO, (Struct, PyObjectType))): raise InvalidCast(CURTYPE, PTRTYPE) CURSTRUC = CURTYPE.TO PTRSTRUC = PTRTYPE.TO @@ -1182,19 +1190,22 @@ __slots__ = () - def __new__(self, TYPE, n=None, parent=None, parentindex=None): + def __new__(self, TYPE, n=None, parent=None, parentindex=None, **kwds): my_variety = _struct_variety(TYPE._names) return object.__new__(my_variety) - def __init__(self, TYPE, n=None, parent=None, parentindex=None): + def __init__(self, TYPE, n=None, parent=None, parentindex=None, **kwds): _parentable.__init__(self, TYPE) if n is not None and TYPE._arrayfld is None: raise TypeError("%r is not variable-sized" % (TYPE,)) if n is None and TYPE._arrayfld is not None: raise TypeError("%r is variable-sized" % (TYPE,)) + first, FIRSTTYPE = TYPE._first_struct() for fld, typ in TYPE._flds.items(): if fld == TYPE._arrayfld: value = _array(typ, n, parent=self, parentindex=fld) + elif fld == first: + value = typ._defl(parent=self, parentindex=fld, **kwds) else: value = typ._defl(parent=self, parentindex=fld) setattr(self, fld, value) @@ -1461,14 +1472,29 @@ return '<%s>' % (self,) def __str__(self): - return "pyobject %s" % (super(_pyobject, self).__str__(),) + return "pyobject %s" % (Hashable.__str__(self),) + +class _pyobjheader(_parentable): + + def __init__(self, ob_type, parent=None, parentindex=None): + _parentable.__init__(self, PyObject) + assert typeOf(ob_type) == Ptr(PyObject) + self.ob_type = ob_type + if parent is not None: + self._setparentstructure(parent, parentindex) + + def __repr__(self): + return '<%s>' % (self,) + + def __str__(self): + return "pyobjheader of type %r" % (self.ob_type,) -def malloc(T, n=None, flavor='gc', immortal=False): +def malloc(T, n=None, flavor='gc', immortal=False, **kwds): if isinstance(T, Struct): - o = _struct(T, n) + o = _struct(T, n, **kwds) elif isinstance(T, Array): - o = _array(T, n) + o = _array(T, n, **kwds) else: raise TypeError, "malloc for Structs and Arrays only" if T._gckind != 'gc' and not immortal and flavor.startswith('gc'): Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py Thu Jun 8 17:27:29 2006 @@ -698,7 +698,19 @@ p = pyobjectptr({42: 84}) assert typeOf(p) == Ptr(PyObject) S1 = PyStruct('S1', ('head', PyObject), ('x', Signed)) - # cannot really instantiate S1 so far py.test.raises(TypeError, PyStruct, 'S2', ('y', Signed)) py.test.raises(TypeError, PyStruct, 'S2', ('x', Struct('X'))) py.test.raises(TypeError, PyStruct, 'S2', ('x', GcStruct('X'))) + + inttype = pyobjectptr(int) + s1 = malloc(S1, flavor='cpy', extra_args=(inttype,)) + s1.x = 17 + assert typeOf(s1.head) == Ptr(PyObject) + h1 = cast_pointer(Ptr(PyObject), s1) + assert s1.head == h1 + s2 = cast_pointer(Ptr(S1), h1) + assert s2 == s1 + + del s1, s2 + s3 = cast_pointer(Ptr(S1), h1) + assert s3.x == 17 From antocuni at codespeak.net Thu Jun 8 17:29:42 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 17:29:42 +0200 (CEST) Subject: [pypy-svn] r28539 - pypy/dist/pypy/translator/cli Message-ID: <20060608152942.194A5100B0@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 17:29:41 2006 New Revision: 28539 Modified: pypy/dist/pypy/translator/cli/opcodes.py Log: Added support for 'cast_char_to_int' Modified: pypy/dist/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/cli/opcodes.py (original) +++ pypy/dist/pypy/translator/cli/opcodes.py Thu Jun 8 17:29:41 2006 @@ -204,7 +204,7 @@ 'cast_bool_to_int': [PushAllArgs, 'ldc.i4.0', 'ceq']+Not, 'cast_bool_to_uint': [PushAllArgs, 'ldc.i4.0', 'ceq']+Not, 'cast_bool_to_float': [PushAllArgs, 'ldc.i4 0', 'ceq']+Not+['conv.r8'], - 'cast_char_to_int': None, + 'cast_char_to_int': DoNothing, 'cast_unichar_to_int': None, 'cast_int_to_char': None, 'cast_int_to_unichar': None, From antocuni at codespeak.net Thu Jun 8 17:29:52 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 17:29:52 +0200 (CEST) Subject: [pypy-svn] r28540 - pypy/dist/pypy/translator/cli Message-ID: <20060608152952.C9741100B4@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 17:29:52 2006 New Revision: 28540 Modified: pypy/dist/pypy/translator/cli/database.py Log: bugfix. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Thu Jun 8 17:29:52 2006 @@ -177,7 +177,7 @@ elif isinstance(value, ootype._class): return ClassConst(db, value, count) else: - assert False, 'Unknown constant: %s' % const + assert False, 'Unknown constant: %s' % value make = staticmethod(make) def load(db, TYPE, value, ilasm): From fijal at codespeak.net Thu Jun 8 17:35:18 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 8 Jun 2006 17:35:18 +0200 (CEST) Subject: [pypy-svn] r28541 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20060608153518.01162100B2@code0.codespeak.net> Author: fijal Date: Thu Jun 8 17:35:18 2006 New Revision: 28541 Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py Log: Fixed global issue, added test. Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Thu Jun 8 17:35:18 2006 @@ -73,6 +73,12 @@ ## ##ExternalInstanceSingleton = ExternalInstance() +class Entry_basicexternalmeta(ExtRegistryEntry): + _metatype_ = BasicMetaExternal + + def compute_annotation(self): + return annmodel.SomeOOInstance(ootype=ExternalType.get(self.instance)) + class Entry_basicexternal(ExtRegistryEntry): _type_ = BasicExternal.__metaclass__ Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py Thu Jun 8 17:35:18 2006 @@ -8,6 +8,7 @@ import exceptions from pypy.rpython.ootypesystem.bltregistry import BasicExternal, ExternalType from pypy.rpython.ootypesystem.ootype import Signed +from pypy.rpython.test.test_llinterp import interpret class C(BasicExternal): pass @@ -53,3 +54,13 @@ a = RPythonAnnotator() s = a.build_types(access_meth, []) assert s.knowntype is int + +glob_b = B() + +def test_global(): + def access_global(): + return glob_b.a + + a = RPythonAnnotator() + s = a.build_types(access_global, []) + assert s.knowntype is int From hpk at codespeak.net Thu Jun 8 17:38:28 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 8 Jun 2006 17:38:28 +0200 (CEST) Subject: [pypy-svn] r28542 - pypy/extradoc/talk/ep2004-pypy Message-ID: <20060608153828.C4B4C10068@code0.codespeak.net> Author: hpk Date: Thu Jun 8 17:38:21 2006 New Revision: 28542 Modified: pypy/extradoc/talk/ep2004-pypy/accu2004-psyco.txt Log: fix ReST of old talk Modified: pypy/extradoc/talk/ep2004-pypy/accu2004-psyco.txt ============================================================================== --- pypy/extradoc/talk/ep2004-pypy/accu2004-psyco.txt (original) +++ pypy/extradoc/talk/ep2004-pypy/accu2004-psyco.txt Thu Jun 8 17:38:21 2006 @@ -50,6 +50,8 @@ Under the hood: example ----------------------- +:: + def acceptable(i): return i % 3 == 0 @@ -64,7 +66,7 @@ sum(lines, initial='') ------------------------ + ----------------------- def sum(lst): total = 0 @@ -85,7 +87,7 @@ # i is an integer, total is an integer > loop closed ------------------------ + ----------------------- # i is an integer, total is an integer # item=lst[i] is an object @@ -98,7 +100,7 @@ # i is an integer, total is a float > loop closed ------------------------ + ----------------------- # total = total + item ! overflows! @@ -110,7 +112,7 @@ # i is an integer, total is a long > loop closed ------------------------ + ----------------------- # i is an integer, total is an integer # item=lst[i] is an object @@ -129,7 +131,7 @@ total = total + x; loop back to label1; ------------------------ + ----------------------- def sum(lst): total = 0 @@ -142,6 +144,8 @@ Reminder: the for loop reads the iterator by calling Iter.next() until it is exhausted. +:: + # lst is an object ! lst is a list # L = PyList_GET_SIZE(lst), L is an integer @@ -167,7 +171,7 @@ ...body of the loop... goto label1; ------------------------ + ----------------------- def sum(lst): total = 0 @@ -182,7 +186,7 @@ PyObject *total_as_obj = PyInt_FromInt(total); return total_as_obj; ------------------------ + ----------------------- def sum(lst): total = 0 @@ -192,6 +196,8 @@ Summary: +:: + // we know that total=0, we don't need a variable for that check(lst->ob_type == &PyList_Type); int L = PyList_GET_SIZE(lst); @@ -219,7 +225,7 @@ // capture and ignore the IndexError return PyInt_FromLong(total); ------------------------ + ----------------------- def sum(lst): total = '' @@ -238,12 +244,12 @@ # total = x is a growable string > loop closed ------------------------ + ----------------------- def addstuff(lst): lst.append(5) ------------------------ + ----------------------- def addstuff(lst): Meth = lst.append @@ -261,6 +267,8 @@ ----------------------- +:: + def acceptable(i): return i % 3 == 0 @@ -278,11 +286,13 @@ ----------------------- +:: + def acceptable(i): return i % 3 == 0 In our case we provide the argument i as an integer, not as an -integer object: +integer object:: PyObject *acceptable_with_int_arg(int i) { @@ -302,6 +312,8 @@ ----------------------- +:: + def acceptable(i): return i % 3 == 0 @@ -323,6 +335,8 @@ Small functions can be inlined! +:: + def acceptable(i): return i % 3 == 0 @@ -452,7 +466,7 @@ ------------------ -It can also combine several instructions into one: +It can also combine several instructions into one:: mode_combine([s_push(1:255), add]). From mwh at codespeak.net Thu Jun 8 17:39:34 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Jun 2006 17:39:34 +0200 (CEST) Subject: [pypy-svn] r28543 - pypy/dist/pypy/rpython Message-ID: <20060608153934.E1A73100AC@code0.codespeak.net> Author: mwh Date: Thu Jun 8 17:39:34 2006 New Revision: 28543 Modified: pypy/dist/pypy/rpython/raddress.py Log: remove commented out dead code Modified: pypy/dist/pypy/rpython/raddress.py ============================================================================== --- pypy/dist/pypy/rpython/raddress.py (original) +++ pypy/dist/pypy/rpython/raddress.py Thu Jun 8 17:39:34 2006 @@ -155,5 +155,4 @@ repr = self.rtyper.bindingrepr(Constant(ob)) newob = repr.convert_const(ob) return cast_object_to_weakgcaddress(newob) - -#weakgcaddress_repr = WeakGcAddressRepr() + From ericvrp at codespeak.net Thu Jun 8 17:45:39 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 8 Jun 2006 17:45:39 +0200 (CEST) Subject: [pypy-svn] r28544 - pypy/dist/pypy/translator/js2/proxy/testme Message-ID: <20060608154539.50010100AF@code0.codespeak.net> Author: ericvrp Date: Thu Jun 8 17:45:37 2006 New Revision: 28544 Modified: pypy/dist/pypy/translator/js2/proxy/testme/controllers.py Log: just a tiny note about BnB messages Modified: pypy/dist/pypy/translator/js2/proxy/testme/controllers.py ============================================================================== --- pypy/dist/pypy/translator/js2/proxy/testme/controllers.py (original) +++ pypy/dist/pypy/translator/js2/proxy/testme/controllers.py Thu Jun 8 17:45:37 2006 @@ -45,6 +45,10 @@ region.save(icon_filename) print 'SAVED:', icon_filename + #note: we should add the feature that we can ignore/replace messages with + # other messages. This is mostly important to avoid sending all the + # pixel data to the client which it can not use in this format anyway. + MESSAGES = { MSG_BROADCAST_PORT : broadcast_port, MSG_PING : ping, From mwh at codespeak.net Thu Jun 8 17:51:27 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Jun 2006 17:51:27 +0200 (CEST) Subject: [pypy-svn] r28546 - in pypy/dist/pypy/translator: backendopt stackless/test Message-ID: <20060608155127.9250A100B7@code0.codespeak.net> Author: mwh Date: Thu Jun 8 17:51:26 2006 New Revision: 28546 Modified: pypy/dist/pypy/translator/backendopt/removenoops.py pypy/dist/pypy/translator/backendopt/support.py pypy/dist/pypy/translator/stackless/test/test_resume_point.py Log: (mwh, pedronis) Fix + test for various grotty interactions of explicit resume points and backend optimizations. Modified: pypy/dist/pypy/translator/backendopt/removenoops.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/removenoops.py (original) +++ pypy/dist/pypy/translator/backendopt/removenoops.py Thu Jun 8 17:51:26 2006 @@ -91,6 +91,8 @@ num_removed += 1 else: available[key] = op.result + elif op.opname == 'resume_point': + available.clear() if num_removed: remove_same_as(graph) # remove casts with unused results Modified: pypy/dist/pypy/translator/backendopt/support.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/support.py (original) +++ pypy/dist/pypy/translator/backendopt/support.py Thu Jun 8 17:51:26 2006 @@ -84,6 +84,9 @@ elif keep_alive_op_args and afterblock.operations: keep_alive_vars = [var for var in afterblock.operations[0].args if isinstance(var, Variable) and var_needsgc(var)] + if len(afterblock.operations) > 1 or afterblock.exitswitch != c_last_exception: + afterblock.operations[1:1] = generate_keepalive(keep_alive_vars) + keep_alive_vars = [] else: keep_alive_vars = [] if afterblock.exitswitch == c_last_exception: Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Thu Jun 8 17:51:26 2006 @@ -4,14 +4,21 @@ import py from pypy.rpython import rstack -def transform_stackless_function(fn): +def transform_stackless_function(fn, do_inline=False): def wrapper(argv): return fn() t = rtype_stackless_function(wrapper) - st = StacklessTransformer(t, wrapper, False) - st.transform_all() + if do_inline: + from pypy.translator.backendopt import inline, removenoops + callgraph = inline.inlinable_static_callers(t.graphs) + inline.auto_inlining(t, 1, callgraph=callgraph) + for graph in t.graphs: + removenoops.remove_superfluous_keep_alive(graph) + removenoops.remove_duplicate_casts(graph, t) if conftest.option.view: t.view() + st = StacklessTransformer(t, wrapper, False) + st.transform_all() def test_no_call(): def f(x, y): @@ -244,7 +251,7 @@ transform_stackless_function(example) def test_except(): - py.test.skip('in-progress') + py.test.skip("please don't write code like this") def f(x): rstack.resume_point("rp1", x) return 1/x @@ -253,10 +260,54 @@ r += f(x) try: y = f(x) - rstack.resume_point("rp0", x, r, returns=y) + rstack.resume_point("rp0", x, r, y, returns=y) except ZeroDivisionError: r += f(x) return r + y def example(): return g(one()) transform_stackless_function(example) + +def test_using_pointers(): + from pypy.interpreter.miscutils import FixedStack + class Arguments: + def __init__(self, a, b, c, d, e): + pass + class W_Root: + pass + class FakeFrame: + def __init__(self, space): + self.space = space + self.valuestack = FixedStack() + self.valuestack.setup(10) + self.valuestack.push(W_Root()) + class FakeSpace: + def call_args(self, args, kw): + return W_Root() + def str_w(self, ob): + return 'a string' + def call_function(f, oparg, w_star=None, w_starstar=None): + n_arguments = oparg & 0xff + n_keywords = (oparg>>8) & 0xff + keywords = None + if n_keywords: + keywords = {} + for i in range(n_keywords): + w_value = f.valuestack.pop() + w_key = f.valuestack.pop() + key = f.space.str_w(w_key) + keywords[key] = w_value + arguments = [None] * n_arguments + for i in range(n_arguments - 1, -1, -1): + arguments[i] = f.valuestack.pop() + args = Arguments(f.space, arguments, keywords, w_star, w_starstar) + w_function = f.valuestack.pop() + w_result = f.space.call_args(w_function, args) + rstack.resume_point("call_function", f, returns=w_result) + f.valuestack.push(w_result) + def example(): + s = FakeSpace() + f = FakeFrame(s) + call_function(f, 100, W_Root(), W_Root()) + return one() + transform_stackless_function(example, do_inline=True) From antocuni at codespeak.net Thu Jun 8 17:52:39 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 17:52:39 +0200 (CEST) Subject: [pypy-svn] r28547 - pypy/dist/pypy/translator/cli Message-ID: <20060608155239.88781100BB@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 17:52:38 2006 New Revision: 28547 Modified: pypy/dist/pypy/translator/cli/database.py Log: bugfix Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Thu Jun 8 17:52:38 2006 @@ -251,11 +251,12 @@ class_name = self.get_type(False) ilasm.new('instance void class %s::.ctor()' % class_name) for f_name, (FIELD_TYPE, f_default) in self.record._TYPE._fields.iteritems(): - f_type = self.cts.lltype_to_cts(FIELD_TYPE) - value = self.record._items[f_name] - ilasm.opcode('dup') - AbstractConst.load(self.db, FIELD_TYPE, value, ilasm) - ilasm.set_field((f_type, class_name, f_name)) + if FIELD_TYPE is not ootype.Void: + f_type = self.cts.lltype_to_cts(FIELD_TYPE) + value = self.record._items[f_name] + ilasm.opcode('dup') + AbstractConst.load(self.db, FIELD_TYPE, value, ilasm) + ilasm.set_field((f_type, class_name, f_name)) class StaticMethodConst(AbstractConst): def __init__(self, db, sm, count): From mwh at codespeak.net Thu Jun 8 18:17:58 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Jun 2006 18:17:58 +0200 (CEST) Subject: [pypy-svn] r28548 - in pypy/dist/pypy: annotation rpython Message-ID: <20060608161758.7AD3B10077@code0.codespeak.net> Author: mwh Date: Thu Jun 8 18:17:57 2006 New Revision: 28548 Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/rpython/raddress.py Log: (mwh, pedronis) TREMENDOUSLY obscure fix for the non-trivia constant weakgcaddress support. Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Thu Jun 8 18:17:57 2006 @@ -462,6 +462,15 @@ self.descs[pyobj] = result return result + def have_seen(self, x): + # this might need to expand some more. + if x in self.descs: + return True + elif x in self.seen_mutable: + return True + else: + return False + def getfrozen(self, pyobj): result = description.FrozenDesc(self, pyobj) cls = result.knowntype Modified: pypy/dist/pypy/rpython/raddress.py ============================================================================== --- pypy/dist/pypy/rpython/raddress.py (original) +++ pypy/dist/pypy/rpython/raddress.py Thu Jun 8 18:17:57 2006 @@ -152,7 +152,12 @@ return value ob = value.ref() assert ob is not None - repr = self.rtyper.bindingrepr(Constant(ob)) - newob = repr.convert_const(ob) - return cast_object_to_weakgcaddress(newob) - + bk = self.rtyper.annotator.bookkeeper + # obscure! if the annotator hasn't seen this object before, + # we don't want to look at it now (confusion tends to result). + if bk.have_seen(ob): + repr = self.rtyper.bindingrepr(Constant(ob)) + newob = repr.convert_const(ob) + return cast_object_to_weakgcaddress(newob) + else: + return llmemory.fakeweakaddress(None) From cfbolz at codespeak.net Thu Jun 8 18:30:04 2006 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Jun 2006 18:30:04 +0200 (CEST) Subject: [pypy-svn] r28549 - in pypy/dist/pypy/module/stackless: . test Message-ID: <20060608163004.38CE010036@code0.codespeak.net> Author: cfbolz Date: Thu Jun 8 18:30:03 2006 New Revision: 28549 Modified: pypy/dist/pypy/module/stackless/interp_coroutine.py pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py Log: (tismer, cfbolz): work in progress: make Coroutines run on top py.py, maybe. there's a bug right now :-( Modified: pypy/dist/pypy/module/stackless/interp_coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/interp_coroutine.py (original) +++ pypy/dist/pypy/module/stackless/interp_coroutine.py Thu Jun 8 18:30:03 2006 @@ -31,6 +31,28 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.rpython.rstack import yield_current_frame_to_caller, resume_point +from pypy.rpython.objectmodel import we_are_translated + +try: + from py.magic import greenlet + main_greenlet = greenlet.getcurrent() + class MyGreenlet(object): + def __init__(self, thunk=None, curr=False): + if curr: + self.greenlet = greenlet.getcurrent() + else: + self.greenlet = greenlet(thunk) + def switch(self): + last = MyGreenlet(curr=True) +# XXX unclear what to do there +# self.greenlet.parent = greenlet.getcurrent() + return self.greenlet.switch(last) + GreenletExit = greenlet.GreenletExit +except ImportError: + def greenlet(*args, **kwargs): + raise NotImplementedError("need either greenlets or a translated version of pypy") + class GreenletExit(Exception): + pass import sys, os @@ -56,57 +78,75 @@ check_for_zombie = staticmethod(check_for_zombie) def postpone_deletion(obj): - costate.to_delete.append(obj) - costate.things_to_do = True + main_coroutine_getter._get_default_costate().to_delete.append(obj) + main_coroutine_getter._get_default_costate().things_to_do = True postpone_deletion = staticmethod(postpone_deletion) def do_things_to_do(): # inlineable stub - if costate.things_to_do: - costate._do_things_to_do() + if main_coroutine_getter._get_default_costate().things_to_do: + main_coroutine_getter._get_default_costate()._do_things_to_do() do_things_to_do = staticmethod(do_things_to_do) def _do_things_to_do(): - if costate.temp_exc is not None: + main_costate = main_coroutine_getter._get_default_costate() + if main_costate.temp_exc is not None: # somebody left an unhandled exception and switched to us. # this both provides default exception handling and the # way to inject an exception, like CoroutineExit. - e, costate.temp_exc = costate.temp_exc, None - costate.things_to_do = len(costate.to_delete) + e, main_costate.temp_exc = main_costate.temp_exc, None + main_costate.things_to_do = len(main_costate.to_delete) raise e - while costate.to_delete: - delete, costate.to_delete = costate.to_delete, [] + while main_costate.to_delete: + delete, main_costate.to_delete = main_costate.to_delete, [] for obj in delete: obj.parent = obj.costate.current obj._kill_finally() else: - costate.things_to_do = False + main_costate.things_to_do = False _do_things_to_do = staticmethod(_do_things_to_do) class CoroutineDamage(SystemError): pass +class MainCoroutineGetter(object): + def __init__(self): + self.costate = None + def _get_default_costate(self): + if self.costate is None: + costate = CoState() + self.costate = costate + return costate + return self.costate + +main_coroutine_getter = MainCoroutineGetter() + class CoroutineExit(SystemExit): # XXX SystemExit's __init__ creates problems in bookkeeper. def __init__(self): pass +def get_exit_class(): # XXX hum + if we_are_translated(): + return CoroutineExit + else: + return GreenletExit + class AbstractThunk(object): def call(self): raise NotImplementedError("abstract base class") class Coroutine(Wrappable): - def __init__(self, state=None): self.frame = None if state is None: - state = costate + state = main_coroutine_getter._get_default_costate() self.costate = state self.parent = None def _get_default_parent(self): - return self.costate.current + return main_coroutine_getter._get_default_costate().current def bind(self, thunk): assert isinstance(thunk, AbstractThunk) @@ -114,20 +154,38 @@ raise CoroutineDamage if self.parent is None: self.parent = self._get_default_parent() - self.frame = self._bind(thunk) + assert self.parent is not None + if we_are_translated(): + self.frame = self._bind(thunk) + else: + self.frame = self._greenlet_bind(thunk) + + def _greenlet_bind(self, thunk): + state = self.costate + self.parent = state.current + assert self.parent is not None + def _greenlet_execute(incoming_frame): + return self._execute(thunk, state, incoming_frame) + return MyGreenlet(_greenlet_execute) def _bind(self, thunk): state = self.costate self.parent = state.current incoming_frame = yield_current_frame_to_caller() + return self._execute(thunk, state, incoming_frame) + + def _execute(self, thunk, state, incoming_frame): left = state.last left.frame = incoming_frame left.goodbye() self.hello() try: - costate.do_things_to_do() + main_coroutine_getter._get_default_costate().do_things_to_do() thunk.call() resume_point("coroutine__bind", self, state) + except GreenletExit: + # ignore a shutdown exception + pass except CoroutineExit: # ignore a shutdown exception pass @@ -152,13 +210,13 @@ left.frame = incoming_frame left.goodbye() self.hello() - costate.do_things_to_do() + main_coroutine_getter._get_default_costate().do_things_to_do() def kill(self): if self.frame is None: return - costate.things_to_do = True - costate.temp_exc = CoroutineExit() + main_coroutine_getter._get_default_costate().things_to_do = True + main_coroutine_getter._get_default_costate().temp_exc = get_exit_class()() state = self.costate self.parent = state.current self.switch() @@ -170,7 +228,7 @@ pass # maybe print a warning? self.kill() - def __del__(self): + def X__del__(self): # provide the necessary clean-up if this coro is left # with a frame. # note that AppCoroutine has to take care about this @@ -179,7 +237,7 @@ # not in the position to issue a switch. # we defer it completely. if self.frame is not None: - costate.postpone_deletion(self) + main_coroutine_getter._get_default_costate().postpone_deletion(self) def _userdel(self): # override this for exposed coros @@ -189,19 +247,20 @@ return self.frame is not None or self is self.costate.current def is_zombie(self): - return self.frame is not None and costate.check_for_zombie(self) + return self.frame is not None and main_coroutine_getter._get_default_costate().check_for_zombie(self) def getcurrent(): - return costate.current + return main_coroutine_getter._get_default_costate().current getcurrent = staticmethod(getcurrent) + def getmain(): + return main_coroutine_getter._get_default_costate().main + getmain = staticmethod(getmain) + def hello(self): "Called when execution is transferred into this coroutine." def goodbye(self): "Called just after execution is transferred away from this coroutine." -costate = None -costate = CoState() - # _________________________________________________ Modified: pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py (original) +++ pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py Thu Jun 8 18:30:03 2006 @@ -3,22 +3,22 @@ """ import os -from pypy.module.stackless.interp_coroutine import costate, Coroutine, AbstractThunk +from pypy.module.stackless.interp_coroutine import main_coroutine_getter, Coroutine, AbstractThunk from pypy.translator.c.test.test_stackless import StacklessTest from pypy.translator.c import gc def output(stuff): os.write(2, stuff + '\n') - class TestCoroutine(StacklessTest): backendopt = True stacklessmode = True gcpolicy = gc.BoehmGcPolicy Coroutine = Coroutine - def setup_meth(self): - costate.__init__() + def setup_method(self, method): + main_coroutine_getter.costate = None + main_coroutine_getter.costate = None def _freeze_(self): # for 'self.Coroutine' return True @@ -51,7 +51,7 @@ def f(): lst = [1] - coro_f = costate.main + coro_f = Coroutine.getcurrent() coro_g = self.Coroutine() coro_h = self.Coroutine() coros = [coro_f, coro_g, coro_h] @@ -146,7 +146,7 @@ return n def f(): - coro_f = costate.main + coro_f = Coroutine.getcurrent() coro_f1 = self.Coroutine() thunk_f1 = T1(f1, coro_f1) output('binding f1 after f set 1') @@ -159,6 +159,7 @@ assert data == 12345678 def test_kill_raise_del_coro(self): + py.test.skip("does not work :-(") class T(AbstractThunk): def __init__(self, func, arg): self.func = func @@ -172,9 +173,10 @@ raise ValueError if nrec: g(nrec-1, t, count+1) - costate.main.switch() + Coroutine.getmain().switch() def f(): + assert Coroutine.getmain().frame is None coro_g = self.Coroutine() thunk_g = T(g, 42) coro_g.bind(thunk_g) @@ -246,7 +248,7 @@ def call(self): self.result = self.consume(self.tree) - costate.main.switch() + Coroutine.getmain().switch() def pre_order_eq(t1, t2): objects = [] @@ -270,3 +272,8 @@ output = self.wrap_stackless_function(ep) assert output == int('0110') + +class TestCoroutineOnCPython(TestCoroutine): + def wrap_stackless_function(self, func): + return func() + From antocuni at codespeak.net Thu Jun 8 19:01:10 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 19:01:10 +0200 (CEST) Subject: [pypy-svn] r28550 - in pypy/dist/pypy/translator/cli: . test Message-ID: <20060608170110.D0A6F1006F@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 19:01:09 2006 New Revision: 28550 Modified: pypy/dist/pypy/translator/cli/database.py pypy/dist/pypy/translator/cli/gencli.py pypy/dist/pypy/translator/cli/record.py pypy/dist/pypy/translator/cli/test/test_rpython.py Log: bugfix. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Thu Jun 8 19:01:09 2006 @@ -31,6 +31,8 @@ self.const_names = set() self.name_count = 0 + self._records = [] + def next_count(self): self.name_count += 1 return self.name_count @@ -41,7 +43,7 @@ def pending_class(self, classdef): self.pending_node(Class(self, classdef)) - def pending_record(self, record): + def pending_record(self, record): r = Record(self, record) self.pending_node(r) return r.get_name() @@ -248,6 +250,10 @@ return self.cts.lltype_to_cts(self.record._TYPE, include_class) def init(self, ilasm): + if self.record is ootype.null(self.record._TYPE): + ilasm.opcode('ldnull') + return + class_name = self.get_type(False) ilasm.new('instance void class %s::.ctor()' % class_name) for f_name, (FIELD_TYPE, f_default) in self.record._TYPE._fields.iteritems(): Modified: pypy/dist/pypy/translator/cli/gencli.py ============================================================================== --- pypy/dist/pypy/translator/cli/gencli.py (original) +++ pypy/dist/pypy/translator/cli/gencli.py Thu Jun 8 19:01:09 2006 @@ -73,6 +73,8 @@ while self.db._pending_nodes: node = self.db._pending_nodes.pop() node.render(self.ilasm) + self.db._rendered_nodes.add(node) + def fix_names(self): # it could happen that two distinct graph have the same name; Modified: pypy/dist/pypy/translator/cli/record.py ============================================================================== --- pypy/dist/pypy/translator/cli/record.py (original) +++ pypy/dist/pypy/translator/cli/record.py Thu Jun 8 19:01:09 2006 @@ -9,12 +9,13 @@ self.cts = CTS(db) self.record = record - trans = string.maketrans('<>(), ', '______') + trans = string.maketrans('<>(), :', '_______') name = ['Record'] for f_name, (FIELD_TYPE, f_default) in record._fields.iteritems(): type_name = FIELD_TYPE._short_name().translate(trans) name.append(type_name) self.name = '__'.join(name) + assert ':' not in self.name record._name = self.name def __hash__(self): Modified: pypy/dist/pypy/translator/cli/test/test_rpython.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_rpython.py (original) +++ pypy/dist/pypy/translator/cli/test/test_rpython.py Thu Jun 8 19:01:09 2006 @@ -4,17 +4,30 @@ from pypy.rpython.test.test_rclass import BaseTestRclass from pypy.rpython.test.test_rlist import BaseTestRlist from pypy.rpython.test.test_rpbc import BaseTestRPBC +from pypy.rpython.test.test_rtuple import BaseTestRtuple -class TestCliException(CliTest, BaseTestException): +##from pypy.rpython.test.test_rbool import BaseTestRbool +##from pypy.rpython.test.test_rfloat import BaseTestRfloat +##from pypy.rpython.test.test_rint import BaseTestRint +##from pypy.rpython.test.test_rbuiltin import BaseTestRbuiltin +##from pypy.rpython.test.test_rrange import BaseTestRrange +##from pypy.rpython.test.test_rstr import BaseTestRstr +##from pypy.rpython.test.test_rdict import BaseTestRdict +##from pypy.rpython.test.test_objectmodel import BaseTestObjectModel +##from pypy.rpython.test.test_remptydict import BaseTestRemptydict +##from pypy.rpython.test.test_rconstantdict import BaseTestRconstantdict +##from pypy.rpython.test.test_rspecialcase import BaseTestRspecialcase + +class xTestCliException(CliTest, BaseTestException): pass -class TestCliClass(CliTest, BaseTestRclass): +class xTestCliClass(CliTest, BaseTestRclass): def test_recursive_prebuilt_instance(self): py.test.skip("gencli doesn't support recursive constants, yet") -class TestCliPBC(CliTest, BaseTestRPBC): +class xTestCliPBC(CliTest, BaseTestRPBC): def test_call_memoized_cache(self): py.test.skip("gencli doesn't support recursive constants, yet") @@ -28,7 +41,7 @@ py.test.skip("CLI doesn't support string, yet") -class TestCliList(CliTest, BaseTestRlist): +class xTestCliList(CliTest, BaseTestRlist): def test_recursive(self): py.test.skip("CLI doesn't support recursive lists") @@ -43,3 +56,14 @@ def test_inst_list(self): py.test.skip("CLI doesn't support string, yet") + +class TestCliTuple(CliTest, BaseTestRtuple): + def test_constant_tuple_contains(self): + py.test.skip("CLI doesn't support dict, yet") + + test_constant_tuple_contains2 = test_constant_tuple_contains + test_constant_unichar_tuple_contains = test_constant_tuple_contains + + def test_inst_tuple_add_getitem(self): + py.test.skip("Need to fix pending nodes rendering") + From antocuni at codespeak.net Thu Jun 8 19:08:14 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Jun 2006 19:08:14 +0200 (CEST) Subject: [pypy-svn] r28551 - pypy/dist/pypy/translator/cli/test Message-ID: <20060608170814.60CC410036@code0.codespeak.net> Author: antocuni Date: Thu Jun 8 19:08:13 2006 New Revision: 28551 Modified: pypy/dist/pypy/translator/cli/test/test_rpython.py Log: Re-enable some tests disabled by mistake. Modified: pypy/dist/pypy/translator/cli/test/test_rpython.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_rpython.py (original) +++ pypy/dist/pypy/translator/cli/test/test_rpython.py Thu Jun 8 19:08:13 2006 @@ -6,11 +6,11 @@ from pypy.rpython.test.test_rpbc import BaseTestRPBC from pypy.rpython.test.test_rtuple import BaseTestRtuple +##from pypy.rpython.test.test_rrange import BaseTestRrange ##from pypy.rpython.test.test_rbool import BaseTestRbool ##from pypy.rpython.test.test_rfloat import BaseTestRfloat ##from pypy.rpython.test.test_rint import BaseTestRint ##from pypy.rpython.test.test_rbuiltin import BaseTestRbuiltin -##from pypy.rpython.test.test_rrange import BaseTestRrange ##from pypy.rpython.test.test_rstr import BaseTestRstr ##from pypy.rpython.test.test_rdict import BaseTestRdict ##from pypy.rpython.test.test_objectmodel import BaseTestObjectModel @@ -18,16 +18,16 @@ ##from pypy.rpython.test.test_rconstantdict import BaseTestRconstantdict ##from pypy.rpython.test.test_rspecialcase import BaseTestRspecialcase -class xTestCliException(CliTest, BaseTestException): +class TestCliException(CliTest, BaseTestException): pass -class xTestCliClass(CliTest, BaseTestRclass): +class TestCliClass(CliTest, BaseTestRclass): def test_recursive_prebuilt_instance(self): py.test.skip("gencli doesn't support recursive constants, yet") -class xTestCliPBC(CliTest, BaseTestRPBC): +class TestCliPBC(CliTest, BaseTestRPBC): def test_call_memoized_cache(self): py.test.skip("gencli doesn't support recursive constants, yet") @@ -41,7 +41,7 @@ py.test.skip("CLI doesn't support string, yet") -class xTestCliList(CliTest, BaseTestRlist): +class TestCliList(CliTest, BaseTestRlist): def test_recursive(self): py.test.skip("CLI doesn't support recursive lists") @@ -57,6 +57,7 @@ def test_inst_list(self): py.test.skip("CLI doesn't support string, yet") + class TestCliTuple(CliTest, BaseTestRtuple): def test_constant_tuple_contains(self): py.test.skip("CLI doesn't support dict, yet") From pedronis at codespeak.net Thu Jun 8 19:41:58 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 8 Jun 2006 19:41:58 +0200 (CEST) Subject: [pypy-svn] r28552 - pypy/dist/pypy/translator/stackless/test Message-ID: <20060608174158.6C61910050@code0.codespeak.net> Author: pedronis Date: Thu Jun 8 19:41:57 2006 New Revision: 28552 Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py Log: test that shows that for always raising functions putting a resume point before is good enough (obscure(tm)) Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Thu Jun 8 19:41:57 2006 @@ -311,3 +311,36 @@ call_function(f, 100, W_Root(), W_Root()) return one() transform_stackless_function(example, do_inline=True) + +def test_always_raising(): + def g(out): + out.append(3) + rstack.resume_point('g') + raise KeyError + + def h(out): + try: + # g is always raising, good enough to put the resume point + # before, instead of after! + rstack.resume_point('h', out) + g(out) + except KeyError: + return 0 + return -1 + + def example(): + out = [] + x = h(out) + l = len(out) + chain = rstack.resume_state_create(None, 'h', out) + chain = rstack.resume_state_create(chain, 'g') + x += rstack.resume_state_invoke(int, chain) + l += len(out) + return l*100+x + + res = llinterp_stackless_function(example) + assert res == 200 + res = run_stackless_function(example) + assert res == 200 + + From bea at codespeak.net Thu Jun 8 19:48:59 2006 From: bea at codespeak.net (bea at codespeak.net) Date: Thu, 8 Jun 2006 19:48:59 +0200 (CEST) Subject: [pypy-svn] r28553 - pypy/extradoc/talk/agile2006 Message-ID: <20060608174859.1273810050@code0.codespeak.net> Author: bea Date: Thu Jun 8 19:48:56 2006 New Revision: 28553 Added: pypy/extradoc/talk/agile2006/during-oss-sprints_talk.pdf (contents, props changed) Log: my talk for agile 2006, please check and feedback Added: pypy/extradoc/talk/agile2006/during-oss-sprints_talk.pdf ============================================================================== Binary file. No diff available. From pedronis at codespeak.net Thu Jun 8 20:25:48 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 8 Jun 2006 20:25:48 +0200 (CEST) Subject: [pypy-svn] r28555 - in pypy/dist/pypy: interpreter module/stackless Message-ID: <20060608182548.A4D3510050@code0.codespeak.net> Author: pedronis Date: Thu Jun 8 20:25:34 2006 New Revision: 28555 Modified: pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/module/stackless/coroutine.py Log: move the resume_point in eval before the dispatch_translated, this is what we want and is legitimate beceause dispatch always raises, there's a test in test_resume_point that should exemplify this case. Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Thu Jun 8 20:25:34 2006 @@ -198,10 +198,9 @@ try: try: if we_are_translated(): - try: - self.dispatch_translated(executioncontext) - finally: - rstack.resume_point("eval", self) + # always raising, put the resume point just before! + rstack.resume_point("eval", self, executioncontext) + self.dispatch_translated(executioncontext) else: self.dispatch(executioncontext) # catch asynchronous exceptions and turn them Modified: pypy/dist/pypy/module/stackless/coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/coroutine.py (original) +++ pypy/dist/pypy/module/stackless/coroutine.py Thu Jun 8 20:25:34 2006 @@ -164,8 +164,8 @@ assert isinstance(frame, PyFrame) # rstack.resume_point("evalframe", self, executioncontext, returns=result) evalframe_frame = resume_state_create(chain, "evalframe", frame, ec) - # rstack.resume_point("eval", self) - eval_frame = resume_state_create(evalframe_frame, "eval", frame) + # rstack.resume_point("eval", self, executioncontext) + eval_frame = resume_state_create(evalframe_frame, "eval", frame, ec) # rstack.resume_point("dispatch_call", self, code, ec) code = frame.getcode().co_code dispatch_call_frame = resume_state_create(eval_frame, "dispatch_call", frame, code, ec) From ericvrp at codespeak.net Fri Jun 9 10:52:00 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 9 Jun 2006 10:52:00 +0200 (CEST) Subject: [pypy-svn] r28571 - pypy/dist/pypy/translator/js2/backup Message-ID: <20060609085200.1E32210034@code0.codespeak.net> Author: ericvrp Date: Fri Jun 9 10:51:56 2006 New Revision: 28571 Added: pypy/dist/pypy/translator/js2/backup/ pypy/dist/pypy/translator/js2/backup/README.txt (contents, props changed) pypy/dist/pypy/translator/js2/backup/js-old.tgz (contents, props changed) Log: Backup of the previous (non-ootypesystem) Javascript backend. We would like to keep this around for a while as reference. This directory should be removed later! note: stored as a binary to avoid running the tests by accident! Added: pypy/dist/pypy/translator/js2/backup/README.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/backup/README.txt Fri Jun 9 10:51:56 2006 @@ -0,0 +1,3 @@ +This is a backup of the previous (non-ootypesystem) Javascript backend. +We would like to keep this around for a while as reference. +This directory should be removed later! Added: pypy/dist/pypy/translator/js2/backup/js-old.tgz ============================================================================== Binary file. No diff available. From ericvrp at codespeak.net Fri Jun 9 11:37:31 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 9 Jun 2006 11:37:31 +0200 (CEST) Subject: [pypy-svn] r28574 - pypy/dist/pypy/translator/js2/backup Message-ID: <20060609093731.CD70410034@code0.codespeak.net> Author: ericvrp Date: Fri Jun 9 11:37:29 2006 New Revision: 28574 Removed: pypy/dist/pypy/translator/js2/backup/ Log: duh From arigo at codespeak.net Fri Jun 9 11:42:42 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Jun 2006 11:42:42 +0200 (CEST) Subject: [pypy-svn] r28575 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/lltypesystem/test translator/c translator/c/src Message-ID: <20060609094242.7CDCF10034@code0.codespeak.net> Author: arigo Date: Fri Jun 9 11:42:39 2006 New Revision: 28575 Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/lltypesystem/rclass.py pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/rpython/rcpy.py pypy/dist/pypy/rpython/rtyper.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/primitive.py pypy/dist/pypy/translator/c/src/module.h Log: (arre, arigo) Fixed the type objects of the hybrid RPython-CPython objects, by creating a PyTypeObject structure with lltype. Added rcpy.cpy_import() to cast from CPython to RPython. lltype pointer solidity fix. A convenient CDefinedIntSymbolic. Wack wack wack until genc produces exactly the correct CPython-friendly kind of code. GenC support for the _pyobjheaders of lltype. Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Fri Jun 9 11:42:39 2006 @@ -752,7 +752,7 @@ raise TypeError, "%s has no field %r" % (CURTYPE, fieldname) if not structptr: raise RuntimeError("direct_fieldptr: NULL argument") - return _subarray._makeptr(structptr._obj, fieldname) + return _subarray._makeptr(structptr._obj, fieldname, structptr._solid) def direct_arrayitems(arrayptr): """Get a pointer to the first item of the array. The resulting @@ -765,7 +765,7 @@ raise TypeError, "direct_arrayitems: not an array" if not arrayptr: raise RuntimeError("direct_arrayitems: NULL argument") - return _subarray._makeptr(arrayptr._obj, 0) + return _subarray._makeptr(arrayptr._obj, 0, arrayptr._solid) def direct_ptradd(ptr, n): """Shift a pointer forward or backward by n items. The pointer must @@ -776,7 +776,7 @@ if not isinstance(ptr._obj, _subarray): raise TypeError("direct_ptradd: only for direct_arrayitems() ptrs") parent, base = parentlink(ptr._obj) - return _subarray._makeptr(parent, base + n) + return _subarray._makeptr(parent, base + n, ptr._solid) def _expose(val, solid=False): """XXX A nice docstring here""" @@ -1130,7 +1130,7 @@ self._parent_type = typeOf(parent) self._parent_index = parentindex if (isinstance(self._parent_type, Struct) - and parentindex == self._parent_type._names[0] + and parentindex in (self._parent_type._names[0], 0) and self._TYPE._gckind == typeOf(parent)._gckind): # keep strong reference to parent, we share the same allocation self._keepparent = parent @@ -1365,7 +1365,7 @@ else: self._parentstructure().setitem(baseoffset + index, value) - def _makeptr(parent, baseoffset_or_fieldname): + def _makeptr(parent, baseoffset_or_fieldname, solid=False): cache = _subarray._cache.setdefault(parent, {}) try: subarray = cache[baseoffset_or_fieldname] @@ -1380,7 +1380,7 @@ ARRAYTYPE = FixedSizeArray(ITEMTYPE, 1) subarray = _subarray(ARRAYTYPE, parent, baseoffset_or_fieldname) cache[baseoffset_or_fieldname] = subarray - return _ptr(Ptr(subarray._TYPE), subarray) + return _ptr(Ptr(subarray._TYPE), subarray, solid) _makeptr = staticmethod(_makeptr) Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Fri Jun 9 11:42:39 2006 @@ -485,8 +485,14 @@ mallocop = 'flavored_malloc' vlist.insert(0, inputconst(Void, flavor)) if flavor == 'cpy': - cpytype = self.classdef._cpy_exported_type_ - c = inputconst(Ptr(PyObject), lltype.pyobjectptr(cpytype)) + cache = self.rtyper.classdef_to_pytypeobject + try: + pytype = cache[self.classdef] + except KeyError: + from pypy.rpython import rcpy + pytype = rcpy.build_pytypeobject(self) + cache[self.classdef] = pytype + c = inputconst(Ptr(PyObject), pytype) vlist.append(c) vptr = llops.genop(mallocop, vlist, resulttype = Ptr(self.object_type)) Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py Fri Jun 9 11:42:39 2006 @@ -1,5 +1,5 @@ from pypy.translator.c.test.test_genc import compile -from pypy.rpython.rcpy import cpy_export +from pypy.rpython.rcpy import cpy_export, cpy_import class W_MyTest(object): @@ -17,8 +17,26 @@ def f(): w = W_MyTest(21) - return cpy_export(w, mytest) + return cpy_export(mytest, w) fn = compile(f, []) res = fn() - assert type(res).__name__.endswith('mytest') + assert type(res).__name__ == 'mytest' + + +def test_cpy_import(): + class mytest(object): + pass + + def f(): + w = W_MyTest(21) + return cpy_export(mytest, w) + + def g(): + obj = f() + w = cpy_import(W_MyTest, obj) + return w.double() + + fn = compile(g, []) + res = fn() + assert res == 42 Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Fri Jun 9 11:42:39 2006 @@ -35,6 +35,19 @@ from pypy.rpython.lltypesystem import lltype return lltype.Signed +class CDefinedIntSymbolic(Symbolic): + + def __init__(self, expr): + self.expr = expr + + def annotation(self): + from pypy.annotation import model + return model.SomeInteger() + + def lltype(self): + from pypy.rpython.lltypesystem import lltype + return lltype.Signed + def instantiate(cls): "Create an empty instance of 'cls'." Modified: pypy/dist/pypy/rpython/rcpy.py ============================================================================== --- pypy/dist/pypy/rpython/rcpy.py (original) +++ pypy/dist/pypy/rpython/rcpy.py Fri Jun 9 11:42:39 2006 @@ -1,14 +1,19 @@ from pypy.rpython.extregistry import ExtRegistryEntry +from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.objectmodel import CDefinedIntSymbolic -def cpy_export(obj, cpytype): +def cpy_export(cpytype, obj): + raise NotImplementedError("only works in translated versions") + +def cpy_import(rpytype, obj): raise NotImplementedError("only works in translated versions") class Entry(ExtRegistryEntry): _about_ = cpy_export - def compute_result_annotation(self, s_obj, s_cpytype): + def compute_result_annotation(self, s_cpytype, s_obj): from pypy.annotation.model import SomeObject from pypy.annotation.model import SomeInstance assert isinstance(s_obj, SomeInstance) @@ -24,7 +29,79 @@ def specialize_call(self, hop): from pypy.rpython.lltypesystem import lltype - r_inst = hop.args_r[0] - v_inst = hop.inputarg(r_inst, arg=0) + s_obj = hop.args_s[1] + r_inst = hop.args_r[1] + v_inst = hop.inputarg(r_inst, arg=1) return hop.genop('cast_pointer', [v_inst], resulttype = lltype.Ptr(lltype.PyObject)) + + +class Entry(ExtRegistryEntry): + _about_ = cpy_import + + def compute_result_annotation(self, s_rpytype, s_obj): + from pypy.annotation.bookkeeper import getbookkeeper + from pypy.annotation.model import SomeInstance + assert s_rpytype.is_constant() + rpytype = s_rpytype.const + bk = getbookkeeper() + return SomeInstance(bk.getuniqueclassdef(rpytype)) + + def specialize_call(self, hop): + from pypy.annotation.model import SomeInstance + from pypy.rpython.robject import pyobj_repr + s_rpytype = hop.args_s[0] + assert s_rpytype.is_constant() + rpytype = s_rpytype.const + classdef = hop.rtyper.annotator.bookkeeper.getuniqueclassdef(rpytype) + s_inst = SomeInstance(classdef) + r_inst = hop.rtyper.getrepr(s_inst) + assert r_inst.lowleveltype.TO._gckind == 'cpy' + v_obj = hop.inputarg(pyobj_repr, arg=1) + return hop.genop('cast_pointer', [v_obj], + resulttype = r_inst.lowleveltype) + + +PyObjPtr = lltype.Ptr(lltype.PyObject) + +PY_TYPE_OBJECT = lltype.PyStruct( + 'PyTypeObject', + ('head', lltype.PyObject), + ('c_ob_size', lltype.Signed), + ('c_tp_name', lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))), + ('c_tp_basicsize', lltype.Signed), + ('c_tp_itemsize', lltype.Signed), + ('c_tp_dealloc', lltype.Signed), + ('c_tp_print', lltype.Signed), + ('c_tp_getattr', lltype.Signed), + ('c_tp_setattr', lltype.Signed), # in + ('c_tp_compare', lltype.Signed), + ('c_tp_repr', lltype.Signed), # progress + ('c_tp_as_number', lltype.Signed), + ('c_tp_as_sequence',lltype.Signed), + ('c_tp_as_mapping',lltype.Signed), + ('c_tp_hash', lltype.Signed), + ('c_tp_call', lltype.Signed), + ('c_tp_str', lltype.Signed), + ('c_tp_getattro', lltype.Signed), + ('c_tp_setattro', lltype.Signed), + ('c_tp_as_buffer', lltype.Signed), + ('c_tp_flags', lltype.Signed), + + hints={'c_name': '_typeobject', 'external': True, 'inline_head': True}) +# XXX should be PyTypeObject but genc inserts 'struct' :-( + +def build_pytypeobject(r_inst): + typetype = lltype.pyobjectptr(type) + pytypeobj = lltype.malloc(PY_TYPE_OBJECT, flavor='cpy', + extra_args=(typetype,)) + name = r_inst.classdef._cpy_exported_type_.__name__ + T = lltype.FixedSizeArray(lltype.Char, len(name)+1) + p = lltype.malloc(T, immortal=True) + for i in range(len(name)): + p[i] = name[i] + p[len(name)] = '\x00' + pytypeobj.c_tp_name = lltype.direct_arrayitems(p) + pytypeobj.c_tp_basicsize = llmemory.sizeof(r_inst.lowleveltype.TO) + pytypeobj.c_tp_flags = CDefinedIntSymbolic('Py_TPFLAGS_DEFAULT') + return lltype.cast_pointer(PyObjPtr, pytypeobj) Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Fri Jun 9 11:42:39 2006 @@ -60,6 +60,7 @@ self.pbc_reprs = {} self.classes_with_wrapper = {} self.wrapper_context = None # or add an extra arg to convertvar? + self.classdef_to_pytypeobject = {} self.concrete_calltables = {} self.class_pbc_attributes = {} self.oo_meth_impls = {} Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Fri Jun 9 11:42:39 2006 @@ -2,13 +2,11 @@ from pypy.translator.c.support import cdecl from pypy.translator.c.node import ContainerNode from pypy.rpython.lltypesystem.lltype import \ - typeOf, Ptr, PyObject, ContainerType, GcArray, GcStruct, \ + typeOf, Ptr, ContainerType, GcArray, GcStruct, \ RuntimeTypeInfo, getRuntimeTypeInfo, top_container from pypy.rpython.memory import gctransform from pypy.rpython.lltypesystem import lltype, llmemory -PyObjPtr = Ptr(PyObject) - class BasicGcPolicy(object): requires_stackless = False @@ -63,13 +61,7 @@ class RefcountingInfo: static_deallocator = None -from pypy.rpython.objectmodel import Symbolic -class REFCOUNT_IMMORTAL(Symbolic): - def annotation(self): - from pypy.annotation.model import SomeInteger - return SomeInteger() - def lltype(self): - return lltype.Signed +from pypy.rpython.objectmodel import CDefinedIntSymbolic class RefcountingGcPolicy(BasicGcPolicy): transformerclass = gctransform.RefcountingGCTransformer @@ -78,7 +70,7 @@ return [('refcount', lltype.Signed)] def common_gcheader_initdata(self, defnode): - return [REFCOUNT_IMMORTAL()] + return [CDefinedIntSymbolic('REFCOUNT_IMMORTAL')] # for structs Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Fri Jun 9 11:42:39 2006 @@ -1,6 +1,6 @@ import autopath import py -from pypy.translator.c.node import PyObjectNode, FuncNode +from pypy.translator.c.node import PyObjectNode, PyObjHeadNode, FuncNode from pypy.translator.c.database import LowLevelDatabase from pypy.translator.c.extfunc import pre_include_code_lines from pypy.translator.gensupp import uniquemodulename, NameManager @@ -689,10 +689,17 @@ print >> f print >> f, 'static globalobjectdef_t globalobjectdefs[] = {' for node in database.globalcontainers(): - if isinstance(node, PyObjectNode): + if isinstance(node, (PyObjectNode, PyObjHeadNode)): for target in node.where_to_copy_me: - print >> f, '\t{%s, "%s"},' % (target, node.name) - print >> f, '\t{ NULL }\t/* Sentinel */' + print >> f, '\t{%s, "%s"},' % (target, node.exported_name) + print >> f, '\t{ NULL, NULL }\t/* Sentinel */' + print >> f, '};' + print >> f + print >> f, 'static cpyobjheaddef_t cpyobjheaddefs[] = {' + for node in database.containerlist: + if isinstance(node, PyObjHeadNode): + print >> f, '\t{"%s", %s},' % (node.exported_name, node.ptrname) + print >> f, '\t{ NULL, NULL }\t/* Sentinel */' print >> f, '};' print >> f print >> f, '/***********************************************************/' Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Fri Jun 9 11:42:39 2006 @@ -1,9 +1,9 @@ from __future__ import generators from pypy.rpython.lltypesystem.lltype import \ Struct, Array, FixedSizeArray, FuncType, PyObjectType, typeOf, \ - GcStruct, GcArray, ContainerType, \ + GcStruct, GcArray, PyStruct, ContainerType, \ parentlink, Ptr, PyObject, Void, OpaqueType, Float, \ - RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray + RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray, _pyobjheader from pypy.rpython.lltypesystem.llmemory import WeakGcAddress from pypy.translator.c.funcgen import FunctionCodeGenerator from pypy.translator.c.external import CExternalFunctionCodeGenerator @@ -16,7 +16,7 @@ def needs_gcheader(T): if not isinstance(T, ContainerType): return False - if T._gckind == 'raw': + if T._gckind != 'gc': return False if isinstance(T, GcStruct): if T._first_struct() != (None, None): @@ -60,6 +60,9 @@ def setup(self): # this computes self.fields + if self.STRUCT._hints.get('external'): # XXX hack + self.fields = None # external definition only + return self.fields = [] db = self.db STRUCT = self.STRUCT @@ -101,22 +104,41 @@ return self.prefix + name def verbatim_field_name(self, name): - assert name.startswith('c_') # produced in this way by rctypes - return name[2:] + if name.startswith('c_'): # produced in this way by rctypes + return name[2:] + else: + # field names have to start with 'c_' or be meant for names that + # vanish from the C source, like 'head' if 'inline_head' is set + raise Exception("field %r should not be accessed in this way" % ( + name,)) def c_struct_field_type(self, name): return self.STRUCT._flds[name] def access_expr(self, baseexpr, fldname): + if self.STRUCT._hints.get('inline_head'): + first, FIRST = self.STRUCT._first_struct() + if fldname == first: + # "invalid" cast according to C99 but that's what CPython + # requires and does all the time :-/ + return '(*(%s) &(%s))' % (cdecl(self.db.gettype(FIRST), '*'), + baseexpr) fldname = self.c_struct_field_name(fldname) return '%s.%s' % (baseexpr, fldname) def ptr_access_expr(self, baseexpr, fldname): + if self.STRUCT._hints.get('inline_head'): + first, FIRST = self.STRUCT._first_struct() + if fldname == first: + # "invalid" cast according to C99 but that's what CPython + # requires and does all the time :-/ + return '(*(%s) %s)' % (cdecl(self.db.gettype(FIRST), '*'), + baseexpr) fldname = self.c_struct_field_name(fldname) return '%s->%s' % (baseexpr, fldname) def definition(self): - if self.STRUCT._hints.get('external'): # XXX hack + if self.fields is None: # external definition only return yield 'struct %s {' % self.name is_empty = True @@ -421,10 +443,13 @@ data.append((name, getattr(self.obj, name))) for name, value in data: - c_name = defnode.c_struct_field_name(name) - lines = generic_initializationexpr(self.db, value, - '%s.%s' % (self.name, c_name), - decoration + name) + if isinstance(value, _pyobjheader): # hack + node = self.db.getcontainernode(value) + lines = [node.pyobj_initexpr()] + else: + c_expr = defnode.access_expr(self.name, name) + lines = generic_initializationexpr(self.db, value, c_expr, + decoration + name) for line in lines: yield '\t' + line if not lines[0].startswith('/*'): @@ -711,6 +736,7 @@ self.obj = obj self.name = db.pyobjmaker.computenameof(obj.value) self.ptrname = self.name + self.exported_name = self.name # a list of expressions giving places where this constant PyObject # must be copied. Normally just in the global variable of the same # name, but see also StructNode.initializationexpr() :-( @@ -725,13 +751,44 @@ return [] +class PyObjHeadNode(ContainerNode): + nodekind = 'pyobj' + + def __init__(self, db, T, obj): + ContainerNode.__init__(self, db, T, obj) + self.where_to_copy_me = [] + self.exported_name = db.namespace.uniquename('cpyobj') + + def basename(self): + raise Exception("PyObjHead should always have a parent") + + def enum_dependencies(self): + yield self.obj.ob_type + + def pyobj_initexpr(self): + parent, parentindex = parentlink(self.obj) + assert typeOf(parent)._hints.get('inline_head') + typenode = self.db.getcontainernode(self.obj.ob_type._obj) + typenode.where_to_copy_me.append('(PyObject **) & %s.ob_type' % ( + self.name,)) + return 'PyObject_HEAD_INIT(NULL)' + + +def objectnode_factory(db, T, obj): + if isinstance(obj, _pyobjheader): + return PyObjHeadNode(db, T, obj) + else: + return PyObjectNode(db, T, obj) + + ContainerNodeFactory = { Struct: StructNode, GcStruct: StructNode, + PyStruct: StructNode, Array: ArrayNode, GcArray: ArrayNode, FixedSizeArray: FixedSizeArrayNode, FuncType: FuncNode, OpaqueType: opaquenode_factory, - PyObjectType: PyObjectNode, + PyObjectType: objectnode_factory, } Modified: pypy/dist/pypy/translator/c/primitive.py ============================================================================== --- pypy/dist/pypy/translator/c/primitive.py (original) +++ pypy/dist/pypy/translator/c/primitive.py Fri Jun 9 11:42:39 2006 @@ -1,5 +1,6 @@ import sys from pypy.rpython.objectmodel import Symbolic, ComputedIntSymbolic +from pypy.rpython.objectmodel import CDefinedIntSymbolic from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.lltypesystem.llmemory import Address, fakeaddress, \ AddressOffset, ItemOffset, ArrayItemsOffset, FieldOffset, \ @@ -14,7 +15,6 @@ def name_signed(value, db): if isinstance(value, Symbolic): - from pypy.translator.c.gc import REFCOUNT_IMMORTAL if isinstance(value, FieldOffset): structnode = db.gettypedefnode(value.TYPE) return 'offsetof(%s, %s)'%( @@ -39,8 +39,8 @@ return '0' elif type(value) == GCHeaderOffset: return '0' - elif type(value) == REFCOUNT_IMMORTAL: - return 'REFCOUNT_IMMORTAL' + elif isinstance(value, CDefinedIntSymbolic): + return str(value.expr) elif isinstance(value, ComputedIntSymbolic): value = value.compute_fn() else: Modified: pypy/dist/pypy/translator/c/src/module.h ============================================================================== --- pypy/dist/pypy/translator/c/src/module.h (original) +++ pypy/dist/pypy/translator/c/src/module.h Fri Jun 9 11:42:39 2006 @@ -40,7 +40,7 @@ return; \ if (setup_initcode(frozen_initcode, FROZEN_INITCODE_SIZE) < 0) \ return; \ - if (setup_globalobjects(globalobjectdefs) < 0) \ + if (setup_globalobjects(globalobjectdefs, cpyobjheaddefs) < 0) \ return; /*** table of global objects ***/ @@ -53,6 +53,11 @@ } globalobjectdef_t; typedef struct { + char* name; + PyObject* cpyobj; +} cpyobjheaddef_t; + +typedef struct { PyObject** p; char* gfunc_name; PyMethodDef ml; @@ -69,11 +74,29 @@ #ifndef PYPY_NOT_MAIN_FILE -static int setup_globalobjects(globalobjectdef_t* def) +static int setup_globalobjects(globalobjectdef_t* globtable, + cpyobjheaddef_t* cpyheadtable) { PyObject* obj; - - for (; def->p != NULL; def++) { + globalobjectdef_t* def; + cpyobjheaddef_t* cpydef; + + /* Store the object given by their heads into the module's dict. + Warning: these object heads might still be invalid, e.g. + typically their ob_type needs patching! + But PyDict_SetItemString() doesn't inspect them... + */ + for (cpydef = cpyheadtable; cpydef->name != NULL; cpydef++) { + obj = cpydef->cpyobj; + if (PyDict_SetItemString(this_module_globals, + cpydef->name, obj) < 0) + return -1; + } + /* Patch all locations that need to contain a specific PyObject*. + This must go after the previous loop, otherwise + PyDict_GetItemString() might not find some of them. + */ + for (def = globtable; def->p != NULL; def++) { obj = PyDict_GetItemString(this_module_globals, def->name); if (obj == NULL) { PyErr_Format(PyExc_AttributeError, @@ -84,6 +107,16 @@ Py_INCREF(obj); *def->p = obj; /* store the object ref in the global var */ } + /* All objects should be valid at this point. Loop again and + make sure all types are ready. + */ + for (cpydef = cpyheadtable; cpydef->name != NULL; cpydef++) { + obj = cpydef->cpyobj; + if (PyType_Check(obj)) { + if (PyType_Ready((PyTypeObject*) obj) < 0) + return -1; + } + } return 0; } From ericvrp at codespeak.net Fri Jun 9 11:56:10 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 9 Jun 2006 11:56:10 +0200 (CEST) Subject: [pypy-svn] r28576 - pypy/extradoc/sprintinfo/post-ep2006 Message-ID: <20060609095610.99F2F10060@code0.codespeak.net> Author: ericvrp Date: Fri Jun 9 11:56:07 2006 New Revision: 28576 Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt Log: Europython flight booked for 2-9th Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/post-ep2006/people.txt (original) +++ pypy/extradoc/sprintinfo/post-ep2006/people.txt Fri Jun 9 11:56:07 2006 @@ -19,7 +19,7 @@ Christian Tismer 6-9th ? Antonio Cuni 6-9th CERN Hostel Anders Lehmann 6-9th ? -Eric van Riet Paap ? ? +Eric van Riet Paap 2-9th ? Lawrence Oluyede 6-9th CERN Hostel ==================== ============== ===================== From ericvrp at codespeak.net Fri Jun 9 12:16:33 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 9 Jun 2006 12:16:33 +0200 (CEST) Subject: [pypy-svn] r28578 - pypy/dist/pypy/translator/js Message-ID: <20060609101633.0FCFB10036@code0.codespeak.net> Author: ericvrp Date: Fri Jun 9 12:16:30 2006 New Revision: 28578 Removed: pypy/dist/pypy/translator/js/ Log: Moved old (non ootypesystem) javascript backend to /svn/user/ericvrp . Before PyPy 0.9 js2 should be renamed to js and (getting_started) docs should be updated. From mwh at codespeak.net Fri Jun 9 13:02:32 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Jun 2006 13:02:32 +0200 (CEST) Subject: [pypy-svn] r28579 - pypy/dist/pypy/rpython/memory Message-ID: <20060609110232.E168A10036@code0.codespeak.net> Author: mwh Date: Fri Jun 9 13:02:30 2006 New Revision: 28579 Modified: pypy/dist/pypy/rpython/memory/gctransform.py Log: remove unused import Modified: pypy/dist/pypy/rpython/memory/gctransform.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform.py (original) +++ pypy/dist/pypy/rpython/memory/gctransform.py Fri Jun 9 13:02:30 2006 @@ -8,7 +8,7 @@ from pypy.translator.unsimplify import starts_with_empty_block from pypy.translator.unsimplify import remove_empty_startblock from pypy.translator.translator import graphof -from pypy.translator.backendopt.support import var_needsgc, needs_conservative_livevar_calculation +from pypy.translator.backendopt.support import var_needsgc from pypy.translator.backendopt import inline from pypy.translator.backendopt import graphanalyze from pypy.translator.backendopt.ssa import DataFlowFamilyBuilder From mwh at codespeak.net Fri Jun 9 13:21:52 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Jun 2006 13:21:52 +0200 (CEST) Subject: [pypy-svn] r28580 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20060609112152.9307410053@code0.codespeak.net> Author: mwh Date: Fri Jun 9 13:21:49 2006 New Revision: 28580 Added: pypy/dist/pypy/translator/backendopt/test/test_support.py (contents, props changed) Modified: pypy/dist/pypy/translator/backendopt/support.py Log: (mwh, pedronis) conform to tradition by fixing a few more cases around the area of where to insert keepalives. break with tradition with ACTUALLY WRITING TESTS for this stuff. ffs. (we've been guilty of this too, not pointing fingers :-) Modified: pypy/dist/pypy/translator/backendopt/support.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/support.py (original) +++ pypy/dist/pypy/translator/backendopt/support.py Fri Jun 9 13:21:49 2006 @@ -40,13 +40,18 @@ def needs_conservative_livevar_calculation(block): from pypy.rpython.lltypesystem import rclass vars = block.getvariables() + assert len(block.exits) == 1 + exitingvars = block.exits[0].args for var in vars: TYPE = getattr(var, "concretetype", lltype.Ptr(lltype.PyObject)) if isinstance(TYPE, lltype.Ptr) and not var_needsgc(var): + if isinstance(TYPE.TO, lltype.FuncType): + continue try: lltype.castable(TYPE, rclass.CLASSTYPE) except lltype.InvalidCast: - return True + if var in exitingvars: + return True else: return False Added: pypy/dist/pypy/translator/backendopt/test/test_support.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/backendopt/test/test_support.py Fri Jun 9 13:21:49 2006 @@ -0,0 +1,58 @@ +from pypy.translator.backendopt.support import \ + needs_conservative_livevar_calculation, split_block_with_keepalive + +from pypy.rpython.rtyper import LowLevelOpList +from pypy.rpython.lltypesystem import lltype +from pypy.objspace.flow import model + +NonGcB = lltype.Struct("B", ('x', lltype.Signed)) +GcA = lltype.GcStruct("A", ('b', NonGcB), ('c', lltype.Ptr(lltype.FuncType([], lltype.Void)))) + +def varoftype(concretetype): + var = model.Variable() + var.concretetype = concretetype + return var + +def test_nclc_should_be_true(): + llops = LowLevelOpList() + ptr_a = varoftype(lltype.Ptr(GcA)) + v_res = llops.genop("getfield", [ptr_a, model.Constant('b', lltype.Void)], + resulttype=lltype.Ptr(NonGcB)) + block = model.Block([ptr_a]) + block.operations.extend(llops) + block.closeblock(model.Link([v_res], None)) + assert needs_conservative_livevar_calculation(block) + +def test_nclc_nongc_not_passed_on(): + llops = LowLevelOpList() + ptr_a = varoftype(lltype.Ptr(GcA)) + v_res = llops.genop("getfield", [ptr_a, model.Constant('b', lltype.Void)], + resulttype=lltype.Ptr(NonGcB)) + block = model.Block([ptr_a]) + block.operations.extend(llops) + block.closeblock(model.Link([ptr_a], None)) + assert not needs_conservative_livevar_calculation(block) + +def test_nclc_ignore_functype(): + llops = LowLevelOpList() + ptr_a = varoftype(lltype.Ptr(GcA)) + v_res = llops.genop("getfield", [ptr_a, model.Constant('c', lltype.Void)], + resulttype=GcA.c) + block = model.Block([ptr_a]) + block.operations.extend(llops) + block.closeblock(model.Link([v_res], None)) + assert not needs_conservative_livevar_calculation(block) + +def test_sbwk_should_insert_keepalives(): + llops = LowLevelOpList() + ptr_a = varoftype(lltype.Ptr(GcA)) + v_res = llops.genop("getfield", [ptr_a, model.Constant('b', lltype.Void)], + resulttype=lltype.Ptr(NonGcB)) + llops.genop("direct_call", [model.Constant(None, lltype.Void), v_res], + resulttype=lltype.Void) + block = model.Block([ptr_a]) + block.operations.extend(llops) + block.closeblock(model.Link([], None)) + link = split_block_with_keepalive(block, 1) + assert 'keepalive' in [op.opname for op in link.target.operations] + From arigo at codespeak.net Fri Jun 9 13:30:37 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Jun 2006 13:30:37 +0200 (CEST) Subject: [pypy-svn] r28581 - in pypy/dist/pypy: annotation rpython rpython/lltypesystem/test translator/c translator/c/src translator/c/test Message-ID: <20060609113037.D166310053@code0.codespeak.net> Author: arigo Date: Fri Jun 9 13:30:35 2006 New Revision: 28581 Modified: pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rcpy.py pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/src/mem.h pypy/dist/pypy/translator/c/test/test_genc.py Log: (arre, arigo) Added tp_alloc/tp_free and the corresponding support for lltyping helpers containing 'malloc(PyObject, flavor='cpy', extra_args=(tp,))'. Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Fri Jun 9 13:30:35 2006 @@ -384,24 +384,31 @@ from pypy.annotation.model import SomePtr from pypy.rpython.lltypesystem import lltype -def malloc(T, n=None, s_flavor=None): - assert n is None or (n.knowntype == int or issubclass(n.knowntype, pypy.rpython.rarithmetic.base_int)) - assert T.is_constant() - if n is not None: +def malloc(s_T, s_n=None, s_flavor=None, s_extra_args=None): + assert (s_n is None or s_n.knowntype == int + or issubclass(s_n.knowntype, pypy.rpython.rarithmetic.base_int)) + assert s_T.is_constant() + if s_n is not None: n = 1 + else: + n = None if s_flavor is None: - p = lltype.malloc(T.const, n) + p = lltype.malloc(s_T.const, n) + r = SomePtr(lltype.typeOf(p)) else: assert s_flavor.is_constant() - p = lltype.malloc(T.const, n, s_flavor.const) - r = SomePtr(lltype.typeOf(p)) + # not sure how to call malloc() for the example 'p' in the + # presence of s_extraargs + r = SomePtr(lltype.Ptr(s_T.const)) return r def free(s_p, s_flavor): assert s_flavor.is_constant() - T = s_p.ll_ptrtype.TO - p = lltype.malloc(T, flavor=s_flavor.const) - lltype.free(p, flavor=s_flavor.const) + # same problem as in malloc(): some flavors are not easy to + # malloc-by-example + #T = s_p.ll_ptrtype.TO + #p = lltype.malloc(T, flavor=s_flavor.const) + #lltype.free(p, flavor=s_flavor.const) def typeOf(s_val): lltype = annotation_to_lltype(s_val, info="in typeOf(): ") Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py Fri Jun 9 13:30:35 2006 @@ -19,7 +19,7 @@ w = W_MyTest(21) return cpy_export(mytest, w) - fn = compile(f, []) + fn = compile(f, [], expected_extra_mallocs=1) res = fn() assert type(res).__name__ == 'mytest' @@ -40,3 +40,29 @@ fn = compile(g, []) res = fn() assert res == 42 + + +def test_tp_dealloc(): + import py; py.test.skip("in-progress") + class mytest(object): + pass + + class A(object): + pass + + def f(): + w = W_MyTest(21) + w.a = A() + w.a.x = 4 + return cpy_export(mytest, w) + + def g(): + obj = f() + w = cpy_import(W_MyTest, obj) + return w.a.x + + fn = compile(g, [], backendopt=False) + res = fn() + # the A() should have been deallocated too, otherwise the number + # of mallocs doesn't match the number of frees + assert res == 4 Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Fri Jun 9 13:30:35 2006 @@ -160,6 +160,23 @@ return NotImplemented return llops.convertvar(v, r_from.self_repr, r_to.self_repr) +def parse_kwds(hop, *argspec_i_r): + lst = [i for (i, r) in argspec_i_r if i is not None] + lst.sort() + if lst != range(hop.nb_args - len(lst), hop.nb_args): + raise TyperError("keyword args are expected to be at the end of " + "the 'hop' arg list") + result = [] + for i, r in argspec_i_r: + if i is not None: + if r is None: + r = hop.args_r[i] + result.append(hop.inputarg(r, arg=i)) + else: + result.append(None) + hop.nb_args -= len(lst) + return result + # ____________________________________________________________ def rtype_builtin_bool(hop): @@ -297,19 +314,28 @@ BUILTIN_TYPER[object.__init__] = rtype_object__init__ # annotation of low-level types -def rtype_malloc(hop, i_flavor=None): +def rtype_malloc(hop, i_flavor=None, i_extra_args=None): assert hop.args_s[0].is_constant() vlist = [hop.inputarg(lltype.Void, arg=0)] opname = 'malloc' - positional_args = hop.nb_args - if i_flavor is not None: - assert i_flavor == hop.nb_args-1 - positional_args -= 1 - vlist.insert(0, hop.inputarg(lltype.Void, arg=i_flavor)) + v_flavor, v_extra_args = parse_kwds(hop, (i_flavor, lltype.Void), + (i_extra_args, None)) + if v_flavor is not None: + vlist.insert(0, v_flavor) opname = 'flavored_' + opname - if positional_args == 2: + if hop.nb_args == 2: vlist.append(hop.inputarg(lltype.Signed, arg=1)) opname += '_varsize' + + if v_extra_args is not None: + # items of the v_extra_args tuple become additional args to the op + from pypy.rpython.rtuple import AbstractTupleRepr + r_tup = hop.args_r[i_extra_args] + assert isinstance(r_tup, AbstractTupleRepr) + for n, r in enumerate(r_tup.items_r): + v = r_tup.getitem(hop.llops, v_extra_args, n) + vlist.append(v) + return hop.genop(opname, vlist, resulttype = hop.r_result.lowleveltype) def rtype_free(hop, i_flavor): Modified: pypy/dist/pypy/rpython/rcpy.py ============================================================================== --- pypy/dist/pypy/rpython/rcpy.py (original) +++ pypy/dist/pypy/rpython/rcpy.py Fri Jun 9 13:30:35 2006 @@ -64,7 +64,8 @@ PyObjPtr = lltype.Ptr(lltype.PyObject) -PY_TYPE_OBJECT = lltype.PyStruct( +PY_TYPE_OBJECT = lltype.PyForwardReference() +PY_TYPE_OBJECT.become(lltype.PyStruct( 'PyTypeObject', ('head', lltype.PyObject), ('c_ob_size', lltype.Signed), @@ -87,10 +88,41 @@ ('c_tp_setattro', lltype.Signed), ('c_tp_as_buffer', lltype.Signed), ('c_tp_flags', lltype.Signed), + ('c_tp_doc', lltype.Signed), + ('c_tp_traverse', lltype.Signed), + ('c_tp_clear', lltype.Signed), + ('c_tp_richcompare',lltype.Signed), + ('c_tp_weaklistoffset',lltype.Signed), + ('c_tp_iter', lltype.Signed), + ('c_tp_iternext', lltype.Signed), + ('c_tp_methods', lltype.Signed), + ('c_tp_members', lltype.Signed), + ('c_tp_getset', lltype.Signed), + ('c_tp_base', lltype.Signed), + ('c_tp_dict', lltype.Signed), + ('c_tp_descr_get', lltype.Signed), + ('c_tp_descr_set', lltype.Signed), + ('c_tp_dictoffset',lltype.Signed), + ('c_tp_init', lltype.Signed), + ('c_tp_alloc', lltype.Ptr(lltype.FuncType([lltype.Ptr(PY_TYPE_OBJECT), + lltype.Signed], + PyObjPtr))), + ('c_tp_new', lltype.Signed), + ('c_tp_free', lltype.Ptr(lltype.FuncType([llmemory.Address], + lltype.Void))), - hints={'c_name': '_typeobject', 'external': True, 'inline_head': True}) + hints={'c_name': '_typeobject', 'external': True, 'inline_head': True})) # XXX should be PyTypeObject but genc inserts 'struct' :-( +def ll_tp_alloc(tp, itemcount): + # XXX pass itemcount too + return lltype.malloc(lltype.PyObject, flavor='cpy', extra_args=(tp,)) + +def ll_tp_free(addr): + # hack: don't cast addr to PyObjPtr, otherwise there is an incref/decref + # added around the free! + lltype.free(addr, flavor='cpy') + def build_pytypeobject(r_inst): typetype = lltype.pyobjectptr(type) pytypeobj = lltype.malloc(PY_TYPE_OBJECT, flavor='cpy', @@ -104,4 +136,10 @@ pytypeobj.c_tp_name = lltype.direct_arrayitems(p) pytypeobj.c_tp_basicsize = llmemory.sizeof(r_inst.lowleveltype.TO) pytypeobj.c_tp_flags = CDefinedIntSymbolic('Py_TPFLAGS_DEFAULT') + pytypeobj.c_tp_alloc = r_inst.rtyper.annotate_helper_fn( + ll_tp_alloc, + [lltype.Ptr(PY_TYPE_OBJECT), lltype.Signed]) + pytypeobj.c_tp_free = r_inst.rtyper.annotate_helper_fn( + ll_tp_free, + [llmemory.Address]) return lltype.cast_pointer(PyObjPtr, pytypeobj) Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Fri Jun 9 13:30:35 2006 @@ -562,16 +562,16 @@ return "OP_STACK_MALLOC(%s, %s);" % (esize, eresult) elif flavor == "cpy": cpytype = self.expr(op.args[2]) - return "%s = PyObject_New(%s, (PyTypeObject *)%s);" % ( - eresult, cdecl(typename, ''), cpytype) + return "OP_CPY_MALLOC(%s, %s);" % (cpytype, eresult) else: raise NotImplementedError def OP_FLAVORED_FREE(self, op): flavor = op.args[0].value if flavor == "raw": - return "OP_RAW_FREE(%s, %s)" % (self.expr(op.args[1]), - self.expr(op.result)) + return "OP_RAW_FREE(%s)" % (self.expr(op.args[1]),) + elif flavor == "cpy": + return "OP_CPY_FREE(%s)" % (self.expr(op.args[1]),) else: raise NotImplementedError Modified: pypy/dist/pypy/translator/c/src/mem.h ============================================================================== --- pypy/dist/pypy/translator/c/src/mem.h (original) +++ pypy/dist/pypy/translator/c/src/mem.h Fri Jun 9 13:30:35 2006 @@ -14,7 +14,7 @@ r = (void*) alloca(size); \ if (r == NULL) FAIL_EXCEPTION(PyExc_MemoryError, "out of memory");\ -#define OP_RAW_FREE(x,r) OP_FREE(x) +#define OP_RAW_FREE(x) OP_FREE(x) #define OP_RAW_MEMCOPY(x,y,size,r) memcpy(y,x,size); /************************************************************/ @@ -119,3 +119,15 @@ #define PUSH_ALIVE(obj) #endif /* USING_NO_GC */ + +/************************************************************/ +/* rcpy support */ + +#define OP_CPY_MALLOC(cpytype, r) { \ + /* XXX add tp_itemsize later */ \ + OP_RAW_MALLOC(((PyTypeObject *)cpytype)->tp_basicsize, r); \ + if (r) { \ + PyObject_Init((PyObject *)r, (PyTypeObject *)cpytype); \ + } \ + } +#define OP_CPY_FREE(x) OP_RAW_FREE(x) Modified: pypy/dist/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_genc.py (original) +++ pypy/dist/pypy/translator/c/test/test_genc.py Fri Jun 9 13:30:35 2006 @@ -31,7 +31,7 @@ return m def compile(fn, argtypes, view=False, gcpolicy=None, backendopt=True, - annotatorpolicy=None): + annotatorpolicy=None, expected_extra_mallocs=0): t = TranslationContext() a = t.buildannotator(policy=annotatorpolicy) a.build_types(fn, argtypes) @@ -50,7 +50,7 @@ return compiled_fn(*args, **kwds) finally: mallocs, frees = module.malloc_counters() - assert mallocs == frees + assert mallocs - frees == expected_extra_mallocs return checking_fn def test_func_as_pyobject(): From mwh at codespeak.net Fri Jun 9 13:31:17 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Jun 2006 13:31:17 +0200 (CEST) Subject: [pypy-svn] r28582 - pypy/dist/pypy/translator/backendopt/test Message-ID: <20060609113117.A337110053@code0.codespeak.net> Author: mwh Date: Fri Jun 9 13:31:15 2006 New Revision: 28582 Modified: pypy/dist/pypy/translator/backendopt/test/test_support.py Log: (mwh, pedronis) add another test and some comments about what we're testing. Modified: pypy/dist/pypy/translator/backendopt/test/test_support.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_support.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_support.py Fri Jun 9 13:31:15 2006 @@ -14,9 +14,13 @@ return var def test_nclc_should_be_true(): + # this is testing a block like: + # +--- inputargs: pointer_to_gc + # | v0 <- op_getsubstruct pointer_to_gc 'b' + # +--- exitargs: v0 (i.e. pointer to non-gc) llops = LowLevelOpList() ptr_a = varoftype(lltype.Ptr(GcA)) - v_res = llops.genop("getfield", [ptr_a, model.Constant('b', lltype.Void)], + v_res = llops.genop("getsubstruct", [ptr_a, model.Constant('b', lltype.Void)], resulttype=lltype.Ptr(NonGcB)) block = model.Block([ptr_a]) block.operations.extend(llops) @@ -24,9 +28,12 @@ assert needs_conservative_livevar_calculation(block) def test_nclc_nongc_not_passed_on(): + # +--- inputargs: pointer_to_gc + # | v0 <- op_getsubstruct pointer_to_gc 'b' + # +--- exitargs: pointer_to_gc (i.e. the pointer to non-gc doesn't leave the block) llops = LowLevelOpList() ptr_a = varoftype(lltype.Ptr(GcA)) - v_res = llops.genop("getfield", [ptr_a, model.Constant('b', lltype.Void)], + v_res = llops.genop("getsubstruct", [ptr_a, model.Constant('b', lltype.Void)], resulttype=lltype.Ptr(NonGcB)) block = model.Block([ptr_a]) block.operations.extend(llops) @@ -34,6 +41,12 @@ assert not needs_conservative_livevar_calculation(block) def test_nclc_ignore_functype(): + # +--- inputargs: pointer_to_gc + # | v0 <- op_getfield pointer_to_gc 'c' + # +--- exitargs: v0 (i.e. a pointer to function) + # pointers to functions are 'not gc' but functions are also + # immortal so you don't need to muck around inserting keepalives + # so *they* don't die! llops = LowLevelOpList() ptr_a = varoftype(lltype.Ptr(GcA)) v_res = llops.genop("getfield", [ptr_a, model.Constant('c', lltype.Void)], @@ -44,6 +57,9 @@ assert not needs_conservative_livevar_calculation(block) def test_sbwk_should_insert_keepalives(): + # this is testing something like: + # v0 <- op_producing_non_gc + # v1 <- op_using_v0 <- split here llops = LowLevelOpList() ptr_a = varoftype(lltype.Ptr(GcA)) v_res = llops.genop("getfield", [ptr_a, model.Constant('b', lltype.Void)], @@ -55,4 +71,24 @@ block.closeblock(model.Link([], None)) link = split_block_with_keepalive(block, 1) assert 'keepalive' in [op.opname for op in link.target.operations] - + +def test_sbwk_should_insert_keepalives_2(): + # this is testing something like: + # v0 <- op_producing_non_gc + # v1 <- op_not_using_v0 <- split here + # v2 <- op_using_v0 + llops = LowLevelOpList() + ptr_a = varoftype(lltype.Ptr(GcA)) + v_res = llops.genop("getfield", [ptr_a, model.Constant('b', lltype.Void)], + resulttype=lltype.Ptr(NonGcB)) + llops.genop("direct_call", [model.Constant(None, lltype.Void)], + resulttype=lltype.Void) + llops.genop("direct_call", [model.Constant(None, lltype.Void), v_res], + resulttype=lltype.Void) + block = model.Block([ptr_a]) + block.operations.extend(llops) + block.closeblock(model.Link([], None)) + link = split_block_with_keepalive(block, 1) + assert 'keepalive' in [op.opname for op in link.target.operations] + + From ericvrp at codespeak.net Fri Jun 9 14:30:54 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 9 Jun 2006 14:30:54 +0200 (CEST) Subject: [pypy-svn] r28583 - pypy/dist/pypy/translator/js2/proxy/testme Message-ID: <20060609123054.3C05910036@code0.codespeak.net> Author: ericvrp Date: Fri Jun 9 14:30:52 2006 New Revision: 28583 Modified: pypy/dist/pypy/translator/js2/proxy/testme/controllers.py Log: Remove hardcoding of BnB server port Modified: pypy/dist/pypy/translator/js2/proxy/testme/controllers.py ============================================================================== --- pypy/dist/pypy/translator/js2/proxy/testme/controllers.py (original) +++ pypy/dist/pypy/translator/js2/proxy/testme/controllers.py Fri Jun 9 14:30:52 2006 @@ -5,6 +5,8 @@ import PIL.Image import zlib import socket +import urllib +import re class SessionData: @@ -72,14 +74,13 @@ class Root(controllers.Root): - host = 'localhost' - port = 32819 #XXX automate this - size = 1024 - - #data _sessionData = {} n_header_lines = 2 + host = 'localhost' + port = re.findall('value=".*"', urllib.urlopen('http://%s:8000' % host).read())[0] + port = int(port[7:-1]) + def sessionData(self): session = cherrypy.session sessionid = session['_id'] @@ -105,7 +106,8 @@ def recv(self): #XXX hangs if not first sending a ping! d = self.sessionData() - data = d.data + self.sessionSocket().recv(self.size) + size = 1024 + data = d.data + self.sessionSocket().recv(size) while self.n_header_lines > 0 and '\n' in data: self.n_header_lines -= 1 header_line, data = data.split('\n',1) From arigo at codespeak.net Fri Jun 9 14:37:28 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Jun 2006 14:37:28 +0200 (CEST) Subject: [pypy-svn] r28584 - pypy/dist/pypy/rpython/lltypesystem Message-ID: <20060609123728.6540F10036@code0.codespeak.net> Author: arigo Date: Fri Jun 9 14:37:26 2006 New Revision: 28584 Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py Log: (arre, arigo) Fix for translator.c.test.test_lladdresses:test_flavored_malloc_stack. Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Fri Jun 9 14:37:26 2006 @@ -80,6 +80,11 @@ 'raw': NONGCOBJECT, 'cpy': CPYOBJECT} +LLFLAVOR = {'gc' : 'gc', + 'raw' : 'raw', + 'cpy' : 'cpy', + 'stack': 'raw', + } def cast_vtable_to_typeptr(vtable): while typeOf(vtable).TO != OBJECT_VTABLE: @@ -298,9 +303,9 @@ def __init__(self, rtyper, classdef, gcflavor='gc'): AbstractInstanceRepr.__init__(self, rtyper, classdef) if classdef is None: - self.object_type = OBJECT_BY_FLAVOR[gcflavor] + self.object_type = OBJECT_BY_FLAVOR[LLFLAVOR[gcflavor]] else: - ForwardRef = lltype.FORWARDREF_BY_FLAVOR[gcflavor] + ForwardRef = lltype.FORWARDREF_BY_FLAVOR[LLFLAVOR[gcflavor]] self.object_type = ForwardRef() self.prebuiltinstances = {} # { id(x): (x, _ptr) } @@ -344,7 +349,7 @@ fields['_wrapper_'] = 'wrapper', pyobj_repr llfields.append(('wrapper', Ptr(PyObject))) - MkStruct = lltype.STRUCT_BY_FLAVOR[self.gcflavor] + MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] object_type = MkStruct(self.classdef.name, ('super', self.rbase.object_type), *llfields) From mwh at codespeak.net Fri Jun 9 14:42:42 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Jun 2006 14:42:42 +0200 (CEST) Subject: [pypy-svn] r28585 - pypy/dist/pypy/translator/stackless/test Message-ID: <20060609124242.A375B10060@code0.codespeak.net> Author: mwh Date: Fri Jun 9 14:42:39 2006 New Revision: 28585 Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py pypy/dist/pypy/translator/stackless/test/test_transform.py Log: (mwh, pedronis) a possibly not quite minimal test for what turned out to the last problem preventing a --new-stackless build with resume points with backend optimization switched on which was fixed by the latest keepalive fiddling. Modified: pypy/dist/pypy/translator/stackless/test/test_resume_point.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_resume_point.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_resume_point.py Fri Jun 9 14:42:39 2006 @@ -4,17 +4,24 @@ import py from pypy.rpython import rstack -def transform_stackless_function(fn, do_inline=False): +def do_inline(t): + from pypy.translator.backendopt import inline, removenoops + callgraph = inline.inlinable_static_callers(t.graphs) + inline.auto_inlining(t, 1, callgraph=callgraph) + for graph in t.graphs: + removenoops.remove_superfluous_keep_alive(graph) + removenoops.remove_duplicate_casts(graph, t) + +def do_backendopt(t): + from pypy.translator.backendopt import all + all.backend_optimizations(t) + +def transform_stackless_function(fn, callback_for_transform=None): def wrapper(argv): return fn() t = rtype_stackless_function(wrapper) - if do_inline: - from pypy.translator.backendopt import inline, removenoops - callgraph = inline.inlinable_static_callers(t.graphs) - inline.auto_inlining(t, 1, callgraph=callgraph) - for graph in t.graphs: - removenoops.remove_superfluous_keep_alive(graph) - removenoops.remove_duplicate_casts(graph, t) + if callback_for_transform: + callback_for_transform(t) if conftest.option.view: t.view() st = StacklessTransformer(t, wrapper, False) @@ -310,7 +317,7 @@ f = FakeFrame(s) call_function(f, 100, W_Root(), W_Root()) return one() - transform_stackless_function(example, do_inline=True) + transform_stackless_function(example, do_backendopt) def test_always_raising(): def g(out): @@ -343,4 +350,115 @@ res = run_stackless_function(example) assert res == 200 - +def test_more_mess(): + from pypy.interpreter.miscutils import Stack + + def new_framestack(): + return Stack() + + class FakeFrame: + pass + class FakeSlpFrame: + def switch(self): + rstack.stack_unwind() + return FakeSlpFrame() + + class FakeCoState: + def update(self, new): + self.last, self.current = self.current, new + frame, new.frame = new.frame, None + return frame + def do_things_to_do(self): + self.do_things_to_do() + + costate = FakeCoState() + costate.current = None + + class FakeExecutionContext: + def __init__(self): + self.space = space + self.framestack = new_framestack() + + def subcontext_new(coobj): + coobj.framestack = new_framestack() + subcontext_new = staticmethod(subcontext_new) + + def subcontext_enter(self, next): + self.framestack = next.framestack + + def subcontext_leave(self, current): + current.framestack = self.framestack + + class FakeSpace: + def __init__(self): + self.ec = None + def getexecutioncontext(self): + if self.ec is None: + self.ec = FakeExecutionContext() + return self.ec + + space = FakeSpace() + + class MainCoroutineGetter(object): + def __init__(self): + self.costate = None + def _get_default_costate(self): + if self.costate is None: + costate = FakeCoState() + self.costate = costate + return costate + return self.costate + + main_coroutine_getter = MainCoroutineGetter() + + class FakeCoroutine: + def __init__(self): + self.frame = None + self.costate = costate + space.getexecutioncontext().subcontext_new(self) + + def switch(self): + if self.frame is None: + raise RuntimeError + state = self.costate + incoming_frame = state.update(self).switch() + rstack.resume_point("coroutine_switch", self, state, returns=incoming_frame) + left = state.last + left.frame = incoming_frame + left.goodbye() + self.hello() + #main_coroutine_getter._get_default_costate().do_things_to_do() + + def hello(self): + pass + + def goodbye(self): + pass + + class FakeAppCoroutine(FakeCoroutine): + def __init__(self): + FakeCoroutine.__init__(self) + self.space = space + + def hello(self): + ec = self.space.getexecutioncontext() + ec.subcontext_enter(self) + + def goodbye(self): + ec = self.space.getexecutioncontext() + ec.subcontext_leave(self) + + def example(): + coro = FakeAppCoroutine() + othercoro = FakeCoroutine() + othercoro.frame = FakeSlpFrame() + if one(): + coro.frame = FakeSlpFrame() + if one() - one(): + coro.costate = FakeCoState() + coro.costate.last = coro.costate.current = othercoro + space.getexecutioncontext().framestack.push(FakeFrame()) + coro.switch() + return one() + + transform_stackless_function(example, do_backendopt) Modified: pypy/dist/pypy/translator/stackless/test/test_transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_transform.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_transform.py Fri Jun 9 14:42:39 2006 @@ -254,8 +254,8 @@ from pypy.translator.transform import insert_ll_stackcheck insert_ll_stackcheck(t) - if conftest.option.view: - t.view() +# if conftest.option.view: +# t.view() return t def run_stackless_function(fn): From mwh at codespeak.net Fri Jun 9 15:15:20 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Jun 2006 15:15:20 +0200 (CEST) Subject: [pypy-svn] r28586 - in pypy/dist/pypy/interpreter: . test Message-ID: <20060609131520.F05C110034@code0.codespeak.net> Author: mwh Date: Fri Jun 9 15:15:18 2006 New Revision: 28586 Modified: pypy/dist/pypy/interpreter/function.py pypy/dist/pypy/interpreter/test/test_pickle.py Log: (mwh, pedronis) Test + implementation for pickling builtin methods. Modified: pypy/dist/pypy/interpreter/function.py ============================================================================== --- pypy/dist/pypy/interpreter/function.py (original) +++ pypy/dist/pypy/interpreter/function.py Fri Jun 9 15:15:18 2006 @@ -404,12 +404,20 @@ def descr_method__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule + from pypy.interpreter.gateway import BuiltinCode w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('method_new') w = space.wrap w_instance = self.w_instance or space.w_None - if space.is_w( self.w_class, space.w_None ): + function = space.interpclass_w(self.w_function) + if isinstance(function, Function) and isinstance(function.code, BuiltinCode): + new_inst = mod.get('builtin_method_new') + if space.is_w(w_instance, space.w_None): + tup = [self.w_class, space.wrap(function.name)] + else: + tup = [w_instance, space.wrap(function.name)] + elif space.is_w( self.w_class, space.w_None ): tup = [self.w_function, w_instance] else: tup = [self.w_function, w_instance, self.w_class] Modified: pypy/dist/pypy/interpreter/test/test_pickle.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pickle.py (original) +++ pypy/dist/pypy/interpreter/test/test_pickle.py Fri Jun 9 15:15:18 2006 @@ -374,3 +374,21 @@ assert list(g1) == list(g2) finally: del sys.modules['mod'] + + def test_pickle_builtin_method(self): + import pickle + + a_list = [1] + meth1 = a_list.append + pckl = pickle.dumps(meth1) + meth2 = pickle.loads(pckl) + meth1(1) + meth2(2) + assert a_list == [1, 1] + assert meth2.im_self == [1, 2] + + unbound_meth = list.append + unbound_meth2 = pickle.loads(pickle.dumps(unbound_meth)) + l = [] + unbound_meth2(l, 1) + assert l == [1] From mwh at codespeak.net Fri Jun 9 15:54:27 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Jun 2006 15:54:27 +0200 (CEST) Subject: [pypy-svn] r28587 - pypy/dist/pypy/module/stackless/test Message-ID: <20060609135427.DE58210034@code0.codespeak.net> Author: mwh Date: Fri Jun 9 15:54:24 2006 New Revision: 28587 Modified: pypy/dist/pypy/module/stackless/test/test_coroutine.py Log: (pedronis, mwh) a skipped that that fails for the traditional No Good Reason. it works interactively! Modified: pypy/dist/pypy/module/stackless/test/test_coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/test_coroutine.py (original) +++ pypy/dist/pypy/module/stackless/test/test_coroutine.py Fri Jun 9 15:54:24 2006 @@ -24,4 +24,32 @@ import pickle pckl = pickle.dumps(co) co2 = pickle.loads(pckl) - \ No newline at end of file + + def test_pickle_coroutine_frame(self): + skip('passes in interactive interpreter but not here :/') + # this requires py.magic.greenlet! + del self # don't look + import pickle, sys, new + mod = new.module('mod') + try: + sys.modules['mod'] = mod + exec ''' +import sys, stackless + +def f(): + global the_frame + the_frame = sys._getframe() + main_coro.switch() + +co = stackless.coroutine() +main_coro = stackless.coroutine.getcurrent() +co.bind(mod.f) +co.switch() +''' in mod.__dict__ + pckl = pickle.dumps(mod.the_frame) + #co2 = pickle.loads(pckl) + finally: + del sys.modules['mod'] + + + From arigo at codespeak.net Fri Jun 9 15:55:08 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Jun 2006 15:55:08 +0200 (CEST) Subject: [pypy-svn] r28588 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/lltypesystem/test rpython/memory translator/c translator/c/src Message-ID: <20060609135508.0764410060@code0.codespeak.net> Author: arigo Date: Fri Jun 9 15:55:04 2006 New Revision: 28588 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/lltypesystem/lloperation.py pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/lltypesystem/rclass.py pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py pypy/dist/pypy/rpython/memory/gctransform.py pypy/dist/pypy/rpython/rcpy.py pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/src/mem.h Log: (arre, arigo) Support deallocation "properly" for PyStruct and rcpy.py. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Fri Jun 9 15:55:04 2006 @@ -751,6 +751,9 @@ def op_gc_call_rtti_destructor(self, rtti, addr): raise NotImplementedError("gc_call_rtti_destructor") + def op_gc_deallocate(self, TYPE, addr): + raise NotImplementedError("gc_deallocate") + def op_gc_push_alive_pyobj(self, pyobj): raise NotImplementedError("gc_push_alive_pyobj") Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Fri Jun 9 15:55:04 2006 @@ -321,6 +321,7 @@ 'gc_fetch_exception': LLOp(), 'gc_restore_exception': LLOp(), 'gc_call_rtti_destructor': LLOp(), + 'gc_deallocate': LLOp(), 'gc_push_alive_pyobj': LLOp(), 'gc_pop_alive_pyobj': LLOp(), 'gc_protect': LLOp(), Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Fri Jun 9 15:55:04 2006 @@ -262,8 +262,7 @@ n = 1 return _struct(self, n) -class GcStruct(Struct): - _gckind = 'gc' +class RttiStruct(Struct): _runtime_type_info = None def _attach_runtime_type_info_funcptr(self, funcptr, destrptr): @@ -290,11 +289,14 @@ "implementation, got: %s" % destrptr) self._runtime_type_info.destructor_funcptr = destrptr -class PyStruct(Struct): +class GcStruct(RttiStruct): + _gckind = 'gc' + +class PyStruct(RttiStruct): _gckind = 'cpy' def __init__(self, name, *fields, **kwds): - Struct.__init__(self, name, *fields, **kwds) + RttiStruct.__init__(self, name, *fields, **kwds) if self._first_struct() == (None, None): raise TypeError("a PyStruct must have another PyStruct or " "PyObject as first field") @@ -457,6 +459,8 @@ def _inline_is_varsize(self, last): raise TypeError, "%r cannot be inlined in structure" % self +FOR_TESTING_ONLY = "for testing only" + class PyObjectType(ContainerType): _gckind = 'cpy' __name__ = 'PyObject' @@ -466,10 +470,10 @@ return False def _defl(self, parent=None, parentindex=None, extra_args=()): if not extra_args: - raise NotImplementedError("PyObjectType._defl()") + ob_type = FOR_TESTING_ONLY else: ob_type = extra_args[0] - return _pyobjheader(ob_type, parent, parentindex) + return _pyobjheader(ob_type, parent, parentindex) PyObject = PyObjectType() @@ -1478,7 +1482,8 @@ def __init__(self, ob_type, parent=None, parentindex=None): _parentable.__init__(self, PyObject) - assert typeOf(ob_type) == Ptr(PyObject) + assert (ob_type is FOR_TESTING_ONLY or + typeOf(ob_type) == Ptr(PyObject)) self.ob_type = ob_type if parent is not None: self._setparentstructure(parent, parentindex) @@ -1540,22 +1545,22 @@ return _ptr(PTRTYPE, oddint, solid=True) def attachRuntimeTypeInfo(GCSTRUCT, funcptr=None, destrptr=None): - if not isinstance(GCSTRUCT, GcStruct): - raise TypeError, "expected a GcStruct: %s" % GCSTRUCT + if not isinstance(GCSTRUCT, RttiStruct): + raise TypeError, "expected a RttiStruct: %s" % GCSTRUCT GCSTRUCT._attach_runtime_type_info_funcptr(funcptr, destrptr) return _ptr(Ptr(RuntimeTypeInfo), GCSTRUCT._runtime_type_info) def getRuntimeTypeInfo(GCSTRUCT): - if not isinstance(GCSTRUCT, GcStruct): - raise TypeError, "expected a GcStruct: %s" % GCSTRUCT + if not isinstance(GCSTRUCT, RttiStruct): + raise TypeError, "expected a RttiStruct: %s" % GCSTRUCT if GCSTRUCT._runtime_type_info is None: raise ValueError, "no attached runtime type info for %s" % GCSTRUCT return _ptr(Ptr(RuntimeTypeInfo), GCSTRUCT._runtime_type_info) def runtime_type_info(p): T = typeOf(p) - if not isinstance(T, Ptr) or not isinstance(T.TO, GcStruct): - raise TypeError, "runtime_type_info on non-GcStruct pointer: %s" % p + if not isinstance(T, Ptr) or not isinstance(T.TO, RttiStruct): + raise TypeError, "runtime_type_info on non-RttiStruct pointer: %s" % p struct = p._obj top_parent = top_container(struct) result = getRuntimeTypeInfo(top_parent._TYPE) Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Fri Jun 9 15:55:04 2006 @@ -85,6 +85,7 @@ 'cpy' : 'cpy', 'stack': 'raw', } +RTTIFLAVORS = ('gc', 'cpy') def cast_vtable_to_typeptr(vtable): while typeOf(vtable).TO != OBJECT_VTABLE: @@ -188,7 +189,7 @@ vtable.subclassrange_max = sys.maxint rinstance = getinstancerepr(self.rtyper, rsubcls.classdef) rinstance.setup() - if rinstance.gcflavor == 'gc': # only gc-case + if rinstance.gcflavor in RTTIFLAVORS: vtable.rtti = getRuntimeTypeInfo(rinstance.object_type) if rsubcls.classdef is None: name = 'object' @@ -358,11 +359,11 @@ allinstancefields.update(fields) self.fields = fields self.allinstancefields = allinstancefields - if self.gcflavor == 'gc': # only gc-case + if self.gcflavor in RTTIFLAVORS: attachRuntimeTypeInfo(self.object_type) def _setup_repr_final(self): - if self.gcflavor == 'gc': # only gc-case + if self.gcflavor in RTTIFLAVORS: if (self.classdef is not None and self.classdef.classdesc.lookup('__del__') is not None): s_func = self.classdef.classdesc.s_read_attribute('__del__') @@ -378,6 +379,7 @@ _callable=graph.func) else: destrptr = None + OBJECT = OBJECT_BY_FLAVOR[LLFLAVOR[self.gcflavor]] self.rtyper.attachRuntimeTypeInfoFunc(self.object_type, ll_runtime_type_info, OBJECT, destrptr) Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py Fri Jun 9 15:55:04 2006 @@ -43,7 +43,6 @@ def test_tp_dealloc(): - import py; py.test.skip("in-progress") class mytest(object): pass Modified: pypy/dist/pypy/rpython/memory/gctransform.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform.py (original) +++ pypy/dist/pypy/rpython/memory/gctransform.py Fri Jun 9 15:55:04 2006 @@ -410,7 +410,7 @@ ADDRESS_VOID_FUNC = lltype.FuncType([llmemory.Address], lltype.Void) def get_rtti(TYPE): - if isinstance(TYPE, lltype.GcStruct): + if isinstance(TYPE, lltype.RttiStruct): try: return lltype.getRuntimeTypeInfo(TYPE) except ValueError: @@ -636,6 +636,16 @@ self.queryptr2dynamic_deallocator_funcptr[queryptr._obj] = fptr return fptr + def replace_gc_deallocate(self, op, livevars, block): + TYPE = op.args[0].value + v_addr = op.args[1] + dealloc_fptr = self.dynamic_deallocation_funcptr_for_type(TYPE) + cdealloc_fptr = rmodel.inputconst( + lltype.typeOf(dealloc_fptr), dealloc_fptr) + return [SpaceOperation("direct_call", [cdealloc_fptr, + v_addr], + varoftype(lltype.Void))] + def varoftype(concretetype): var = Variable() var.concretetype = concretetype Modified: pypy/dist/pypy/rpython/rcpy.py ============================================================================== --- pypy/dist/pypy/rpython/rcpy.py (original) +++ pypy/dist/pypy/rpython/rcpy.py Fri Jun 9 15:55:04 2006 @@ -1,6 +1,8 @@ from pypy.rpython.extregistry import ExtRegistryEntry from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.objectmodel import CDefinedIntSymbolic +from pypy.objspace.flow.model import Constant def cpy_export(cpytype, obj): @@ -72,7 +74,8 @@ ('c_tp_name', lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))), ('c_tp_basicsize', lltype.Signed), ('c_tp_itemsize', lltype.Signed), - ('c_tp_dealloc', lltype.Signed), + ('c_tp_dealloc', lltype.Ptr(lltype.FuncType([PyObjPtr], + lltype.Void))), ('c_tp_print', lltype.Signed), ('c_tp_getattr', lltype.Signed), ('c_tp_setattr', lltype.Signed), # in @@ -104,24 +107,31 @@ ('c_tp_descr_set', lltype.Signed), ('c_tp_dictoffset',lltype.Signed), ('c_tp_init', lltype.Signed), - ('c_tp_alloc', lltype.Ptr(lltype.FuncType([lltype.Ptr(PY_TYPE_OBJECT), - lltype.Signed], + ('c_tp_alloc', lltype.Signed), + #lltype.Ptr(lltype.FuncType([lltype.Ptr(PY_TYPE_OBJECT), + # lltype.Signed], + # PyObjPtr))), + ('c_tp_new', lltype.Ptr(lltype.FuncType([lltype.Ptr(PY_TYPE_OBJECT), + PyObjPtr, + PyObjPtr], PyObjPtr))), - ('c_tp_new', lltype.Signed), - ('c_tp_free', lltype.Ptr(lltype.FuncType([llmemory.Address], - lltype.Void))), + ('c_tp_free', lltype.Signed), + #lltype.Ptr(lltype.FuncType([llmemory.Address], + # lltype.Void))), hints={'c_name': '_typeobject', 'external': True, 'inline_head': True})) # XXX should be PyTypeObject but genc inserts 'struct' :-( -def ll_tp_alloc(tp, itemcount): - # XXX pass itemcount too +def ll_tp_new(tp, args, kwds): return lltype.malloc(lltype.PyObject, flavor='cpy', extra_args=(tp,)) -def ll_tp_free(addr): - # hack: don't cast addr to PyObjPtr, otherwise there is an incref/decref - # added around the free! - lltype.free(addr, flavor='cpy') +def ll_tp_dealloc(p): + addr = llmemory.cast_ptr_to_adr(p) + # Warning: this relies on an optimization in gctransformer, which will + # not insert any incref/decref for 'p'. That would lead to infinite + # recursion, as the refcnt of 'p' is already zero! + from pypy.rpython.lltypesystem.rclass import CPYOBJECT + llop.gc_deallocate(lltype.Void, CPYOBJECT, addr) def build_pytypeobject(r_inst): typetype = lltype.pyobjectptr(type) @@ -136,10 +146,10 @@ pytypeobj.c_tp_name = lltype.direct_arrayitems(p) pytypeobj.c_tp_basicsize = llmemory.sizeof(r_inst.lowleveltype.TO) pytypeobj.c_tp_flags = CDefinedIntSymbolic('Py_TPFLAGS_DEFAULT') - pytypeobj.c_tp_alloc = r_inst.rtyper.annotate_helper_fn( - ll_tp_alloc, - [lltype.Ptr(PY_TYPE_OBJECT), lltype.Signed]) - pytypeobj.c_tp_free = r_inst.rtyper.annotate_helper_fn( - ll_tp_free, - [llmemory.Address]) + pytypeobj.c_tp_new = r_inst.rtyper.annotate_helper_fn( + ll_tp_new, + [lltype.Ptr(PY_TYPE_OBJECT), PyObjPtr, PyObjPtr]) + pytypeobj.c_tp_dealloc = r_inst.rtyper.annotate_helper_fn( + ll_tp_dealloc, + [PyObjPtr]) return lltype.cast_pointer(PyObjPtr, pytypeobj) Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Fri Jun 9 15:55:04 2006 @@ -569,7 +569,8 @@ def OP_FLAVORED_FREE(self, op): flavor = op.args[0].value if flavor == "raw": - return "OP_RAW_FREE(%s)" % (self.expr(op.args[1]),) + return "OP_RAW_FREE(%s, %s)" % (self.expr(op.args[1]), + self.expr(op.result)) elif flavor == "cpy": return "OP_CPY_FREE(%s)" % (self.expr(op.args[1]),) else: Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Fri Jun 9 15:55:04 2006 @@ -2,7 +2,7 @@ from pypy.translator.c.support import cdecl from pypy.translator.c.node import ContainerNode from pypy.rpython.lltypesystem.lltype import \ - typeOf, Ptr, ContainerType, GcArray, GcStruct, \ + typeOf, Ptr, ContainerType, RttiStruct, \ RuntimeTypeInfo, getRuntimeTypeInfo, top_container from pypy.rpython.memory import gctransform from pypy.rpython.lltypesystem import lltype, llmemory @@ -131,7 +131,7 @@ def __init__(self, db, T, obj): assert T == RuntimeTypeInfo - assert isinstance(obj.about, GcStruct) + assert isinstance(obj.about, RttiStruct) self.db = db self.T = T self.obj = obj @@ -238,7 +238,7 @@ def __init__(self, db, T, obj): assert T == RuntimeTypeInfo - assert isinstance(obj.about, GcStruct) + assert isinstance(obj.about, RttiStruct) self.db = db self.T = T self.obj = obj Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Fri Jun 9 15:55:04 2006 @@ -1,7 +1,7 @@ from __future__ import generators from pypy.rpython.lltypesystem.lltype import \ Struct, Array, FixedSizeArray, FuncType, PyObjectType, typeOf, \ - GcStruct, GcArray, PyStruct, ContainerType, \ + GcStruct, GcArray, RttiStruct, PyStruct, ContainerType, \ parentlink, Ptr, PyObject, Void, OpaqueType, Float, \ RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray, _pyobjheader from pypy.rpython.lltypesystem.llmemory import WeakGcAddress @@ -85,7 +85,7 @@ self.gcinfo = None # unless overwritten below rtti = None STRUCT = self.STRUCT - if isinstance(STRUCT, GcStruct): + if isinstance(STRUCT, RttiStruct): try: rtti = getRuntimeTypeInfo(STRUCT) except ValueError: Modified: pypy/dist/pypy/translator/c/src/mem.h ============================================================================== --- pypy/dist/pypy/translator/c/src/mem.h (original) +++ pypy/dist/pypy/translator/c/src/mem.h Fri Jun 9 15:55:04 2006 @@ -14,7 +14,7 @@ r = (void*) alloca(size); \ if (r == NULL) FAIL_EXCEPTION(PyExc_MemoryError, "out of memory");\ -#define OP_RAW_FREE(x) OP_FREE(x) +#define OP_RAW_FREE(x,r) OP_FREE(x) #define OP_RAW_MEMCOPY(x,y,size,r) memcpy(y,x,size); /************************************************************/ @@ -130,4 +130,4 @@ PyObject_Init((PyObject *)r, (PyTypeObject *)cpytype); \ } \ } -#define OP_CPY_FREE(x) OP_RAW_FREE(x) +#define OP_CPY_FREE(x) OP_RAW_FREE(x, /*nothing*/) From arigo at codespeak.net Fri Jun 9 16:11:57 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Jun 2006 16:11:57 +0200 (CEST) Subject: [pypy-svn] r28589 - in pypy/dist/pypy/rpython/lltypesystem: . test Message-ID: <20060609141157.2A14910034@code0.codespeak.net> Author: arigo Date: Fri Jun 9 16:11:55 2006 New Revision: 28589 Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py Log: Some clean-up and a test for lltype. Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Fri Jun 9 16:11:55 2006 @@ -252,8 +252,8 @@ def _short_name(self): return "%s %s" % (self.__class__.__name__, self._name) - def _defl(self, parent=None, parentindex=None, **kwds): - return _struct(self, parent=parent, parentindex=parentindex, **kwds) + def _defl(self, parent=None, parentindex=None): + return _struct(self, parent=parent, parentindex=parentindex) def _container_example(self): if self._arrayfld is None: @@ -445,8 +445,8 @@ def _container_example(self): return _opaque(self) - def _defl(self, parent=None, parentindex=None, **kwds): - return _opaque(self, parent=parent, parentindex=parentindex, **kwds) + def _defl(self, parent=None, parentindex=None): + return _opaque(self, parent=parent, parentindex=parentindex) RuntimeTypeInfo = OpaqueType("RuntimeTypeInfo") @@ -459,8 +459,6 @@ def _inline_is_varsize(self, last): raise TypeError, "%r cannot be inlined in structure" % self -FOR_TESTING_ONLY = "for testing only" - class PyObjectType(ContainerType): _gckind = 'cpy' __name__ = 'PyObject' @@ -468,12 +466,8 @@ return "PyObject" def _inline_is_varsize(self, last): return False - def _defl(self, parent=None, parentindex=None, extra_args=()): - if not extra_args: - ob_type = FOR_TESTING_ONLY - else: - ob_type = extra_args[0] - return _pyobjheader(ob_type, parent, parentindex) + def _defl(self, parent=None, parentindex=None): + return _pyobjheader(Ellipsis, parent, parentindex) PyObject = PyObjectType() @@ -1194,11 +1188,11 @@ __slots__ = () - def __new__(self, TYPE, n=None, parent=None, parentindex=None, **kwds): + def __new__(self, TYPE, n=None, parent=None, parentindex=None): my_variety = _struct_variety(TYPE._names) return object.__new__(my_variety) - def __init__(self, TYPE, n=None, parent=None, parentindex=None, **kwds): + def __init__(self, TYPE, n=None, parent=None, parentindex=None): _parentable.__init__(self, TYPE) if n is not None and TYPE._arrayfld is None: raise TypeError("%r is not variable-sized" % (TYPE,)) @@ -1208,8 +1202,6 @@ for fld, typ in TYPE._flds.items(): if fld == TYPE._arrayfld: value = _array(typ, n, parent=self, parentindex=fld) - elif fld == first: - value = typ._defl(parent=self, parentindex=fld, **kwds) else: value = typ._defl(parent=self, parentindex=fld) setattr(self, fld, value) @@ -1261,6 +1253,9 @@ assert isinstance(self._TYPE, FixedSizeArray) setattr(self, 'item%d' % index, value) + def _setup_extra_args(self, *args): + getattr(self, self._TYPE._names[0])._setup_extra_args(*args) + class _array(_parentable): _kind = "array" @@ -1482,12 +1477,14 @@ def __init__(self, ob_type, parent=None, parentindex=None): _parentable.__init__(self, PyObject) - assert (ob_type is FOR_TESTING_ONLY or - typeOf(ob_type) == Ptr(PyObject)) - self.ob_type = ob_type + self._setup_extra_args(ob_type) if parent is not None: self._setparentstructure(parent, parentindex) + def _setup_extra_args(self, ob_type): + assert ob_type is Ellipsis or typeOf(ob_type) == Ptr(PyObject) + self.ob_type = ob_type + def __repr__(self): return '<%s>' % (self,) @@ -1495,15 +1492,17 @@ return "pyobjheader of type %r" % (self.ob_type,) -def malloc(T, n=None, flavor='gc', immortal=False, **kwds): +def malloc(T, n=None, flavor='gc', immortal=False, extra_args=()): if isinstance(T, Struct): - o = _struct(T, n, **kwds) + o = _struct(T, n) elif isinstance(T, Array): - o = _array(T, n, **kwds) + o = _array(T, n) else: raise TypeError, "malloc for Structs and Arrays only" if T._gckind != 'gc' and not immortal and flavor.startswith('gc'): raise TypeError, "gc flavor malloc of a non-GC non-immortal structure" + if extra_args: + o._setup_extra_args(*extra_args) solid = immortal or not flavor.startswith('gc') # immortal or non-gc case return _ptr(Ptr(T), o, solid) Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py Fri Jun 9 16:11:55 2006 @@ -714,3 +714,21 @@ del s1, s2 s3 = cast_pointer(Ptr(S1), h1) assert s3.x == 17 + +def test_name_clash(): + import re + from pypy.rpython.lltypesystem import lltype + fn = lltype.__file__ + if fn.lower().endswith('pyc') or fn.lower().endswith('pyo'): + fn = fn[:-1] + f = open(fn, 'r') + data = f.read() + f.close() + words = dict.fromkeys(re.compile(r"[a-zA-Z][_a-zA-Z0-9]*").findall(data)) + words = words.keys() + S = GcStruct('name_clash', *[(word, Signed) for word in words]) + s = malloc(S) + for i, word in enumerate(words): + setattr(s, word, i) + for i, word in enumerate(words): + assert getattr(s, word) == i From arigo at codespeak.net Fri Jun 9 16:26:45 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Jun 2006 16:26:45 +0200 (CEST) Subject: [pypy-svn] r28590 - in pypy/dist/pypy: rpython/lltypesystem/test translator/c/test Message-ID: <20060609142645.33D0D10063@code0.codespeak.net> Author: arigo Date: Fri Jun 9 16:26:43 2006 New Revision: 28590 Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py pypy/dist/pypy/translator/c/test/test_genc.py Log: A passing test about rcpy.py. Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py Fri Jun 9 16:26:43 2006 @@ -19,8 +19,8 @@ w = W_MyTest(21) return cpy_export(mytest, w) - fn = compile(f, [], expected_extra_mallocs=1) - res = fn() + fn = compile(f, []) + res = fn(expected_extra_mallocs=1) assert type(res).__name__ == 'mytest' @@ -60,8 +60,38 @@ w = cpy_import(W_MyTest, obj) return w.a.x - fn = compile(g, [], backendopt=False) + fn = compile(g, []) res = fn() # the A() should have been deallocated too, otherwise the number # of mallocs doesn't match the number of frees assert res == 4 + + +def test_subclass_from_cpython(): + class mytest(object): + pass + + def f(input): + current = total = 0 + if input: + w = cpy_import(W_MyTest, input) + current, total = w.stuff + w = W_MyTest(21) + current += 1 + total += current + w.stuff = current, total + return cpy_export(mytest, w), total + + fn = compile(f, [object]) + obj, total = fn(None, expected_extra_mallocs=2) # 1 W_MyTest (with 1 tuple) + assert total == 1 + obj, total = fn(obj, expected_extra_mallocs=4) # 2 W_MyTests alive + assert total == 3 + obj, total = fn(obj, expected_extra_mallocs=4) # 2 W_MyTests alive + assert total == 6 + obj, total = fn(obj, expected_extra_mallocs=4) # etc + assert total == 10 + obj, total = fn(obj, expected_extra_mallocs=4) + assert total == 15 + obj, total = fn(obj, expected_extra_mallocs=4) + assert total == 21 Modified: pypy/dist/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_genc.py (original) +++ pypy/dist/pypy/translator/c/test/test_genc.py Fri Jun 9 16:26:43 2006 @@ -31,7 +31,7 @@ return m def compile(fn, argtypes, view=False, gcpolicy=None, backendopt=True, - annotatorpolicy=None, expected_extra_mallocs=0): + annotatorpolicy=None): t = TranslationContext() a = t.buildannotator(policy=annotatorpolicy) a.build_types(fn, argtypes) @@ -46,6 +46,10 @@ t.view() compiled_fn = getattr(module, entrypoint) def checking_fn(*args, **kwds): + if 'expected_extra_mallocs' in kwds: + expected_extra_mallocs = kwds.pop('expected_extra_mallocs') + else: + expected_extra_mallocs = 0 try: return compiled_fn(*args, **kwds) finally: From arigo at codespeak.net Fri Jun 9 17:05:44 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Jun 2006 17:05:44 +0200 (CEST) Subject: [pypy-svn] r28591 - in pypy/dist/pypy/rpython: . lltypesystem lltypesystem/test Message-ID: <20060609150544.1B81E10068@code0.codespeak.net> Author: arigo Date: Fri Jun 9 17:05:43 2006 New Revision: 28591 Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py pypy/dist/pypy/rpython/rcpy.py Log: Correctly initialize the instance when the type is called from CPython. Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Fri Jun 9 17:05:43 2006 @@ -481,7 +481,7 @@ raise MissingRTypeAttribute(attr) self.rbase.setfield(vinst, attr, vvalue, llops, force_cast=True, opname=opname) - def new_instance(self, llops, classcallhop=None): + def new_instance(self, llops, classcallhop=None, v_cpytype=None): """Build a new instance, without calling __init__.""" mallocop = 'malloc' ctype = inputconst(Void, self.object_type) @@ -492,15 +492,16 @@ mallocop = 'flavored_malloc' vlist.insert(0, inputconst(Void, flavor)) if flavor == 'cpy': - cache = self.rtyper.classdef_to_pytypeobject - try: - pytype = cache[self.classdef] - except KeyError: - from pypy.rpython import rcpy - pytype = rcpy.build_pytypeobject(self) - cache[self.classdef] = pytype - c = inputconst(Ptr(PyObject), pytype) - vlist.append(c) + if v_cpytype is None: + cache = self.rtyper.classdef_to_pytypeobject + try: + cpytype = cache[self.classdef] + except KeyError: + from pypy.rpython import rcpy + cpytype = rcpy.build_pytypeobject(self) + cache[self.classdef] = cpytype + v_cpytype = inputconst(Ptr(PyObject), cpytype) + vlist.append(v_cpytype) vptr = llops.genop(mallocop, vlist, resulttype = Ptr(self.object_type)) ctypeptr = inputconst(CLASSTYPE, self.rclass.getvtable()) Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py Fri Jun 9 17:05:43 2006 @@ -3,6 +3,7 @@ class W_MyTest(object): + x = 600 def __init__(self, x): self.x = x @@ -67,7 +68,7 @@ assert res == 4 -def test_subclass_from_cpython(): +def test_manipulate_more(): class mytest(object): pass @@ -95,3 +96,62 @@ assert total == 15 obj, total = fn(obj, expected_extra_mallocs=4) assert total == 21 + + +def test_instantiate_from_cpython(): + class mytest(object): + pass + + def f(input): + if input: + w = cpy_import(W_MyTest, input) + else: + w = W_MyTest(21) + w.x += 1 + return cpy_export(mytest, w), w.x + + fn = compile(f, [object]) + obj, x = fn(None, expected_extra_mallocs=1) # 1 W_MyTest + assert x == 22 + + obj2 = type(obj)() + del obj + obj, x = fn(obj2, expected_extra_mallocs=1) # 1 W_MyTest (obj2) + assert obj is obj2 + assert x == 601 # 600 is the class default of W_MyTest.x + + +def test_subclass_from_cpython(): + import py; py.test.skip("not implemented (see comments in rcpy.py)") + class mytest(object): + pass + + def f(input): + current = total = 10 + if input: + w = cpy_import(W_MyTest, input) + current, total = w.stuff + w = W_MyTest(21) + current += 1 + total += current + w.stuff = current, total + return cpy_export(mytest, w), total + + fn = compile(f, [object]) + obj, total = fn(None, expected_extra_mallocs=2) # 1 W_MyTest (with 1 tuple) + assert total == 21 + T = type(obj) + class U(T): + pass + obj2 = U() + obj2.bla = 123 + assert obj2.bla == 123 + del obj + + objlist = [U() for i in range(100)] + obj, total = fn(obj2, expected_extra_mallocs=204) # 102 W_MyTests alive + assert total == 1 + + del objlist + obj, total = fn(obj, expected_extra_mallocs=6) # 3 W_MyTests alive + assert total == 3 Modified: pypy/dist/pypy/rpython/rcpy.py ============================================================================== --- pypy/dist/pypy/rpython/rcpy.py (original) +++ pypy/dist/pypy/rpython/rcpy.py Fri Jun 9 17:05:43 2006 @@ -2,7 +2,8 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.objectmodel import CDefinedIntSymbolic -from pypy.objspace.flow.model import Constant +from pypy.objspace.flow.model import Constant, Variable +from pypy.objspace.flow.model import FunctionGraph, Block, Link def cpy_export(cpytype, obj): @@ -122,9 +123,6 @@ hints={'c_name': '_typeobject', 'external': True, 'inline_head': True})) # XXX should be PyTypeObject but genc inserts 'struct' :-( -def ll_tp_new(tp, args, kwds): - return lltype.malloc(lltype.PyObject, flavor='cpy', extra_args=(tp,)) - def ll_tp_dealloc(p): addr = llmemory.cast_ptr_to_adr(p) # Warning: this relies on an optimization in gctransformer, which will @@ -134,7 +132,24 @@ llop.gc_deallocate(lltype.Void, CPYOBJECT, addr) def build_pytypeobject(r_inst): + from pypy.rpython.lltypesystem.rclass import CPYOBJECTPTR + from pypy.rpython.rtyper import LowLevelOpList typetype = lltype.pyobjectptr(type) + + # make the graph of tp_new manually + v1 = Variable('tp'); v1.concretetype = lltype.Ptr(PY_TYPE_OBJECT) + v2 = Variable('args'); v2.concretetype = PyObjPtr + v3 = Variable('kwds'); v3.concretetype = PyObjPtr + block = Block([v1, v2, v3]) + llops = LowLevelOpList(None) + v4 = r_inst.new_instance(llops, v_cpytype = v1) + v5 = llops.genop('cast_pointer', [v4], resulttype = PyObjPtr) + block.operations = list(llops) + tp_new_graph = FunctionGraph('ll_tp_new', block) + block.closeblock(Link([v5], tp_new_graph.returnblock)) + tp_new_graph.getreturnvar().concretetype = v5.concretetype + + # build the PyTypeObject structure pytypeobj = lltype.malloc(PY_TYPE_OBJECT, flavor='cpy', extra_args=(typetype,)) name = r_inst.classdef._cpy_exported_type_.__name__ @@ -146,10 +161,14 @@ pytypeobj.c_tp_name = lltype.direct_arrayitems(p) pytypeobj.c_tp_basicsize = llmemory.sizeof(r_inst.lowleveltype.TO) pytypeobj.c_tp_flags = CDefinedIntSymbolic('Py_TPFLAGS_DEFAULT') - pytypeobj.c_tp_new = r_inst.rtyper.annotate_helper_fn( - ll_tp_new, - [lltype.Ptr(PY_TYPE_OBJECT), PyObjPtr, PyObjPtr]) + pytypeobj.c_tp_new = r_inst.rtyper.type_system.getcallable(tp_new_graph) pytypeobj.c_tp_dealloc = r_inst.rtyper.annotate_helper_fn( ll_tp_dealloc, [PyObjPtr]) return lltype.cast_pointer(PyObjPtr, pytypeobj) + +# To make this a Py_TPFLAGS_BASETYPE, we need to have a tp_new that does +# something different for subclasses: it needs to allocate a bit more +# for CPython's GC (see PyObject_GC_Malloc); it needs to Py_INCREF the +# type if it's a heap type; and it needs to PyObject_GC_Track() the object. +# Also, tp_dealloc needs to untrack the object. From ericvrp at codespeak.net Fri Jun 9 17:22:48 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 9 Jun 2006 17:22:48 +0200 (CEST) Subject: [pypy-svn] r28592 - in pypy/dist/pypy/translator/js2/proxy: . testme Message-ID: <20060609152248.8225F10034@code0.codespeak.net> Author: ericvrp Date: Fri Jun 9 17:22:47 2006 New Revision: 28592 Modified: pypy/dist/pypy/translator/js2/proxy/dev.cfg pypy/dist/pypy/translator/js2/proxy/testme/controllers.py Log: Let the http server return data received (over tcp) from the BnB server to the (javascript) client in json format. This includes converting, adding (and sometimes ignoring) packets. Modified: pypy/dist/pypy/translator/js2/proxy/dev.cfg ============================================================================== --- pypy/dist/pypy/translator/js2/proxy/dev.cfg (original) +++ pypy/dist/pypy/translator/js2/proxy/dev.cfg Fri Jun 9 17:22:47 2006 @@ -30,7 +30,7 @@ # Disable the debug output at the end on pages. # logDebugInfoFilter.on = False -server.environment="production" #"development" +server.environment="development" autoreload.package="testme" autoreload.on = False Modified: pypy/dist/pypy/translator/js2/proxy/testme/controllers.py ============================================================================== --- pypy/dist/pypy/translator/js2/proxy/testme/controllers.py (original) +++ pypy/dist/pypy/translator/js2/proxy/testme/controllers.py Fri Jun 9 17:22:47 2006 @@ -1,6 +1,5 @@ -import turbogears -from turbogears import controllers -import cherrypy +from turbogears import controllers, expose +from cherrypy import session from msgstruct import * import PIL.Image import zlib @@ -47,9 +46,8 @@ region.save(icon_filename) print 'SAVED:', icon_filename - #note: we should add the feature that we can ignore/replace messages with - # other messages. This is mostly important to avoid sending all the - # pixel data to the client which it can not use in this format anyway. + filename = '../static/images/icon%d.gif' % code + return dict(type='def_icon', code=code, filename=filename) MESSAGES = { MSG_BROADCAST_PORT : broadcast_port, @@ -67,9 +65,10 @@ #print 'RECEIVED MESSAGE:%s(%d)' % (values[0], len(values[1:])) fn = self.MESSAGES.get(values[0]) if fn: - fn(self, *values[1:]) + return fn(self, *values[1:]) else: print "UNKNOWN MESSAGE:", values + return dict(type='unknown', values=values) class Root(controllers.Root): @@ -82,7 +81,6 @@ port = int(port[7:-1]) def sessionData(self): - session = cherrypy.session sessionid = session['_id'] if sessionid not in self._sessionData: self._sessionData[sessionid] = SessionData() @@ -96,13 +94,13 @@ #XXX todo: session.socket.close() after a timeout return d.socket - @turbogears.expose() + @expose(format='json') def send(self, data=message(CMSG_PING)): self.sessionSocket().send(data) print 'SENT:' + repr(data) return self.recv() - @turbogears.expose() + @expose(format='json') def recv(self): #XXX hangs if not first sending a ping! d = self.sessionData() @@ -114,22 +112,26 @@ print 'RECEIVED HEADER LINE: %s' % header_line #print 'RECEIVED DATA CONTAINS %d BYTES' % len(data) + messages = [] while data: values, data = decodemessage(data) if not values: break # incomplete message - d.handleServerMessage(*values) + messageOutput = d.handleServerMessage(*values) + if messageOutput: + messages.append(messageOutput) d.data = data #print 'RECEIVED DATA REMAINING CONTAINS %d BYTES' % len(data) - return dict(data=data) + print 'MESSAGES:', messages + return dict(messages=messages) - @turbogears.expose() + @expose(format='json') def close(self): - session = cherrypy.session sessionid = session['_id'] d = self.sessionData() if d.socket is not None: d.socket.close() del self._sessionData[sessionid] + return dict() From tismer at codespeak.net Fri Jun 9 19:25:16 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 9 Jun 2006 19:25:16 +0200 (CEST) Subject: [pypy-svn] r28597 - in pypy/dist/pypy/module/stackless: . test Message-ID: <20060609172516.2EFDC10036@code0.codespeak.net> Author: tismer Date: Fri Jun 9 19:25:15 2006 New Revision: 28597 Modified: pypy/dist/pypy/module/stackless/interp_coroutine.py pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py Log: WAAAAAAHHHH now coroutines seem to work on top of CPython Modified: pypy/dist/pypy/module/stackless/interp_coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/interp_coroutine.py (original) +++ pypy/dist/pypy/module/stackless/interp_coroutine.py Fri Jun 9 19:25:15 2006 @@ -36,35 +36,46 @@ try: from py.magic import greenlet main_greenlet = greenlet.getcurrent() - class MyGreenlet(object): - def __init__(self, thunk=None, curr=False): - if curr: - self.greenlet = greenlet.getcurrent() - else: + + class FrameChain(object): + + def __init__(self, thunk=None): + if thunk: self.greenlet = greenlet(thunk) + else: + self.greenlet = greenlet.getcurrent() + def switch(self): - last = MyGreenlet(curr=True) -# XXX unclear what to do there -# self.greenlet.parent = greenlet.getcurrent() + last = FrameChain() return self.greenlet.switch(last) - GreenletExit = greenlet.GreenletExit + + def shutdown(self): + current = FrameChain() + target = current.greenlet.parent + target.switch(None) + except ImportError: def greenlet(*args, **kwargs): raise NotImplementedError("need either greenlets or a translated version of pypy") - class GreenletExit(Exception): - pass import sys, os + class BaseCoState(object): def __init__(self): self.current = self.main = self.last = None + def __repr__(self): + "NOT_RPYTHON" + # for debugging only + return '<%s last=%r current=%r>' % (self.__class__.__name__, + self.last, self.current) def update(self, new): self.last, self.current = self.current, new frame, new.frame = new.frame, None return frame + class CoState(BaseCoState): def __init__(self): BaseCoState.__init__(self) @@ -78,18 +89,20 @@ check_for_zombie = staticmethod(check_for_zombie) def postpone_deletion(obj): - main_coroutine_getter._get_default_costate().to_delete.append(obj) - main_coroutine_getter._get_default_costate().things_to_do = True + main_costate = main_costate_getter._get_default_costate() + main_costate.to_delete.append(obj) + main_costate.things_to_do = True postpone_deletion = staticmethod(postpone_deletion) def do_things_to_do(): # inlineable stub - if main_coroutine_getter._get_default_costate().things_to_do: - main_coroutine_getter._get_default_costate()._do_things_to_do() + main_costate = main_costate_getter._get_default_costate() + if main_costate.things_to_do: + main_costate._do_things_to_do() do_things_to_do = staticmethod(do_things_to_do) def _do_things_to_do(): - main_costate = main_coroutine_getter._get_default_costate() + main_costate = main_costate_getter._get_default_costate() if main_costate.temp_exc is not None: # somebody left an unhandled exception and switched to us. # this both provides default exception handling and the @@ -110,7 +123,8 @@ class CoroutineDamage(SystemError): pass -class MainCoroutineGetter(object): + +class MainCostateGetter(object): def __init__(self): self.costate = None def _get_default_costate(self): @@ -119,34 +133,39 @@ self.costate = costate return costate return self.costate - -main_coroutine_getter = MainCoroutineGetter() + +main_costate_getter = MainCostateGetter() + class CoroutineExit(SystemExit): # XXX SystemExit's __init__ creates problems in bookkeeper. def __init__(self): pass -def get_exit_class(): # XXX hum - if we_are_translated(): - return CoroutineExit - else: - return GreenletExit - class AbstractThunk(object): def call(self): raise NotImplementedError("abstract base class") + class Coroutine(Wrappable): def __init__(self, state=None): self.frame = None if state is None: - state = main_coroutine_getter._get_default_costate() + state = main_costate_getter._get_default_costate() self.costate = state self.parent = None + self.thunk = None + + def __repr__(self): + 'NOT_RPYTHON' + # just for debugging + if hasattr(self, '__name__'): + return '' % (self.__name__, self.frame, self.thunk is not None) + else: + return '' % (self.frame, self.thunk is not None) def _get_default_parent(self): - return main_coroutine_getter._get_default_costate().current + return main_costate_getter._get_default_costate().current def bind(self, thunk): assert isinstance(thunk, AbstractThunk) @@ -155,37 +174,45 @@ if self.parent is None: self.parent = self._get_default_parent() assert self.parent is not None + self.thunk = thunk if we_are_translated(): - self.frame = self._bind(thunk) + self.frame = self._bind() else: - self.frame = self._greenlet_bind(thunk) + self.frame = self._greenlet_bind() - def _greenlet_bind(self, thunk): + def _greenlet_bind(self): state = self.costate self.parent = state.current assert self.parent is not None + weak = [self] def _greenlet_execute(incoming_frame): - return self._execute(thunk, state, incoming_frame) - return MyGreenlet(_greenlet_execute) + try: + return weak[0]._execute(incoming_frame) + finally: + del weak[0] + chain.shutdown() + chain = FrameChain(_greenlet_execute) + return chain - def _bind(self, thunk): + def _bind(self): state = self.costate self.parent = state.current incoming_frame = yield_current_frame_to_caller() - return self._execute(thunk, state, incoming_frame) + return self._execute(incoming_frame) - def _execute(self, thunk, state, incoming_frame): + def _execute(self, incoming_frame): + state = self.costate left = state.last left.frame = incoming_frame left.goodbye() self.hello() try: - main_coroutine_getter._get_default_costate().do_things_to_do() - thunk.call() + main_costate_getter._get_default_costate().do_things_to_do() + try: + self.thunk.call() + finally: + self.thunk = None resume_point("coroutine__bind", self, state) - except GreenletExit: - # ignore a shutdown exception - pass except CoroutineExit: # ignore a shutdown exception pass @@ -210,13 +237,13 @@ left.frame = incoming_frame left.goodbye() self.hello() - main_coroutine_getter._get_default_costate().do_things_to_do() + main_costate_getter._get_default_costate().do_things_to_do() def kill(self): if self.frame is None: return - main_coroutine_getter._get_default_costate().things_to_do = True - main_coroutine_getter._get_default_costate().temp_exc = get_exit_class()() + main_costate_getter._get_default_costate().things_to_do = True + main_costate_getter._get_default_costate().temp_exc = CoroutineExit() state = self.costate self.parent = state.current self.switch() @@ -228,7 +255,7 @@ pass # maybe print a warning? self.kill() - def X__del__(self): + def __del__(self): # provide the necessary clean-up if this coro is left # with a frame. # note that AppCoroutine has to take care about this @@ -237,7 +264,7 @@ # not in the position to issue a switch. # we defer it completely. if self.frame is not None: - main_coroutine_getter._get_default_costate().postpone_deletion(self) + main_costate_getter._get_default_costate().postpone_deletion(self) def _userdel(self): # override this for exposed coros @@ -247,14 +274,14 @@ return self.frame is not None or self is self.costate.current def is_zombie(self): - return self.frame is not None and main_coroutine_getter._get_default_costate().check_for_zombie(self) + return self.frame is not None and main_costate_getter._get_default_costate().check_for_zombie(self) def getcurrent(): - return main_coroutine_getter._get_default_costate().current + return main_costate_getter._get_default_costate().current getcurrent = staticmethod(getcurrent) def getmain(): - return main_coroutine_getter._get_default_costate().main + return main_costate_getter._get_default_costate().main getmain = staticmethod(getmain) def hello(self): Modified: pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py (original) +++ pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py Fri Jun 9 19:25:15 2006 @@ -3,27 +3,27 @@ """ import os -from pypy.module.stackless.interp_coroutine import main_coroutine_getter, Coroutine, AbstractThunk +from pypy.module.stackless.interp_coroutine import main_costate_getter, Coroutine, AbstractThunk from pypy.translator.c.test.test_stackless import StacklessTest from pypy.translator.c import gc def output(stuff): os.write(2, stuff + '\n') -class TestCoroutine(StacklessTest): +class _TestCoroutine(StacklessTest): backendopt = True stacklessmode = True gcpolicy = gc.BoehmGcPolicy Coroutine = Coroutine def setup_method(self, method): - main_coroutine_getter.costate = None - main_coroutine_getter.costate = None + main_costate_getter.costate = None + main_costate_getter.costate = None def _freeze_(self): # for 'self.Coroutine' return True - def test_coroutine(self): + def test_coroutine1(self): def g(lst, coros): coro_f, coro_g, coro_h = coros @@ -121,7 +121,9 @@ def f1(coro_f1): lst = [1] coro_g = self.Coroutine() + coro_g.__name__ = 'coro_g' coro_h = self.Coroutine() + coro_h.__name__ = 'coro_h' coros = [coro_f1, coro_g, coro_h] thunk_g = T(g, lst, coros) output('binding g after f1 set 1') @@ -147,11 +149,13 @@ def f(): coro_f = Coroutine.getcurrent() + coro_f.__name__ = 'coro_f' coro_f1 = self.Coroutine() + coro_f1.__name__ = 'coro_f1' thunk_f1 = T1(f1, coro_f1) output('binding f1 after f set 1') coro_f1.bind(thunk_f1) - coro_f1.switch() + coro_f1.switch() output('return to main :-(') return thunk_f1.res @@ -159,7 +163,6 @@ assert data == 12345678 def test_kill_raise_del_coro(self): - py.test.skip("does not work :-(") class T(AbstractThunk): def __init__(self, func, arg): self.func = func @@ -178,6 +181,7 @@ def f(): assert Coroutine.getmain().frame is None coro_g = self.Coroutine() + coro_g.__name__ = 'coro_g' thunk_g = T(g, 42) coro_g.bind(thunk_g) coro_g.switch() @@ -189,6 +193,7 @@ res *= 10 res |= coro_g.frame is None coro_g = self.Coroutine() + # see what happens if we __del__ thunk_g = T(g, -42) coro_g.bind(thunk_g) try: @@ -273,7 +278,8 @@ output = self.wrap_stackless_function(ep) assert output == int('0110') -class TestCoroutineOnCPython(TestCoroutine): +TestCoroutine = _TestCoroutine # to activate +class TestCoroutineOnCPython(_TestCoroutine): def wrap_stackless_function(self, func): return func() From mwh at codespeak.net Fri Jun 9 21:20:16 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Jun 2006 21:20:16 +0200 (CEST) Subject: [pypy-svn] r28605 - pypy/dist/pypy/module/_pickle_support Message-ID: <20060609192016.B546010036@code0.codespeak.net> Author: mwh Date: Fri Jun 9 21:20:15 2006 New Revision: 28605 Modified: pypy/dist/pypy/module/_pickle_support/__init__.py pypy/dist/pypy/module/_pickle_support/maker.py Log: AAAAARGH forgot to check this in :/ Modified: pypy/dist/pypy/module/_pickle_support/__init__.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/__init__.py (original) +++ pypy/dist/pypy/module/_pickle_support/__init__.py Fri Jun 9 21:20:15 2006 @@ -12,6 +12,7 @@ 'func_new' : 'maker.func_new', 'module_new' : 'maker.module_new', 'method_new' : 'maker.method_new', + 'builtin_method_new' : 'maker.builtin_method_new', 'dictiter_surrogate_new' : 'maker.dictiter_surrogate_new', 'seqiter_new' : 'maker.seqiter_new', 'reverseseqiter_new' : 'maker.reverseseqiter_new', Modified: pypy/dist/pypy/module/_pickle_support/maker.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/maker.py (original) +++ pypy/dist/pypy/module/_pickle_support/maker.py Fri Jun 9 21:20:15 2006 @@ -38,6 +38,9 @@ return space.call_args(w_type, __args__) method_new.unwrap_spec = [ObjSpace, Arguments] +def builtin_method_new(space, w_instance, w_name): + return space.getattr(w_instance, w_name) + def dictiter_surrogate_new(space, w_lis): # we got a listobject. # simply create an iterator and that's it. @@ -110,4 +113,4 @@ for w_p in nulls: p = space.int_w(w_p) tup_w[p] = None - return tup_w \ No newline at end of file + return tup_w From arigo at codespeak.net Sat Jun 10 15:05:17 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Jun 2006 15:05:17 +0200 (CEST) Subject: [pypy-svn] r28614 - pypy/dist/pypy/module/stackless/test Message-ID: <20060610130517.862D210053@code0.codespeak.net> Author: arigo Date: Sat Jun 10 15:05:15 2006 New Revision: 28614 Modified: pypy/dist/pypy/module/stackless/test/test_interp_clonable.py Log: ImportError. Modified: pypy/dist/pypy/module/stackless/test/test_interp_clonable.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/test_interp_clonable.py (original) +++ pypy/dist/pypy/module/stackless/test/test_interp_clonable.py Sat Jun 10 15:05:15 2006 @@ -5,7 +5,6 @@ from pypy.translator.c import gc from pypy.rpython.memory import gctransform from pypy.rpython.memory.test import test_transformed_gc -from pypy.module.stackless.interp_coroutine import costate from pypy.module.stackless.interp_clonable import ClonableCoroutine from pypy.module.stackless.interp_clonable import AbstractThunk, fork @@ -22,7 +21,7 @@ self.result = result def call(self): self.result.append(2) - costate.main.switch() + ClonableCoroutine.getmain().switch() self.result.append(4) def f(): result = [] @@ -53,7 +52,7 @@ localstate = [] localstate.append(10) self.result.append(2) - costate.main.switch() + ClonableCoroutine.getmain().switch() localstate.append(20) if localstate == [10, 20]: self.result.append(4) From arigo at codespeak.net Sat Jun 10 15:08:02 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Jun 2006 15:08:02 +0200 (CEST) Subject: [pypy-svn] r28615 - in pypy/dist/pypy/module/stackless: . test Message-ID: <20060610130802.DAA3510053@code0.codespeak.net> Author: arigo Date: Sat Jun 10 15:07:59 2006 New Revision: 28615 Modified: pypy/dist/pypy/module/stackless/interp_coroutine.py pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py Log: Long test and one-liner fix for coroutines and app-coroutines, broken in pypy-c. Modified: pypy/dist/pypy/module/stackless/interp_coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/interp_coroutine.py (original) +++ pypy/dist/pypy/module/stackless/interp_coroutine.py Sat Jun 10 15:07:59 2006 @@ -236,7 +236,7 @@ left = state.last left.frame = incoming_frame left.goodbye() - self.hello() + state.current.hello() main_costate_getter._get_default_costate().do_things_to_do() def kill(self): Modified: pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py (original) +++ pypy/dist/pypy/module/stackless/test/test_interp_coroutine.py Sat Jun 10 15:07:59 2006 @@ -278,6 +278,43 @@ output = self.wrap_stackless_function(ep) assert output == int('0110') + def test_hello_goodbye(self): + + class C(Coroutine): + n = 2 + def __init__(self, n): + Coroutine.__init__(self) + self.n = n + def hello(self): + costate.hello_goodbye *= 10 + costate.hello_goodbye += self.n + def goodbye(self): + costate.hello_goodbye *= 10 + costate.hello_goodbye += self.n + 1 + + class T(AbstractThunk): + def call(self): + pass + + costate = main_costate_getter._get_default_costate() + costate.current.__class__ = C + costate.hello_goodbye = 0 + + def ep(): + costate.hello_goodbye = 0 + c1 = C(4) + c1.bind(T()) + c1.switch() + return costate.hello_goodbye + + output = self.wrap_stackless_function(ep) + # expected result: + # goodbye main 3 + # hello c1 4 + # goodbye c1 5 + # hello main 2 + assert output == 3452 + TestCoroutine = _TestCoroutine # to activate class TestCoroutineOnCPython(_TestCoroutine): def wrap_stackless_function(self, func): From tismer at codespeak.net Sat Jun 10 17:08:09 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 10 Jun 2006 17:08:09 +0200 (CEST) Subject: [pypy-svn] r28628 - pypy/dist/pypy/module/stackless/test Message-ID: <20060610150809.6ED0010060@code0.codespeak.net> Author: tismer Date: Sat Jun 10 17:08:06 2006 New Revision: 28628 Modified: pypy/dist/pypy/module/stackless/test/slp_test_pickle.py Log: making this test theoretically run on top of CPython. Doesn't work right now, but then it can be renamed to a normal test. Probably the unpickling would be disabled depending on we_are_translated() Modified: pypy/dist/pypy/module/stackless/test/slp_test_pickle.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/slp_test_pickle.py (original) +++ pypy/dist/pypy/module/stackless/test/slp_test_pickle.py Sat Jun 10 17:08:06 2006 @@ -1,11 +1,17 @@ +from pypy.conftest import gettestobjspace + # app-level testing of coroutine pickling -import stackless -class TestPickle: +class AppTest_Pickle: + + def setup_class(cls): + space = gettestobjspace(usemodules=('stackless',)) + cls.space = space def test_simple_ish(self): output = [] + import stackless def f(coro, n, x): if n == 0: coro.switch() From tismer at codespeak.net Sat Jun 10 17:10:52 2006 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 10 Jun 2006 17:10:52 +0200 (CEST) Subject: [pypy-svn] r28629 - in pypy/dist/pypy: interpreter module/_pickle_support Message-ID: <20060610151052.EF3A210060@code0.codespeak.net> Author: tismer Date: Sat Jun 10 17:10:47 2006 New Revision: 28629 Modified: pypy/dist/pypy/interpreter/function.py pypy/dist/pypy/interpreter/typedef.py pypy/dist/pypy/module/_pickle_support/maker.py Log: explicitly creating functions in the __setstate__ phase. More code but less crashes. Still, something is broken with pickling. I think to add a debug mode to pickling. Modified: pypy/dist/pypy/interpreter/function.py ============================================================================== --- pypy/dist/pypy/interpreter/function.py (original) +++ pypy/dist/pypy/interpreter/function.py Sat Jun 10 17:10:47 2006 @@ -179,14 +179,39 @@ w_closure = space.w_None else: w_closure = space.newtuple([w(cell) for cell in self.closure]) - tup = [ + + nt = space.newtuple + tup_base = [] + tup_state = [ + w(self.name), + self.w_doc, w(self.code), self.w_func_globals, - w(self.name), - space.newtuple(self.defs_w), w_closure, + nt(self.defs_w), + self.w_func_dict, + self.w_module, ] - return space.newtuple([new_inst, space.newtuple(tup)]) + return nt([new_inst, nt(tup_base), nt(tup_state)]) + + def descr_function__setstate__(self, space, w_args): + from pypy.interpreter.pycode import PyCode + args_w = space.unpackiterable(w_args) + (w_name, w_doc, w_code, w_func_globals, w_closure, w_defs_w, + w_func_dict, w_module) = args_w + + self.space = space + self.name = space.str_w(w_name) + self.w_doc = w_doc + self.code = space.interp_w(PyCode, w_code) + self.w_func_globals = w_func_globals + if w_closure is not space.w_None: + self.closure = space.unpackiterable(w_closure) + else: + self.closure = None + self.defs_w = space.unpackiterable(w_defs_w) + self.w_func_dict = w_func_dict + self.w_module = w_module def fget_func_defaults(space, self): values_w = self.defs_w Modified: pypy/dist/pypy/interpreter/typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/typedef.py (original) +++ pypy/dist/pypy/interpreter/typedef.py Sat Jun 10 17:10:47 2006 @@ -578,6 +578,8 @@ __repr__ = interp2app(Function.descr_function_repr), __reduce__ = interp2app(Function.descr_function__reduce__, unwrap_spec=['self', ObjSpace]), + __setstate__ = interp2app(Function.descr_function__setstate__, + unwrap_spec=['self', ObjSpace, W_Root]), func_code = getset_func_code, func_doc = getset_func_doc, func_name = getset_func_name, Modified: pypy/dist/pypy/module/_pickle_support/maker.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/maker.py (original) +++ pypy/dist/pypy/module/_pickle_support/maker.py Sat Jun 10 17:10:47 2006 @@ -24,10 +24,11 @@ return space.call_args(w_type, __args__) code_new.unwrap_spec = [ObjSpace, Arguments] -def func_new(space, __args__): - w_type = space.gettypeobject(Function.typedef) - return space.call_args(w_type, __args__) -func_new.unwrap_spec = [ObjSpace, Arguments] +def func_new(space): + fu = instantiate(Function) + fu.w_func_dict = space.newdict([]) + return space.wrap(fu) +func_new.unwrap_spec = [ObjSpace] def module_new(space, w_name, w_dict): new_mod = Module(space, w_name, w_dict) @@ -62,7 +63,7 @@ w = space.wrap # let the code object create the right kind of frame - # the distinction is a littleover-done but computable + # the distinction is a little over-done but computable Klass = pycode.get_frame_class() new_frame = instantiate(Klass) return space.wrap(new_frame) From arigo at codespeak.net Sat Jun 10 20:05:24 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Jun 2006 20:05:24 +0200 (CEST) Subject: [pypy-svn] r28644 - pypy/dist/pypy/translator/c/test Message-ID: <20060610180524.5FDCF10053@code0.codespeak.net> Author: arigo Date: Sat Jun 10 20:05:23 2006 New Revision: 28644 Modified: pypy/dist/pypy/translator/c/test/test_lltyped.py Log: A test for PyStruct in genc. Modified: pypy/dist/pypy/translator/c/test/test_lltyped.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_lltyped.py (original) +++ pypy/dist/pypy/translator/c/test/test_lltyped.py Sat Jun 10 20:05:23 2006 @@ -195,3 +195,16 @@ fn = self.getcompiled(llf) res = fn() assert res == 8765 + + def test_pystruct(self): + PS1 = PyStruct('PS1', ('head', PyObject), ('x', Signed)) + class mytype(object): + pass + mytype_ptr = pyobjectptr(mytype) + def llf(): + p = malloc(PS1, flavor='cpy', extra_args=(mytype_ptr,)) + return cast_pointer(Ptr(PyObject), p) + + fn = self.getcompiled(llf) + res = fn() + assert type(res).__name__.endswith('mytype') From arigo at codespeak.net Sat Jun 10 20:50:39 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Jun 2006 20:50:39 +0200 (CEST) Subject: [pypy-svn] r28646 - in pypy/dist/pypy/translator/c: . src test Message-ID: <20060610185039.53B9110053@code0.codespeak.net> Author: arigo Date: Sat Jun 10 20:50:37 2006 New Revision: 28646 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/src/module.h pypy/dist/pypy/translator/c/test/test_lltyped.py pypy/dist/pypy/translator/c/test/test_typed.py Log: * Support for ll functions called when the CPython ext module is imported, to initialize some PyObjects. * Makefile tweak. * Clean up an overly strange test idiom. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Sat Jun 10 20:50:37 2006 @@ -698,8 +698,10 @@ print >> f, 'static cpyobjheaddef_t cpyobjheaddefs[] = {' for node in database.containerlist: if isinstance(node, PyObjHeadNode): - print >> f, '\t{"%s", %s},' % (node.exported_name, node.ptrname) - print >> f, '\t{ NULL, NULL }\t/* Sentinel */' + print >> f, '\t{"%s", %s, %s},' % (node.exported_name, + node.ptrname, + node.get_setupfn_name()) + print >> f, '\t{ NULL, NULL, NULL }\t/* Sentinel */' print >> f, '};' print >> f print >> f, '/***********************************************************/' @@ -802,9 +804,9 @@ clean: \trm -f $(OBJECTS) $(TARGET) -debug: clean +debug: \tmake CFLAGS="-g -pthread" -profile: clean +profile: \tmake CFLAGS="-pg $(CFLAGS)" LDFLAGS="-pg $(LDFLAGS)" ''' Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Sat Jun 10 20:50:37 2006 @@ -764,6 +764,14 @@ def enum_dependencies(self): yield self.obj.ob_type + if self.obj.setup_fnptr: + yield self.obj.setup_fnptr + + def get_setupfn_name(self): + if self.obj.setup_fnptr: + return self.db.get(self.obj.setup_fnptr) + else: + return 'NULL' def pyobj_initexpr(self): parent, parentindex = parentlink(self.obj) Modified: pypy/dist/pypy/translator/c/src/module.h ============================================================================== --- pypy/dist/pypy/translator/c/src/module.h (original) +++ pypy/dist/pypy/translator/c/src/module.h Sat Jun 10 20:50:37 2006 @@ -55,6 +55,7 @@ typedef struct { char* name; PyObject* cpyobj; + void (*setupfn)(PyObject *); } cpyobjheaddef_t; typedef struct { @@ -108,7 +109,7 @@ *def->p = obj; /* store the object ref in the global var */ } /* All objects should be valid at this point. Loop again and - make sure all types are ready. + make sure all types are ready, and call the user-defined setups. */ for (cpydef = cpyheadtable; cpydef->name != NULL; cpydef++) { obj = cpydef->cpyobj; @@ -116,6 +117,14 @@ if (PyType_Ready((PyTypeObject*) obj) < 0) return -1; } + if (cpydef->setupfn) { + cpydef->setupfn(obj); + if (RPyExceptionOccurred()) { + PyErr_SetString(PyExc_SystemError, + "failed to setup CPython objects"); + return -1; + } + } } return 0; } Modified: pypy/dist/pypy/translator/c/test/test_lltyped.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_lltyped.py (original) +++ pypy/dist/pypy/translator/c/test/test_lltyped.py Sat Jun 10 20:50:37 2006 @@ -2,8 +2,7 @@ from pypy.translator.c.test import test_typed -class TestLowLevelType: - getcompiled = test_typed.TestTypedTestCase().getcompiled +class TestLowLevelType(test_typed.CompilationTestCase): def test_simple(self): S = GcStruct("s", ('v', Signed)) @@ -197,7 +196,8 @@ assert res == 8765 def test_pystruct(self): - PS1 = PyStruct('PS1', ('head', PyObject), ('x', Signed)) + PS1 = PyStruct('PS1', ('head', PyObject), ('x', Signed), + hints = {'inline_head': True}) class mytype(object): pass mytype_ptr = pyobjectptr(mytype) @@ -208,3 +208,33 @@ fn = self.getcompiled(llf) res = fn() assert type(res).__name__.endswith('mytype') + + def test_pystruct_prebuilt(self): + PS1 = PyStruct('PS1', ('head', PyObject), ('x', Signed), + hints = {'inline_head': True}) + class mytype(object): + pass + + def llsetup(phead): + "Called when the CPython ext module is imported." + p = cast_pointer(Ptr(PS1), phead) + p.x = 27 + + mytype_ptr = pyobjectptr(mytype) + p = malloc(PS1, flavor='cpy', extra_args=(mytype_ptr,)) + p.x = -5 # overridden by llsetup() + + def llf(): + return p.x + + def process(t): + rtyper = t.buildrtyper() + rtyper.specialize() + llsetup_ptr = rtyper.annotate_helper_fn(llsetup, [Ptr(PyObject)]) + phead = cast_pointer(Ptr(PyObject), p) + phead._obj.setup_fnptr = llsetup_ptr + + self.process = process + fn = self.getcompiled(llf) + res = fn() + assert res == 27 Modified: pypy/dist/pypy/translator/c/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_typed.py (original) +++ pypy/dist/pypy/translator/c/test/test_typed.py Sat Jun 10 20:50:37 2006 @@ -13,7 +13,7 @@ from pypy.translator.tool import cbuild cbuild.enable_fast_compilation() -class TestTypedTestCase: +class CompilationTestCase: def annotatefunc(self, func): t = TranslationContext(simplifying=True) @@ -47,6 +47,13 @@ insert_ll_stackcheck(t) return self.compilefunc(t, func) + def process(self, t): + t.buildrtyper().specialize() + #raisingop2direct_call(t) + + +class TestTypedTestCase(CompilationTestCase): + def test_set_attr(self): set_attr = self.getcompiled(snippet.set_attr) assert set_attr() == 2 @@ -283,10 +290,6 @@ assert fn(0) == 2 assert fn(1) == 1 - def process(self, t): - t.buildrtyper().specialize() - #raisingop2direct_call(t) - def test_call_five(self): # -- the result of call_five() isn't a real list, but an rlist # that can't be converted to a PyListObject From mwh at codespeak.net Sat Jun 10 22:17:39 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 10 Jun 2006 22:17:39 +0200 (CEST) Subject: [pypy-svn] r28649 - in pypy/dist/pypy/module: _pickle_support stackless Message-ID: <20060610201739.6EC9410053@code0.codespeak.net> Author: mwh Date: Sat Jun 10 22:17:38 2006 New Revision: 28649 Modified: pypy/dist/pypy/module/_pickle_support/__init__.py pypy/dist/pypy/module/_pickle_support/maker.py pypy/dist/pypy/module/stackless/coroutine.py Log: special case attempts to pickle the main coroutine. ugly, possibly not a good idea in general, but it enables a coroutine to be successfully pickled. haven't even tried unpickling yet :-) also, add a _framestack applevel attribute to AppCoroutine. Modified: pypy/dist/pypy/module/_pickle_support/__init__.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/__init__.py (original) +++ pypy/dist/pypy/module/_pickle_support/__init__.py Sat Jun 10 22:17:38 2006 @@ -19,4 +19,5 @@ 'frame_new' : 'maker.frame_new', 'traceback_new' : 'maker.traceback_new', 'generator_new' : 'maker.generator_new', + 'return_main' : 'maker.return_main', } Modified: pypy/dist/pypy/module/_pickle_support/maker.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/maker.py (original) +++ pypy/dist/pypy/module/_pickle_support/maker.py Sat Jun 10 22:17:38 2006 @@ -86,6 +86,11 @@ return space.wrap(new_generator) generator_new.unwrap_spec = [ObjSpace, Arguments] +def return_main(space): + from pypy.module.stackless.coroutine import AppCoroutine + return AppCoroutine._get_state(space).main +return_main.unwrap_spec = [ObjSpace] + # ___________________________________________________________________ # Helper functions for internal use Modified: pypy/dist/pypy/module/stackless/coroutine.py ============================================================================== --- pypy/dist/pypy/module/stackless/coroutine.py (original) +++ pypy/dist/pypy/module/stackless/coroutine.py Sat Jun 10 22:17:38 2006 @@ -56,6 +56,7 @@ state = self._get_state(space) Coroutine.__init__(self, state) self.flags = 0 + self.framestack = None if not is_main: space.getexecutioncontext().subcontext_new(self) @@ -121,11 +122,16 @@ from pypy.interpreter.mixedmodule import MixedModule w_mod = space.getbuiltinmodule('stackless') mod = space.interp_w(MixedModule, w_mod) + w_mod2 = space.getbuiltinmodule('_pickle_support') + mod2 = space.interp_w(MixedModule, w_mod2) new_inst = mod.get('coroutine') w = space.wrap nt = space.newtuple ec = self.space.getexecutioncontext() + if self is self._get_state(space).main: + return space.newtuple([mod2.get('return_main'), space.newtuple([])]) + tup_base = [ ] tup_state = [ @@ -142,7 +148,7 @@ ec = self.space.getexecutioncontext() ec.subcontext_setstate(self, w_state) self.reconstruct_framechain() - + def reconstruct_framechain(self): from pypy.interpreter.pyframe import PyFrame from pypy.rpython.rstack import resume_state_create @@ -201,6 +207,14 @@ return space.wrap(self.get_is_zombie()) AppCoroutine.w_get_is_zombie = w_get_is_zombie +def w_descr__framestack(space, self): + assert isinstance(self, AppCoroutine) + if self.framestack: + items = [space.wrap(item) for item in self.framestack.items] + return space.newtuple(items) + else: + return space.newtuple([]) + def makeStaticMethod(module, classname, funcname): space = module.space space.appexec(map(space.wrap, (module, classname, funcname)), """ @@ -226,6 +240,7 @@ switch = interp2app(AppCoroutine.w_switch), kill = interp2app(AppCoroutine.w_kill), is_zombie = GetSetProperty(AppCoroutine.w_get_is_zombie, doc=AppCoroutine.get_is_zombie.__doc__), + _framestack = GetSetProperty(w_descr__framestack), getcurrent = interp2app(AppCoroutine.w_getcurrent), __reduce__ = interp2app(AppCoroutine.descr__reduce__, unwrap_spec=['self', ObjSpace]), From pedronis at codespeak.net Sun Jun 11 12:22:27 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 11 Jun 2006 12:22:27 +0200 (CEST) Subject: [pypy-svn] r28663 - pypy/dist/pypy/interpreter Message-ID: <20060611102227.95FDB10063@code0.codespeak.net> Author: pedronis Date: Sun Jun 11 12:22:25 2006 New Revision: 28663 Modified: pypy/dist/pypy/interpreter/function.py Log: fix annotation Modified: pypy/dist/pypy/interpreter/function.py ============================================================================== --- pypy/dist/pypy/interpreter/function.py (original) +++ pypy/dist/pypy/interpreter/function.py Sun Jun 11 12:22:25 2006 @@ -206,7 +206,9 @@ self.code = space.interp_w(PyCode, w_code) self.w_func_globals = w_func_globals if w_closure is not space.w_None: - self.closure = space.unpackiterable(w_closure) + from pypy.interpreter.nestedscope import Cell + closure_w = space.unpackiterable(w_closure) + self.closure = [space.interp_w(Cell, w_cell) for w_cell in closure_w] else: self.closure = None self.defs_w = space.unpackiterable(w_defs_w) From arigo at codespeak.net Sun Jun 11 13:22:36 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Jun 2006 13:22:36 +0200 (CEST) Subject: [pypy-svn] r28664 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/lltypesystem/test translator/c/src Message-ID: <20060611112236.B061710063@code0.codespeak.net> Author: arigo Date: Sun Jun 11 13:22:34 2006 New Revision: 28664 Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py pypy/dist/pypy/rpython/rcpy.py pypy/dist/pypy/translator/c/src/module.h Log: Support exporting class attributes from rcpy.py. Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Sun Jun 11 13:22:34 2006 @@ -467,7 +467,7 @@ def _inline_is_varsize(self, last): return False def _defl(self, parent=None, parentindex=None): - return _pyobjheader(Ellipsis, parent, parentindex) + return _pyobjheader(parent, parentindex) PyObject = PyObjectType() @@ -1474,16 +1474,17 @@ return "pyobject %s" % (Hashable.__str__(self),) class _pyobjheader(_parentable): - - def __init__(self, ob_type, parent=None, parentindex=None): + def __init__(self, parent=None, parentindex=None): _parentable.__init__(self, PyObject) - self._setup_extra_args(ob_type) if parent is not None: self._setparentstructure(parent, parentindex) + # the extra attributes 'ob_type' and 'setup_fnptr' are + # not set by __init__(), but by malloc(extra_args=(...)) - def _setup_extra_args(self, ob_type): - assert ob_type is Ellipsis or typeOf(ob_type) == Ptr(PyObject) + def _setup_extra_args(self, ob_type, setup_fnptr=None): + assert typeOf(ob_type) == Ptr(PyObject) self.ob_type = ob_type + self.setup_fnptr = setup_fnptr def __repr__(self): return '<%s>' % (self,) Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py Sun Jun 11 13:22:34 2006 @@ -1,5 +1,6 @@ from pypy.translator.c.test.test_genc import compile -from pypy.rpython.rcpy import cpy_export, cpy_import +from pypy.rpython.rcpy import cpy_export, cpy_import, CPyTypeInterface +from pypy.rpython.lltypesystem import lltype class W_MyTest(object): @@ -12,10 +13,9 @@ return self.x * 2 -def test_cpy_export(): - class mytest(object): - pass +mytest = CPyTypeInterface('mytest', {}) +def test_cpy_export(): def f(): w = W_MyTest(21) return cpy_export(mytest, w) @@ -26,9 +26,6 @@ def test_cpy_import(): - class mytest(object): - pass - def f(): w = W_MyTest(21) return cpy_export(mytest, w) @@ -44,9 +41,6 @@ def test_tp_dealloc(): - class mytest(object): - pass - class A(object): pass @@ -69,9 +63,6 @@ def test_manipulate_more(): - class mytest(object): - pass - def f(input): current = total = 0 if input: @@ -99,9 +90,6 @@ def test_instantiate_from_cpython(): - class mytest(object): - pass - def f(input): if input: w = cpy_import(W_MyTest, input) @@ -123,8 +111,6 @@ def test_subclass_from_cpython(): import py; py.test.skip("not implemented (see comments in rcpy.py)") - class mytest(object): - pass def f(input): current = total = 10 @@ -155,3 +141,30 @@ del objlist obj, total = fn(obj, expected_extra_mallocs=6) # 3 W_MyTests alive assert total == 3 + + +def test_export_constant(): + mytest2 = CPyTypeInterface('mytest2', {'hi': lltype.pyobjectptr(123)}) + def f(): + w = W_MyTest(21) + return cpy_export(mytest2, w) + + fn = compile(f, []) + obj = fn(expected_extra_mallocs=1) + assert obj.hi == 123 + assert type(obj).hi == 123 + + +def test_export_two_constants(): + mytest2 = CPyTypeInterface('mytest2', {'hi': lltype.pyobjectptr(123), + 'there': lltype.pyobjectptr("foo")}) + def f(): + w = W_MyTest(21) + return cpy_export(mytest2, w) + + fn = compile(f, []) + obj = fn(expected_extra_mallocs=1) + assert obj.hi == 123 + assert type(obj).hi == 123 + assert obj.there == "foo" + assert type(obj).there == "foo" Modified: pypy/dist/pypy/rpython/rcpy.py ============================================================================== --- pypy/dist/pypy/rpython/rcpy.py (original) +++ pypy/dist/pypy/rpython/rcpy.py Sun Jun 11 13:22:34 2006 @@ -6,6 +6,21 @@ from pypy.objspace.flow.model import FunctionGraph, Block, Link +class CPyTypeInterface(object): + + def __init__(self, name, objects): + + # the exported name of the type + self.name = name + + # a dict {name, pyobjectptr()} for general class attributes + # (not for special methods!) + self.objects = objects + + def _freeze_(self): + return True + + def cpy_export(cpytype, obj): raise NotImplementedError("only works in translated versions") @@ -13,6 +28,9 @@ raise NotImplementedError("only works in translated versions") +# ____________________________________________________________ +# Implementation + class Entry(ExtRegistryEntry): _about_ = cpy_export @@ -26,9 +44,7 @@ assert s_obj.classdef._cpy_exported_type_ == cpytype else: s_obj.classdef._cpy_exported_type_ = cpytype - s = SomeObject() - s.knowntype = cpytype - return s + return SomeObject() def specialize_call(self, hop): from pypy.rpython.lltypesystem import lltype @@ -103,7 +119,7 @@ ('c_tp_members', lltype.Signed), ('c_tp_getset', lltype.Signed), ('c_tp_base', lltype.Signed), - ('c_tp_dict', lltype.Signed), + ('c_tp_dict', PyObjPtr), ('c_tp_descr_get', lltype.Signed), ('c_tp_descr_set', lltype.Signed), ('c_tp_dictoffset',lltype.Signed), @@ -121,7 +137,7 @@ # lltype.Void))), hints={'c_name': '_typeobject', 'external': True, 'inline_head': True})) -# XXX should be PyTypeObject but genc inserts 'struct' :-( +# XXX 'c_name' should be 'PyTypeObject' but genc inserts 'struct' :-( def ll_tp_dealloc(p): addr = llmemory.cast_ptr_to_adr(p) @@ -134,6 +150,7 @@ def build_pytypeobject(r_inst): from pypy.rpython.lltypesystem.rclass import CPYOBJECTPTR from pypy.rpython.rtyper import LowLevelOpList + rtyper = r_inst.rtyper typetype = lltype.pyobjectptr(type) # make the graph of tp_new manually @@ -152,7 +169,8 @@ # build the PyTypeObject structure pytypeobj = lltype.malloc(PY_TYPE_OBJECT, flavor='cpy', extra_args=(typetype,)) - name = r_inst.classdef._cpy_exported_type_.__name__ + cpytype = r_inst.classdef._cpy_exported_type_ + name = cpytype.name T = lltype.FixedSizeArray(lltype.Char, len(name)+1) p = lltype.malloc(T, immortal=True) for i in range(len(name)): @@ -161,11 +179,26 @@ pytypeobj.c_tp_name = lltype.direct_arrayitems(p) pytypeobj.c_tp_basicsize = llmemory.sizeof(r_inst.lowleveltype.TO) pytypeobj.c_tp_flags = CDefinedIntSymbolic('Py_TPFLAGS_DEFAULT') - pytypeobj.c_tp_new = r_inst.rtyper.type_system.getcallable(tp_new_graph) - pytypeobj.c_tp_dealloc = r_inst.rtyper.annotate_helper_fn( - ll_tp_dealloc, - [PyObjPtr]) - return lltype.cast_pointer(PyObjPtr, pytypeobj) + pytypeobj.c_tp_new = rtyper.type_system.getcallable(tp_new_graph) + pytypeobj.c_tp_dealloc = rtyper.annotate_helper_fn(ll_tp_dealloc, + [PyObjPtr]) + result = lltype.cast_pointer(PyObjPtr, pytypeobj) + + # the llsetup function that will store the 'objects' into the + # type's tp_dict + if cpytype.objects: + objects = [(lltype.pyobjectptr(name), value) + for name, value in cpytype.objects.items()] + + def ll_type_setup(p): + tp = lltype.cast_pointer(lltype.Ptr(PY_TYPE_OBJECT), p) + tp_dict = tp.c_tp_dict + for name, value in objects: + llop.setitem(PyObjPtr, tp_dict, name, value) + result._obj.setup_fnptr = rtyper.annotate_helper_fn(ll_type_setup, + [PyObjPtr]) + + return result # To make this a Py_TPFLAGS_BASETYPE, we need to have a tp_new that does # something different for subclasses: it needs to allocate a bit more Modified: pypy/dist/pypy/translator/c/src/module.h ============================================================================== --- pypy/dist/pypy/translator/c/src/module.h (original) +++ pypy/dist/pypy/translator/c/src/module.h Sun Jun 11 13:22:34 2006 @@ -120,8 +120,7 @@ if (cpydef->setupfn) { cpydef->setupfn(obj); if (RPyExceptionOccurred()) { - PyErr_SetString(PyExc_SystemError, - "failed to setup CPython objects"); + RPyConvertExceptionToCPython(); return -1; } } From arigo at codespeak.net Sun Jun 11 13:44:36 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Jun 2006 13:44:36 +0200 (CEST) Subject: [pypy-svn] r28668 - pypy/dist/pypy/module/readline Message-ID: <20060611114436.5FA5810063@code0.codespeak.net> Author: arigo Date: Sun Jun 11 13:44:35 2006 New Revision: 28668 Modified: pypy/dist/pypy/module/readline/__init__.py Log: Skip these failing tests. Modified: pypy/dist/pypy/module/readline/__init__.py ============================================================================== --- pypy/dist/pypy/module/readline/__init__.py (original) +++ pypy/dist/pypy/module/readline/__init__.py Sun Jun 11 13:44:35 2006 @@ -1,5 +1,6 @@ # this is a sketch of how one might one day be able to define a pretty simple # ctypes-using module, suitable for feeding to the ext-compiler +import py; py.test.skip("in-progress") from pypy.interpreter.ctypesmodule import CTypesModule From pedronis at codespeak.net Sun Jun 11 14:19:04 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 11 Jun 2006 14:19:04 +0200 (CEST) Subject: [pypy-svn] r28671 - pypy/dist/pypy/translator/stackless/test Message-ID: <20060611121904.0A9B010063@code0.codespeak.net> Author: pedronis Date: Sun Jun 11 14:19:02 2006 New Revision: 28671 Modified: pypy/dist/pypy/translator/stackless/test/test_coroutine_reconstruction.py Log: updagte and fix test. Modified: pypy/dist/pypy/translator/stackless/test/test_coroutine_reconstruction.py ============================================================================== --- pypy/dist/pypy/translator/stackless/test/test_coroutine_reconstruction.py (original) +++ pypy/dist/pypy/translator/stackless/test/test_coroutine_reconstruction.py Sun Jun 11 14:19:02 2006 @@ -8,7 +8,7 @@ class TestCoroutineReconstruction: def setup_meth(self): - interp_coroutine.costate.__init__() + interp_coroutine.main_costate_getter.costate = None def test_simple_ish(self): @@ -31,7 +31,7 @@ f(self.arg_coro, self.arg_n, self.arg_x) def example(): - main_coro = interp_coroutine.costate.main + main_coro = interp_coroutine.Coroutine.getcurrent() sub_coro = interp_coroutine.Coroutine() thunk_f = T(main_coro, 5, 1) sub_coro.bind(thunk_f) @@ -41,15 +41,16 @@ new_thunk_f = T(main_coro, 5, 1) new_coro.bind(new_thunk_f) + costate = interp_coroutine.main_costate_getter._get_default_costate() bottom = resume_state_create(None, "yield_current_frame_to_caller_1") - _bind_frame = resume_state_create(bottom, "coroutine__bind", new_coro, interp_coroutine.costate) + _bind_frame = resume_state_create(bottom, "coroutine__bind", new_coro, costate) f_frame_1 = resume_state_create(_bind_frame, "f_1", main_coro, 5, 1) f_frame_2 = resume_state_create(f_frame_1, "f_1", main_coro, 4, 2) f_frame_3 = resume_state_create(f_frame_2, "f_1", main_coro, 3, 4) f_frame_4 = resume_state_create(f_frame_3, "f_1", main_coro, 2, 8) f_frame_5 = resume_state_create(f_frame_4, "f_1", main_coro, 1, 16) f_frame_0 = resume_state_create(f_frame_5, "f_0") - switch_frame = resume_state_create(f_frame_0, "coroutine_switch", new_coro, interp_coroutine.costate) + switch_frame = resume_state_create(f_frame_0, "coroutine_switch", new_coro, costate) new_coro.frame = switch_frame From stephan at codespeak.net Sun Jun 11 14:30:25 2006 From: stephan at codespeak.net (stephan at codespeak.net) Date: Sun, 11 Jun 2006 14:30:25 +0200 (CEST) Subject: [pypy-svn] r28672 - pypy/dist/pypy/module/stackless/test Message-ID: <20060611123025.5AEAD10063@code0.codespeak.net> Author: stephan Date: Sun Jun 11 14:30:21 2006 New Revision: 28672 Modified: pypy/dist/pypy/module/stackless/test/stack1.py pypy/dist/pypy/module/stackless/test/stack2.py pypy/dist/pypy/module/stackless/test/stackless_.py Log: scheduling is still not really working (run stack2.py with both: stackless cpython and stackless pypy to see what I mean), but, it's somewhat working which is not too bad. Modified: pypy/dist/pypy/module/stackless/test/stack1.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/stack1.py (original) +++ pypy/dist/pypy/module/stackless/test/stack1.py Sun Jun 11 14:30:21 2006 @@ -10,7 +10,7 @@ def main(): cg = tasklet(g)('test') cf = tasklet(f)() - schedule() + run() print 'in main', getcurrent() if __name__ == '__main__': Modified: pypy/dist/pypy/module/stackless/test/stack2.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/stack2.py (original) +++ pypy/dist/pypy/module/stackless/test/stack2.py Sun Jun 11 14:30:21 2006 @@ -24,16 +24,17 @@ def f(outchan): for i in range(10): - print 'f: sending',i - print + print 'T1: sending',i outchan.send(i) + print 'T1: after sending' + print 'T1: sending -1' outchan.send(-1) def g(inchan): while 1: + print 'T2: before receiving' val = inchan.receive() - print 'g: received',val - print + print 'T2: received',val if val == -1: break Modified: pypy/dist/pypy/module/stackless/test/stackless_.py ============================================================================== --- pypy/dist/pypy/module/stackless/test/stackless_.py (original) +++ pypy/dist/pypy/module/stackless/test/stackless_.py Sun Jun 11 14:30:21 2006 @@ -7,7 +7,7 @@ import sys #DEBUG = True -DEBUG = True +DEBUG = False switches = 0 @@ -47,6 +47,21 @@ This is a necessary Stackless 3.1 feature. """ +def SWAPVAL(task1, task2): + assert task1 is not None + assert task2 is not None + if DEBUG: + print 'SWAPVAL(%s, %s)' % (task1, task2) + print '\t', task1.tempval + print '\t', task2.tempval + task1.tempval, task2.tempval = task2.tempval, task1.tempval + +def SETVAL(task, val): + assert task is not None + if DEBUG: + print 'SETVAL(%s, %s)' % (task, val) + task.tempval = val + # thread related stuff: assuming NON threaded execution for now def check_for_deadlock(): @@ -79,7 +94,7 @@ self._coro = coro def __str__(self): - return 'Tasklet-%s' % self.thread_id + return tasklet.__str__(self) def __getattr__(self,attr): return getattr(self._coro,attr) @@ -267,7 +282,7 @@ except Exception, exp: b = curexc_to_bomb() main = main_tasklet - main.tempval = b + SETVAL(main, b) scheduler.current_insert_after(main) scheduler.schedule_task(me, main, 1) @@ -403,7 +418,11 @@ def __str__(self): next = (self.next and self.next.thread_id) or None prev = (self.prev and self.prev.thread_id) or None - return 'Tasklet-%s(%s) n: %s; p: %s' % (self.thread_id, str(self.blocked), next, prev) + if self.blocked: + bs = 'b' + else: + bs = '-' + return 'T%s(%s) (%s, %s)' % (self.thread_id, bs, next, prev) def bind(self, func): """ @@ -415,7 +434,7 @@ """ if not callable(func): raise TypeError('tasklet function must be a callable') - self.tempval = func + SETVAL(self, func) def _is_dead(self): return False @@ -519,7 +538,7 @@ if self.tempval is None: raise TypeError('cframe function must be callable') coroutine.bind(self,self.tempval,*argl,**argd) - self.tempval = None + SETVAL(self, None) self.insert() """ /*************************************************************************** @@ -571,7 +590,8 @@ self.thread_id = -2 def __str__(self): - return 'channel(' + str(self.balance) + ')' + parts = ['%s' % x.thread_id for x in self._content()] + return 'channel(' + str(self.balance) + '): ['+' -> '.join(parts)+']' def _get_closed(self): return self.closing and self.next is None @@ -583,6 +603,17 @@ self.balance += d task.blocked = d + def _content(self): + visited = set((self,)) + items = [] + next = self.next + if next is not self: + while next is not None and next not in visited: + items.append(next) + visited.add(next) + next = next.next + return items + def _queue(self): if self.next is self: return None @@ -618,14 +649,14 @@ self.prev = task def _rem(self, task): + if DEBUG: + print '### channel._rem(%s)' % task assert task.next is not None assert task.prev is not None #remove at end task.next.prev = task.prev task.prev.next = task.next task.next = task.prev = None - if DEBUG: - print '### channel._rem(%s)' % task def _notify(self, task, d, cando, res): global schedlock @@ -641,31 +672,34 @@ try: #source = getcurrent() source = scheduler._head - if DEBUG: - print '_channel_action -> source:', source target = self.next - if DEBUG: - print '_channel_action -> target:', target - print + if not source is getcurrent(): + print '!!!!! scheduler._head is not current !!!!!' interthread = 0 # no interthreading at the moment if d > 0: cando = self.balance < 0 else: cando = self.balance > 0 + if DEBUG: + print + print self + print '_channel_action(%s, %s)' % (arg, d) + print '_channel_action -> source:', source + print '_channel_action -> target:', target + print '--- cando --- :',cando + print scheduler + print + print assert abs(d) == 1 - source.tempval = arg + SETVAL(source, arg) if not interthread: self._notify(source, d, cando, None) - if DEBUG: - print '_channel_action(',arg, ',', d, ')' - print 'cando:',cando - print if cando: # communication 1): there is somebody waiting target = self._channel_remove(-d) - source.tempval, target.tempval = target.tempval, source.tempval + SWAPVAL(source, target) if interthread: raise Exception('no interthreading: I can not be reached...') else: @@ -680,6 +714,7 @@ scheduler.current_insert(target) target = source else: + # communication 2): there is nobody waiting if source.block_trap: raise RuntimeError("this tasklet does not like to be blocked") if self.closing: @@ -692,7 +727,8 @@ print 'Exception in channel_action', exp, '\n\n' raise try: - print '# channel action: calling schedule with', source, target + if DEBUG: + print 'BEFORE SWITCH:',self retval = scheduler.schedule_task(source, target, stackl) except Exception, exp: print 'schedule_task raised', exp @@ -815,8 +851,6 @@ def __init__(self): self._head = getcurrent() - #self.chain = None - #self.current = getcurrent() def _set_head(self, task): self._head = task @@ -844,9 +878,7 @@ currid = self._head.thread_id else: currid = -1 - return '===== Scheduler ====\nchain:' + \ - ' -> '.join(parts) + '\ncurrent: %s' % currid + \ - '\n====================' + return 'Scheduler: [' + ' -> '.join(parts) + ']' def _chain_insert(self, task): assert task.next is None @@ -907,7 +939,7 @@ def bomb_explode(self, task): thisbomb = task.tempval assert isinstance(thisbomb, bomb) - task.tempval = None + SETVAL(task, None) thisbomb._explode() def _notify_schedule(self, prev, next, errflag): @@ -926,10 +958,10 @@ if check_for_deadlock(): if main_tasklet.next is None: if isinstance(prev.tempval, bomb): - main_tasklet.tempval = prev.tempval + SETVAL(main_tasklet, prev.tempval) return self.schedule_task(prev, main_tasklet, stackl) retval = make_deadlock_bomb() - prev.tempval = retval + SETVAL(prev, retval) return self.schedule_task(prev, prev, stackl) @@ -938,7 +970,9 @@ global switches switches += 1 myswitch = switches - print '\nschedule_task(%s)' % myswitch, prev, next + if DEBUG: + print '\n\n!!! schedule_task(%s)' % myswitch, prev, next + print if next is None: return self.schedule_task_block(prev, stackl) if next.blocked: @@ -965,9 +999,9 @@ print 'after switch(%s) ->' % myswitch ,next print #self._set_head(next) - self._head = next + #self._head = next - retval = next.tempval + retval = prev.tempval if isinstance(retval, bomb): print '!!!!! exploding !!!!!!' self.bomb_explode(next) From ericvrp at codespeak.net Sun Jun 11 16:01:52 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sun, 11 Jun 2006 16:01:52 +0200 (CEST) Subject: [pypy-svn] r28673 - in pypy/dist/pypy/translator/js2/proxy/testme: . static/javascript templates Message-ID: <20060611140152.827A310071@code0.codespeak.net> Author: ericvrp Date: Sun Jun 11 16:01:50 2006 New Revision: 28673 Added: pypy/dist/pypy/translator/js2/proxy/testme/servermessage.py - copied, changed from r28644, pypy/dist/pypy/translator/js2/proxy/testme/controllers.py pypy/dist/pypy/translator/js2/proxy/testme/static/javascript/bnb.js pypy/dist/pypy/translator/js2/proxy/testme/templates/bnb.kid Removed: pypy/dist/pypy/translator/js2/proxy/testme/templates/welcome.kid Modified: pypy/dist/pypy/translator/js2/proxy/testme/controllers.py pypy/dist/pypy/translator/js2/proxy/testme/templates/master.kid Log: intermediate (weekend) checkin, includes a little javascript to test the proxy Modified: pypy/dist/pypy/translator/js2/proxy/testme/controllers.py ============================================================================== --- pypy/dist/pypy/translator/js2/proxy/testme/controllers.py (original) +++ pypy/dist/pypy/translator/js2/proxy/testme/controllers.py Sun Jun 11 16:01:50 2006 @@ -6,132 +6,74 @@ import socket import urllib import re - - -class SessionData: - - def broadcast_port(self, *values): - print 'MESSAGE (IGNORE):broadcast_port', values - - def ping(self): - print 'MESSAGE:ping' - - def def_playfield(self, width, height, backcolor, FnDesc): - print 'MESSAGE:def_playfield width=%s, height=%s, backcolor=%s, FnDesc=%s' %\ - (width, height, backcolor, FnDesc) - - def def_bitmap(self, code, data, *rest): - print 'MESSAGE:def_bitmap code=%s, data=%d bytes, colorkey=%s' %\ - (code, len(data), rest) - bitmap_filename = 'testme/static/images/bitmap%d.ppm' % code - f = open(bitmap_filename, 'wb') - f.write(zlib.decompress(data)) - f.close() - - #TODO: use in memory (don't save ppm first) - bitmap = PIL.Image.open(bitmap_filename) - gif_bitmap_filename = 'testme/static/images/bitmap%d.gif' % code - bitmap.save(gif_bitmap_filename) - - def def_icon(self, bitmap_code, code, x,y,w,h, *rest): - print 'MESSAGE:def_icon bitmap_code=%s, code=%s, x=%s, y=%s, w=%s, h=%s, alpha=%s' %\ - (bitmap_code, code, x,y,w,h, rest) - - #TODO: use in memory (don't save ppm first) - bitmap_filename = 'testme/static/images/bitmap%d.gif' % bitmap_code - icon_filename = 'testme/static/images/icon%d.gif' % code - icon = PIL.Image.open(bitmap_filename) - box = (x, y, x+w, y+h) - region = icon.crop(box) - region.save(icon_filename) - print 'SAVED:', icon_filename - - filename = '../static/images/icon%d.gif' % code - return dict(type='def_icon', code=code, filename=filename) - - MESSAGES = { - MSG_BROADCAST_PORT : broadcast_port, - MSG_PING : ping, - MSG_DEF_PLAYFIELD : def_playfield, - MSG_DEF_BITMAP : def_bitmap, - MSG_DEF_ICON : def_icon, - } - - def __init__(self): - self.socket = None - self.data = '' - - def handleServerMessage(self, *values): - #print 'RECEIVED MESSAGE:%s(%d)' % (values[0], len(values[1:])) - fn = self.MESSAGES.get(values[0]) - if fn: - return fn(self, *values[1:]) - else: - print "UNKNOWN MESSAGE:", values - return dict(type='unknown', values=values) +from servermessage import ServerMessage, log class Root(controllers.Root): - _sessionData = {} + _serverMessage = {} n_header_lines = 2 host = 'localhost' port = re.findall('value=".*"', urllib.urlopen('http://%s:8000' % host).read())[0] port = int(port[7:-1]) - def sessionData(self): + def serverMessage(self): sessionid = session['_id'] - if sessionid not in self._sessionData: - self._sessionData[sessionid] = SessionData() - return self._sessionData[sessionid] + if sessionid not in self._serverMessage: + self._serverMessage[sessionid] = ServerMessage() + return self._serverMessage[sessionid] def sessionSocket(self, close=False): - d = self.sessionData() - if d.socket is None: - d.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - d.socket.connect((self.host, self.port)) + sm = self.serverMessage() + if sm.socket is None: + sm.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sm.socket.connect((self.host, self.port)) #XXX todo: session.socket.close() after a timeout - return d.socket + return sm.socket + + @expose(html='testme.templates.bnb') + def index(self): + return dict() @expose(format='json') def send(self, data=message(CMSG_PING)): self.sessionSocket().send(data) - print 'SENT:' + repr(data) + log('SENT: %s' % repr(data)) return self.recv() @expose(format='json') def recv(self): #XXX hangs if not first sending a ping! - d = self.sessionData() + sm = self.serverMessage() size = 1024 - data = d.data + self.sessionSocket().recv(size) + data = sm.data + self.sessionSocket().recv(size) while self.n_header_lines > 0 and '\n' in data: self.n_header_lines -= 1 header_line, data = data.split('\n',1) - print 'RECEIVED HEADER LINE: %s' % header_line + log('RECEIVED HEADER LINE: %s' % header_line) - #print 'RECEIVED DATA CONTAINS %d BYTES' % len(data) + #log('RECEIVED DATA CONTAINS %d BYTES' % len(data)) messages = [] while data: values, data = decodemessage(data) if not values: break # incomplete message - messageOutput = d.handleServerMessage(*values) + messageOutput = sm.dispatch(*values) if messageOutput: messages.append(messageOutput) - d.data = data - #print 'RECEIVED DATA REMAINING CONTAINS %d BYTES' % len(data) + sm.data = data + #log('RECEIVED DATA REMAINING CONTAINS %d BYTES' % len(data)) - print 'MESSAGES:', messages + log('MESSAGES:%s' % messages) return dict(messages=messages) @expose(format='json') def close(self): sessionid = session['_id'] - d = self.sessionData() - if d.socket is not None: - d.socket.close() - del self._sessionData[sessionid] + sm = self.serverMessage() + if sm.socket is not None: + sm.socket.close() + del self._serverMessage[sessionid] return dict() Added: pypy/dist/pypy/translator/js2/proxy/testme/static/javascript/bnb.js ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme/static/javascript/bnb.js Sun Jun 11 16:01:50 2006 @@ -0,0 +1,20 @@ +//note: we assume Mochikit is already included + +function sendToServer() { //XXX for now, just get (proxy) server data + loadJSONDoc('send').addCallback( + function (json_doc) { + var messages = json_doc.messages; + for (var i in messages) { + var message = messages[i]; + var s = message.type; + if (message.type == 'def_icon') { //code, filename, width, height + s += ', filename=' + message.filename; + } + document.body.firstChild.nodeValue = s; + } + callLater(0.01, sendToServer); //again... + } + ); +} + +callLater(0.01, sendToServer); Added: pypy/dist/pypy/translator/js2/proxy/testme/templates/bnb.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js2/proxy/testme/templates/bnb.kid Sun Jun 11 16:01:50 2006 @@ -0,0 +1,11 @@ + + + + + +

This is a test!


+

Code:


+
+    ${code}
+  
+ + Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.pyc ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/main.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/main.kid Thu Jun 22 19:12:51 2006 @@ -0,0 +1,30 @@ + + + + + Bub'n'bros + + + +

This is a test!


+

Code:


+
+    ${code}
+  
+ + Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/main.pyc ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/master.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/master.kid Thu Jun 22 19:12:51 2006 @@ -0,0 +1,15 @@ + + + + + + + Your title goes here + + + +
+ +
+ + Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/welcome.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/welcome.kid Thu Jun 22 19:12:51 2006 @@ -0,0 +1,13 @@ + + + + + + Welcome to TurboGears + + + +Ding dong. BnB + + Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/xmlhttp.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/xmlhttp.kid Thu Jun 22 19:12:51 2006 @@ -0,0 +1,30 @@ + + + + + XMLHTTP test + + + +

This is a test!


+

Code:


+
+    ${code}
+  
+ + Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/xmlhttp.pyc ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/translator/js/demo/prod.cfg ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/prod.cfg Thu Jun 22 19:12:51 2006 @@ -0,0 +1,40 @@ +# This is where all of your settings go for your development environment + +[global] + +# DATABASE + +# pick the form for your database +# sqlobject.dburi="postgres://username at hostname/databasename" +# sqlobject.dburi="mysql://username:password at hostname:port/databasename" +# sqlobject.dburi="sqlite:///file_name_and_path" + +# for Windows users, sqlite URIs look like: +# sqlobject.dburi="sqlite:///drive_letter|/path/to/file" + + +# VIEW + +# kid.outputformat="html" + +# The sitetemplate is used for overall styling of a site that +# includes multiple TurboGears applications +# tg.sitetemplate="" + + +# SERVER + +# Some server parameters that you may want to tweak +# server.socketPort=8080 + +server.environment="production" +server.logFile="server.log" +server.logToScreen=False + +# if this is part of a larger site, you can set the path +# to the TurboGears instance here +# server.webpath="" + +[/static] +staticFilter.on = True +staticFilter.dir = "static" Added: pypy/dist/pypy/translator/js/demo/setup.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/setup.py Thu Jun 22 19:12:51 2006 @@ -0,0 +1,18 @@ +from setuptools import setup, find_packages +from turbogears.finddata import find_package_data + +setup( + name="jsdemo", + version="1.0", + #description="", + #author="", + #author_email="", + #url="", + install_requires = ["TurboGears >= 0.8a5"], + scripts = ["jsdemo-start.py"], + zip_safe=False, + packages=find_packages(), + package_data = find_package_data(where='jsdemo', + package='jsdemo'), + ) + From fijal at codespeak.net Thu Jun 22 19:16:14 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Jun 2006 19:16:14 +0200 (CEST) Subject: [pypy-svn] r29158 - pypy/dist/pypy/translator/js/demo Message-ID: <20060622171614.2599610068@code0.codespeak.net> Author: fijal Date: Thu Jun 22 19:16:13 2006 New Revision: 29158 Removed: pypy/dist/pypy/translator/js/demo/ Log: Deleted those files. From fijal at codespeak.net Thu Jun 22 19:22:33 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Jun 2006 19:22:33 +0200 (CEST) Subject: [pypy-svn] r29164 - in pypy/dist/pypy/translator/js/demo: . jsdemo jsdemo/static jsdemo/static/css jsdemo/static/images jsdemo/static/javascript jsdemo/templates Message-ID: <20060622172233.F013A10072@code0.codespeak.net> Author: fijal Date: Thu Jun 22 19:22:30 2006 New Revision: 29164 Added: pypy/dist/pypy/translator/js/demo/ pypy/dist/pypy/translator/js/demo/__init__.py pypy/dist/pypy/translator/js/demo/dev.cfg pypy/dist/pypy/translator/js/demo/jsdemo/ pypy/dist/pypy/translator/js/demo/jsdemo/__init__.py pypy/dist/pypy/translator/js/demo/jsdemo/autopath.py pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py pypy/dist/pypy/translator/js/demo/jsdemo/proxy.py pypy/dist/pypy/translator/js/demo/jsdemo/static/ pypy/dist/pypy/translator/js/demo/jsdemo/static/css/ pypy/dist/pypy/translator/js/demo/jsdemo/static/images/ pypy/dist/pypy/translator/js/demo/jsdemo/static/javascript/ pypy/dist/pypy/translator/js/demo/jsdemo/templates/ pypy/dist/pypy/translator/js/demo/jsdemo/templates/__init__.py pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.html pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid pypy/dist/pypy/translator/js/demo/jsdemo/templates/main.kid pypy/dist/pypy/translator/js/demo/jsdemo/templates/master.kid pypy/dist/pypy/translator/js/demo/jsdemo/templates/welcome.kid pypy/dist/pypy/translator/js/demo/jsdemo/templates/xmlhttp.kid Log: Added files that seems to be necessary. Added: pypy/dist/pypy/translator/js/demo/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/__init__.py Thu Jun 22 19:22:30 2006 @@ -0,0 +1 @@ + Added: pypy/dist/pypy/translator/js/demo/dev.cfg ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/dev.cfg Thu Jun 22 19:22:30 2006 @@ -0,0 +1,46 @@ +# This is where all of your settings go for your development environment + +[global] + +# DATABASE + +# pick the form for your database +# sqlobject.dburi="postgres://username at hostname/databasename" +# sqlobject.dburi="mysql://username:password at hostname:port/databasename" +# sqlobject.dburi="sqlite:///file_name_and_path" + +# for Windows users, sqlite URIs look like: +# sqlobject.dburi="sqlite:///drive_letter|/path/to/file" + + +# VIEW + +# kid.outputformat="html" + +# The sitetemplate is used for overall styling of a site that +# includes multiple TurboGears applications +# tg.sitetemplate="" + + +# SERVER + +# Some server parameters that you may want to tweak +server.socketPort=8080 +server.socketHost="127.0.0.1" + +# Disable the debug output at the end on pages. +# logDebugInfoFilter.on = False +server.logFile="server.log" +server.logToScreen=True + +server.environment="production" #"development" +#autoreload.package="testme" +autoreload.on = False + +sessionFilter.on = True +sessionFilter.storageType = "Ram" +sessionFilter.cookieName = "BnB" + +[/static] +staticFilter.on = True +staticFilter.dir = "static" Added: pypy/dist/pypy/translator/js/demo/jsdemo/__init__.py ============================================================================== Added: pypy/dist/pypy/translator/js/demo/jsdemo/autopath.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/autopath.py Thu Jun 22 19:22:30 2006 @@ -0,0 +1,112 @@ +""" +self cloning, automatic path configuration + +copy this into any subdirectory of pypy from which scripts need +to be run, typically all of the test subdirs. +The idea is that any such script simply issues + + import autopath + +and this will make sure that the parent directory containing "pypy" +is in sys.path. + +If you modify the master "autopath.py" version (in pypy/tool/autopath.py) +you can directly run it which will copy itself on all autopath.py files +it finds under the pypy root directory. + +This module always provides these attributes: + + pypydir pypy root directory path + this_dir directory where this autopath.py resides + +""" + + +def __dirinfo(part): + """ return (partdir, this_dir) and insert parent of partdir + into sys.path. If the parent directories don't have the part + an EnvironmentError is raised.""" + + import sys, os + try: + head = this_dir = os.path.realpath(os.path.dirname(__file__)) + except NameError: + head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0])) + + while head: + partdir = head + head, tail = os.path.split(head) + if tail == part: + break + else: + raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir) + + pypy_root = os.path.join(head, '') + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) + + munged = {} + for name, mod in sys.modules.items(): + fn = getattr(mod, '__file__', None) + if '.' in name or not isinstance(fn, str): + continue + newname = os.path.splitext(os.path.basename(fn))[0] + if not newname.startswith(part + '.'): + continue + path = os.path.join(os.path.dirname(os.path.realpath(fn)), '') + if path.startswith(pypy_root) and newname != part: + modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep) + if newname != '__init__': + modpaths.append(newname) + modpath = '.'.join(modpaths) + if modpath not in sys.modules: + munged[modpath] = mod + + for name, mod in munged.iteritems(): + if name not in sys.modules: + sys.modules[name] = mod + if '.' in name: + prename = name[:name.rfind('.')] + postname = name[len(prename)+1:] + if prename not in sys.modules: + __import__(prename) + if not hasattr(sys.modules[prename], postname): + setattr(sys.modules[prename], postname, mod) + + return partdir, this_dir + +def __clone(): + """ clone master version of autopath.py into all subdirs """ + from os.path import join, walk + if not this_dir.endswith(join('pypy','tool')): + raise EnvironmentError("can only clone master version " + "'%s'" % join(pypydir, 'tool',_myname)) + + + def sync_walker(arg, dirname, fnames): + if _myname in fnames: + fn = join(dirname, _myname) + f = open(fn, 'rwb+') + try: + if f.read() == arg: + print "checkok", fn + else: + print "syncing", fn + f = open(fn, 'w') + f.write(arg) + finally: + f.close() + s = open(join(pypydir, 'tool', _myname), 'rb').read() + walk(pypydir, sync_walker, s) + +_myname = 'autopath.py' + +# set guaranteed attributes + +pypydir, this_dir = __dirinfo('pypy') + +if __name__ == '__main__': + __clone() Added: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py Thu Jun 22 19:22:30 2006 @@ -0,0 +1,13 @@ + +""" xmlhttp controllers, usefull for testing +""" + +import turbogears +import cherrypy +from pypy.jsdemo.jsdemo.controllers import Root +from pypy.rpython.ootypesystem.bltregistry import BasicExternal + +# Needed double inheritance for both server job +# and semi-transparent communication proxy +class BnbRoot(Root, BasicExternal): + @turbogears.expose Added: pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py Thu Jun 22 19:22:30 2006 @@ -0,0 +1,63 @@ +import turbogears +from turbogears import controllers +import cherrypy + +import autopath + +from pypy.translator.js.test.runtest import compile_function +from pypy.translator.js.modules import dom,xmlhttp + +import thread +import os + +def move_it(): + pass + +def js_fun(): + document = dom.get_document() + obj = document.createElement('img') + obj.id = 'gfx' + obj.setAttribute('style', 'position:absolute; top:0; left:0;') + obj.src = '/static/gfx/BubBob.gif' + document.body.appendChild(obj) + +def esc_html(data): + return data.replace("&", "&").replace("<", "<").replace(">", ">") \ + .replace("\n", "
").replace(" ", " ") + +class Root(controllers.Root): + def __init__(self): + self.lock = thread.allocate_lock() + self.lock.acquire() + self.results = None + + @turbogears.expose(html="jsdemo.templates.main") + def index(self): + import time + return dict(now=time.ctime(), onload=self.jsname, code=self.jssource) + + @turbogears.expose(format="json") + def send_result(self, result, exc): + self.results = (result, exc) + self.lock.release() + return dict() + + def get_some_info(self, *args, **kwargs): + print "Info: %s" % cherrypy.response.body.read() + return dict() + + get_some_info.exposed = True + + def js_basic_js(self): + def gen(data): + yield data + + cherrypy.response.headerMap['Content-Type'] = 'test/javascript' + cherrypy.response.headerMap['Content-Length'] = len(self.jssource) + return gen(self.jssource) + + def wait_for_results(self): + self.lock.acquire() + self.lock.release() + + js_basic_js.exposed = True Added: pypy/dist/pypy/translator/js/demo/jsdemo/proxy.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/proxy.py Thu Jun 22 19:22:30 2006 @@ -0,0 +1,25 @@ + +""" xmlhttp controllers, usefull for testing +""" + +import turbogears +import cherrypy +from pypy.translator.js.demo.jsdemo.controllers import Root +from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc + +# Needed double inheritance for both server job +# and semi-transparent communication proxy +class ProxyRoot(Root, BasicExternal): + """ Class for running communication tests which are not designed to end + after single function call + """ + _methods = { + 'send_result' : MethodDesc((('result', "aa"), ('exc', "aa"), ('callback',(lambda : None))), None) + } + + @turbogears.expose(html="jsdemo.templates.xmlhttp") + def index(self): + import time + return dict(now=time.ctime(), onload=self.jsname, code=self.jssource) + +ProxyRootInstance = ProxyRoot() Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/__init__.py ============================================================================== Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.html Thu Jun 22 19:22:30 2006 @@ -0,0 +1 @@ + Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid Thu Jun 22 19:22:30 2006 @@ -0,0 +1,30 @@ + + + + + Bub'n'bros + + + +

This is a test!


+

Code:


+
+    ${code}
+  
+ + Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/main.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/main.kid Thu Jun 22 19:22:30 2006 @@ -0,0 +1,30 @@ + + + + + Bub'n'bros + + + +

This is a test!


+

Code:


+
+    ${code}
+  
+ + Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/master.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/master.kid Thu Jun 22 19:22:30 2006 @@ -0,0 +1,15 @@ + + + + + + + Your title goes here + + + +
+ +
+ + Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/welcome.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/welcome.kid Thu Jun 22 19:22:30 2006 @@ -0,0 +1,13 @@ + + + + + + Welcome to TurboGears + + + +Ding dong. BnB + + Added: pypy/dist/pypy/translator/js/demo/jsdemo/templates/xmlhttp.kid ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/xmlhttp.kid Thu Jun 22 19:22:30 2006 @@ -0,0 +1,30 @@ + + + + + XMLHTTP test + + + +

This is a test!


+

Code:


+
+    ${code}
+  
+ + From fijal at codespeak.net Thu Jun 22 19:39:21 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Jun 2006 19:39:21 +0200 (CEST) Subject: [pypy-svn] r29166 - pypy/dist/pypy/translator/js/modules/test Message-ID: <20060622173921.0DB4610070@code0.codespeak.net> Author: fijal Date: Thu Jun 22 19:39:20 2006 New Revision: 29166 Modified: pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py Log: Added two way proxy. Modified: pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py (original) +++ pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py Thu Jun 22 19:39:20 2006 @@ -16,4 +16,13 @@ result = fn() assert result == 3 -#def test_proxy_double_side +def reply_fun(data): + ProxyRootInstance.send_result(str(data['eight']), "", empty_fun) + +def test_proxy_double_side(): + def run_double_proxy(): + ProxyRootInstance.return_eight(reply_fun) + + fn = compile_function(run_double_proxy, [], root = ProxyRoot) + result = fn() + assert result == 8 From fijal at codespeak.net Thu Jun 22 19:42:05 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Jun 2006 19:42:05 +0200 (CEST) Subject: [pypy-svn] r29167 - pypy/dist/pypy/translator/js/demo/jsdemo Message-ID: <20060622174205.D1A0510053@code0.codespeak.net> Author: fijal Date: Thu Jun 22 19:42:00 2006 New Revision: 29167 Modified: pypy/dist/pypy/translator/js/demo/jsdemo/proxy.py Log: Added two-way proxy server side. Modified: pypy/dist/pypy/translator/js/demo/jsdemo/proxy.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/proxy.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/proxy.py Thu Jun 22 19:42:00 2006 @@ -17,6 +17,10 @@ 'send_result' : MethodDesc((('result', "aa"), ('exc', "aa"), ('callback',(lambda : None))), None) } + @turbogears.expose(format="json") + def return_eight(self): + return dict(eight = 8) + @turbogears.expose(html="jsdemo.templates.xmlhttp") def index(self): import time From hpk at codespeak.net Thu Jun 22 20:42:10 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Jun 2006 20:42:10 +0200 (CEST) Subject: [pypy-svn] r29168 - pypy/dist/lib-python Message-ID: <20060622184210.43A4F10060@code0.codespeak.net> Author: hpk Date: Thu Jun 22 20:42:09 2006 New Revision: 29168 Modified: pypy/dist/lib-python/conftest.py Log: issue225 testing for now, let all tests run through test/regrtest.py and not our own shortcut. this avoids the test_threading.py hang (i don't know exactly why - i am guessing it is because of some IO issue but it probably makes sense anyway to use regrtest.py for python regression testing, although it adds a somewhat constant overhead). side-effect: test_extcall doesn't compare correctly against our modified output (modified-2.4.1/test/output/test_extcall) but likely it's best to modify regrtest.py to have an extra option where one can specify a specific outputpath Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Thu Jun 22 20:42:09 2006 @@ -885,8 +885,6 @@ python = sys.executable pypy_script = pypydir.join('bin', 'py.py') alarm_script = pypydir.join('tool', 'alarm.py') - regr_script = pypydir.join('tool', 'pytest', - 'run-script', 'regrverbose.py') pypy_options = [] if regrtest.oldstyle: pypy_options.append('--oldstyle') @@ -901,21 +899,27 @@ # previously we only did it if regrtest.outputpath() was True # the regrverbose script now does the logic that CPython # uses in its regrtest.py - regrrun = str(regr_script) - regrrun_verbosity = regrtest.getoutputpath() and '0' or '1' - + + #if regrtest.getoutputpath(): + # regr_script = pypydir.join('tool', 'pytest', + # 'run-script', 'regrverbose.py') + # regr_script_options = "1" + #else: + regr_script = regrtestdir.join("regrtest.py") + regr_script_options = " " + + regrrun = "%s %s" %(regr_script, regr_script_options) TIMEOUT = gettimeout() if option.use_compiled: execpath, info = getexecutable() - cmd = "%s %s %s %s" %( + cmd = "%s %s %s" %( execpath, - regrrun, regrrun_verbosity, fspath.purebasename) - print cmd + regrrun, fspath.purebasename) else: - cmd = "%s %s %d %s %s %s %s %s" %( + cmd = "%s %s %d %s %s %s %s" %( python, alarm_script, TIMEOUT, pypy_script, sopt, - regrrun, regrrun_verbosity, fspath.purebasename) + regrrun, fspath.purebasename) return cmd def run(self): @@ -955,13 +959,16 @@ try: stdout = tempdir.join(self.fspath.basename) + '.out' stderr = tempdir.join(self.fspath.basename) + '.err' + print >>sys.stderr, "executing:", cmd if sys.platform == 'win32': + #stderr.write("executing: %s" %(cmd,)) XXX not sure we could append like below status = os.system("%s >%s 2>%s" %(cmd, stdout, stderr)) if status>=0: status = status else: status = 'abnormal termination 0x%x' % status else: + stderr.write("executing: %s" %(cmd,)) status = os.system("%s >>%s 2>>%s" %(cmd, stdout, stderr)) if os.WIFEXITED(status): status = os.WEXITSTATUS(status) @@ -1001,19 +1008,19 @@ outcome = 'OK' expectedpath = regrtest.getoutputpath() - if not exit_status: - if expectedpath is not None: - expected = expectedpath.read(mode='rU') - test_stdout = "%s\n%s" % (self.fspath.purebasename, test_stdout) - if test_stdout != expected: - exit_status = 2 - res, out, err = callcapture(reportdiff, expected, test_stdout) - outcome = 'ERROUT' - result.addnamedtext('reportdiff', out) - else: - if 'FAIL' in test_stdout or 'ERROR' in test_stderr: - outcome = 'FAIL' - elif timedout: + #if expectedpath is not None: + # if not exit_status: + # expected = expectedpath.read(mode='rU') + # test_stdout = "%s\n%s" % (self.fspath.purebasename, test_stdout) + # if test_stdout != expected: + # exit_status = 2 + # res, out, err = callcapture(reportdiff, expected, test_stdout) + # outcome = 'ERROUT' + # result.addnamedtext('reportdiff', out) + # else: + # if 'FAIL' in test_stdout or 'ERROR' in test_stderr: + # outcome = 'FAIL' + if exit_status and timedout: outcome = "T/O" else: outcome = "ERR" From pedronis at codespeak.net Thu Jun 22 22:33:05 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 22 Jun 2006 22:33:05 +0200 (CEST) Subject: [pypy-svn] r29182 - pypy/extradoc/planning Message-ID: <20060622203305.DABFD10060@code0.codespeak.net> Author: pedronis Date: Thu Jun 22 22:33:04 2006 New Revision: 29182 Modified: pypy/extradoc/planning/conference-planning.txt Log: Vancouver Python Worshop + as promised in ddof: deadlines for some conferences we may want to try to submit papers (especially about jit work) before the end of the project Modified: pypy/extradoc/planning/conference-planning.txt ============================================================================== --- pypy/extradoc/planning/conference-planning.txt (original) +++ pypy/extradoc/planning/conference-planning.txt Thu Jun 22 22:33:04 2006 @@ -160,3 +160,30 @@ "Novel development paradigms, APIs, and languages"/PyPy? Suggestion by Holger. Submission/attendance? + +Vancouver Python Worshop +------------------------- +Time & Location: August 4 - August 5, Vancouver + +we have been invited there. + +Samuele is organizing to give a talk there + +PEPM 2007 - Workshop on Partial Evaluation and Program Manipulation +--------------------------------------------------------------------- +abstracts due Oct. 18 + +Time & Location: January 15-16, 2007 Nice, France + +ECOOP 2007 - European Conference on Object Oriented Programming +----------------------------------------------------------------- +estimated papers due date: November 1, 2006 + +PLDI 2007 - Programming Language Design and Implementation +------------------------------------------------------------ +http://ties.ucsd.edu/PLDI/papers.shtml + +Abstract deadline: Tuesday November 7, 2006, 1 PM CST +Submission deadline: Tuesday November 14, 2006, 1 PM CST (no extensions) + +Time & Location: June 10-13, 2006, San Diego CA From hpk at codespeak.net Fri Jun 23 09:03:10 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Jun 2006 09:03:10 +0200 (CEST) Subject: [pypy-svn] r29194 - pypy/dist/lib-python Message-ID: <20060623070310.8428F10068@code0.codespeak.net> Author: hpk Date: Fri Jun 23 09:03:09 2006 New Revision: 29194 Modified: pypy/dist/lib-python/conftest.py Log: regcongizning OK status correctly (ugh) Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Jun 23 09:03:09 2006 @@ -1020,7 +1020,9 @@ # else: # if 'FAIL' in test_stdout or 'ERROR' in test_stderr: # outcome = 'FAIL' - if exit_status and timedout: + if not exit_status: + outcome = "OK" + elif exit_status and timedout: outcome = "T/O" else: outcome = "ERR" From hpk at codespeak.net Fri Jun 23 09:27:20 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Jun 2006 09:27:20 +0200 (CEST) Subject: [pypy-svn] r29195 - pypy/dist/lib-python Message-ID: <20060623072720.0F5C810068@code0.codespeak.net> Author: hpk Date: Fri Jun 23 09:27:19 2006 New Revision: 29195 Modified: pypy/dist/lib-python/conftest.py Log: small tweaks, but somehow the regrtest.py --verbose flag does not carry through. humpf. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Jun 23 09:27:19 2006 @@ -906,7 +906,9 @@ # regr_script_options = "1" #else: regr_script = regrtestdir.join("regrtest.py") - regr_script_options = " " + regr_script_options = "" + if not regrtest.getoutputpath(): + regr_script_options = "-v " regrrun = "%s %s" %(regr_script, regr_script_options) TIMEOUT = gettimeout() @@ -968,7 +970,7 @@ else: status = 'abnormal termination 0x%x' % status else: - stderr.write("executing: %s" %(cmd,)) + stderr.write("executing: %s\n" %(cmd,)) status = os.system("%s >>%s 2>>%s" %(cmd, stdout, stderr)) if os.WIFEXITED(status): status = os.WEXITSTATUS(status) From fijal at codespeak.net Fri Jun 23 10:24:58 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 23 Jun 2006 10:24:58 +0200 (CEST) Subject: [pypy-svn] r29196 - pypy/dist/pypy/translator/js/test Message-ID: <20060623082458.E0C0310068@code0.codespeak.net> Author: fijal Date: Fri Jun 23 10:24:57 2006 New Revision: 29196 Modified: pypy/dist/pypy/translator/js/test/runtest.py Log: Added flag for not loading torbogears if not necessary. Modified: pypy/dist/pypy/translator/js/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/js/test/runtest.py (original) +++ pypy/dist/pypy/translator/js/test/runtest.py Fri Jun 23 10:24:57 2006 @@ -44,7 +44,7 @@ #self.js = JS(t, [function, callback_function], stackless) self.js = JS(t, [function], stackless) self.js.write_source() - if root is None: + if root is None and use_tg: from pypy.translator.js.demo.jsdemo.controllers import Root self.root = Root else: From fijal at codespeak.net Fri Jun 23 10:38:33 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 23 Jun 2006 10:38:33 +0200 (CEST) Subject: [pypy-svn] r29197 - in pypy/dist/pypy/translator/js: modules/test modules/test/html test/html Message-ID: <20060623083833.4BF6010068@code0.codespeak.net> Author: fijal Date: Fri Jun 23 10:38:30 2006 New Revision: 29197 Added: pypy/dist/pypy/translator/js/modules/test/html/ - copied from r29166, pypy/dist/pypy/translator/js/test/html/ Removed: pypy/dist/pypy/translator/js/test/html/ Modified: pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py Log: Moved test html's to new location. Modified: pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py (original) +++ pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py Fri Jun 23 10:38:30 2006 @@ -26,3 +26,4 @@ fn = compile_function(run_double_proxy, [], root = ProxyRoot) result = fn() assert result == 8 + From fijal at codespeak.net Fri Jun 23 10:42:24 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 23 Jun 2006 10:42:24 +0200 (CEST) Subject: [pypy-svn] r29198 - pypy/dist/pypy/translator/js/modules/test Message-ID: <20060623084224.A791810069@code0.codespeak.net> Author: fijal Date: Fri Jun 23 10:42:23 2006 New Revision: 29198 Modified: pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py Log: Browser check. Modified: pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py (original) +++ pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py Fri Jun 23 10:42:23 2006 @@ -2,6 +2,12 @@ """ xmlhttp proxy test """ +import py +from pypy import conftest + +if not conftest.option.browser or not conftest.option.tg: + py.test.skip("Works only in browser and with turbogears") + from pypy.translator.js.demo.jsdemo.proxy import ProxyRootInstance, ProxyRoot from pypy.translator.js.test.runtest import compile_function From pedronis at codespeak.net Fri Jun 23 10:52:00 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 23 Jun 2006 10:52:00 +0200 (CEST) Subject: [pypy-svn] r29199 - pypy/dist/pypy/translator/llvm/test Message-ID: <20060623085200.860C010068@code0.codespeak.net> Author: pedronis Date: Fri Jun 23 10:51:59 2006 New Revision: 29199 Modified: pypy/dist/pypy/translator/llvm/test/test_extfunc.py Log: skip in unreliable os.dup test Modified: pypy/dist/pypy/translator/llvm/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_extfunc.py Fri Jun 23 10:51:59 2006 @@ -13,7 +13,9 @@ def fn(): return os.dup(0) f = compile_function(fn, []) - assert os.path.sameopenfile(f(), fn()) + fn() + py.test.skip("cannot naively and reliably test os.dup using isolate") + #assert os.path.sameopenfile(f(), fn()) def test_external_function_ll_time_time(): import time From ericvrp at codespeak.net Fri Jun 23 11:00:43 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 23 Jun 2006 11:00:43 +0200 (CEST) Subject: [pypy-svn] r29200 - pypy/dist/pypy/doc Message-ID: <20060623090043.0F5E810070@code0.codespeak.net> Author: ericvrp Date: Fri Jun 23 11:00:41 2006 New Revision: 29200 Modified: pypy/dist/pypy/doc/index.txt Log: Mention the glossary from the index (docs) page Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Fri Jun 23 11:00:41 2006 @@ -26,6 +26,9 @@ `FAQ`_ contains the beginning of frequently asked questions. Right now it's a bit empty. +`Glossary`_ of PyPy words to help you align your inner self with +the PyPy universe. + PyPy documentation =============================================== @@ -78,6 +81,7 @@ .. _`FAQ`: faq.html +.. _Glossary: glossary.html .. _parser: parser.html .. _`development methodology`: dev_method.html .. _`talks and related projects`: extradoc.html From pedronis at codespeak.net Fri Jun 23 11:09:24 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 23 Jun 2006 11:09:24 +0200 (CEST) Subject: [pypy-svn] r29201 - pypy/dist/pypy/tool Message-ID: <20060623090924.7857210072@code0.codespeak.net> Author: pedronis Date: Fri Jun 23 11:09:23 2006 New Revision: 29201 Modified: pypy/dist/pypy/tool/slaveproc.py Log: slaves should not worry too much if the master connection dies, as long as the master is happy Modified: pypy/dist/pypy/tool/slaveproc.py ============================================================================== --- pypy/dist/pypy/tool/slaveproc.py (original) +++ pypy/dist/pypy/tool/slaveproc.py Fri Jun 23 11:09:23 2006 @@ -49,7 +49,10 @@ def do(self): exchg = Exchange(sys.stdin, sys.stdout) while True: - cmd = exchg.recv() + try: + cmd = exchg.recv() + except EOFError: # master died + break if cmd is None: exchg.send('done') break From mwh at codespeak.net Fri Jun 23 11:52:00 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 11:52:00 +0200 (CEST) Subject: [pypy-svn] r29204 - pypy/dist/pypy/tool Message-ID: <20060623095200.5049C10064@code0.codespeak.net> Author: mwh Date: Fri Jun 23 11:51:55 2006 New Revision: 29204 Modified: pypy/dist/pypy/tool/makerelease.py Log: small guessed changes to makerelease for 0.9 Modified: pypy/dist/pypy/tool/makerelease.py ============================================================================== --- pypy/dist/pypy/tool/makerelease.py (original) +++ pypy/dist/pypy/tool/makerelease.py Fri Jun 23 11:51:55 2006 @@ -5,7 +5,7 @@ log = py.log.Producer("log") logexec = py.log.Producer("exec") -BASEURL = "file:///svn/pypy/release/0.8.x" +BASEURL = "file:///svn/pypy/release/0.9.x" DDIR = py.path.local('/www/codespeak.net/htdocs/download/pypy') def usage(): @@ -59,7 +59,7 @@ log("copying to download location") #fn.copy(dtarget) ddir = DDIR - out = cexec("rsync %(fn)s code2.codespeak.net:%(ddir)s" + out = cexec("cp %(fn)s %(ddir)s" % locals()) def forced_export(BASEURL, target, lineend="LF"): From hpk at codespeak.net Fri Jun 23 11:56:29 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Jun 2006 11:56:29 +0200 (CEST) Subject: [pypy-svn] r29205 - pypy/dist/lib-python Message-ID: <20060623095629.819FD10064@code0.codespeak.net> Author: hpk Date: Fri Jun 23 11:56:28 2006 New Revision: 29205 Modified: pypy/dist/lib-python/conftest.py Log: revert to 28308 - using regrtest.py needs to be investigated a lot more and it seems there were good reasons for not using it. this means that test_threading.py will hang again, but trying to tweak a different way to run tests resulted in more problems (especially reporting wise) Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Jun 23 11:56:28 2006 @@ -885,6 +885,8 @@ python = sys.executable pypy_script = pypydir.join('bin', 'py.py') alarm_script = pypydir.join('tool', 'alarm.py') + regr_script = pypydir.join('tool', 'pytest', + 'run-script', 'regrverbose.py') pypy_options = [] if regrtest.oldstyle: pypy_options.append('--oldstyle') @@ -899,29 +901,21 @@ # previously we only did it if regrtest.outputpath() was True # the regrverbose script now does the logic that CPython # uses in its regrtest.py - - #if regrtest.getoutputpath(): - # regr_script = pypydir.join('tool', 'pytest', - # 'run-script', 'regrverbose.py') - # regr_script_options = "1" - #else: - regr_script = regrtestdir.join("regrtest.py") - regr_script_options = "" - if not regrtest.getoutputpath(): - regr_script_options = "-v " - - regrrun = "%s %s" %(regr_script, regr_script_options) + regrrun = str(regr_script) + regrrun_verbosity = regrtest.getoutputpath() and '0' or '1' + TIMEOUT = gettimeout() if option.use_compiled: execpath, info = getexecutable() - cmd = "%s %s %s" %( + cmd = "%s %s %s %s" %( execpath, - regrrun, fspath.purebasename) + regrrun, regrrun_verbosity, fspath.purebasename) + print cmd else: - cmd = "%s %s %d %s %s %s %s" %( + cmd = "%s %s %d %s %s %s %s %s" %( python, alarm_script, TIMEOUT, pypy_script, sopt, - regrrun, fspath.purebasename) + regrrun, regrrun_verbosity, fspath.purebasename) return cmd def run(self): @@ -961,16 +955,13 @@ try: stdout = tempdir.join(self.fspath.basename) + '.out' stderr = tempdir.join(self.fspath.basename) + '.err' - print >>sys.stderr, "executing:", cmd if sys.platform == 'win32': - #stderr.write("executing: %s" %(cmd,)) XXX not sure we could append like below status = os.system("%s >%s 2>%s" %(cmd, stdout, stderr)) if status>=0: status = status else: status = 'abnormal termination 0x%x' % status else: - stderr.write("executing: %s\n" %(cmd,)) status = os.system("%s >>%s 2>>%s" %(cmd, stdout, stderr)) if os.WIFEXITED(status): status = os.WEXITSTATUS(status) @@ -1010,21 +1001,19 @@ outcome = 'OK' expectedpath = regrtest.getoutputpath() - #if expectedpath is not None: - # if not exit_status: - # expected = expectedpath.read(mode='rU') - # test_stdout = "%s\n%s" % (self.fspath.purebasename, test_stdout) - # if test_stdout != expected: - # exit_status = 2 - # res, out, err = callcapture(reportdiff, expected, test_stdout) - # outcome = 'ERROUT' - # result.addnamedtext('reportdiff', out) - # else: - # if 'FAIL' in test_stdout or 'ERROR' in test_stderr: - # outcome = 'FAIL' if not exit_status: - outcome = "OK" - elif exit_status and timedout: + if expectedpath is not None: + expected = expectedpath.read(mode='rU') + test_stdout = "%s\n%s" % (self.fspath.purebasename, test_stdout) + if test_stdout != expected: + exit_status = 2 + res, out, err = callcapture(reportdiff, expected, test_stdout) + outcome = 'ERROUT' + result.addnamedtext('reportdiff', out) + else: + if 'FAIL' in test_stdout or 'ERROR' in test_stderr: + outcome = 'FAIL' + elif timedout: outcome = "T/O" else: outcome = "ERR" From ericvrp at codespeak.net Fri Jun 23 11:57:17 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 23 Jun 2006 11:57:17 +0200 (CEST) Subject: [pypy-svn] r29207 - pypy/dist/pypy/doc Message-ID: <20060623095717.D0E4310069@code0.codespeak.net> Author: ericvrp Date: Fri Jun 23 11:57:16 2006 New Revision: 29207 Modified: pypy/dist/pypy/doc/glossary.txt Log: Removed content listing at top of glossary and changed layout. Modified: pypy/dist/pypy/doc/glossary.txt ============================================================================== --- pypy/dist/pypy/doc/glossary.txt (original) +++ pypy/dist/pypy/doc/glossary.txt Fri Jun 23 11:57:16 2006 @@ -1,173 +1,91 @@ -========================== -PyPy - Glossary -========================== +**annotator** - Performs a form of `type inference`_ on the flow graph. -.. contents:: +**application level** - applevel_ code is normal Python code running on +top of the PyPy or CPython interpreter (See interpreter level) +.. _backend: -annotator ----------------------------------------------------------------------- +**backend** - Code generator that convert a RPython_ program to a +`target language`_ using the PyPy toolchain_. A backend uses either the +lltypesystem_ or the ootypesystem_. -Performs a form of `type inference`_ on the flow graph. +**external function** - Functions that we don't want to implement in Python +for various reasons (e.g. if they need to make calls into the OS) and will +be implemented by the backend. +**garbage collection framework** - Code that makes it possible to write +`PyPy's garbage collectors`_ in Python itself. -application level --------------------------------------------- +.. _`interpreter level`: -applevel_ code is normal Python code running on top of the PyPy or -CPython interpreter +**interpreter level** - Code running at this level is part of the +implementation of the PyPy interpreter and cannot interact normally with +application level code; it typically provides implementation for an object +space and its builtins. (See application level) -See interpreter level +**jit** - `just in time compiler`_ -backend ----------------------------------------------------------------------- +**l3interpreter** - Piece of code that is able to interpret L3 flow graphs. +This code is unfinished and its future is unclear. -Code generator that convert a RPython_ program to a `target language`_ using -the PyPy toolchain_. A backend uses either the lltypesystem_ or the ootypesystem_. +**llinterpreter** - Piece of code that is able to interpret flow graphs. +This is very useful for testing purposes, especially if you work on the +RPython_ Typer. +.. _lltypesystem: -external function ----------------------------------------------------------------------- +**lltypesystem** - A backend_ that uses this typessystem is also called a +low-level backend. The C and LLVM backends are using this typesystem. -Functions that we don't want to implement in Python for various reasons -(e.g. if they need to make calls into the OS) and will be implemented by the backend. +**mixed module** - a module that accesses PyPy's `interpreter level`_ +**object space** - The `object space`_ creates all objects and knows how to +perform operations on the objects. You may think of an object space as being +a library offering a fixed API, a set of operations, with implementations +that a) correspond to the known semantics of Python objects, b) extend or +twist these semantics, or c) serve whole-program analysis purposes. -garbage collection framework --------------------------------------------- +.. _ootypesystem: -Code that makes it possible to write `PyPy's garbage collectors`_ in Python -itself. +**ootypesystem** - A backend_ that uses this typessystem is also called a +high-level backend. The common lisp, javascript and cli backends are all +using this typesystem. +**prebuilt constant** - In RPython_ module globals are considered constants. +Moreover, global (i.e. prebuilt) lists and dictionaries are supposed to be +immutable. (prebuilts are sometimes called pbc's) -interpreter level --------------------------------------------- +**rpython** - `Restricted Python`_, which is the limited subset of the +Python_ specification. It is also the language that the PyPy interpreter +itself is written in. -Code running at this level is part of the implementation of the PyPy -interpreter and cannot interact normally with application level code; -it typically provides implementation for an object space and its -builtins. +**rtyper** - Based on the type annotations, the `RPython Typer`_ turns the +flow graph into one that fits the model of the target platform/backend_ using +either the lltypesystem_ or the ootypesystem_. -See application level. +**specialization** - XXX +**stackless** - Technology that enables various forms of coroutining. -jit --------------------------------------------- +**standard interpreter** - It is the +`subsystem implementing the Python language`_, composed of the bytecode +interpreter and of the standard objectspace. -`just in time compiler`_ +.. _toolchain: +**toolchain** - The `annotator pass`_, `The RPython Typer`_, and various +`backends`_. -l3interpreter ----------------------------------------------------------------------- +**transformation** - Code that modifies flowgraphs to weave in +`translation-aspects`_ -Piece of code that is able to interpret L3 flow graphs. This code is -unfinished and its future is unclear. +**translator** - Tool_ based on the PyPy interpreter which can translate +sufficiently static Python programs into low-level code. +.. _`type inference`: -llinterpreter ----------------------------------------------------------------------- - -Piece of code that is able to interpret flow graphs. This is very useful for -testing purposes, especially if you work on the RPython_ Typer. - - -lltypesystem ----------------------------------------------------------------------- - -A backend_ that uses this typessystem is also called a low-level backend. -The C and LLVM backends are using this typesystem. - - -mixed module ----------------------------------------------------------------------- - -a module that accesses PyPy's `interpreter level`_ - - -object space ----------------------------------------------------------------------- - -The `object space`_ creates all objects and knows how to perform -operations on the objects. You may think of an object space as being a -library offering a fixed API, a set of operations, with -implementations that a) correspond to the known semantics of Python -objects, b) extend or twist these semantics, or c) serve -whole-program analysis purposes. - - -ootypesystem ----------------------------------------------------------------------- - -A backend_ that uses this typessystem is also called a high-level backend. -The common lisp, javascript and cli backends are all using this typesystem. - - -prebuilt constant --------------------------------------------- -In RPython_ module globals are considered constants. Moreover, global -(i.e. prebuilt) lists and dictionaries are supposed to be immutable. -(prebuilts are sometimes called pbc's) - - -rpython --------------------------------------------- - -`Restricted Python`_, which is the limited subset of the -Python_ specification. It is also the language that the PyPy -interpreter itself is written in. - - -rtyper --------------------------------------------- - -Based on the type annotations, the `RPython Typer`_ turns the flow graph into one that fits the -model of the target platform/backend_ using either the lltypesystem_ or -the ootypesystem_. - - -specialization --------------------------------------------- - -XXX - - -stackless ----------------------------------------------------------------------- - -Technology that enables various forms of coroutining. - - -standard interpreter --------------------------------------------- - -It is the `subsystem implementing the Python language`_, composed of the -bytecode interpreter and of the standard objectspace. - -toolchain ----------------------------------------------------------------------- - -The `annotator pass`_, `The RPython Typer`_, and various `backends`_. - - -transformation ----------------------------------------------------------------------- - -Code that modifies flowgraphs to weave in `translation-aspects`_ - - -translator ----------------------------------------------------------------------- - -Tool_ based on the PyPy interpreter which can translate sufficiently static -Python programs into low-level code. - - -type inference ----------------------------------------------------------------------- - -Deduces either partially or fully the type of expressions as described in -this `type inference article`_. - +**type inference** - Deduces either partially or fully the type of +expressions as described in this `type inference article`_. .. _applevel: coding-guide.html#application-level From auc at codespeak.net Fri Jun 23 12:10:59 2006 From: auc at codespeak.net (auc at codespeak.net) Date: Fri, 23 Jun 2006 12:10:59 +0200 (CEST) Subject: [pypy-svn] r29209 - pypy/dist/pypy/doc Message-ID: <20060623101059.6C0A910076@code0.codespeak.net> Author: auc Date: Fri Jun 23 12:10:55 2006 New Revision: 29209 Modified: pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt Log: a small addition + better doc structure Modified: pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt ============================================================================== --- pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt (original) +++ pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt Fri Jun 23 12:10:55 2006 @@ -157,6 +157,9 @@ Threads and dataflow synchronisation ++++++++++++++++++++++++++++++++++++ +Description and examples +------------------------ + When a piece of code tries to access a free logic variable, the thread in which it runs is blocked (suspended) until the variable becomes bound. This behaviour is known as "dataflow synchronization" and @@ -263,6 +266,26 @@ are quite similar to send and synchronous receive primitives for inter-process communication. +The operators table +------------------- + +Blocking ops + + wait/1 # blocks if first arg. is a free logic var., til it becomes bound + value -> value + + wait_needed/1 # blocks until its arg. receives a wait + logic var. -> logic var. + + wait_two/2 + logic var., logic var. -> int in {1,2} + +Coroutine spawning + + uthread/n | 1 <= n + callable, opt args. -> logic var. + + Constraint Programming ====================== @@ -274,8 +297,11 @@ satisfaction problem, and then highlight how to extend the solver with new strategies. -Specification of a problem, getting solutions -+++++++++++++++++++++++++++++++++++++++++++++ +Using the constraint engine ++++++++++++++++++++++++++++ + +Specification of a problem +-------------------------- A constraint satisfaction problem is defined by a triple (X, D, C) where X is a set of finite domain variables, D the set of domains @@ -313,7 +339,12 @@ We must be careful to return the set of variables whose candidate values we are interested in. The rest should be sufficiently -self-describing... Now to get and print solutions out of this, we +self-describing... + +Getting solutions +----------------- + +Now to get and print solutions out of this, we must:: import solver @@ -329,8 +360,8 @@ cpython... It is expected that the compiled version of PyPy + LO will provide decent performance. -Operators for CSP specification -+++++++++++++++++++++++++++++++ +Table of Operators +------------------ Note that below, "variable/expression designators" really are strings. From auc at codespeak.net Fri Jun 23 12:13:34 2006 From: auc at codespeak.net (auc at codespeak.net) Date: Fri, 23 Jun 2006 12:13:34 +0200 (CEST) Subject: [pypy-svn] r29210 - pypy/dist/pypy/doc Message-ID: <20060623101334.5B37110076@code0.codespeak.net> Author: auc Date: Fri Jun 23 12:13:33 2006 New Revision: 29210 Modified: pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt Log: micro fix Modified: pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt ============================================================================== --- pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt (original) +++ pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt Fri Jun 23 12:13:33 2006 @@ -344,8 +344,7 @@ Getting solutions ----------------- -Now to get and print solutions out of this, we -must:: +Now to get and print solutions out of this, we must:: import solver cs = newspace() From mwh at codespeak.net Fri Jun 23 12:19:01 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 12:19:01 +0200 (CEST) Subject: [pypy-svn] r29211 - pypy/dist/pypy/tool Message-ID: <20060623101901.4E48A10076@code0.codespeak.net> Author: mwh Date: Fri Jun 23 12:19:00 2006 New Revision: 29211 Modified: pypy/dist/pypy/tool/makerelease.py Log: trivial fixes Modified: pypy/dist/pypy/tool/makerelease.py ============================================================================== --- pypy/dist/pypy/tool/makerelease.py (original) +++ pypy/dist/pypy/tool/makerelease.py Fri Jun 23 12:19:00 2006 @@ -9,7 +9,7 @@ DDIR = py.path.local('/www/codespeak.net/htdocs/download/pypy') def usage(): - print "usage: %s versionbasename" %(py.std.argv[0]) + print "usage: %s versionbasename" %(py.std.sys.argv[0]) raise SystemExit, 1 def cexec(cmd): @@ -72,7 +72,7 @@ if __name__ == '__main__': argc = len(py.std.sys.argv) - if argc < 1: + if argc <= 1: usage() ver = py.std.sys.argv[1] tmpdir = py.path.local("/tmp/pypy-release") From auc at codespeak.net Fri Jun 23 12:27:54 2006 From: auc at codespeak.net (auc at codespeak.net) Date: Fri, 23 Jun 2006 12:27:54 +0200 (CEST) Subject: [pypy-svn] r29212 - pypy/dist/pypy/doc Message-ID: <20060623102754.75B8B10068@code0.codespeak.net> Author: auc Date: Fri Jun 23 12:27:50 2006 New Revision: 29212 Added: pypy/dist/pypy/doc/howto-logicobjspace-0.9.html Modified: pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt Log: small links, + crude html version Added: pypy/dist/pypy/doc/howto-logicobjspace-0.9.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/howto-logicobjspace-0.9.html Fri Jun 23 12:27:50 2006 @@ -0,0 +1,804 @@ + + + + + + +How to use the Logic Object space features of PyPy 0.9 + + + +
+

How to use the Logic Object space features of PyPy 0.9

+
+

Outline

+

This document gives some information about the content and usage of an +extension of PyPy known as the Logic Objectspace (LO). The LO, when +finished, will provide additional builtins that will allow to write:

+
    +
  • concurrent programs based on coroutines scheduled by dataflow logic +variables,
  • +
  • concurrent logic programs,
  • +
  • concurrent constraint problems,
  • +
  • new search "engines" to help solve logic/constraint programs.
  • +
+

The 0.9 preview comes without logic programming; the constraint solver +is only lightly tested, is not equipped with some specialized but +important propagators for linear relations on numeric variables, and +might support concurrency - but that would be an accident; the +dataflow scheduling of coroutines is known to fail in at least one +basic and important case.

+

In this document, we skim over these topics, hoping to give enough +information and examples for an uninformed user to understand what is +going on and how to use the provided functionnality.

+

To fire up a working PyPy with the LO, please type:

+
+/root-of-pypy-dist/pypy/bin/py.py -o logic --usemodules=_stackless
+
+
+
+

Logic Variables and Dataflow Synchronisation of Coroutines

+
+

Logic Variables

+
+

Description and examples

+

Logic variables are (should be, in an ideal LO) similar to Python +variables in the following sense: they map names to values in a +defined scope. But unlike normal Python variables, they have two +states: free and bound. A bound logic variable is indistinguishable +from a normal Python value, which it wraps. A free variable can only +be bound once (it is also said to be a single-assignment variable). It +is good practice to denote these variables with a beginning capital +letter, so as to avoid confusion with normal variables.

+

The following snippet creates a new logic variable and asserts its +state:

+
+X = newvar()
+assert is_free(X)
+assert not is_bound(X)
+
+

Logic variables can be bound thusly:

+
+bind(X, 42)
+assert X / 2 == 24
+
+

The single-assignment property is easily checked:

+
+bind(X, 'hello') # would raise a FailureException
+bind(X, 42)      # is admitted (it is a noop)
+
+

In the current state of the LO, a generic Exception will be raised. +It is quite obvious from this that logic variables are really objects +acting as boxes for python values. No syntactic extension to Python is +provided yet to lessen this inconvenience.

+

The bind operator is low-level. The more general operation that binds +a logic variable is known as "unification". Unify is an operator that +takes two arbitrary data structures and tries to assert their +equalness, much in the sense of the == operator, but with one +important twist: unify mutates the state of the involved logic +variables.

+

Unifying structures devoid of logic variables, like:

+
+unify([1, 2], [1, 2])
+unify(42, 43)
+
+

is equivalent to an assertion about their equalness, the difference +being that a FailureException will be raised instead of an +AssertionError, would the assertion be violated:

+
+assert [1, 2] == [1, 2]
+assert 42 == 43
+
+

A basic example involving logic variables embedded into dictionnaries:

+
+Z, W = newvar(), newvar()
+unify({'a': 42, 'b': Z},
+      {'a':  Z, 'b': W})
+assert Z == W == 42
+
+

Unifying one unbound variable with some value (a) means assigning the +value to the variable (which then satisfies equalness), unifying two +unbound variables (b) aliases them (they are constrained to reference +the same -future- value).

+

Assignment or aliasing of variables is provided underneath by the +'bind' operator.

+

An example involving custom data types:

+
+class Foo(object):
+    def __init__(self, a):
+        self.a = a
+        self.b = newvar()
+
+f1 = Foo(newvar())
+f2 = Foo(42)
+unify(f1, f2)
+assert f1.a == f2.a == 42    # assert (a)
+assert alias_of(f1.b, f2.b)  # assert (b)
+unify(f2.b, 'foo')
+assert f1.b == f2.b == 'foo' # (b) is entailed indeed
+
+
+
+

The operators table

+

Logic variables support the following operators (with their arity):

+

Predicates

+
+
+
is_free/1
+
any -> bool
+
is_bound/1
+
any -> bool
+
alias_of/2
+
logic vars. -> bool
+
+
+

Variable Creation

+
+
+
newvar/0
+
nothing -> logic variable
+
+
+

Mutators

+
+
+
bind/2
+
logic var., any -> None
+
unify/2
+
any, any -> None
+
+
+
+
+
+

Threads and dataflow synchronisation

+
+

Description and examples

+

When a piece of code tries to access a free logic variable, the thread +in which it runs is blocked (suspended) until the variable becomes +bound. This behaviour is known as "dataflow synchronization" and +mimics exactly the dataflow variables from the Oz programming +language. With respect to behaviour under concurrency conditions, +logic variables come with two operators :

+
    +
  • wait: this suspends the current thread until the variable is bound, +it returns the value otherwise (impl. note: in the logic +objectspace, all operators make an implicit wait on their arguments)
  • +
  • wait_needed: this suspends the current thread until the variable +has received a wait message. It has to be used explicitly, +typically by a producer thread that wants to produce data only when +needed.
  • +
+

In this context, binding a variable to a value will make runnable all +threads blocked on this variable.

+

Wait and wait_needed allow to write efficient lazy evaluating code.

+

Using the "uthread" builtin (which spawns a coroutine and applies the +2..n args to its first arg), here is how to implement a +producer/consummer scheme:

+
+def generate(n, limit):
+    if n < limit:
+        return (n, generate(n + 1, limit))
+    return None
+
+def sum(L, a):
+    Head, Tail = newvar(), newvar()
+    unify(L, (Head, Tail))
+    if Tail != None:
+        return sum(Tail, Head + a)
+    return a + Head
+
+X = newvar()
+S = newvar()
+
+unify(S, uthread(sum, X, 0))
+unify(X, uthread(generate, 0, 10))
+
+assert S == 45
+
+

Note that this eagerly generates all elements before the first of them +is consummed. Wait_needed helps write us a lazy version of the +generator. But the consummer will be responsible of the termination, +and thus must be adapted too:

+
+def lgenerate(n, L):
+    """lazy version of generate"""
+    wait_needed(L)
+    Tail = newvar()
+    bind(L, (n, Tail))
+    lgenerate(n+1, Tail)
+
+def lsum(L, a, limit):
+    """this summer controls the generator"""
+    if limit > 0:
+        Head, Tail = newvar(), newvar()
+        wait(L)
+        unify(L, (Head, Tail))
+        return lsum(Tail, a+Head, limit-1)
+    else:
+        return a
+
+Y = newvar()
+T = newvar()
+
+uthread(lgenerate, 0, Y)
+unify(T, uthread(lsum, Y, 0, 10))
+
+wait(T)
+assert T == 45
+
+

Please note that in the current LO, we deal with coroutines, not +threads (thus we can't rely on preemtive scheduling to lessen the +problem with the eager consummer/producer program). Also nested +coroutines don't schedule properly yet. This impacts the ability to +write a simple program like the following:

+
+def sleep(X, Barrier):
+    wait(X)
+    bind(Barrier, True)
+
+def wait_two(X, Y):
+    Barrier = newvar()
+    uthread(sleep, X, Barrier)
+    uthread(sleep, Y, Barrier)
+    wait(Barrier)
+    if is_free(Y):
+        return 1
+    return 2
+
+X, Y = newvar(), newvar()
+o = uthread(wait_two, X, Y)
+unify(X, Y)
+unify(Y, 42)
+assert X == Y == 42
+assert o == 2
+
+

Finally, it must be noted that bind/unify and wait pair of operations +are quite similar to send and synchronous receive primitives for +inter-process communication.

+
+
+

The operators table

+

Blocking ops

+
+
+
wait/1 # blocks if first arg. is a free logic var., til it becomes bound
+
value -> value
+
wait_needed/1 # blocks until its arg. receives a wait
+
logic var. -> logic var.
+
wait_two/2
+
logic var., logic var. -> int in {1,2}
+
+
+

Coroutine spawning

+
+
+
uthread/n | 1 <= n
+
callable, opt args. -> logic var.
+
+
+
+
+
+
+

Constraint Programming

+

The LO comes with a flexible, extensible constraint solver +engine. While regular search strategies such as depth-first or +breadth-first search are provided, you can write better, specialized +strategies (an exemple would be best-search). We therein describe how +to use the solver to specify and get the solutions of a constraint +satisfaction problem, and then highlight how to extend the solver with +new strategies.

+
+

Using the constraint engine

+
+

Specification of a problem

+

A constraint satisfaction problem is defined by a triple (X, D, C) +where X is a set of finite domain variables, D the set of domains +associated with the variables in X, and C the set of constraints, or +relations, that bind together the variables of X.

+

Note that the constraint variables are NOT logic variables. Not yet +anyway.

+

So we basically need a way to declare variables, their domains and +relations; and something to hold these together. The later is what we +call a "computation space". The notion of computation space is broad +enough to encompass constraint and logic programming, but we use it +there only as a box that holds the elements of our constraint +satisfaction problem. Note that it is completely unrelated to the +notion of object space (as in the logic object space).

+

A problem is a one-argument procedure defined as follows:

+
+def simple_problem(cs):
+    cs.var('x', FiniteDomain(['spam', 'egg', 'ham']))
+    cs.var('y', FiniteDomain([3, 4, 5]))
+
+

This snippet defines a couple of variables and their domains, on the +'cs' argument which is indeed a computation space. Note that we didn't +take a reference of the created variables. We can query the space to +get these back if needed, and then complete the definition of our +problem. Our problem, continued:

+
+... x = cs.find_var('x')
+    y = cs.find_var('y')
+    cs.tell(make_expression([x,y], 'len(x) == y'))
+
+    return x, y
+
+

We must be careful to return the set of variables whose candidate +values we are interested in. The rest should be sufficiently +self-describing...

+
+
+

Getting solutions

+

Now to get and print solutions out of this, we must:

+
+import solver
+cs = newspace()
+cs.define_problem(simple_problem)
+
+for sol in solver.solve(cs):
+    print sol
+
+

The builtin solve function returns a generator. You will note with +pleasure how slow the search can be on a solver running on a Python +interpreter written in Python, the later running on top of +cpython... It is expected that the compiled version of PyPy + LO will +provide decent performance.

+
+
+

Table of Operators

+

Note that below, "variable/expression designators" really are strings.

+

Space creation

+
+newspace/0
+

Finite domain creation

+
+
+
FiniteDomain/1
+
list of any -> FiniteDomain
+
+
+

Expressions

+
+
+
make_expression/2
+
list of var. designators, expression designator -> Expression
+
AllDistinct/1
+
list of var. designators -> Expression
+
+
+

Space methods

+
+
+
var/2
+
var. designator, FiniteDomain -> constraint variable instance
+
find_var/1
+
var. designator -> constraint variable instance
+
tell/1
+
Expression -> None
+
define_problem/1
+
procedure (space -> tuple of constraint variables) -> None
+
+
+
+
+
+

Extending the search engine

+
+

Writing a solver

+

Here we show how the additional builtin primitives allow you to write, +in pure Python, a very basic solver that will search depth-first and +return the first found solution.

+

As we've seen, a CSP is encapsulated into a so-called "computation +space". The space object has additional methods that allow the solver +implementor to drive the search. First, let us see some code driving a +binary depth-first search:

+
+1   def first_solution_dfs(space):
+2       status = space.ask()
+3       if status == 0:
+4           return None
+5       elif status == 1:
+6           return space.merge()
+7       else:
+8           new_space = space.clone()
+9           space.commit(1)
+10          outcome = first_solution_dfs(space)
+11          if outcome is None:
+13              new_space.commit(2)
+14              outcome = first_solution_dfs(new_space)
+15          return outcome
+
+

This recursive solver takes a space as argument, and returns the first +solution or None. Let us examine it piece by piece and discover the +basics of the solver protocol.

+

The first thing to do is "asking" the space about its status. This may +force the "inside" of the space to check that the values of the +domains are compatibles with the constraints. Every inconsistent value +is removed from the variable domains. This phase is called "constraint +propagation". It is crucial because it prunes as much as possible of +the search space. Then, the call to ask returns a positive integer +value which we call the space status; at this point, all (possibly +concurrent) computations happening inside the space are terminated.

+

Depending on the status value, either:

+
    +
  • the space is failed (status == 0), which means that there is no +combination of values of the finite domains that can satisfy the +constraints,
  • +
  • one solution has been found (status == 1): there is exactly one +valuation of the variables that satisfy the constraints,
  • +
  • several branches of the search space can be taken (status represents +the exact number of available alternatives, or branches).
  • +
+

Now, we have written this toy solver as if there could be a maximum of +two alternatives. This assumption holds for the simple_problem we +defined above, where a binary "distributor" (see below for an +explanation of this term) has been chosen automatically for us, but +not in the general case. See the sources for a more general-purpose +solver and more involved sample problems (currently, probably +only conference_scheduling is up to date with the current API).

+

In line 8, we take a clone of the space; nothing is shared between +space and newspace (the clone). Having taken a clone, we now have two +identical versions of the space that we got as parameter. This will +allow us to explore the two alternatives. This step is done, line 9 +and 13, with the call to commit, each time with a different integer +value representing the branch to be taken. The rest should be +sufficiently self-describing.

+

This shows the two important space methods used by a search engine: +ask, which waits for the stability of the space and informs the solver +of its status, and commit, which tells a space which road to take in +case of a fork.

+
+
+

Using distributors

+

Now, earlier, we talked of a "distributor": it is a program running in +a computation space. It could be anything, and in fact, in the final +version of the LO, it will be any Python program, augmented with calls +to non-deterministic choice points. Each time a program embedded in a +computation space reaches such a point, it blocks until some Deus ex +machina makes the choice for him. Only a solver can be responsible for +the actual choice (that is the reason for the name "non +deterministic": the decision does not belong to the embedded program, +only to the solver that drives it).

+

In the case of a CSP, the distributor is a simple piece of code, which +works only after the propagation phase has reached a fixpoint. Its +policy will determine the fanout, or branching factor, of the current +computation space (or node in the abstract search space).

+

Here are two examples of distribution strategies:

+
    +
  • take the variable with the biggest domain, and remove exactly one +value from its domain; thus we always get two branches: one with the +value removed, the other with only this value remaining,
  • +
  • take a variable with a small domain, and keep only one value in the +domain for each branch (in other words, we "instantiate" the +variable); this makes for a branching factor equal to the size of +the domain of the variable.
  • +
+

There are a great many ways to distribute... Some of them perform +better, depending on the caracteristics of the problem to be +solved. But there is no absolutely better distribution strategy. Note +that the second strategy given as example there is what is used (and +hard-wired) in the MAC algorithm.

+

Currently in the LO we have two builtin distributors:

+
    +
  • NaiveDistributor, which distributes domains by splitting the +smallest domain in 2 new domains; the first new domain has a size of +one, and the second has all the other values,
  • +
  • SplitDistributor, which distributes domains by splitting the +smallest domain in N equal parts (or as equal as possible). If N is +0, then the smallest domain is split in domains of size 1; a special +case of this, DichotomyDistributor, for which N == 2, is also +provided and is the default one.
  • +
+

To explicitly specify a distributor for a constraint problem, you +need to say, in the procedure that defines the problem:

+
+cs.set_distributor(NaiveDistributor())
+
+

It is not possible currently to write distributors in pure Python; +this is scheduled for PyPy version 1.

+
+
+

Remaining space operators

+

For solver writers

+
+
+
ask/0
+
nothing -> a positive integer i
+
commit/1
+
integer in [1, i] -> None
+
merge/0
+
nothing -> list of values (solution)
+
+
+

For distributor writers

+
+choose
+
+
+
+
+ + Modified: pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt ============================================================================== --- pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt (original) +++ pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt Fri Jun 23 12:27:50 2006 @@ -163,8 +163,8 @@ When a piece of code tries to access a free logic variable, the thread in which it runs is blocked (suspended) until the variable becomes bound. This behaviour is known as "dataflow synchronization" and -mimics exactly the dataflow variables from the Oz programming -language. With respect to behaviour under concurrency conditions, +mimics exactly the dataflow variables from the `Oz programming +language`_. With respect to behaviour under concurrency conditions, logic variables come with two operators : * wait: this suspends the current thread until the variable is bound, @@ -426,8 +426,8 @@ 15 return outcome This recursive solver takes a space as argument, and returns the first -space containing a solution or None. Let us examine it piece by piece -and discover the basics of the solver protocol. +solution or None. Let us examine it piece by piece and discover the +basics of the solver protocol. The first thing to do is "asking" the space about its status. This may force the "inside" of the space to check that the values of the @@ -454,8 +454,9 @@ two alternatives. This assumption holds for the simple_problem we defined above, where a binary "distributor" (see below for an explanation of this term) has been chosen automatically for us, but -not in the general case. See the sources (applevel/solver.py) for a -more general-purpose solver. +not in the general case. See the sources for a more general-purpose +`solver`_ and more involved `sample problems`_ (currently, probably +only conference_scheduling is up to date with the current API). In line 8, we take a clone of the space; nothing is shared between space and newspace (the clone). Having taken a clone, we now have two @@ -537,19 +538,15 @@ integer in [1, i] -> None merge/0 - nothing -> list of values + nothing -> list of values (solution) For distributor writers choose -Were to look ------------- -See also: +.. _`solver`: ../objspace/constraint/applevel/solver.py +.. _`sample problems`: ../objspace/constraint/applevel/problems.py +.. _`Oz programming language`: http://www.mozart-oz.org -* pypy-dist/pypy/objspace/constraint/applevel for the existing solver - and some sample problems (I'm quite sure that the conference - scheduling problem is up to date wrt the current API, the others - likely lag behind). From hpk at codespeak.net Fri Jun 23 12:41:49 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Jun 2006 12:41:49 +0200 (CEST) Subject: [pypy-svn] r29213 - pypy/dist/pypy/doc Message-ID: <20060623104149.AA8A010076@code0.codespeak.net> Author: hpk Date: Fri Jun 23 12:41:47 2006 New Revision: 29213 Modified: pypy/dist/pypy/doc/release-0.9.0.txt Log: mention a bit of testing Modified: pypy/dist/pypy/doc/release-0.9.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-0.9.0.txt (original) +++ pypy/dist/pypy/doc/release-0.9.0.txt Fri Jun 23 12:41:47 2006 @@ -29,6 +29,8 @@ - 2.5-3x times faster than 0.8 (on richards and pystone). - pypy-c can complete CPython's test suite + - testing refinements: preliminary doctest support + - some other stuff - some 2.5 features? From hpk at codespeak.net Fri Jun 23 12:42:40 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Jun 2006 12:42:40 +0200 (CEST) Subject: [pypy-svn] r29214 - pypy/dist/pypy/doc Message-ID: <20060623104240.7141510076@code0.codespeak.net> Author: hpk Date: Fri Jun 23 12:42:38 2006 New Revision: 29214 Modified: pypy/dist/pypy/doc/release-0.9.0.txt Log: mention's armins htmlreporting Modified: pypy/dist/pypy/doc/release-0.9.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-0.9.0.txt (original) +++ pypy/dist/pypy/doc/release-0.9.0.txt Fri Jun 23 12:42:38 2006 @@ -29,7 +29,7 @@ - 2.5-3x times faster than 0.8 (on richards and pystone). - pypy-c can complete CPython's test suite - - testing refinements: preliminary doctest support + - testing refinements: preliminary doctest support, daily html reports - some other stuff From hpk at codespeak.net Fri Jun 23 12:45:28 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Jun 2006 12:45:28 +0200 (CEST) Subject: [pypy-svn] r29215 - pypy/dist/pypy/doc Message-ID: <20060623104528.9E30210078@code0.codespeak.net> Author: hpk Date: Fri Jun 23 12:45:27 2006 New Revision: 29215 Removed: pypy/dist/pypy/doc/howto-logicobjspace-0.9.html Log: please don't checkin (generated) html files here From mwh at codespeak.net Fri Jun 23 13:13:02 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 13:13:02 +0200 (CEST) Subject: [pypy-svn] r29220 - pypy/dist/pypy/doc Message-ID: <20060623111302.CF06110070@code0.codespeak.net> Author: mwh Date: Fri Jun 23 13:13:01 2006 New Revision: 29220 Modified: pypy/dist/pypy/doc/glossary.txt Log: semi-mechanically add target names for all the glossary definitions (i like query-replace-regexp) Modified: pypy/dist/pypy/doc/glossary.txt ============================================================================== --- pypy/dist/pypy/doc/glossary.txt (original) +++ pypy/dist/pypy/doc/glossary.txt Fri Jun 23 13:13:01 2006 @@ -1,18 +1,25 @@ **annotator** - Performs a form of `type inference`_ on the flow graph. +.. _`application level`: + **application level** - applevel_ code is normal Python code running on -top of the PyPy or CPython interpreter (See interpreter level) +top of the PyPy or CPython interpreter (See `interpreter level`_) .. _backend: -**backend** - Code generator that convert a RPython_ program to a -`target language`_ using the PyPy toolchain_. A backend uses either the +**backend** - Code generator that converts a `RPython +`__ program to a `target +language`_ using the PyPy toolchain_. A backend uses either the lltypesystem_ or the ootypesystem_. +.. _`external function`: + **external function** - Functions that we don't want to implement in Python for various reasons (e.g. if they need to make calls into the OS) and will be implemented by the backend. +.. _`garbage collection framework`: + **garbage collection framework** - Code that makes it possible to write `PyPy's garbage collectors`_ in Python itself. @@ -23,11 +30,17 @@ application level code; it typically provides implementation for an object space and its builtins. (See application level) +.. _`jit`: + **jit** - `just in time compiler`_ +.. _`l3interpreter`: + **l3interpreter** - Piece of code that is able to interpret L3 flow graphs. This code is unfinished and its future is unclear. +.. _`llinterpreter`: + **llinterpreter** - Piece of code that is able to interpret flow graphs. This is very useful for testing purposes, especially if you work on the RPython_ Typer. @@ -37,13 +50,18 @@ **lltypesystem** - A backend_ that uses this typessystem is also called a low-level backend. The C and LLVM backends are using this typesystem. +.. _`mixed module`: + **mixed module** - a module that accesses PyPy's `interpreter level`_ -**object space** - The `object space`_ creates all objects and knows how to -perform operations on the objects. You may think of an object space as being -a library offering a fixed API, a set of operations, with implementations -that a) correspond to the known semantics of Python objects, b) extend or -twist these semantics, or c) serve whole-program analysis purposes. +.. _`object space`: + +**object space** - The `object space `__ creates all +objects and knows how to perform operations on the objects. You may +think of an object space as being a library offering a fixed API, a +set of operations, with implementations that a) correspond to the +known semantics of Python objects, b) extend or twist these semantics, +or c) serve whole-program analysis purposes. .. _ootypesystem: @@ -51,22 +69,34 @@ high-level backend. The common lisp, javascript and cli backends are all using this typesystem. +.. _`prebuilt constant`: + **prebuilt constant** - In RPython_ module globals are considered constants. Moreover, global (i.e. prebuilt) lists and dictionaries are supposed to be immutable. (prebuilts are sometimes called pbc's) +.. _`rpython`: + **rpython** - `Restricted Python`_, which is the limited subset of the Python_ specification. It is also the language that the PyPy interpreter itself is written in. +.. _`rtyper`: + **rtyper** - Based on the type annotations, the `RPython Typer`_ turns the flow graph into one that fits the model of the target platform/backend_ using either the lltypesystem_ or the ootypesystem_. +.. _`specialization`: + **specialization** - XXX +.. _`stackless`: + **stackless** - Technology that enables various forms of coroutining. +.. _`standard interpreter`: + **standard interpreter** - It is the `subsystem implementing the Python language`_, composed of the bytecode interpreter and of the standard objectspace. @@ -76,9 +106,13 @@ **toolchain** - The `annotator pass`_, `The RPython Typer`_, and various `backends`_. +.. _`transformation`: + **transformation** - Code that modifies flowgraphs to weave in `translation-aspects`_ +.. _`translator`: + **translator** - Tool_ based on the PyPy interpreter which can translate sufficiently static Python programs into low-level code. @@ -99,9 +133,7 @@ .. _`translation-aspects`: translation-aspects.html .. _`PyPy's garbage collectors`: garbage_collection.html .. _`Restricted Python`: coding-guide.html#restricted-python -.. _RPython: coding-guide.html#restricted-python .. _Python: http://www.python.org -.. _`object space`: objspace.html .. _`RPython Typer`: rtyper.html .. _`subsystem implementing the Python language`: architecture.html#standard-interpreter From mwh at codespeak.net Fri Jun 23 13:19:09 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 13:19:09 +0200 (CEST) Subject: [pypy-svn] r29221 - pypy/dist/pypy/doc Message-ID: <20060623111909.F018A10070@code0.codespeak.net> Author: mwh Date: Fri Jun 23 13:19:07 2006 New Revision: 29221 Modified: pypy/dist/pypy/doc/glossary.txt Log: use reST definition lists (more emacs gee-whizzery) Modified: pypy/dist/pypy/doc/glossary.txt ============================================================================== --- pypy/dist/pypy/doc/glossary.txt (original) +++ pypy/dist/pypy/doc/glossary.txt Fri Jun 23 13:19:07 2006 @@ -1,125 +1,146 @@ -**annotator** - Performs a form of `type inference`_ on the flow graph. +**annotator** + Performs a form of `type inference`_ on the flow graph. .. _`application level`: -**application level** - applevel_ code is normal Python code running on -top of the PyPy or CPython interpreter (See `interpreter level`_) +**application level** + applevel_ code is normal Python code running on top of the PyPy or + CPython interpreter (see `interpreter level`_) .. _backend: -**backend** - Code generator that converts a `RPython -`__ program to a `target -language`_ using the PyPy toolchain_. A backend uses either the -lltypesystem_ or the ootypesystem_. +**backend** + Code generator that converts a `RPython + `__ program to a `target + language`_ using the PyPy toolchain_. A backend uses either the + lltypesystem_ or the ootypesystem_. .. _`external function`: -**external function** - Functions that we don't want to implement in Python -for various reasons (e.g. if they need to make calls into the OS) and will -be implemented by the backend. +**external function** + Functions that we don't want to implement in Python for various + reasons (e.g. if they need to make calls into the OS) and will be + implemented by the backend. .. _`garbage collection framework`: -**garbage collection framework** - Code that makes it possible to write -`PyPy's garbage collectors`_ in Python itself. +**garbage collection framework** + Code that makes it possible to write `PyPy's garbage collectors`_ + in Python itself. .. _`interpreter level`: -**interpreter level** - Code running at this level is part of the -implementation of the PyPy interpreter and cannot interact normally with -application level code; it typically provides implementation for an object -space and its builtins. (See application level) +**interpreter level** + Code running at this level is part of the implementation of the + PyPy interpreter and cannot interact normally with application + level code; it typically provides implementation for an object + space and its builtins. (See application level) .. _`jit`: -**jit** - `just in time compiler`_ - +**jit** + `just in time compiler`_ + .. _`l3interpreter`: -**l3interpreter** - Piece of code that is able to interpret L3 flow graphs. -This code is unfinished and its future is unclear. +**l3interpreter** + Piece of code that is able to interpret L3 flow graphs. This code + is unfinished and its future is unclear. .. _`llinterpreter`: -**llinterpreter** - Piece of code that is able to interpret flow graphs. -This is very useful for testing purposes, especially if you work on the -RPython_ Typer. +**llinterpreter** + Piece of code that is able to interpret flow graphs. This is very + useful for testing purposes, especially if you work on the RPython_ + Typer. .. _lltypesystem: -**lltypesystem** - A backend_ that uses this typessystem is also called a -low-level backend. The C and LLVM backends are using this typesystem. +**lltypesystem** + A backend_ that uses this typessystem is also called a low-level + backend. The C and LLVM backends are using this typesystem. .. _`mixed module`: -**mixed module** - a module that accesses PyPy's `interpreter level`_ - +**mixed module** + a module that accesses PyPy's `interpreter level`_ + .. _`object space`: -**object space** - The `object space `__ creates all -objects and knows how to perform operations on the objects. You may -think of an object space as being a library offering a fixed API, a -set of operations, with implementations that a) correspond to the -known semantics of Python objects, b) extend or twist these semantics, -or c) serve whole-program analysis purposes. +**object space** + The `object space `__ creates all objects and knows + how to perform operations on the objects. You may think of an + object space as being a library offering a fixed API, a set of + operations, with implementations that a) correspond to the known + semantics of Python objects, b) extend or twist these semantics, or + c) serve whole-program analysis purposes. .. _ootypesystem: -**ootypesystem** - A backend_ that uses this typessystem is also called a -high-level backend. The common lisp, javascript and cli backends are all -using this typesystem. +**ootypesystem** + A backend_ that uses this typessystem is also called a high-level + backend. The common lisp, javascript and cli backends are all + using this typesystem. .. _`prebuilt constant`: -**prebuilt constant** - In RPython_ module globals are considered constants. -Moreover, global (i.e. prebuilt) lists and dictionaries are supposed to be -immutable. (prebuilts are sometimes called pbc's) +**prebuilt constant** + In RPython_ module globals are considered constants. Moreover, + global (i.e. prebuilt) lists and dictionaries are supposed to be + immutable. (prebuilts are sometimes called pbc's) .. _`rpython`: -**rpython** - `Restricted Python`_, which is the limited subset of the -Python_ specification. It is also the language that the PyPy interpreter -itself is written in. +**rpython** + `Restricted Python`_, which is the limited subset of the Python_ + specification. It is also the language that the PyPy interpreter + itself is written in. .. _`rtyper`: -**rtyper** - Based on the type annotations, the `RPython Typer`_ turns the -flow graph into one that fits the model of the target platform/backend_ using -either the lltypesystem_ or the ootypesystem_. +**rtyper** + Based on the type annotations, the `RPython Typer`_ turns the flow + graph into one that fits the model of the target platform/backend_ + using either the lltypesystem_ or the ootypesystem_. .. _`specialization`: -**specialization** - XXX +**specialization** + XXX .. _`stackless`: -**stackless** - Technology that enables various forms of coroutining. +**stackless** + Technology that enables various forms of coroutining. .. _`standard interpreter`: -**standard interpreter** - It is the -`subsystem implementing the Python language`_, composed of the bytecode -interpreter and of the standard objectspace. +**standard interpreter** + It is the `subsystem implementing the Python language`_, composed + of the bytecode interpreter and of the standard objectspace. .. _toolchain: -**toolchain** - The `annotator pass`_, `The RPython Typer`_, and various -`backends`_. +**toolchain** + The `annotator pass`_, `The RPython Typer`_, and various + `backends`_. .. _`transformation`: -**transformation** - Code that modifies flowgraphs to weave in -`translation-aspects`_ +**transformation** + Code that modifies flowgraphs to weave in `translation-aspects`_ .. _`translator`: -**translator** - Tool_ based on the PyPy interpreter which can translate -sufficiently static Python programs into low-level code. +**translator** + Tool_ based on the PyPy interpreter which can translate + sufficiently static Python programs into low-level code. .. _`type inference`: -**type inference** - Deduces either partially or fully the type of -expressions as described in this `type inference article`_. +**type inference** + Deduces either partially or fully the type of expressions as + described in this `type inference article`_. .. _applevel: coding-guide.html#application-level From mwh at codespeak.net Fri Jun 23 13:37:41 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 13:37:41 +0200 (CEST) Subject: [pypy-svn] r29222 - pypy/dist/pypy/doc Message-ID: <20060623113741.BBF1C10076@code0.codespeak.net> Author: mwh Date: Fri Jun 23 13:37:39 2006 New Revision: 29222 Modified: pypy/dist/pypy/doc/glossary.txt Log: a review pass, changing a little bit of wording but mainly adding links. good enough, says i! Modified: pypy/dist/pypy/doc/glossary.txt ============================================================================== --- pypy/dist/pypy/doc/glossary.txt (original) +++ pypy/dist/pypy/doc/glossary.txt Fri Jun 23 13:37:39 2006 @@ -1,26 +1,39 @@ +PyPy, like any large project, has developed a jargon of its own. This +document gives brief definition of some of these terms and provides +links to more information. + +.. _annotator: + **annotator** - Performs a form of `type inference`_ on the flow graph. + The component of the translator_\ 's toolchain_ that performs a form + of `type inference`_ on the flow graph. .. _`application level`: **application level** applevel_ code is normal Python code running on top of the PyPy or - CPython interpreter (see `interpreter level`_) + CPython_ interpreter (see `interpreter level`_) .. _backend: **backend** - Code generator that converts a `RPython + Code generator that converts an `RPython `__ program to a `target language`_ using the PyPy toolchain_. A backend uses either the lltypesystem_ or the ootypesystem_. +.. _CPython: + +**CPython** + The "default" implementation of Python, written in C and + distributed by the PSF_ on http://www.python.org. + .. _`external function`: **external function** Functions that we don't want to implement in Python for various - reasons (e.g. if they need to make calls into the OS) and will be - implemented by the backend. + reasons (e.g. if they need to make calls into the OS) and whose + implementation will be provided by the backend. .. _`garbage collection framework`: @@ -31,10 +44,10 @@ .. _`interpreter level`: **interpreter level** - Code running at this level is part of the implementation of the - PyPy interpreter and cannot interact normally with application - level code; it typically provides implementation for an object - space and its builtins. (See application level) + Code running at this level is part of the implementation of the + PyPy interpreter and cannot interact normally with `application + level`_ code; it typically provides implementation for an object + space and its builtins. .. _`jit`: @@ -47,7 +60,7 @@ Piece of code that is able to interpret L3 flow graphs. This code is unfinished and its future is unclear. -.. _`llinterpreter`: +.. _llinterpreter: **llinterpreter** Piece of code that is able to interpret flow graphs. This is very @@ -57,44 +70,47 @@ .. _lltypesystem: **lltypesystem** - A backend_ that uses this typessystem is also called a low-level - backend. The C and LLVM backends are using this typesystem. + A backend_ that uses this type system is also called a low-level + backend. The C and LLVM backends use this typesystem. .. _`mixed module`: **mixed module** - a module that accesses PyPy's `interpreter level`_ + a module that accesses PyPy's `interpreter level`_. The name comes + from the fact that the module's implementation can be a mixture of + `application level`_ and `interpreter level`_ code. .. _`object space`: **object space** - The `object space `__ creates all objects and knows - how to perform operations on the objects. You may think of an - object space as being a library offering a fixed API, a set of - operations, with implementations that a) correspond to the known - semantics of Python objects, b) extend or twist these semantics, or - c) serve whole-program analysis purposes. + The `object space `__ (often abbreviated to + "objspace") creates all objects and knows how to perform operations + on the objects. You may think of an object space as being a library + offering a fixed API, a set of operations, with implementations + that a) correspond to the known semantics of Python objects, b) + extend or twist these semantics, or c) serve whole-program analysis + purposes. .. _ootypesystem: **ootypesystem** - A backend_ that uses this typessystem is also called a high-level - backend. The common lisp, javascript and cli backends are all - using this typesystem. + A backend_ that uses this type system is also called a high-level + backend. The common lisp, javascript and cli backends all use this + typesystem. .. _`prebuilt constant`: **prebuilt constant** In RPython_ module globals are considered constants. Moreover, global (i.e. prebuilt) lists and dictionaries are supposed to be - immutable. (prebuilts are sometimes called pbc's) + immutable ("prebuilt constant" is sometimes abbreviated to "pbc"). .. _`rpython`: **rpython** - `Restricted Python`_, which is the limited subset of the Python_ - specification. It is also the language that the PyPy interpreter - itself is written in. + `Restricted Python`_, a limited subset of the Python_ language. It + is also the language that the PyPy interpreter itself is written + in. .. _`rtyper`: @@ -106,12 +122,17 @@ .. _`specialization`: **specialization** - XXX + A way of controlling how a specifc function is handled by the + annotator_. One specialization is to treat calls to a function + with different argument types as if they were calls to different + functions with identical source. .. _`stackless`: **stackless** - Technology that enables various forms of coroutining. + Technology that enables various forms of non conventional control + flow, such as coroutines, greenlets and tasklets. Inspired by + Christian Tismer's `Stackless Python `__. .. _`standard interpreter`: @@ -134,19 +155,19 @@ **translator** Tool_ based on the PyPy interpreter which can translate - sufficiently static Python programs into low-level code. + sufficiently static Python programs into low-level code. .. _`type inference`: **type inference** Deduces either partially or fully the type of expressions as - described in this `type inference article`_. + described in this `type inference article on Wikipedia`_. .. _applevel: coding-guide.html#application-level .. _`target language`: getting-started.html#trying-out-the-translator .. _`just in time compiler`: http://en.wikipedia.org/wiki/Just-in-time_compilation -.. _`type inference article`: http://en.wikipedia.org/wiki/Type_inference +.. _`type inference article on Wikipedia`: http://en.wikipedia.org/wiki/Type_inference .. _`annotator pass`: translation.html#the-annotation-pass .. _`The RPython Typer`: translation.html#the-rpython-typer .. _`backends`: getting-started.html#trying-out-the-translator @@ -154,6 +175,7 @@ .. _`translation-aspects`: translation-aspects.html .. _`PyPy's garbage collectors`: garbage_collection.html .. _`Restricted Python`: coding-guide.html#restricted-python +.. _PSF: http://www.python.org/psf/ .. _Python: http://www.python.org .. _`RPython Typer`: rtyper.html .. _`subsystem implementing the Python language`: architecture.html#standard-interpreter From pedronis at codespeak.net Fri Jun 23 13:46:59 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 23 Jun 2006 13:46:59 +0200 (CEST) Subject: [pypy-svn] r29224 - pypy/dist/pypy/doc Message-ID: <20060623114659.9E6AE10070@code0.codespeak.net> Author: pedronis Date: Fri Jun 23 13:46:58 2006 New Revision: 29224 Modified: pypy/dist/pypy/doc/glossary.txt Log: extend rpython entry Modified: pypy/dist/pypy/doc/glossary.txt ============================================================================== --- pypy/dist/pypy/doc/glossary.txt (original) +++ pypy/dist/pypy/doc/glossary.txt Fri Jun 23 13:46:58 2006 @@ -108,8 +108,9 @@ .. _`rpython`: **rpython** - `Restricted Python`_, a limited subset of the Python_ language. It - is also the language that the PyPy interpreter itself is written + `Restricted Python`_, a limited subset of the Python_ language. + The limitations make `type inference`_ possible. + It is also the language that the PyPy interpreter itself is written in. .. _`rtyper`: From mwh at codespeak.net Fri Jun 23 13:48:07 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 13:48:07 +0200 (CEST) Subject: [pypy-svn] r29225 - pypy/dist/pypy/doc Message-ID: <20060623114807.DAABA10075@code0.codespeak.net> Author: mwh Date: Fri Jun 23 13:48:05 2006 New Revision: 29225 Modified: pypy/dist/pypy/doc/glossary.txt Log: more links, two more entries Modified: pypy/dist/pypy/doc/glossary.txt ============================================================================== --- pypy/dist/pypy/doc/glossary.txt (original) +++ pypy/dist/pypy/doc/glossary.txt Fri Jun 23 13:48:05 2006 @@ -70,8 +70,16 @@ .. _lltypesystem: **lltypesystem** - A backend_ that uses this type system is also called a low-level - backend. The C and LLVM backends use this typesystem. + A `C-like type model `__ that contains + structs and pointers. A backend_ that uses this type system is also + called a low-level backend. The C and LLVM backends use this + typesystem. + +.. _`low-level helper`: + +**low-level helper** + A function that the RTyper_ can use a call to as part of implementing + some operation in terms of the target `type system`_. .. _`mixed module`: @@ -94,9 +102,10 @@ .. _ootypesystem: **ootypesystem** - A backend_ that uses this type system is also called a high-level - backend. The common lisp, javascript and cli backends all use this - typesystem. + An `object oriented type model `__ + containing classes and instances. A backend_ that uses this type system + is also called a high-level backend. The common lisp, javascript and + cli backends all use this typesystem. .. _`prebuilt constant`: @@ -158,6 +167,11 @@ Tool_ based on the PyPy interpreter which can translate sufficiently static Python programs into low-level code. +.. _`type system`: + +**type system** + The RTyper can target either the lltypesystem_ or the ootypesystem_. + .. _`type inference`: **type inference** From cfbolz at codespeak.net Fri Jun 23 13:51:12 2006 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 23 Jun 2006 13:51:12 +0200 (CEST) Subject: [pypy-svn] r29226 - pypy/dist/pypy/doc Message-ID: <20060623115112.F32BD10070@code0.codespeak.net> Author: cfbolz Date: Fri Jun 23 13:51:10 2006 New Revision: 29226 Modified: pypy/dist/pypy/doc/garbage_collection.txt Log: add a warning a very few words about the gc situation at the moment Modified: pypy/dist/pypy/doc/garbage_collection.txt ============================================================================== --- pypy/dist/pypy/doc/garbage_collection.txt (original) +++ pypy/dist/pypy/doc/garbage_collection.txt Fri Jun 23 13:51:10 2006 @@ -8,17 +8,27 @@ Current Situation and Objectives ================================ -This document describes the current status as well as plans for the future of -garbage collection in PyPy. Work on this began as a `Summer-of-Code-project`_ -(thanks Google, especially Chris DiBona, who put lots of effort in making -everything run smoothly) of Carl Friedrich Bolz. +XXX *Warning*: The information below is unfortunately incomplete. I describes +the garbage collectors themselves, but not how they are actually used in PyPy +(via the GC transformer) + +This document describes how garbage collectors are implemented in PyPy. Work on +this began as a `Summer-of-Code-project`_ (many thanks to Google!) of Carl +Friedrich Bolz but has since been worked on by many PyPy developers. The central idea is of course to implement PyPy's garbage collectors in Python -itself. At the moment (August 2005) the backends have the responsibility for -implementing garbage collection. GenC provides the choice between reference -counting and using the `Boehm-Demers-Weiser garbage collector`_ The LLVM -backend offers only the Boehm collector. The idea is that the collectors -should be written in a way so that the backends can share this code. +itself. RPython itself is a garbage collected language that means at one point +garbage collection has to be inserted into the flow graphs, since the typical +target languages (C, LLVM) need explicit memory management. + +At the moment it is possible to do garbage collections in different ways in +PyPy. The easiest one (and the one that performs best at the moment) is to use +the `Boehm-Demers-Weiser garbage collector`_. Then there is a reference +counting implementation (which is atrociously slow). In addition the +mark-and-sweep collector that is described below can be used. + +Of these three, only the mark-and-sweep collector is written in Python itself. +How garbage collectors can be written in Python is described in the following. .. _`Summer-of-Code-project`: http://code.google.com/summerofcode.html .. _`Boehm-Demers-Weiser garbage collector`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ From ericvrp at codespeak.net Fri Jun 23 13:52:13 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 23 Jun 2006 13:52:13 +0200 (CEST) Subject: [pypy-svn] r29227 - pypy/dist/pypy/doc Message-ID: <20060623115213.8E30F10070@code0.codespeak.net> Author: ericvrp Date: Fri Jun 23 13:52:12 2006 New Revision: 29227 Modified: pypy/dist/pypy/doc/glossary.txt Log: typo Modified: pypy/dist/pypy/doc/glossary.txt ============================================================================== --- pypy/dist/pypy/doc/glossary.txt (original) +++ pypy/dist/pypy/doc/glossary.txt Fri Jun 23 13:52:12 2006 @@ -132,7 +132,7 @@ .. _`specialization`: **specialization** - A way of controlling how a specifc function is handled by the + A way of controlling how a specific function is handled by the annotator_. One specialization is to treat calls to a function with different argument types as if they were calls to different functions with identical source. From pedronis at codespeak.net Fri Jun 23 13:54:03 2006 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 23 Jun 2006 13:54:03 +0200 (CEST) Subject: [pypy-svn] r29228 - pypy/dist/pypy/doc Message-ID: <20060623115403.9D6D510075@code0.codespeak.net> Author: pedronis Date: Fri Jun 23 13:54:02 2006 New Revision: 29228 Modified: pypy/dist/pypy/doc/glossary.txt Log: link the entries on annotation to the annotation pass section Modified: pypy/dist/pypy/doc/glossary.txt ============================================================================== --- pypy/dist/pypy/doc/glossary.txt (original) +++ pypy/dist/pypy/doc/glossary.txt Fri Jun 23 13:54:02 2006 @@ -6,7 +6,8 @@ **annotator** The component of the translator_\ 's toolchain_ that performs a form - of `type inference`_ on the flow graph. + of `type inference`_ on the flow graph. See the `annotator pass`_ + in the documentation. .. _`application level`: @@ -177,7 +178,8 @@ **type inference** Deduces either partially or fully the type of expressions as described in this `type inference article on Wikipedia`_. - + PyPy's tool-chain own flavour of type inference is described + in the `annotator pass`_ section. .. _applevel: coding-guide.html#application-level .. _`target language`: getting-started.html#trying-out-the-translator From mwh at codespeak.net Fri Jun 23 14:06:40 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 14:06:40 +0200 (CEST) Subject: [pypy-svn] r29235 - in pypy/dist/pypy/doc: . image Message-ID: <20060623120640.B525F10072@code0.codespeak.net> Author: mwh Date: Fri Jun 23 14:06:34 2006 New Revision: 29235 Modified: pypy/dist/pypy/doc/image/translation-detail-0.9.graffle pypy/dist/pypy/doc/image/translation-detail-0.9.png pypy/dist/pypy/doc/translation.txt Log: finish? the "how it fits together" section. final small tweaks to the translation-detail image. Modified: pypy/dist/pypy/doc/image/translation-detail-0.9.graffle ============================================================================== --- pypy/dist/pypy/doc/image/translation-detail-0.9.graffle (original) +++ pypy/dist/pypy/doc/image/translation-detail-0.9.graffle Fri Jun 23 14:06:34 2006 @@ -14,7 +14,7 @@ ColumnSpacing 36 CreationDate - 2006-06-16 16:03:55 +0200 + 2006-06-16 15:03:55 +0100 Creator Michael Hudson GraphDocumentVersion @@ -34,7 +34,7 @@ 12 ID - 404 + 104 Magnets {0, 1} @@ -88,7 +88,7 @@ 12 ID - 403 + 103 Shape RoundedRectangle Style @@ -119,7 +119,7 @@ {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural -\f0\fs24 \cf0 Translation Task} +\f0\fs24 \cf0 Translation Step} @@ -135,7 +135,7 @@ 12 ID - 402 + 102 Shape Circle Style @@ -175,12 +175,12 @@ Head ID - 396 + 96 Info 1 ID - 401 + 101 OrthogonalBarAutomatic OrthogonalBarPosition @@ -207,7 +207,7 @@ Tail ID - 380 + 80 @@ -216,14 +216,14 @@ Head ID - 395 + 95 ID - 400 + 100 Points - {221.102, 418.131} - {155.1, 435.5} + {220, 414.737} + {161.196, 427.117} Style @@ -240,7 +240,7 @@ Tail ID - 363 + 63 @@ -249,10 +249,10 @@ Head ID - 363 + 63 ID - 399 + 99 Points {161.196, 372.883} @@ -273,7 +273,7 @@ Tail ID - 357 + 57 @@ -282,12 +282,12 @@ Head ID - 376 + 76 Info 3 ID - 398 + 98 OrthogonalBarAutomatic OrthogonalBarPosition @@ -314,7 +314,7 @@ Tail ID - 396 + 96 Info 4 @@ -325,12 +325,12 @@ Head ID - 377 + 77 Info 3 ID - 397 + 97 OrthogonalBarAutomatic OrthogonalBarPosition @@ -357,7 +357,7 @@ Tail ID - 396 + 96 Info 3 @@ -375,7 +375,7 @@ 12 ID - 396 + 96 Magnets {1, 0.5} @@ -412,7 +412,7 @@ Bounds - {{20, 430}, {160, 40}} + {{20, 420}, {160, 40}} Class ShapedGraphic FontInfo @@ -423,7 +423,7 @@ 12 ID - 395 + 95 Shape Circle Style @@ -451,12 +451,12 @@ Head ID - 396 + 96 Info 2 ID - 394 + 94 OrthogonalBarAutomatic OrthogonalBarPosition @@ -485,7 +485,7 @@ Tail ID - 381 + 81 Info 1 @@ -496,12 +496,12 @@ Head ID - 378 + 78 Info 9 ID - 393 + 93 OrthogonalBarAutomatic OrthogonalBarPosition @@ -531,7 +531,7 @@ Tail ID - 381 + 81 Info 2 @@ -542,10 +542,10 @@ Head ID - 382 + 82 ID - 392 + 92 Points {360, 572.526} @@ -568,7 +568,7 @@ Tail ID - 370 + 70 @@ -577,12 +577,12 @@ Head ID - 381 + 81 Info 4 ID - 391 + 91 Points {358.355, 498.708} @@ -605,7 +605,7 @@ Tail ID - 369 + 69 @@ -614,12 +614,12 @@ Head ID - 380 + 80 Info 9 ID - 390 + 90 Points {360, 476.316} @@ -642,7 +642,7 @@ Tail ID - 369 + 69 @@ -651,10 +651,10 @@ Head ID - 379 + 79 ID - 389 + 89 Points {360, 402.947} @@ -677,7 +677,7 @@ Tail ID - 363 + 63 @@ -693,12 +693,12 @@ Head ID - 378 + 78 Info 10 ID - 388 + 88 Points {357.665, 380.769} @@ -721,7 +721,7 @@ Tail ID - 363 + 63 @@ -737,10 +737,10 @@ Head ID - 376 + 76 ID - 387 + 87 OrthogonalBarAutomatic OrthogonalBarPosition @@ -769,7 +769,7 @@ Tail ID - 377 + 77 @@ -785,12 +785,12 @@ Head ID - 377 + 77 Info 10 ID - 386 + 86 Points {360, 306.737} @@ -813,7 +813,7 @@ Tail ID - 362 + 62 @@ -829,10 +829,10 @@ Head ID - 375 + 75 ID - 385 + 85 OrthogonalBarAutomatic OrthogonalBarPosition @@ -861,7 +861,7 @@ Tail ID - 376 + 76 @@ -870,12 +870,12 @@ Head ID - 376 + 76 Info 10 ID - 384 + 84 Points {360, 233.368} @@ -898,7 +898,7 @@ Tail ID - 361 + 61 @@ -907,10 +907,10 @@ Head ID - 375 + 75 ID - 383 + 83 Points {360, 160} @@ -933,7 +933,7 @@ Tail ID - 354 + 54 @@ -949,7 +949,7 @@ 12 ID - 382 + 82 Magnets {0, 1} @@ -991,7 +991,7 @@ 12 ID - 381 + 81 Magnets {1, 0.5} @@ -1037,7 +1037,7 @@ 12 ID - 380 + 80 Magnets {1, 0} @@ -1077,7 +1077,7 @@ 12 ID - 379 + 79 Magnets {1, 0} @@ -1118,7 +1118,7 @@ 12 ID - 378 + 78 Magnets {1, 0.5} @@ -1166,7 +1166,7 @@ 12 ID - 377 + 77 Magnets {0, 1} @@ -1208,7 +1208,7 @@ 12 ID - 376 + 76 Magnets {0, 1} @@ -1250,7 +1250,7 @@ 12 ID - 375 + 75 Magnets {0, 1} @@ -1285,14 +1285,14 @@ Head ID - 364 + 64 ID - 374 + 74 Points - {221.102, 578.131} - {155.1, 595.5} + {220, 574.737} + {161.196, 587.117} Style @@ -1309,7 +1309,7 @@ Tail ID - 370 + 70 @@ -1318,14 +1318,14 @@ Head ID - 370 + 70 ID - 373 + 73 Points - {167.654, 540.682} - {220, 548.947} + {161.196, 532.883} + {220, 545.263} Style @@ -1342,7 +1342,7 @@ Tail ID - 358 + 58 @@ -1351,14 +1351,14 @@ Head ID - 358 + 58 ID - 372 + 72 Points - {221.102, 498.131} - {155.1, 515.5} + {220, 494.737} + {161.196, 507.117} Style @@ -1375,7 +1375,7 @@ Tail ID - 369 + 69 @@ -1384,14 +1384,14 @@ Head ID - 369 + 69 ID - 371 + 71 Points - {167.654, 460.682} - {220, 468.947} + {161.196, 452.883} + {220, 465.263} Style @@ -1408,7 +1408,7 @@ Tail ID - 395 + 95 @@ -1424,7 +1424,7 @@ 12 ID - 370 + 70 Shape RoundedRectangle Style @@ -1459,7 +1459,7 @@ 12 ID - 369 + 69 Shape RoundedRectangle Style @@ -1487,10 +1487,10 @@ Head ID - 357 + 57 ID - 368 + 68 Points {220, 334.737} @@ -1511,7 +1511,7 @@ Tail ID - 362 + 62 @@ -1520,10 +1520,10 @@ Head ID - 362 + 62 ID - 367 + 67 Points {161.196, 292.883} @@ -1544,7 +1544,7 @@ Tail ID - 356 + 56 @@ -1553,10 +1553,10 @@ Head ID - 356 + 56 ID - 366 + 66 Points {220, 254.737} @@ -1577,7 +1577,7 @@ Tail ID - 361 + 61 @@ -1586,10 +1586,10 @@ Head ID - 361 + 61 ID - 365 + 65 Points {161.196, 212.883} @@ -1610,12 +1610,12 @@ Tail ID - 355 + 55 Bounds - {{20, 590}, {160, 40}} + {{20, 580}, {160, 40}} Class ShapedGraphic FontInfo @@ -1626,7 +1626,7 @@ 12 ID - 364 + 64 Shape Circle Style @@ -1661,7 +1661,7 @@ 12 ID - 363 + 63 Shape RoundedRectangle Style @@ -1696,7 +1696,7 @@ 12 ID - 362 + 62 Shape RoundedRectangle Style @@ -1731,7 +1731,7 @@ 12 ID - 361 + 61 Shape RoundedRectangle Style @@ -1759,10 +1759,10 @@ Head ID - 355 + 55 ID - 360 + 60 Points {220, 174.737} @@ -1783,7 +1783,7 @@ Tail ID - 354 + 54 @@ -1792,10 +1792,10 @@ Head ID - 354 + 54 ID - 359 + 59 Points {161.196, 132.883} @@ -1816,12 +1816,12 @@ Tail ID - 353 + 53 Bounds - {{20, 510}, {160, 40}} + {{20, 500}, {160, 40}} Class ShapedGraphic FontInfo @@ -1832,7 +1832,7 @@ 12 ID - 358 + 58 Shape Circle Style @@ -1867,7 +1867,7 @@ 12 ID - 357 + 57 Shape Circle Style @@ -1902,7 +1902,7 @@ 12 ID - 356 + 56 Shape Circle Style @@ -1937,7 +1937,7 @@ 12 ID - 355 + 55 Shape Circle Style @@ -1973,7 +1973,7 @@ 12 ID - 354 + 54 Shape RoundedRectangle Style @@ -2008,7 +2008,7 @@ 12 ID - 353 + 53 Shape Circle Style @@ -2035,9 +2035,9 @@ GridInfo GridSpacing - 2 + 5 MajorGridSpacing - 10 + 4 MinorGridColor a @@ -2072,13 +2072,16 @@ LayoutInfo - + + ChildOrdering + 0 + LinksVisible NO MagnetsVisible NO ModificationDate - 2006-06-16 17:33:15 +0200 + 2006-06-23 13:01:31 +0100 Modifier Michael Hudson Orientation @@ -2165,7 +2168,7 @@ CQkJCTwvYXJyYXk+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVu dDwva2V5PgoJCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3Ry aW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+ - CgkJCQkJPGRhdGU+MjAwNi0wNi0xNlQxNDowMzo1NVo8L2RhdGU+CgkJCQkJPGtleT5j + CgkJCQkJPGRhdGU+MjAwNi0wNi0yM1QxMjowMDoxOFo8L2RhdGU+CgkJCQkJPGtleT5j b20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2Vy PjA8L2ludGVnZXI+CgkJCQk8L2RpY3Q+CgkJCTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxr ZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVyUmVjdDwv @@ -2179,7 +2182,7 @@ CQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jbGllbnQ8L2tleT4KCQkJCQk8 c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCQk8a2V5 PmNvbS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJCTxkYXRlPjIw - MDYtMDYtMTZUMTQ6MDM6NTVaPC9kYXRlPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50 + MDYtMDYtMjNUMTI6MDA6MThaPC9kYXRlPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50 LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJ CQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5w cmludC5QYXBlckluZm8uUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5j @@ -2273,7 +2276,7 @@ CurrentSheet 0 Frame - {{572, 61}, {973, 807}} + {{395, 71}, {973, 807}} ShowRuler ShowStatusBar Modified: pypy/dist/pypy/doc/image/translation-detail-0.9.png ============================================================================== Binary files. No diff available. Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Fri Jun 23 14:06:34 2006 @@ -277,7 +277,8 @@ Example: Integer operations --------------------------- -Integer operations are the easiest. Assume a graph containing the following operation:: +Integer operations are make an easy example. Assume a graph containing the +following operation:: v3 = add(v1, v2) @@ -717,5 +718,25 @@ :align: center A detail that has not yet been emphasised is the interaction of the +various components. It makes for a nice presentation to say that +after the annotator has finished the RTyper processes the graphs and +then the exception handling is made explicit and so on, but it's not +entirely true. For example, the RTyper inserts calls to many +`low-level helpers`_ which must first be annotated, and the GC +transformer can use inlining (one of the `backend optimizations`_) of +some of its small helper functions to improve performance. The +following picture attempts to summarize the components involved in +perfoming each step of the default translation process: + +.. image:: image/translation-detail-0.9.png + :align: center + +.. _`low-level helpers`: glossary.html#low-level-helper + +A component not mentioned before is the "MixLevelAnnotator"; it +provides a convenient interface for a "late" (after RTyping) +translation step to declare that it needs to be able to call each of a +collection of functions (which may refer to each other in a mutually +recursive fashion) and annotate and rtype them all at once. .. include:: _ref.txt From arigo at codespeak.net Fri Jun 23 14:58:13 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Jun 2006 14:58:13 +0200 (CEST) Subject: [pypy-svn] r29241 - pypy/dist/pypy/doc Message-ID: <20060623125813.42E6110072@code0.codespeak.net> Author: arigo Date: Fri Jun 23 14:58:11 2006 New Revision: 29241 Added: pypy/dist/pypy/doc/stackless.txt (contents, props changed) Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/index.txt Log: Very concise documentation of the app-level stackless module. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Fri Jun 23 14:58:11 2006 @@ -24,6 +24,7 @@ .. _`pypy/interpreter/typedef.py`: ../../pypy/interpreter/typedef.py .. _`lib/`: .. _`pypy/lib/`: ../../pypy/lib +.. _`pypy/lib/stackless.py`: ../../pypy/lib/stackless.py .. _`lib/test2/`: .. _`pypy/lib/test2`: ../../pypy/lib/test2 .. _`module/`: @@ -51,7 +52,6 @@ .. _`pypy/rpython/extfunctable.py`: ../../pypy/rpython/extfunctable.py .. _`pypy/rpython/lltypesystem/lltype.py`: .. _`rpython/lltypesystem/lltype.py`: ../../pypy/rpython/lltypesystem/lltype.py -.. _`rpython/ootypesystem/ootype.py`: ../../pypy/rpython/ootypesystem/ootype.py .. _`rpython/memory/`: ../../pypy/rpython/memory .. _`pypy/rpython/memory/gc.py`: ../../pypy/rpython/memory/gc.py .. _`pypy/rpython/memory/lladdress.py`: ../../pypy/rpython/memory/lladdress.py @@ -61,6 +61,7 @@ .. _`pypy/rpython/module/ll_os.py`: ../../pypy/rpython/module/ll_os.py .. _`pypy/rpython/module/test`: ../../pypy/rpython/module/test .. _`pypy/rpython/objectmodel.py`: ../../pypy/rpython/objectmodel.py +.. _`rpython/ootypesystem/ootype.py`: ../../pypy/rpython/ootypesystem/ootype.py .. _`pypy/rpython/rctypes/test/test_ctypes.py`: ../../pypy/rpython/rctypes/test/test_ctypes.py .. _`rpython/rint.py`: ../../pypy/rpython/rint.py .. _`rpython/rlist.py`: ../../pypy/rpython/rlist.py Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Fri Jun 23 14:58:11 2006 @@ -67,6 +67,21 @@ preliminary reports that we submitted to the European Union. +New Python features +========================================== + +(Note that emphasis so far has not been on adding new features to the +Python language. These new features are experimental, and require you +to enable them explicitly while running or translating PyPy.) + +The Thunk_ Object Space: lazily computed objects. + +Stackless_ and coroutines + +.. _Thunk: getting-started.html#lazily-computed-objects +.. _Stackless: stackless.html + + Status ====================================== Added: pypy/dist/pypy/doc/stackless.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/stackless.txt Fri Jun 23 14:58:11 2006 @@ -0,0 +1,130 @@ +========================================================== + Application-level Stackless features +========================================================== + +.. contents:: +.. sectnum:: + +Introduction +================ + +PyPy can expose to its user language features similar to the ones +present in `Stackless Python`_: the ability to write code in a massively +concurrent style. It actually exposes three different paradigms to +choose from: + +* Tasklets and channels; + +* Greenlets; + +* Plain coroutines. + +All of them are extremely light-weight, which means that PyPy should be +able to handle programs containing large amounts of +coroutines/tasklet/greenlets. + + +Requirements +================= + +If you are running py.py on top of CPython, then you need to enable +the _stackless module by running it as follows:: + + py.py --usemodules=_stackless + +This is implemented internally using greenlets, so it only works on a +platform where greenlets_ are supported. + +To translate a version of ``pypy-c`` that includes Stackless support, +run translate.py as follows:: + + cd pypy/translator/goal + python translate.py --stackless + + +Quick reference +========================== + +The new features are exposed in a module called ``stackless``. + + +Tasklets and channels ++++++++++++++++++++++ + +The ``stackless`` module provides an interface that is roughly +compatible with the interface of the ``stackless`` module in `Stackless +Python`_: it contains ``stackless.tasklet`` and ``stackless.channel`` +classes. Tasklets are similar to microthreads, but don't actually run +in parallel with other microthreads; instead, they synchronize and +exchange data with each other over Channels, and these exchanges +determine which Tasklet run next. + +For usage reference, see the documentation on the `Stackless Python`_ +website. + +Note that Tasklets and Channels are implemented at appplication-level in +`pypy/lib/stackless.py`_ on top of coroutines. You can refer to this +module for more details. + + +Greenlets ++++++++++ + +Greenlets are primitive Tasklets with a lower-level interface and +with exact control over the execution order. For usage reference, +see the greenlets_ documentation. + + +Coroutines +++++++++++ + +Coroutines are similar to greenlets, with a slightly different +interface. One way to see the difference is to note that greenlets put +more emphasis on a tree structure: the various greenlets of a program +form a precise tree, which controls the order of execution. + +The ``stackless.coroutine`` class is instantiated with no argument. +Such a coroutine object is similar to a microthread. When execution is +transferred to it, it starts to execute some Python code. When +execution is transferred away from it, it is temporarily suspended. +When the execution comes back to it, it resumes its execution from the +point where it was suspend. Only one coroutine is actively running at +any given time. + +The class ``stackless.coroutine`` has the following methods and +attributes: + +* ``stackless.coroutine.getcurrent()`` + + Static method returning the currently running coroutine. There is a + so-called "main" coroutine object that represents the "outer" + execution context, where your main program started and where it runs + as long as it does not switch to another coroutine. + +* ``coro.bind(callable, *args, **kwds)`` + + Bind the coroutine so that it will execute ``callable(*args, + **kwds)``. The call is not performed immediately, but only the + first time we call the ``coro.switch()`` method. A coroutine must + be bound before it is switched to. When the coroutine finishes + (because the call to the callable returns), the coroutine exits and + implicitly switches back to its parent coroutine; after this point, + it is possible to bind it again and switch to it again. + +* ``coro.switch()`` + + Suspend the current (caller) coroutine, and resume execution in the + target coroutine ``coro``. + +* ``coro.kill()`` + + Kill ``coro`` by sending an exception to it. (At the moment, the + exception is not visible to app-level, which means that you cannot + catch it, and that ``try: finally:`` clauses are not honored. This + will be fixed in the future.) + + +.. _`Stackless Python`: http://www.stackless.com +.. _greenlets: http://codespeak.net/py/current/doc/greenlet.html + +.. include:: _ref.txt From arigo at codespeak.net Fri Jun 23 15:01:09 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Jun 2006 15:01:09 +0200 (CEST) Subject: [pypy-svn] r29242 - pypy/dist/pypy/doc Message-ID: <20060623130109.44C6010072@code0.codespeak.net> Author: arigo Date: Fri Jun 23 15:01:08 2006 New Revision: 29242 Modified: pypy/dist/pypy/doc/index.txt Log: Link howto-logicobjspace-0.9 from index.txt. Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Fri Jun 23 15:01:08 2006 @@ -78,8 +78,11 @@ Stackless_ and coroutines +`Logic and Constraint`_ programming features + .. _Thunk: getting-started.html#lazily-computed-objects .. _Stackless: stackless.html +.. _`Logic and Constraint`: howto-logicobjspace-0.9.html Status From arigo at codespeak.net Fri Jun 23 15:23:42 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Jun 2006 15:23:42 +0200 (CEST) Subject: [pypy-svn] r29243 - pypy/dist/pypy/doc Message-ID: <20060623132342.168CF10076@code0.codespeak.net> Author: arigo Date: Fri Jun 23 15:23:40 2006 New Revision: 29243 Modified: pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt Log: A Logic paragraph in getting-started. Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Fri Jun 23 15:23:40 2006 @@ -275,6 +275,40 @@ of around 100 lines of code. Since the 0.8.0 release it is even possible to `translate PyPy with the thunk object space`_. +Logic programming ++++++++++++++++++ + +People familiar with logic programming languages will be interested to +know that PyPy optionally supports logic variables and constraint-based +programming. Among the many interesting features of logic programming +-- like unification --, this subsumes the thunk object space by +providing a more extensive way to deal with laziness. + +Try it out:: + + cd pypy/bin + python py.py -o logic --usemodules=_stackless + + >>>> X = newvar() # a logic variable + >>>> bind(X, 42) # give it a value + >>>> assert X / 2 == 21 # then use it + >>>> assert type(X) is int + + >>>> X, Y, Z = newvar(), newvar(), newvar() # three logic vars + >>>> unify({'hello': Y, 'world': Z}, X) # a complex unification + >>>> bind(Y, 5) # then give values to Y + >>>> bind(Z, 7) # ... and Z + >>>> X + {'hello': 5, 'world': 7} + + >>>> bind(Z, 8) + RuntimeError: Cannot bind twice + +Read more about `Logic Object space features`_. + +.. _`Logic Object space features`: howto-logicobjspace-0.9.html + + Running the tests +++++++++++++++++ Modified: pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt ============================================================================== --- pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt (original) +++ pypy/dist/pypy/doc/howto-logicobjspace-0.9.txt Fri Jun 23 15:23:40 2006 @@ -62,7 +62,7 @@ Logic variables can be bound thusly:: bind(X, 42) - assert X / 2 == 24 + assert X / 2 == 21 The single-assignment property is easily checked:: From hpk at codespeak.net Fri Jun 23 15:36:01 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Jun 2006 15:36:01 +0200 (CEST) Subject: [pypy-svn] r29246 - pypy/dist/pypy/doc Message-ID: <20060623133601.3506410079@code0.codespeak.net> Author: hpk Date: Fri Jun 23 15:35:58 2006 New Revision: 29246 Modified: pypy/dist/pypy/doc/translation.txt Log: not worth a commit log Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Fri Jun 23 15:35:58 2006 @@ -213,7 +213,7 @@ the attribute is *read*. If, at some later time, we discover an assignment that forces the annotation about the attribute to be generalized, then all the places that read the attribute so far are -marked as invalid and the annotator will have to restart its analysis +marked as invalid and the annotator will restart its analysis from there. The distinction between instance-level and class-level attributes is From mwh at codespeak.net Fri Jun 23 16:49:36 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 16:49:36 +0200 (CEST) Subject: [pypy-svn] r29252 - pypy/dist/pypy/doc Message-ID: <20060623144936.B10D910069@code0.codespeak.net> Author: mwh Date: Fri Jun 23 16:49:35 2006 New Revision: 29252 Modified: pypy/dist/pypy/doc/translation.txt Log: more stuff for translation.txt, including stuff stolen from the WP07 report draft. Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Fri Jun 23 16:49:35 2006 @@ -139,8 +139,8 @@ inference. It operates on the control flow graphs built by the Flow Object Space. -For a more comprehensive description of the annotation process, see -sections XXX of `Compiling Dynamic Language Implementations`_. +For a more comprehensive description of the annotation process, see section 4 +of `Compiling Dynamic Language Implementations`_. The major goal of the annotator is to "annotate" each variable that appears in a flow graph. An "annotation" describes all the possible @@ -311,14 +311,138 @@ Backend Optimizations --------------------- -Inlining, malloc removal, ... +The point of the backend optimizations are to make the compiled program run +faster. Compared to many parts of the PyPy translator, which are very unlike +a traditional compiler, most of these will be fairly familiar to people who +know how compilers work. + +Function Inlining ++++++++++++++++++ + +To reduce the overhead of the many funtion calls that occur when running the +PyPy interpreter we implemented function inlining. This is an optimization +which takes a flow graph and a callsite and inserts a copy of the flow graph +into the graph of the calling function, renaming occuring variables as +appropriate. This leads to problems if the original function was surrounded by +a ``try: ... except: ...`` guard. In this case inlining is not always +possible. If the called function is not directly raising an exception (but an +exception is potentially raised by further called functions) inlining is safe, +though. + +In addition we also implemented heuristics which function to inline where. For +this purpose we assign every function a "size". This size should roughly +correspond to the increase in code-size which is to be expected should the +function be inlined somewhere. This estimate is the sum of two numbers: for +one every operations is assigned a specific weight, the default being a weight +of one. Some operations are considered to be more effort than others, +e.g. memory allocation and calls others are considered to be no effort at all +(casts...). The size estimate is for one the sum of the weights of all +operations occuring in the graph. This is called the "static instruction +count". The other part of the size estimate of a graph is the "median +execution cost". This is again the sum of the weight of all operations in the +graph, but this time weighted with a guess how often the operation is +executed. To arrive at this guess we assume that at every branch we take both +paths equally often, except for branches that are the end of loops, where the +jump back to the end of the loop is considered more likely. This leads to a +system of equations which can be solved to get approximate weights for all +operations. + +After the size estimate for all function has been determined, functions are +being inlined into their callsites, starting from the smallest functions. Every +time a function is being inlined into another function, the size of the outer +function is recalculated. This is done until the remaining functions all have a +size greater than a predefined limit. + +Malloc Removal +++++++++++++++ + +Since RPython is a garbage collected language there is a lot of heap memory +allocation going on all the time, which would either not occur at all in a more +traditional explicitely managed language or results in an object which dies at +a time known in advance and can thus be explicitely deallocated. For example a +loop of the following form:: + + for i in range(n): + ... + +which simply iterates over all numbers from 0 to n - 1 is equivalent to the +following in Python:: + + l = range(n) + iterator = iter(n) + try: + while 1: + i = iterator.next() + ... + except StopIteration: + pass + +Which means that three memory allocations are executed: The range object, the +iterator for the range object and the StopIteration instance, which ends the +loop. + +After a small bit of inlining all these three objects are never even passed as +arguments to another function and are also not stored into a globally reachable +position. In such a situation the object can be removed (since it would die +anyway after the function returns) and can be replaced by its contained values. + +This pattern (an allocated object never leaves the current function and thus +dies after the function returns) occurs quite often, especially after some +inlining has happened. Therefore we implemented an optimization which +"explodes" objects and thus saves one allocation in this simple (but quite +common) situation. + +Escape Analysis and Stack Allocation +++++++++++++++++++++++++++++++++++++ + +Another technique to reduce the memory allocation penalty is to use stack +allocation for objects that can be proved not to life longer than the stack +frame they have been allocated in. If this is the case it is possible to +allocate the object on the stack. This makes allocation faster, since stack +allocation is just the increase of a pointer, and makes deallocation basically +free since deallocation happens automatically when the function returns. +Therefore we wrote an analysis, which analyses which malloc positions lead to +mallocs which "escape" the current function, e.g. have references to them +stored into a place where they can be accessed by something outside of the +stack of frames starting with the frame where the malloc occured. + +For this we choose a naive, pessimistic approach (XXX reference). The analysis +assumes that an object escapes if one of the following situation occurs: + + * the object is returned + + * the object is raised as an exception + + * the object is stored into a field of any another object + +The algorithm uses abstract interpretation together with a fix point search to +find a solution. + +After using the escape analysis to find malloc sites that don't escape, we +replace the mallocs by stack allocations. This cannot be done in all cases, +namely if the allocated object is variable-sized or if the allocation occurs in +a loop. Both cases should be avoided because they make stack overflows more +likely. Also objects that have a finalizer cannot be allocated on the stack, +since the finalizer might resurrect the object. + +The resulting performance improvements by this optimization were quite +poor. We think that this is due to the fact that the Boehm garbage +collector becomes slower when the stack is bigger, thus compensating +any speed improvement achieved by having faster allocation. We did not +implement stack allocation with any of the other GCs that PyPy can +use. The Stackless Transform ----------------------- -XXX write this bit +(this section is very incomplete currently) -.. or steal it from Carl... +The stackless transform converts functions into a form that knows how +to save the execution point and active variables into a heap structure +and resume execution at that point. This is used to implement +coroutines as an RPython-level feature, which in turn are used to +implement `coroutines, greenlets and tasklets`_ as an application +level feature for the Standard Interpreter. .. _`preparing the graphs for source generation`: @@ -342,16 +466,68 @@ Making Exception Handling Explicit ---------------------------------- -XXX +RPython code is free to use exceptions in much the same way as unrestricted +Python, but the final result is a C program, and C has no concept of +exceptions. The exception transformer implements exception handling in a +similar way to CPython: exceptions are indicated by special return values and +the current exception is stored in a global data structure. + +In a sense the input to the exception transformer is a program in terms of the +lltypesystem_ with exceptions and the output is a program in terms of the bare +lltypesystem. + +.. _lltypesystem: glossary.html#lltypesystem Memory Management Details ------------------------- -Three options: +As well as featuring exceptions, RPython is a garbage collected language; +again, C is not. To square this circle, decisions about memory management +must be made. In keeping with PyPy's approach to flexibility, there is +freedom to change how to do it. There are three approaches implemented today: - reference counting - - Boehm GC - - our own frameworks + - using the `Boehm-Demers-Weiser conservative garbage collector`_ + - using a mark and sweep collector implemented in RPython + +.. _`Boehm-Demers-Weiser conservative garbage collector`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ + +Almost all application-level Python code allocates objects at a very fast +rate; this means that the memory management implementation is critical too the +performance of the PyPy interpreter. That said, work so far has many focussed +on flexibility and robustness, not performance. + +Reference Counting +++++++++++++++++++ + +`Reference counting`_ is a well-known and conceptually simple approach to +memory management. An integer is stored at the front of each heap object that +counts how many references exist to the object, and this count is updated as +references are created and disposed of. + +Reference counting has some well known problems: it can be slow if you make +frequent updates to the reference count, and unless you take special steps, +cycles of objects will leak. We make a little effort to reduce unnecessary +reference counts, but not a great deal, and no efforts to avoid the problems +with cyclic reference counts. It is the worst performing of the three options. + +For these reasons and others, the reference counting option doesn't seem the +most interesting at present. It will be maintained, but probably not +developed further. + +.. _`Reference counting`: http://en.wikipedia.org/wiki/Reference_counting + +Using the B-D-W collector ++++++++++++++++++++++++++ + +C with the addition of the Boehm collector actually has a very similar memory +management model to that of RPython, so the BoehmGCTransformer is quite +simple. The Boehm GC performs somewhat better than the other options currently. + +Using our own collector ++++++++++++++++++++++++ + +XXX Building the Low-Level Database ------------------------------- From mwh at codespeak.net Fri Jun 23 16:54:05 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 16:54:05 +0200 (CEST) Subject: [pypy-svn] r29253 - pypy/dist/pypy/doc Message-ID: <20060623145405.4729F10069@code0.codespeak.net> Author: mwh Date: Fri Jun 23 16:54:03 2006 New Revision: 29253 Modified: pypy/dist/pypy/doc/translation.txt Log: fix rest Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Fri Jun 23 16:54:03 2006 @@ -444,6 +444,8 @@ implement `coroutines, greenlets and tasklets`_ as an application level feature for the Standard Interpreter. +.. _`coroutines, greenlets and tasklets`: stackless.html + .. _`preparing the graphs for source generation`: Preparation for Source Generation From mwh at codespeak.net Fri Jun 23 17:09:12 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 17:09:12 +0200 (CEST) Subject: [pypy-svn] r29254 - pypy/dist/pypy/doc Message-ID: <20060623150912.78F4810072@code0.codespeak.net> Author: mwh Date: Fri Jun 23 17:09:11 2006 New Revision: 29254 Modified: pypy/dist/pypy/doc/getting-started.txt Log: 0.8.0 -> 0.9.0 for getting started Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Fri Jun 23 17:09:11 2006 @@ -27,45 +27,44 @@ .. _gettingpypy: -Downloading & running the PyPy 0.8 release +Downloading & running the PyPy 0.9 release ------------------------------------------- Download one of the following release files and unpack it: -*pypy-0.8* +*pypy-0.9* * download one of - * `pypy-0.8.0.tar.bz2`_ (unix line endings) or - * `pypy-0.8.0.tar.gz`_ (unix line endings) or - * `pypy-0.8.0.zip`_ (windows line-endings) and unpack it + * `pypy-0.9.0.tar.bz2`_ (unix line endings) or + * `pypy-0.9.0.tar.gz`_ (unix line endings) or + * `pypy-0.9.0.zip`_ (windows line-endings) and unpack it * alternatively run - * ``svn co http://codespeak.net/svn/pypy/release/0.8.x pypy-0.8.x`` - (the 0.8 maintenance branch) + * ``svn co http://codespeak.net/svn/pypy/release/0.9.x pypy-0.9.x`` + (the 0.9 maintenance branch) to get it from the subversion repository then change to the -``pypy-0.8.0`` or ``pypy-0.8.x`` directory and execute the following +``pypy-0.9.0`` or ``pypy-0.9.x`` directory and execute the following command line:: python pypy/bin/py.py -This will give you a PyPy prompt, i.e. a very compliant -Python interpreter implemented in Python. PyPy passes -around `90% of CPythons core language regression tests`_. -Because this invocation of PyPy still runs on top of -CPython, it runs around 2000 times slower than the -original CPython. +This will give you a PyPy prompt, i.e. a very compliant Python +interpreter implemented in Python. PyPy passes around `95% of +CPythons core language regression tests`_. Because this invocation of +PyPy still runs on top of CPython, it runs around 2000 times slower +than the original CPython. However, since the 0.7.0 release it is possible to use PyPy to `translate itself to lower level languages`_ after which it runs standalone, is not dependant on CPython anymore and becomes faster. -.. _`90% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ -.. _`pypy-0.8.0.tar.bz2`: http://code2.codespeak.net/download/pypy/pypy-0.8.0.tar.bz2 -.. _`pypy-0.8.0.zip`: http://code2.codespeak.net/download/pypy/pypy-0.8.0.zip -.. _`pypy-0.8.0.tar.gz`: http://code2.codespeak.net/download/pypy/pypy-0.8.0.tar.gz +.. _`95% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ +.. _`pypy-0.9.0.tar.bz2`: http://code.codespeak.net/download/pypy/pypy-0.9.0.tar.bz2 +.. _`pypy-0.9.0.zip`: http://code.codespeak.net/download/pypy/pypy-0.9.0.zip +.. _`pypy-0.9.0.tar.gz`: http://code.codespeak.net/download/pypy/pypy-0.8.0.tar.gz Svn-check out & run the latest PyPy as a two-liner -------------------------------------------------- @@ -281,7 +280,7 @@ People familiar with logic programming languages will be interested to know that PyPy optionally supports logic variables and constraint-based programming. Among the many interesting features of logic programming --- like unification --, this subsumes the thunk object space by +-- like unification -- this subsumes the thunk object space by providing a more extensive way to deal with laziness. Try it out:: @@ -570,12 +569,17 @@ what to translate and how. See ``translate.py -h``. Some of the more interesting options are: - * ``--text``: don't show the flowgraph after the translation is done. This - is useful if you don't have pygame installed. + * ``--text``: don't show the flowgraph after the translation is + done. This is useful if you don't have pygame installed. - * ``--gc=boehm|ref``: choose between using the `Boehm-Demers-Weiser - garbage collector`_ or our own reference counting implementation - (as we have seen Boehm's collector is the default). + * ``--stackless``: this produces a pypy-c that includes features + inspired by `Stackless Python `__. + + * ``--gc=boehm|ref|framework|stacklessgc``: choose between using + the `Boehm-Demers-Weiser garbage collector`_, our reference + counting implementation or our own implementation of a mark and + sweep collector, with two different approaches for finding roots + (as we have seen Boehm's collector is the default). You can also use the translate.py script to try out several smaller programs, e.g. a slightly changed version of Pystone:: From mwh at codespeak.net Fri Jun 23 17:10:15 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 17:10:15 +0200 (CEST) Subject: [pypy-svn] r29255 - pypy/dist/pypy/doc Message-ID: <20060623151015.A961510072@code0.codespeak.net> Author: mwh Date: Fri Jun 23 17:10:14 2006 New Revision: 29255 Modified: pypy/dist/pypy/doc/rtyper.txt Log: wording tweaks Modified: pypy/dist/pypy/doc/rtyper.txt ============================================================================== --- pypy/dist/pypy/doc/rtyper.txt (original) +++ pypy/dist/pypy/doc/rtyper.txt Fri Jun 23 17:10:14 2006 @@ -8,16 +8,16 @@ -------- The RPython Typer is the bridge between the Annotator_ and the low-level code -generators. The annotator computes types (or "annotations") that are -high-level, in the sense that they describe RPython types like lists or -instances of user-defined classes. In general, though, to emit code we need -to represent these high-level annotations into the low-level model of the -target language; for C, this means structures and pointers and arrays. The -Typer both determines the appropriate low-level type for each annotation, and -tries to replace *all* operations in the control flow graphs with one or a few -low-level operations. Just like low-level types, there is only a fairly -restricted set of low-level operations, along the lines of reading or writing -from or to a field of a structure. +generators. The annotations of the Annotator_ are high-level, in the sense +that they describe RPython types like lists or instances of user-defined +classes. In general, though, to emit code we need to represent these +high-level annotations in the low-level model of the target language; for C, +this means structures and pointers and arrays. The Typer both determines the +appropriate low-level type for each annotation, and tries to replace *all* +operations in the control flow graphs with one or a few low-level operations. +Just like low-level types, there is only a fairly restricted set of low-level +operations, along the lines of reading or writing from or to a field of a +structure. In theory, this step is optional; some code generators might be able to read directly the high-level types. However, we expect that case to be the @@ -125,8 +125,8 @@ --------------- The RPython Typer uses a standard low-level model which we believe can -correspond rather directly to various target languages such as C and LLVM_. -This model is implemented in the first part of +correspond rather directly to various target languages such as C and +LLVM_. This model is implemented in the first part of `rpython/lltypesystem/lltype.py`_. The second part of `rpython/lltypesystem/lltype.py`_ is a runnable From mwh at codespeak.net Fri Jun 23 17:18:53 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 17:18:53 +0200 (CEST) Subject: [pypy-svn] r29257 - pypy/dist/pypy/doc Message-ID: <20060623151853.20CD810077@code0.codespeak.net> Author: mwh Date: Fri Jun 23 17:18:51 2006 New Revision: 29257 Modified: pypy/dist/pypy/doc/architecture.txt Log: update the 'infamous/famous status section of architecture.txt' Modified: pypy/dist/pypy/doc/architecture.txt ============================================================================== --- pypy/dist/pypy/doc/architecture.txt (original) +++ pypy/dist/pypy/doc/architecture.txt Fri Jun 23 17:18:51 2006 @@ -249,41 +249,36 @@ more theoretically-oriented paper `Compiling dynamic language implementations`_. -Status of the implementation (Oct 2005) +Status of the implementation (June 2006) ========================================== -With the pypy-0.8.0 release we have integrated our AST compiler with -the rest of PyPy. The compiler gets translated with the rest to a -static self-contained version of our `standard interpreter`_. Like -with 0.7.0 this version is `very compliant`_ to CPython 2.4.1 but you -cannot run many existing programs on it yet because we are -still missing a number of C-modules like socket or support for process -creation. +The work leading up to the pypy-0.9.0 release has concentrated on the +features of the translation. + +We can now produce a pypy-c that `has the majority of the features`_ +of `Stackless Python`_. We have integrated the mark and sweep garbage +collector written in RPython by Carl Friedrich as part of Google's +Summer of Code 2005 with the translation machinery, and can produce a +pypy-c that uses it for memory management. + +.. _`has the majority of the features`: stackless.html +.. _`Stackless Python`: http://www.stackless.com/ The self-contained PyPy version (single-threaded and using the -`Boehm-Demers-Weiser garbage collector`_) now runs around 10-20 times -slower than CPython, i.e. around 10 times faster than 0.7.0. -This is the result of optimizing, adding short -cuts for some common paths in our interpreter and adding relatively -straightforward optimization transforms to our tool chain, like inlining -paired with simple escape analysis to remove unnecessary heap allocations. -We still have some way to go, and we still expect most of our speed -will come from our Just-In-Time compiler work, which we have barely started -at the moment. - -With the 0.8.0 release the "thunk" object space can also be translated -(see `getting started`_), obtaining a self-contained version of PyPy -with its features (and some speed degradation), show-casing at a small -scale how our whole tool-chain supports flexibility from the interpreter -written in Python to the resulting self-contained executable. +`Boehm-Demers-Weiser garbage collector`_) now runs around 4-5 times +slower than CPython, i.e. around 3 times faster than 0.8.0. + +We have improved our CPython compatibility still further, and now pass +around 95% of CPython's core tests, the main improvement over 0.8.0 +being the implementation of the _weakref module. Our rather complete and Python 2.4-compliant interpreter consists of about 30,000-50,000 lines of code (depending on the way you count code borrowed and adapted from other sources), with another 14,000 lines of unit tests. If we include the tools, the parts related to code analysis and generation, and the -standard library modules ported from C, PyPy is now 138,000 -lines of code and 32,000 lines of tests. Refer to +standard library modules ported from C, PyPy is now 230,000 +lines of code including 62,000 lines of tests. Refer to the `statistics web page`_ for more detailed information. .. _`statistics web page`: http://codespeak.net/~hpk/pypy-stat/ From mwh at codespeak.net Fri Jun 23 17:23:44 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 17:23:44 +0200 (CEST) Subject: [pypy-svn] r29258 - pypy/dist/pypy/doc Message-ID: <20060623152344.E54B710072@code0.codespeak.net> Author: mwh Date: Fri Jun 23 17:23:43 2006 New Revision: 29258 Modified: pypy/dist/pypy/doc/architecture.txt Log: remove a now incorrect line from architecture.txt Modified: pypy/dist/pypy/doc/architecture.txt ============================================================================== --- pypy/dist/pypy/doc/architecture.txt (original) +++ pypy/dist/pypy/doc/architecture.txt Fri Jun 23 17:23:43 2006 @@ -230,15 +230,12 @@ The actual low-level code (and, in fact, also other high-level code) is emitted by "visiting" the type-annotated flow graph. Currently we have -a C-producing backend, and an LLVM_-producing backend. The former also -accepts non-annotated or partially-annotated graphs, which allow us to -test it on a larger class of programs than what the Annotator can (or -ever will) fully process. - -The newest piece of this puzzle is the -*Typer*, which inputs the high-level types inferred by the Annotator and -uses them to modify the flow graph in-place to replace its operations with -low-level ones, directly manipulating C-like values and data structures. +a C-producing backend, and an LLVM_-producing backend. + +The newest piece of this puzzle is the *Typer*, which inputs the +high-level types inferred by the Annotator and uses them to modify the +flow graph in-place to replace its operations with low-level ones, +directly manipulating C-like values and data structures. Here is an overview of the translation process (`PDF color version`_): From arigo at codespeak.net Fri Jun 23 17:43:13 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Jun 2006 17:43:13 +0200 (CEST) Subject: [pypy-svn] r29259 - pypy/dist/pypy/doc Message-ID: <20060623154313.D58CA10077@code0.codespeak.net> Author: arigo Date: Fri Jun 23 17:43:13 2006 New Revision: 29259 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/rtyper.txt Log: Typos, added section numbers. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Fri Jun 23 17:43:13 2006 @@ -48,6 +48,7 @@ .. _`objspace/trace.py`: .. _`pypy/objspace/trace.py`: ../../pypy/objspace/trace.py .. _`pypy/rpython`: +.. _`pypy/rpython/`: .. _`rpython/`: ../../pypy/rpython .. _`pypy/rpython/extfunctable.py`: ../../pypy/rpython/extfunctable.py .. _`pypy/rpython/lltypesystem/lltype.py`: Modified: pypy/dist/pypy/doc/rtyper.txt ============================================================================== --- pypy/dist/pypy/doc/rtyper.txt (original) +++ pypy/dist/pypy/doc/rtyper.txt Fri Jun 23 17:43:13 2006 @@ -1,7 +1,10 @@ The RPython Typer ================= -http://codespeak.net/pypy/dist/pypy/rpython/ +.. contents:: +.. sectnum:: + +The RPython Typer lives in the directory `pypy/rpython/`_. Overview @@ -710,12 +713,12 @@ The LLInterpreter ----------------- -The LLInterpreter is a simply piece of code that is able to interpret flow +The LLInterpreter is a simple piece of code that is able to interpret flow graphs. This is very useful for testing purposes, especially if you work on the `RPython Typer`_. The most useful interface for it is the ``interpret`` function in the file `pypy/rpython/test/test_llinterp.py`_. It takes as arguments a function and a list of arguments with which the function is -supposed to be called. Then it generates the flow graph, annotates is +supposed to be called. Then it generates the flow graph, annotates it according to the types of the arguments you passed to it and runs the LLInterpreter on the result. Example:: From stephan at codespeak.net Fri Jun 23 17:48:24 2006 From: stephan at codespeak.net (stephan at codespeak.net) Date: Fri, 23 Jun 2006 17:48:24 +0200 (CEST) Subject: [pypy-svn] r29260 - in pypy/dist/pypy: doc lib Message-ID: <20060623154824.7BC3610079@code0.codespeak.net> Author: stephan Date: Fri Jun 23 17:48:22 2006 New Revision: 29260 Modified: pypy/dist/pypy/doc/stackless.txt pypy/dist/pypy/lib/stackless.py Log: added a bit stackless documentation Modified: pypy/dist/pypy/doc/stackless.txt ============================================================================== --- pypy/dist/pypy/doc/stackless.txt (original) +++ pypy/dist/pypy/doc/stackless.txt Fri Jun 23 17:48:22 2006 @@ -62,10 +62,41 @@ For usage reference, see the documentation on the `Stackless Python`_ website. -Note that Tasklets and Channels are implemented at appplication-level in +Note that Tasklets and Channels are implemented at application-level in `pypy/lib/stackless.py`_ on top of coroutines. You can refer to this -module for more details. +module for more details and the actual documentation. +The current ``stackless`` module (pypy 0.9) is not yet feature complete and +will probably fail in spectacular ways. Just be warned. + +There is no support for stackless in a threaded environment whatsoever. + +The stackless.py code tries to resemble the stackless C code as much +as possible. This makes the code somewhat unpythonic. + +Bird eyes view of tasklets and channels +---------------------------------------- + +tasklets are a bit like threads: they capsulate a function in such a way that +they can be suspended/restarted any time. Unlike threads, they won't +run concurrently, but must be quite cooperative. When using stackless +features, it is vitaly important that no action is performed that blocks +everything else. + +Communication between tasklets is done via channels. + +There are three ways for a tasklet to give up control: + +1. call ``schedule()`` +2. send something over a channel +3. receive something from a channel + +A (living) tasklet can be either running, or wait to get scheduled, or be +blocked by a channel. + +Scheduling is done strictly round-robin. A blocked tasklet is removed from +the scheduling queue and a blocked tasklet will be reinserted into the +queue when it becomes unblocked. Greenlets +++++++++ Modified: pypy/dist/pypy/lib/stackless.py ============================================================================== --- pypy/dist/pypy/lib/stackless.py (original) +++ pypy/dist/pypy/lib/stackless.py Fri Jun 23 17:48:22 2006 @@ -30,34 +30,37 @@ class TaskletExit(Exception):pass def SETNEXT(obj, val): + "this function just makes debugging a bit easier :-)" obj.next = val def SETPREV(obj, val): + "just for debugging" obj.prev = val def SETNONE(obj): + "just for debugging" obj.prev = obj.next = None def SWAPVAL(task1, task2): + "just for debugging" assert task1 is not None assert task2 is not None task1.tempval, task2.tempval = task2.tempval, task1.tempval def SETVAL(task, val): + "just for debugging" assert task is not None task.tempval = val -last_thread_id = 0 +last_task_id = 0 def restore_exception(etype, value, stack): """until I find out how to restore an exception on python level""" #sys.excepthook(etype, value, stack) raise etype(value) -def _return_main(): - return main_tasklet - class TaskletProxy(object): + """TaskletProxy is needed to give the main_coroutine tasklet behaviour""" def __init__(self, coro): self.alive = True self.atomic = False @@ -72,7 +75,7 @@ self.recursion_depth = 0 self.restorable = False self.scheduled = False - self.thread_id = 0 + self.task_id = 0 self.tempval = None self._coro = coro @@ -85,7 +88,7 @@ return getattr(self._coro,attr) def __reduce__(self): - return _return_main, () + return getmain, () class bomb(object): """ @@ -136,16 +139,20 @@ For inquiry only, use the phrase ret = enable_softswitch(0); enable_softswitch(ret) By default, soft switching is enabled. + + This is not implemented yet!!!! """ pass -def get_thread_info(thread_id): +def get_thread_info(task_id): """ - get_thread_info(thread_id) -- return a 3-tuple of the thread's + get_thread_info(task_id) -- return a 3-tuple of the thread's main tasklet, current tasklet and runcount. To obtain a list of all thread infos, use map (stackless.get_thread_info, stackless.threads) + + This is not implemented yet!!!! """ pass @@ -201,6 +208,8 @@ It is inserted back after the function stops, right before the tasklet that caused a timeout, if any. If an exception occours, it will be passed to the main tasklet. + + Please note that the 'timeout' feature is not yet implemented """ me = scheduler.current_remove() if me is not main_tasklet: @@ -261,13 +270,13 @@ __slots__ = ['alive','atomic','blocked','block_trap','frame', 'ignore_nesting','is_current','is_main', 'nesting_level','next','paused','prev','recursion_depth', - 'restorable','scheduled','tempval','thread_id'] + 'restorable','scheduled','tempval','task_id'] def __new__(cls, func=None): return super(tasklet,cls).__new__(cls) def __init__(self, func=None): - global last_thread_id + global last_task_id super(tasklet,self).__init__() self.alive = False self.atomic = False @@ -283,8 +292,8 @@ self.recursion_depth = 0 self.restorable = False self.scheduled = False - last_thread_id += 1 - self.thread_id = last_thread_id + last_task_id += 1 + self.task_id = last_task_id self.tempval = None if func is not None: self.bind(func) @@ -296,15 +305,15 @@ def __repr__(self): next = None if self.next is not None: - next = self.next.thread_id + next = self.next.task_id prev = None if self.prev is not None: - prev = self.prev.thread_id + prev = self.prev.task_id if self.blocked: bs = 'b' else: bs = '-' - return 'T%s(%s) (%s, %s)' % (self.thread_id, bs, next, prev) + return 'T%s(%s) (%s, %s)' % (self.task_id, bs, next, prev) __str__ = __repr__ @@ -395,7 +404,7 @@ def set_ignore_nesting(self, flag): """ t.set_ignore_nesting(flag) -- set tasklet ignore_nesting status and - return current one. If set, the tasklet may be be auto-scheduled, + return current one. If set, the tasklet may be auto-scheduled, even if its nesting_level is > 0. This flag makes sense if you know that nested interpreter levels are safe for auto-scheduling. This is on your own risk, handle with care! @@ -403,13 +412,17 @@ tmp = t.set_ignore_nesting(1) # do critical stuff t.set_ignore_nesting(tmp) + + Please note that this piece of code does effectively nothing. """ tmpval = self.ignore_nesting self.ignore_nesting = flag return tmpval def finished(self, excinfo): - #print 'finished(%s)' % excinfo + """called, when coroutine is finished. This gives the tasklet + a chance to clean up after himself.""" + if self.alive: self.alive = False if self.next is not self: @@ -469,10 +482,10 @@ self.preference = -1 self.next = self.prev = self self.schedule_all = False - self.thread_id = -2 + self.task_id = -2 def __str__(self): - parts = ['%s' % x.thread_id for x in self._content()] + parts = ['%s' % x.task_id for x in self._content()] return 'channel(' + str(self.balance) + '): ['+' -> '.join(parts)+']' def _get_closed(self): @@ -654,6 +667,10 @@ self.send(item) class Scheduler(object): + """The singleton Scheduler. Provides mostly scheduling convenience + functions. In normal circumstances, scheduler._head point the + current running tasklet. _head and current_tasklet might be + out of sync just before the actual task switch takes place.""" def __init__(self): self._set_head(getcurrent()) @@ -675,6 +692,7 @@ return len(self._content()) def _content(self): + "convenience method to get the tasklets that are in the queue" visited = set() items = [] next = self._head @@ -686,9 +704,9 @@ return items def __str__(self): - parts = ['%s' % x.thread_id for x in self._content()] + parts = ['%s' % x.task_id for x in self._content()] if self._head is not self: - currid = self._head.thread_id + currid = self._head.task_id else: currid = -1 return 'Scheduler: [' + ' -> '.join(parts) + ']' @@ -726,9 +744,11 @@ return self.remove_task(self._head) def current_insert(self, task): + "insert 'task' at end of running queue" self._chain_insert(task) def current_insert_after(self, task): + "insert 'task' just after the current one" if self._head is not None: curr = self._head self._set_head(curr.next) @@ -738,6 +758,7 @@ self.current_insert(task) def current_remove(self): + "remove current tasklet from queue" return self._chain_remove() def channel_remove_slow(self, task): From mwh at codespeak.net Fri Jun 23 17:49:10 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 17:49:10 +0200 (CEST) Subject: [pypy-svn] r29261 - pypy/dist/pypy/doc Message-ID: <20060623154910.250B510079@code0.codespeak.net> Author: mwh Date: Fri Jun 23 17:49:09 2006 New Revision: 29261 Modified: pypy/dist/pypy/doc/release-0.9.0.txt Log: flesh out release announcement Modified: pypy/dist/pypy/doc/release-0.9.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-0.9.0.txt (original) +++ pypy/dist/pypy/doc/release-0.9.0.txt Fri Jun 23 17:49:09 2006 @@ -1,4 +1,4 @@ -pypy-0.9.0: +pypy-0.9.0: improved stackless, new extension compiler ============================================================== The PyPy development team has been busy working and we've now packaged @@ -7,35 +7,59 @@ The highlights of this fourth release of PyPy are: - - stackless - - - extended app-level interface - - tasklet pickling - - - ext-compiler - - - rctypes - - - framework gcs - - - __del__/weakref/__subclasses__ - - - logic space preview - - - high level backends preview - - - bugfixes, better performance - - - 2.5-3x times faster than 0.8 (on richards and pystone). - - pypy-c can complete CPython's test suite - - - testing refinements: preliminary doctest support, daily html reports - - - some other stuff - - - some 2.5 features? - -XXX clearly this needs expansion +**Improved implementation of the "stackless" features** + We now support the larger part of the interface of the original + Stackless Python -- see http://www.stackless.com for more. A + significant part of this is the pickling and unpickling of a running + tasklet. + + These features, especially the pickling, can be considered to be a + "technology preview" -- they work, but for example the error handling + is a little patchy in places. + +**ext-compiler** + The "extension compiler" is a new way of writing a C extension for + CPython and PyPy at the same time. For more information, see its + documentation: http://codespeak.net/pypy/dist/pypy/doc/extcompiler.html + +**rctypes** + Most useful in combination with the ext-compiler is the fact that our + translation framework can translate code that uses the + standard-in-Python-2.5 ctypes module. See its documentation for more: + http://codespeak.net/pypy/dist/pypy/doc/rctypes.html + +**framework GCs** + PyPy's interpreter can now be compiled to use a garbage collector + written in RPython. This added control over PyPy's execution makes the + implementation of new and interesting features possible, apart from + being a significant achievement in its own right. + +**__del__/weakref/__subclasses__** + The PyPy interpreter's compatibility with CPython continues improves: + now we support __del__ methods, the __subclasses__ method on types and + weak references. We now pass around 95% of CPython's core tests. + +**logic space preview** + This release contains the first version of the logic object space, + which will add logical variables to Python. See it's docs for more: + http://codespeak.net/pypy/dist/pypy/doc/howto-logicobjspace-0.9.html + +**high level backends preview** + This release contains the first versions of new backends targeting high + level languages such as Squeak and .NET/CLI and updated versions of the + JavaScript and Common Lisp backends. They can't compile the PyPy + interpreter yet, but they're getting there... + +**bugfixes, better performance** + As you would expect, performance continues to improve and bugs continue + to be fixed. The performance of the translated PyPy interpreter is + 2.5-3x times faster than 0.8 (on richards and pystone), and is now + stable enough to be able to run CPython's test suite to the end. + +**testing refinements** + py.test, our testing tool, now has preliminary support for doctests. + We now run all our tests every night, and you can see the summary at: + http://snake.cs.uni-duesseldorf.de/pypytest/summary.html What is PyPy (about)? ------------------------------------------------ @@ -77,7 +101,9 @@ Ongoing work and near term goals --------------------------------- -XXX +The Just-in-Time compiler and other performance improvements will be one of +the main topics of the next few months' work, along with finishing the +logic object space. Project Details --------------- From mwh at codespeak.net Fri Jun 23 18:00:32 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 18:00:32 +0200 (CEST) Subject: [pypy-svn] r29262 - pypy/dist/pypy/doc Message-ID: <20060623160032.7A67610072@code0.codespeak.net> Author: mwh Date: Fri Jun 23 18:00:31 2006 New Revision: 29262 Modified: pypy/dist/pypy/doc/stackless.txt Log: be marginally less pessimistic :-) Modified: pypy/dist/pypy/doc/stackless.txt ============================================================================== --- pypy/dist/pypy/doc/stackless.txt (original) +++ pypy/dist/pypy/doc/stackless.txt Fri Jun 23 18:00:31 2006 @@ -67,7 +67,7 @@ module for more details and the actual documentation. The current ``stackless`` module (pypy 0.9) is not yet feature complete and -will probably fail in spectacular ways. Just be warned. +will may fail in spectacular ways. Just be warned. There is no support for stackless in a threaded environment whatsoever. From mwh at codespeak.net Fri Jun 23 18:04:17 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 18:04:17 +0200 (CEST) Subject: [pypy-svn] r29263 - pypy/dist/pypy/doc Message-ID: <20060623160417.AED731007B@code0.codespeak.net> Author: mwh Date: Fri Jun 23 18:04:16 2006 New Revision: 29263 Modified: pypy/dist/pypy/doc/stackless.txt Log: MORE GRAMMAR LIKE Modified: pypy/dist/pypy/doc/stackless.txt ============================================================================== --- pypy/dist/pypy/doc/stackless.txt (original) +++ pypy/dist/pypy/doc/stackless.txt Fri Jun 23 18:04:16 2006 @@ -67,7 +67,7 @@ module for more details and the actual documentation. The current ``stackless`` module (pypy 0.9) is not yet feature complete and -will may fail in spectacular ways. Just be warned. +may fail in spectacular ways. Just be warned. There is no support for stackless in a threaded environment whatsoever. From mwh at codespeak.net Fri Jun 23 18:14:50 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 18:14:50 +0200 (CEST) Subject: [pypy-svn] r29264 - pypy/dist/pypy/doc Message-ID: <20060623161450.7836310069@code0.codespeak.net> Author: mwh Date: Fri Jun 23 18:14:49 2006 New Revision: 29264 Modified: pypy/dist/pypy/doc/release-0.9.0.txt Log: the stackless features are new. :-) Modified: pypy/dist/pypy/doc/release-0.9.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-0.9.0.txt (original) +++ pypy/dist/pypy/doc/release-0.9.0.txt Fri Jun 23 18:14:49 2006 @@ -1,4 +1,4 @@ -pypy-0.9.0: improved stackless, new extension compiler +pypy-0.9.0: stackless, new extension compiler ============================================================== The PyPy development team has been busy working and we've now packaged @@ -7,7 +7,7 @@ The highlights of this fourth release of PyPy are: -**Improved implementation of the "stackless" features** +**implementation of "stackless" features** We now support the larger part of the interface of the original Stackless Python -- see http://www.stackless.com for more. A significant part of this is the pickling and unpickling of a running From mwh at codespeak.net Fri Jun 23 18:21:20 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 18:21:20 +0200 (CEST) Subject: [pypy-svn] r29265 - pypy/release/0.9.x Message-ID: <20060623162120.01BA010069@code0.codespeak.net> Author: mwh Date: Fri Jun 23 18:21:19 2006 New Revision: 29265 Added: pypy/release/0.9.x/ - copied from r29264, pypy/dist/ Log: finally, only 2.whatever days late, make the release branch From mwh at codespeak.net Fri Jun 23 18:35:50 2006 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jun 2006 18:35:50 +0200 (CEST) Subject: [pypy-svn] r29266 - pypy/release/0.9.x/pypy/translator/c/test Message-ID: <20060623163550.1A1C710069@code0.codespeak.net> Author: mwh Date: Fri Jun 23 18:35:48 2006 New Revision: 29266 Modified: pypy/release/0.9.x/pypy/translator/c/test/test_wrapping.py Log: skip test wrapping on the release branch Modified: pypy/release/0.9.x/pypy/translator/c/test/test_wrapping.py ============================================================================== --- pypy/release/0.9.x/pypy/translator/c/test/test_wrapping.py (original) +++ pypy/release/0.9.x/pypy/translator/c/test/test_wrapping.py Fri Jun 23 18:35:48 2006 @@ -2,6 +2,10 @@ wrap, unwrap, __init__, ExtCompiler) +import py + +py.test.skip("segfaults sometimes") + import sys, types P = False # debug printing @@ -160,4 +164,4 @@ if __name__=='__main__': test_expose_classes() - \ No newline at end of file + From arigo at codespeak.net Fri Jun 23 18:37:15 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Jun 2006 18:37:15 +0200 (CEST) Subject: [pypy-svn] r29267 - pypy/dist/pypy/doc Message-ID: <20060623163715.0CB9D10069@code0.codespeak.net> Author: arigo Date: Fri Jun 23 18:37:15 2006 New Revision: 29267 Modified: pypy/dist/pypy/doc/release-0.9.0.txt Log: Typo. Modified: pypy/dist/pypy/doc/release-0.9.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-0.9.0.txt (original) +++ pypy/dist/pypy/doc/release-0.9.0.txt Fri Jun 23 18:37:15 2006 @@ -41,7 +41,7 @@ **logic space preview** This release contains the first version of the logic object space, - which will add logical variables to Python. See it's docs for more: + which will add logical variables to Python. See its docs for more: http://codespeak.net/pypy/dist/pypy/doc/howto-logicobjspace-0.9.html **high level backends preview** From antocuni at codespeak.net Fri Jun 23 18:38:22 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 23 Jun 2006 18:38:22 +0200 (CEST) Subject: [pypy-svn] r29268 - pypy/dist/pypy/translator/cli Message-ID: <20060623163822.141ED10069@code0.codespeak.net> Author: antocuni Date: Fri Jun 23 18:38:17 2006 New Revision: 29268 Modified: pypy/dist/pypy/translator/cli/sdk.py Log: Python-2.3-ify Modified: pypy/dist/pypy/translator/cli/sdk.py ============================================================================== --- pypy/dist/pypy/translator/cli/sdk.py (original) +++ pypy/dist/pypy/translator/cli/sdk.py Fri Jun 23 18:38:17 2006 @@ -2,27 +2,27 @@ import py class AbstractSDK(object): - @classmethod def _check_helper(cls, helper): try: py.path.local.sysfind(helper) return helper except py.error.ENOENT: py.test.skip("%s is not on your path." % helper) + _check_helper = classmethod(_check_helper) - @classmethod def runtime(cls): for item in cls.RUNTIME: cls._check_helper(item) return cls.RUNTIME + runtime = classmethod(runtime) - @classmethod def ilasm(cls): return cls._check_helper(cls.ILASM) + ilasm = classmethod(ilasm) - @classmethod def csc(cls): return cls._check_helper(cls.CSC) + csc = classmethod(csc) class MicrosoftSDK(AbstractSDK): RUNTIME = [] From arigo at codespeak.net Fri Jun 23 18:41:33 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Jun 2006 18:41:33 +0200 (CEST) Subject: [pypy-svn] r29269 - pypy/release/0.9.x/pypy/doc Message-ID: <20060623164133.31DC010072@code0.codespeak.net> Author: arigo Date: Fri Jun 23 18:41:32 2006 New Revision: 29269 Modified: pypy/release/0.9.x/pypy/doc/release-0.9.0.txt Log: Typo (backport). Modified: pypy/release/0.9.x/pypy/doc/release-0.9.0.txt ============================================================================== --- pypy/release/0.9.x/pypy/doc/release-0.9.0.txt (original) +++ pypy/release/0.9.x/pypy/doc/release-0.9.0.txt Fri Jun 23 18:41:32 2006 @@ -41,7 +41,7 @@ **logic space preview** This release contains the first version of the logic object space, - which will add logical variables to Python. See it's docs for more: + which will add logical variables to Python. See its docs for more: http://codespeak.net/pypy/dist/pypy/doc/howto-logicobjspace-0.9.html **high level backends preview** From antocuni at codespeak.net Fri Jun 23 19:27:31 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 23 Jun 2006 19:27:31 +0200 (CEST) Subject: [pypy-svn] r29270 - pypy/dist/pypy/translator/cli/test Message-ID: <20060623172731.89CB610070@code0.codespeak.net> Author: antocuni Date: Fri Jun 23 19:27:26 2006 New Revision: 29270 Modified: pypy/dist/pypy/translator/cli/test/runtest.py Log: Windows compatibilty (the strip() serves to remove the trailing \r\n). Modified: pypy/dist/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/runtest.py (original) +++ pypy/dist/pypy/translator/cli/test/runtest.py Fri Jun 23 19:27:26 2006 @@ -167,6 +167,9 @@ if self._exe is None: py.test.skip("Compilation disabled") + if getoption('norun'): + py.test.skip("Execution disabled") + arglist = SDK.runtime() + [self._exe] + map(str, args) env = os.environ.copy() env['LANG'] = 'C' @@ -176,7 +179,7 @@ retval = mono.wait() assert retval == 0, stderr - res = eval(stdout) + res = eval(stdout.strip()) if isinstance(res, tuple): res = StructTuple(res) # so tests can access tuple elements with .item0, .item1, etc. elif isinstance(res, list): From hpk at codespeak.net Fri Jun 23 19:41:59 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Jun 2006 19:41:59 +0200 (CEST) Subject: [pypy-svn] r29271 - pypy/release/0.9.x/pypy/translator/cli/test Message-ID: <20060623174159.400A910075@code0.codespeak.net> Author: hpk Date: Fri Jun 23 19:41:55 2006 New Revision: 29271 Modified: pypy/release/0.9.x/pypy/translator/cli/test/runtest.py Log: port rev-29270 of dist (Anto) Modified: pypy/release/0.9.x/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/release/0.9.x/pypy/translator/cli/test/runtest.py (original) +++ pypy/release/0.9.x/pypy/translator/cli/test/runtest.py Fri Jun 23 19:41:55 2006 @@ -167,6 +167,9 @@ if self._exe is None: py.test.skip("Compilation disabled") + if getoption('norun'): + py.test.skip("Execution disabled") + arglist = SDK.runtime() + [self._exe] + map(str, args) env = os.environ.copy() env['LANG'] = 'C' @@ -176,7 +179,7 @@ retval = mono.wait() assert retval == 0, stderr - res = eval(stdout) + res = eval(stdout.strip()) if isinstance(res, tuple): res = StructTuple(res) # so tests can access tuple elements with .item0, .item1, etc. elif isinstance(res, list): From hpk at codespeak.net Fri Jun 23 19:43:56 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Jun 2006 19:43:56 +0200 (CEST) Subject: [pypy-svn] r29272 - pypy/release/0.9.x/pypy/translator/cli Message-ID: <20060623174356.15AD810075@code0.codespeak.net> Author: hpk Date: Fri Jun 23 19:43:55 2006 New Revision: 29272 Modified: pypy/release/0.9.x/pypy/translator/cli/sdk.py Log: port rev-29268 of dist (anto) Modified: pypy/release/0.9.x/pypy/translator/cli/sdk.py ============================================================================== --- pypy/release/0.9.x/pypy/translator/cli/sdk.py (original) +++ pypy/release/0.9.x/pypy/translator/cli/sdk.py Fri Jun 23 19:43:55 2006 @@ -2,27 +2,27 @@ import py class AbstractSDK(object): - @classmethod def _check_helper(cls, helper): try: py.path.local.sysfind(helper) return helper except py.error.ENOENT: py.test.skip("%s is not on your path." % helper) + _check_helper = classmethod(_check_helper) - @classmethod def runtime(cls): for item in cls.RUNTIME: cls._check_helper(item) return cls.RUNTIME + runtime = classmethod(runtime) - @classmethod def ilasm(cls): return cls._check_helper(cls.ILASM) + ilasm = classmethod(ilasm) - @classmethod def csc(cls): return cls._check_helper(cls.CSC) + csc = classmethod(csc) class MicrosoftSDK(AbstractSDK): RUNTIME = [] From antocuni at codespeak.net Fri Jun 23 20:29:14 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 23 Jun 2006 20:29:14 +0200 (CEST) Subject: [pypy-svn] r29273 - pypy/dist/pypy/translator/cli Message-ID: <20060623182914.6A88B10075@code0.codespeak.net> Author: antocuni Date: Fri Jun 23 20:29:03 2006 New Revision: 29273 Modified: pypy/dist/pypy/translator/cli/conftest.py pypy/dist/pypy/translator/cli/gencli.py pypy/dist/pypy/translator/cli/sdk.py Log: Added two new options: * --verify run peverify on the compiled code, and fails if the code it's not verifiable. It works only under windows, because mono doens't provide peverify * --norun prevent compiled code to be executed. Useful in conjunction with --verify. Modified: pypy/dist/pypy/translator/cli/conftest.py ============================================================================== --- pypy/dist/pypy/translator/cli/conftest.py (original) +++ pypy/dist/pypy/translator/cli/conftest.py Fri Jun 23 20:29:03 2006 @@ -18,6 +18,14 @@ help="don't stop on warning. The generated IL code could not compile"), Option('--nowrap', action="store_true", dest="nowrap", default=False, - help="don't wrap exceptions but let them to flow out of the entry point") + help="don't wrap exceptions but let them to flow out of the entry point"), + + Option('--verify', action="store_true", dest="verify", default=False, + help="check that compiled executables are verifiable"), + + Option('--norun', action='store_true', dest="norun", default=False, + help="don't run the compiled executable"), ) + + Modified: pypy/dist/pypy/translator/cli/gencli.py ============================================================================== --- pypy/dist/pypy/translator/cli/gencli.py (original) +++ pypy/dist/pypy/translator/cli/gencli.py Fri Jun 23 20:29:03 2006 @@ -97,8 +97,17 @@ ilasm = SDK.ilasm() tmpfile = self.tmpfile.strpath - proc = subprocess.Popen([ilasm, tmpfile], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + self._exec_helper(ilasm, tmpfile, 'ilasm failed to assemble (%s):\n%s\n%s') + + exefile = tmpfile.replace('.il', '.exe') + if getoption('verify'): + peverify = SDK.peverify() + self._exec_helper(peverify, exefile, 'peverify failed to verify (%s):\n%s\n%s') + return exefile + + def _exec_helper(self, helper, filename, msg): + proc = subprocess.Popen([helper, filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = proc.communicate() retval = proc.wait() - assert retval == 0, 'ilasm failed to assemble (%s):\n%s\n%s' % (tmpfile, stdout, stderr) - return tmpfile.replace('.il', '.exe') + assert retval == 0, msg % (filename, stdout, stderr) + Modified: pypy/dist/pypy/translator/cli/sdk.py ============================================================================== --- pypy/dist/pypy/translator/cli/sdk.py (original) +++ pypy/dist/pypy/translator/cli/sdk.py Fri Jun 23 20:29:03 2006 @@ -24,15 +24,21 @@ return cls._check_helper(cls.CSC) csc = classmethod(csc) + def peverify(cls): + return cls._check_helper(cls.PEVERIFY) + peverify = classmethod(peverify) + class MicrosoftSDK(AbstractSDK): RUNTIME = [] ILASM = 'ilasm' CSC = 'csc' + PEVERIFY = 'peverify' class MonoSDK(AbstractSDK): RUNTIME = ['mono'] ILASM = 'ilasm2' CSC = 'gmcs' + PEVERIFY = 'peverify' # it's not part of mono, but we get a meaningful skip message if platform.system() == 'Windows': SDK = MicrosoftSDK From antocuni at codespeak.net Fri Jun 23 20:54:37 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 23 Jun 2006 20:54:37 +0200 (CEST) Subject: [pypy-svn] r29274 - pypy/dist/pypy/translator/cli/test Message-ID: <20060623185437.4C17510075@code0.codespeak.net> Author: antocuni Date: Fri Jun 23 20:54:28 2006 New Revision: 29274 Modified: pypy/dist/pypy/translator/cli/test/runtest.py Log: Move the .try above to make the verifier happy. Modified: pypy/dist/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/runtest.py (original) +++ pypy/dist/pypy/translator/cli/test/runtest.py Fri Jun 23 20:54:28 2006 @@ -59,6 +59,9 @@ def render(self, ilasm): ilasm.begin_function('main', [('string[]', 'argv')], 'void', True, 'static') + if self.wrap_exceptions: + ilasm.begin_try() + # convert string arguments to their true type for i, arg in enumerate(self.graph.getargs()): ilasm.opcode('ldarg.0') @@ -69,9 +72,6 @@ (arg_type, self.__convert_method(arg_type))) # call the function and convert the result to a string containing a valid python expression - if self.wrap_exceptions: - ilasm.begin_try() - ilasm.call(cts.graph_to_signature(self.graph)) TYPE = self.graph.getreturnvar().concretetype format_object(TYPE, ilasm) From arigo at codespeak.net Fri Jun 23 21:24:30 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Jun 2006 21:24:30 +0200 (CEST) Subject: [pypy-svn] r29275 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20060623192430.2A62E10072@code0.codespeak.net> Author: arigo Date: Fri Jun 23 21:24:27 2006 New Revision: 29275 Added: pypy/dist/lib-python/modified-2.4.1/test/test_scope.py - copied, changed from r29256, pypy/dist/lib-python/2.4.1/test/test_scope.py Modified: pypy/dist/lib-python/modified-2.4.1/test/test_class.py Log: Add a couple of missing gc.collect() in the CPython tests. (backport candidate) Modified: pypy/dist/lib-python/modified-2.4.1/test/test_class.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_class.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_class.py Fri Jun 23 21:24:27 2006 @@ -244,6 +244,9 @@ if sys.platform[:4] == 'java': import java java.lang.System.gc() +else: + import gc + gc.collect() # Interfering tests From arigo at codespeak.net Fri Jun 23 21:26:59 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Jun 2006 21:26:59 +0200 (CEST) Subject: [pypy-svn] r29276 - pypy/dist/lib-python Message-ID: <20060623192659.D295A10072@code0.codespeak.net> Author: arigo Date: Fri Jun 23 21:26:59 2006 New Revision: 29276 Modified: pypy/dist/lib-python/conftest.py Log: Skip tests depending on old-style classes when running within pypy-c. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Jun 23 21:26:59 2006 @@ -889,6 +889,8 @@ 'run-script', 'regrverbose.py') pypy_options = [] if regrtest.oldstyle: + if option.use_compiled: + py.test.skip("old-style classes not available in pypy-c") pypy_options.append('--oldstyle') if regrtest.uselibfile: pypy_options.append('--uselibfile') From arigo at codespeak.net Fri Jun 23 21:45:36 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Jun 2006 21:45:36 +0200 (CEST) Subject: [pypy-svn] r29277 - pypy/dist/pypy/interpreter Message-ID: <20060623194536.45E7D1007B@code0.codespeak.net> Author: arigo Date: Fri Jun 23 21:45:35 2006 New Revision: 29277 Modified: pypy/dist/pypy/interpreter/argument.py Log: A missing "not". This was actually caught by a lib-python test (here test_extcall), which we definitely don't check often enough. Modified: pypy/dist/pypy/interpreter/argument.py ============================================================================== --- pypy/dist/pypy/interpreter/argument.py (original) +++ pypy/dist/pypy/interpreter/argument.py Fri Jun 23 21:45:35 2006 @@ -602,7 +602,7 @@ nargs) else: defcount = self.num_defaults - if defcount == 0 and has_vararg: + if defcount == 0 and not has_vararg: msg1 = "exactly" elif not self.missing_args: msg1 = "at most" From arigo at codespeak.net Fri Jun 23 21:54:17 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Jun 2006 21:54:17 +0200 (CEST) Subject: [pypy-svn] r29280 - pypy/dist/pypy/translator/js/modules/test Message-ID: <20060623195417.3DFAB10077@code0.codespeak.net> Author: arigo Date: Fri Jun 23 21:54:17 2006 New Revision: 29280 Modified: pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py Log: Import the local conftest to check options. Fixes a crash when the test is run as part of a whole-scale py.test. Modified: pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py (original) +++ pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py Fri Jun 23 21:54:17 2006 @@ -3,7 +3,7 @@ """ import py -from pypy import conftest +from pypy.translator.js import conftest if not conftest.option.browser or not conftest.option.tg: py.test.skip("Works only in browser and with turbogears") From arigo at codespeak.net Sat Jun 24 08:28:52 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 24 Jun 2006 08:28:52 +0200 (CEST) Subject: [pypy-svn] r29288 - in pypy/release/0.9.x: lib-python lib-python/modified-2.4.1/test pypy/interpreter pypy/translator/js/modules/test Message-ID: <20060624062852.C96AF10072@code0.codespeak.net> Author: arigo Date: Sat Jun 24 08:28:49 2006 New Revision: 29288 Added: pypy/release/0.9.x/lib-python/modified-2.4.1/test/test_scope.py - copied unchanged from r29281, pypy/dist/lib-python/modified-2.4.1/test/test_scope.py Modified: pypy/release/0.9.x/lib-python/conftest.py pypy/release/0.9.x/lib-python/modified-2.4.1/test/test_class.py pypy/release/0.9.x/pypy/interpreter/argument.py pypy/release/0.9.x/pypy/translator/js/modules/test/test_xmlhttp.py Log: Backport r29275 to r29280 (arigo). Modified: pypy/release/0.9.x/lib-python/conftest.py ============================================================================== --- pypy/release/0.9.x/lib-python/conftest.py (original) +++ pypy/release/0.9.x/lib-python/conftest.py Sat Jun 24 08:28:49 2006 @@ -889,6 +889,8 @@ 'run-script', 'regrverbose.py') pypy_options = [] if regrtest.oldstyle: + if option.use_compiled: + py.test.skip("old-style classes not available in pypy-c") pypy_options.append('--oldstyle') if regrtest.uselibfile: pypy_options.append('--uselibfile') Modified: pypy/release/0.9.x/lib-python/modified-2.4.1/test/test_class.py ============================================================================== --- pypy/release/0.9.x/lib-python/modified-2.4.1/test/test_class.py (original) +++ pypy/release/0.9.x/lib-python/modified-2.4.1/test/test_class.py Sat Jun 24 08:28:49 2006 @@ -244,6 +244,9 @@ if sys.platform[:4] == 'java': import java java.lang.System.gc() +else: + import gc + gc.collect() # Interfering tests Modified: pypy/release/0.9.x/pypy/interpreter/argument.py ============================================================================== --- pypy/release/0.9.x/pypy/interpreter/argument.py (original) +++ pypy/release/0.9.x/pypy/interpreter/argument.py Sat Jun 24 08:28:49 2006 @@ -602,7 +602,7 @@ nargs) else: defcount = self.num_defaults - if defcount == 0 and has_vararg: + if defcount == 0 and not has_vararg: msg1 = "exactly" elif not self.missing_args: msg1 = "at most" Modified: pypy/release/0.9.x/pypy/translator/js/modules/test/test_xmlhttp.py ============================================================================== --- pypy/release/0.9.x/pypy/translator/js/modules/test/test_xmlhttp.py (original) +++ pypy/release/0.9.x/pypy/translator/js/modules/test/test_xmlhttp.py Sat Jun 24 08:28:49 2006 @@ -3,7 +3,7 @@ """ import py -from pypy import conftest +from pypy.translator.js import conftest if not conftest.option.browser or not conftest.option.tg: py.test.skip("Works only in browser and with turbogears") From hpk at codespeak.net Sat Jun 24 12:27:10 2006 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Jun 2006 12:27:10 +0200 (CEST) Subject: [pypy-svn] r29294 - pypy/dist/pypy/interpreter/stablecompiler Message-ID: <20060624102710.D02ED10075@code0.codespeak.net> Author: hpk Date: Sat Jun 24 12:27:09 2006 New Revision: 29294 Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py Log: lowering parser-related large default for recursion depth, armin and me each tried with 3000 and 1000 on pypy2 and a full py.test run did complete successfully (where it previously segfaulted at test_unification). setting the default to 2000 now, it's good to run some more tests with this - there may be side effects, not covered by a full py.test run. Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Sat Jun 24 12:27:09 2006 @@ -48,8 +48,8 @@ setattr(symbol, name, value) # transforming is requiring a lot of recursion depth so make sure we have enough -if sys.getrecursionlimit()<5000: - sys.setrecursionlimit(5000) +if sys.getrecursionlimit()<2000: + sys.setrecursionlimit(2000) class WalkerError(StandardError): From fijal at codespeak.net Sat Jun 24 20:32:29 2006 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 24 Jun 2006 20:32:29 +0200 (CEST) Subject: [pypy-svn] r29299 - in pypy/dist/pypy/translator/js: . demo demo/jsdemo demo/jsdemo/templates modules modules/test proxy/testme test tools Message-ID: <20060624183229.95FC010075@code0.codespeak.net> Author: fijal Date: Sat Jun 24 20:32:22 2006 New Revision: 29299 Added: pypy/dist/pypy/translator/js/modules/start_bnb.py Modified: pypy/dist/pypy/translator/js/commproxy.py (contents, props changed) pypy/dist/pypy/translator/js/demo/ (props changed) pypy/dist/pypy/translator/js/demo/__init__.py (props changed) pypy/dist/pypy/translator/js/demo/dev.cfg pypy/dist/pypy/translator/js/demo/jsdemo/ (props changed) pypy/dist/pypy/translator/js/demo/jsdemo/__init__.py (props changed) pypy/dist/pypy/translator/js/demo/jsdemo/autopath.py (props changed) pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py (contents, props changed) pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py (props changed) pypy/dist/pypy/translator/js/demo/jsdemo/proxy.py (props changed) pypy/dist/pypy/translator/js/demo/jsdemo/templates/ (props changed) pypy/dist/pypy/translator/js/demo/jsdemo/templates/__init__.py (props changed) pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid pypy/dist/pypy/translator/js/jsbuiltin.py pypy/dist/pypy/translator/js/modules/mochikit.py (props changed) pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py (contents, props changed) pypy/dist/pypy/translator/js/proxy/testme/servermessage.py pypy/dist/pypy/translator/js/test/runtest.py pypy/dist/pypy/translator/js/test/tgtest.py pypy/dist/pypy/translator/js/tools/ (props changed) Log: Fixed several small issues, added first runnable version of bnb. Modified: pypy/dist/pypy/translator/js/commproxy.py ============================================================================== --- pypy/dist/pypy/translator/js/commproxy.py (original) +++ pypy/dist/pypy/translator/js/commproxy.py Sat Jun 24 20:32:22 2006 @@ -12,7 +12,9 @@ data = %(data)s; str = "?" for(i in data) { - str += i + "=" + data[i].toString() + ";"; + if (data[i]) { + str += i + "=" + data[i].toString() + ";"; + } } x.open("GET", '%(call)s' + str, true); //x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); @@ -37,6 +39,20 @@ } """ +MOCHIKIT_BODY = """ +%(class)s.prototype.%(method)s = function ( %(args)s ) { + var data,str; + data = %(data)s; + str = "?" + for(i in data) { + if (data[i]) { + str += i + "=" + data[i].toString() + ";"; + } + } + loadJSONDoc('%(call)s' + str).addCallback(callback); +} +""" + class XmlHttp(object): """ Class for rendering xmlhttp request communication over normal js code @@ -55,12 +71,18 @@ ilasm.end_function() def render_method(self, method_name, method, ilasm): + USE_MOCHIKIT = True # FIXME: some option? + args, retval = method.args, method.retval.name real_args = list(arg.name for arg in args) # FIXME: dirty JS here data = "{%s}" % ",".join(["'%s':%s" % (i,i) for i in real_args if i != 'callback']) real_callback = Variable("callback").name - ilasm.codegenerator.write(CALLBACK_BODY % {'real_callback':real_callback}) - ilasm.codegenerator.write(METHOD_BODY % {'class':self.name, 'method':method_name,\ - 'args':",".join(real_args), 'data':data, 'call':'http://localhost:8080/'+method_name,\ - 'real_callback':real_callback}) + if USE_MOCHIKIT: + ilasm.codegenerator.write(MOCHIKIT_BODY % {'class':self.name, 'method':method_name,\ + 'args':','.join(real_args), 'data':data, 'call':method_name}) + else: + ilasm.codegenerator.write(CALLBACK_BODY % {'real_callback':real_callback}) + ilasm.codegenerator.write(METHOD_BODY % {'class':self.name, 'method':method_name,\ + 'args':",".join(real_args), 'data':data, 'call':'http://localhost:8080/'+method_name,\ + 'real_callback':real_callback}) Modified: pypy/dist/pypy/translator/js/demo/dev.cfg ============================================================================== --- pypy/dist/pypy/translator/js/demo/dev.cfg (original) +++ pypy/dist/pypy/translator/js/demo/dev.cfg Sat Jun 24 20:32:22 2006 @@ -26,12 +26,12 @@ # Some server parameters that you may want to tweak server.socketPort=8080 -server.socketHost="127.0.0.1" +#server.socketHost="" # Disable the debug output at the end on pages. # logDebugInfoFilter.on = False server.logFile="server.log" -server.logToScreen=True +server.logToScreen=False server.environment="production" #"development" #autoreload.package="testme" Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py Sat Jun 24 20:32:22 2006 @@ -4,10 +4,120 @@ import turbogears import cherrypy -from pypy.jsdemo.jsdemo.controllers import Root -from pypy.rpython.ootypesystem.bltregistry import BasicExternal +from pypy.translator.js.demo.jsdemo.controllers import Root +from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc + +from pypy.translator.js.proxy.testme.servermessage import ServerMessage, PMSG_INLINE_FRAME +from pypy.translator.js.proxy.testme.msgstruct import * +from cherrypy import session + +import re, time, sys, os, urllib, socket + +class SortY(object): + def __init__(self, data): + self.data = data + + def __cmp__(self, other): + return cmp(self.data['y'], other.data['y']) # Needed double inheritance for both server job # and semi-transparent communication proxy class BnbRoot(Root, BasicExternal): - @turbogears.expose + _serverMessage = {} + + host = 'localhost' + try: + port = re.findall('value=".*"', urllib.urlopen('http://%s:8000' % host).read())[0] + except IOError: + import sys + log("ERROR: Can't connect to BnB server on %s:8000" % host) + sys.exit() + port = int(port[7:-1]) + + _methods = { + 'get_message' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}) + } + + def serverMessage(self): + sessionid = session['_id'] + if sessionid not in self._serverMessage: + self._serverMessage[sessionid] = ServerMessage('static/images') + return self._serverMessage[sessionid] + + @turbogears.expose(html="jsdemo.templates.bnb") + def index(self): + import time + self.last_frames = set() + return dict(now=time.ctime(), onload=self.jsname, code=self.jssource) + + def sessionSocket(self, close=False): + sm = self.serverMessage() + if sm.socket is None: + player_id = 0 #XXX hardcoded for now + sm.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sm.socket.connect((self.host, self.port)) + sm.socket.send(message(CMSG_PROTO_VERSION, 2)) #, version a kuku + sm.socket.send(message(CMSG_ENABLE_SOUND, 0)) #, has_sound + sm.socket.send(message(CMSG_ENABLE_MUSIC, 0)) #, has_music + sm.socket.send(message(CMSG_UDP_PORT, "\\")) #, port + sm.socket.send(message(CMSG_PING)) #so server starts sending data + #sm.socket.send(message(CMSG_ADD_PLAYER, player_id)) + #sm.socket.send(message(CMSG_PLAYER_NAME, player_id, 'PyPy')) + #XXX todo: session.socket.close() after a timeout + return sm.socket + + @turbogears.expose(format="json") + def get_message(self): + #XXX hangs if not first sending CMSG_PING! + sm = self.serverMessage() + size = 10000 #XXX should really loop until all data is handled + data = sm.data + self.sessionSocket().recv(size) + while sm.n_header_lines > 0 and '\n' in data: + sm.n_header_lines -= 1 + header_line, data = data.split('\n',1) + #log('RECEIVED HEADER LINE: %s' % header_line) + + #log('RECEIVED DATA CONTAINS %d BYTES' % len(data)) + messages = [] + while data: + values, data = decodemessage(data) + if not values: + break # incomplete message + messageOutput = sm.dispatch(*values) + if messageOutput: + if type(messageOutput) is type([]): + messages += messageOutput + else: + messages.append(messageOutput) + sm.data = data + #log('RECEIVED DATA REMAINING CONTAINS %d BYTES' % len(data)) + + len_before = len(messages) + #XXX we could do better by not generating only the last inline_frame message anyway! + inline_frames = [i for i,msg in enumerate(messages) if msg['type'] == PMSG_INLINE_FRAME] + for i in reversed(inline_frames[:-1]): + del messages[i] + + #if messages: + # log('MESSAGES:lenbefore=%d, inline_frames=%s, lenafter=%d' % ( + # len_before, inline_frames, len(messages))) + to_append = [] + next_last = set() + keep_sprites = [] + for i, msg in enumerate(messages): + if msg['type'] == PMSG_INLINE_FRAME: + for next in msg['sprites']: +# if not next in self.last_frames: + # sort them by y axis + to_append.append(SortY({'type':'sprite', 'x':str(next[1]), 'y':str(next[2]), 'icon_code':str(next[0])})) + #next_last.add(next) + del messages[i] + + self.last_frames = next_last + to_append.sort() + messages += [i.data for i in to_append] + + messages.append({'type':'end_frame'}) + return dict(messages=messages) + +BnbRootInstance = BnbRoot() Modified: pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid Sat Jun 24 20:32:22 2006 @@ -13,14 +13,14 @@ result = ${onload}(); } catch ( e ) { exc = e; + xml = new XMLHttpRequest(); + xml.open('GET', '/send_result?result=0;exc='+exc, true); + xml.send(null); } - xml = new XMLHttpRequest(); - xml.open('GET', 'http://localhost:8080/send_result?result='+result+';exc='+exc, true); - xml.send(null); } - +

This is a test!


Code:



Modified: pypy/dist/pypy/translator/js/jsbuiltin.py
==============================================================================
--- pypy/dist/pypy/translator/js/jsbuiltin.py	(original)
+++ pypy/dist/pypy/translator/js/jsbuiltin.py	Sat Jun 24 20:32:22 2006
@@ -44,6 +44,12 @@
             },
             ootype.Dict: {
                 'll_get' : ListGetitem,
+                'll_set' : ListSetitem,
+                'll_contains' : ListContains,
+            },
+            ootype.Record: {
+                'll_get' : ListGetitem,
+                'll_set' : ListSetitem,
                 'll_contains' : ListContains,
             }
         }

Added: pypy/dist/pypy/translator/js/modules/start_bnb.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/modules/start_bnb.py	Sat Jun 24 20:32:22 2006
@@ -0,0 +1,114 @@
+""" bub-n-bros testing utility
+"""
+
+import py
+
+from pypy.translator.js.test.runtest import compile_function
+from pypy.translator.js.modules.dom import Node, get_document, setTimeout, alert
+from pypy.translator.js.modules.xmlhttp import XMLHttpRequest
+from pypy.translator.js import conftest
+from pypy.translator.js.modules.mochikit import logDebug, createLoggingPane
+from pypy.translator.js.modules.dom import get_document
+
+import time
+
+if not conftest.option.browser:
+    py.test.skip("Works only in browser (right now?)")
+
+from pypy.translator.js.demo.jsdemo.bnb import BnbRootInstance
+        
+##def msg_dispatcher(data):
+##    for i in data['messages']:
+##        logDebug(i['type'])
+##    BnbRootInstance.get_message(msg_dispatcher)
+##
+##def test_mochikit():
+##    def mochikit():
+##        createLoggingPane(True)
+##        BnbRootInstance.get_message(msg_dispatcher)
+##
+##    from pypy.translator.js.proxy.testme.controllers import Root
+##    fn = compile_function(mochikit, [], root = Root)
+##    fn()
+
+class SpriteContainer(object):
+    """ Class containing all sprites
+    """
+    def __init__(self):
+        self.sprite_queues = {}
+        self.used = {}
+        self.filenames = {}
+        self.icon_codes = []
+    
+    def add_icon(self, icon_code, filename):
+        self.filenames[icon_code] = filename
+        self.sprite_queues[icon_code] = []
+        self.used[icon_code] = []
+        # FIXME: Need to write down DictIterator once...
+        self.icon_codes.append(icon_code)
+    
+    def get_sprite(self, icon_code):
+        #logDebug(str(len(self.sprite_queues[icon_code])))
+        try:
+            elem = self.sprite_queues[icon_code].pop()
+            elem.style.visibility = "visible"
+            self.used[icon_code].append(elem)
+            return elem
+        except IndexError:
+            img = get_document().createElement("img")
+            img.setAttribute("src", self.filenames[icon_code])
+            img.setAttribute("style", 'position:absolute; left:0px; top:0px; visibility:visible')
+            self.sprite_queues[icon_code].append(img)
+            get_document().getElementById("playfield").appendChild(img)
+            return img
+    
+    def revive(self):
+        for i in self.icon_codes:
+            for j in self.sprite_queues[i]:
+                j.style.visibility = "hidden"
+            self.sprite_queues[i] = self.sprite_queues[i] + self.used[i]
+            self.used[i] = []
+        
+sc = SpriteContainer();
+
+def process_message(msg):
+    if msg['type'] == 'def_playfield':
+        bgcolor = '#000000'
+        get_document().body.setAttribute('bgcolor', bgcolor)
+        div = get_document().createElement("div")
+        div.setAttribute("id", "playfield")
+        div.setAttribute('width', msg['width'])
+        div.setAttribute('height', msg['height'])
+        div.setAttribute('style', 'position:absolute; top:0px; left:0px')
+        get_document().body.appendChild(div)
+    elif msg['type'] == 'def_icon':
+##        img = get_document().createElement("img")
+##        img.setAttribute("src", msg["filename"])
+##        img.setAttribute("style", 'position:absolute; left:0; top:0')
+##        img.setAttribute("id", msg["icon_code"])
+##        get_document().getElementById("playfield").appendChild(img)
+        sc.add_icon(msg['icon_code'], msg['filename'])
+    elif msg['type'] == 'sprite':
+        #img = get_document().getElementById(msg["icon_code"])
+        #logDebug(str(img.left) + " " + str(img.right))
+        img = sc.get_sprite(msg['icon_code'])
+        img.style.left = msg['x'] + 'px'
+        img.style.top = msg['y'] + 'px'
+    elif msg['type'] == 'end_frame':
+        pass
+        sc.revive()
+
+def bnb_dispatcher(msgs):
+    BnbRootInstance.get_message(bnb_dispatcher)
+    for msg in msgs['messages']:
+        process_message(msg)
+    
+def test_some():
+    def bnb():
+        #get_document().
+        createLoggingPane(True)
+        BnbRootInstance.get_message(bnb_dispatcher)
+    
+    from pypy.translator.js.demo.jsdemo.bnb import BnbRoot
+    fn = compile_function(bnb, [], root = BnbRoot)
+    fn()

Modified: pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py	(original)
+++ pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py	Sat Jun 24 20:32:22 2006
@@ -32,4 +32,3 @@
     fn = compile_function(run_double_proxy, [], root = ProxyRoot)
     result = fn()
     assert result == 8
-

Modified: pypy/dist/pypy/translator/js/proxy/testme/servermessage.py
==============================================================================
--- pypy/dist/pypy/translator/js/proxy/testme/servermessage.py	(original)
+++ pypy/dist/pypy/translator/js/proxy/testme/servermessage.py	Sat Jun 24 20:32:22 2006
@@ -40,7 +40,9 @@
     base_gfx_url = 'static/images/'
     gfx_extension = 'gif'
 
-    def __init__(self):
+    def __init__(self, base_gfx_dir = None):
+        if base_gfx_dir:
+            self.base_gfx_dir = base_gfx_dir
         self.socket = None
         self.data   = ''
         self.n_header_lines = 2

Modified: pypy/dist/pypy/translator/js/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/runtest.py	(original)
+++ pypy/dist/pypy/translator/js/test/runtest.py	Sat Jun 24 20:32:22 2006
@@ -25,7 +25,7 @@
     return True
 
 class compile_function(object):
-    def __init__(self, function, annotation, stackless=False, view=False, html=None, is_interactive=False, root = None):
+    def __init__(self, function, annotation, stackless=False, view=False, html=None, is_interactive=False, root = None, run_browser = True):
         if not use_browsertest and not _CLI_is_on_path():
             py.test.skip('Javascript CLI (js) not found')
 
@@ -70,7 +70,7 @@
             else:
                 global port
                 from pypy.translator.js.test.tgtest import run_tgtest
-                out = run_tgtest(self, tg_root = self.root, port=port).results
+                out = run_tgtest(self, tg_root = self.root, port=port, run_browser=run_browser).results
                 assert out[1] == 'undefined' or out[1] == ""
                 output = out[0]
                 port += 1

Modified: pypy/dist/pypy/translator/js/test/tgtest.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/tgtest.py	(original)
+++ pypy/dist/pypy/translator/js/test/tgtest.py	Sat Jun 24 20:32:22 2006
@@ -17,10 +17,11 @@
 conf_file = os.path.join(os.path.dirname(controllers.__file__), "..", "dev.cfg")
 
 class run_tgtest(object):
-    def __init__(self, compiled_fun, tg_root = None, port = 8080):
+    def __init__(self, compiled_fun, tg_root = None, port = 8080, run_browser=True):
         def cont():
             cherrypy.server.wait()
-            webbrowser.open("http://localhost:%d/" % port)
+            if run_browser:
+                webbrowser.open("http://localhost:%d/" % port)
             cherrypy.root.wait_for_results()
             self.results = cherrypy.root.results
             cherrypy.server.stop()


From fijal at codespeak.net  Sat Jun 24 20:41:37 2006
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 24 Jun 2006 20:41:37 +0200 (CEST)
Subject: [pypy-svn] r29303 - in pypy/dist/pypy/translator/js: modules test
	tools
Message-ID: <20060624184137.CD63C10075@code0.codespeak.net>

Author: fijal
Date: Sat Jun 24 20:41:35 2006
New Revision: 29303

Added:
   pypy/dist/pypy/translator/js/tools/autopath.py
   pypy/dist/pypy/translator/js/tools/start_bnb.py   (contents, props changed)
      - copied, changed from r29299, pypy/dist/pypy/translator/js/modules/start_bnb.py
Removed:
   pypy/dist/pypy/translator/js/modules/start_bnb.py
Modified:
   pypy/dist/pypy/translator/js/test/runtest.py
Log:
Fixed executable issues.


Modified: pypy/dist/pypy/translator/js/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/runtest.py	(original)
+++ pypy/dist/pypy/translator/js/test/runtest.py	Sat Jun 24 20:41:35 2006
@@ -49,6 +49,7 @@
             self.root = Root
         else:
             self.root = root
+        self.run_browser = run_browser
 
     def _conv(self, v):
         #if isinstance(v, str):
@@ -70,7 +71,7 @@
             else:
                 global port
                 from pypy.translator.js.test.tgtest import run_tgtest
-                out = run_tgtest(self, tg_root = self.root, port=port, run_browser=run_browser).results
+                out = run_tgtest(self, tg_root = self.root, port=port, run_browser=self.run_browser).results
                 assert out[1] == 'undefined' or out[1] == ""
                 output = out[0]
                 port += 1

Added: pypy/dist/pypy/translator/js/tools/autopath.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/tools/autopath.py	Sat Jun 24 20:41:35 2006
@@ -0,0 +1,112 @@
+"""
+self cloning, automatic path configuration 
+
+copy this into any subdirectory of pypy from which scripts need 
+to be run, typically all of the test subdirs. 
+The idea is that any such script simply issues
+
+    import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path. 
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py) 
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory. 
+
+This module always provides these attributes:
+
+    pypydir    pypy root directory path 
+    this_dir   directory where this autopath.py resides 
+
+"""
+
+
+def __dirinfo(part):
+    """ return (partdir, this_dir) and insert parent of partdir
+    into sys.path.  If the parent directories don't have the part
+    an EnvironmentError is raised."""
+
+    import sys, os
+    try:
+        head = this_dir = os.path.realpath(os.path.dirname(__file__))
+    except NameError:
+        head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+    while head:
+        partdir = head
+        head, tail = os.path.split(head)
+        if tail == part:
+            break
+    else:
+        raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir)
+    
+    pypy_root = os.path.join(head, '')
+    try:
+        sys.path.remove(head)
+    except ValueError:
+        pass
+    sys.path.insert(0, head)
+
+    munged = {}
+    for name, mod in sys.modules.items():
+        fn = getattr(mod, '__file__', None)
+        if '.' in name or not isinstance(fn, str):
+            continue
+        newname = os.path.splitext(os.path.basename(fn))[0]
+        if not newname.startswith(part + '.'):
+            continue
+        path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
+        if path.startswith(pypy_root) and newname != part:
+            modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
+            if newname != '__init__':
+                modpaths.append(newname)
+            modpath = '.'.join(modpaths)
+            if modpath not in sys.modules:
+                munged[modpath] = mod
+
+    for name, mod in munged.iteritems():
+        if name not in sys.modules:
+            sys.modules[name] = mod
+        if '.' in name:
+            prename = name[:name.rfind('.')]
+            postname = name[len(prename)+1:]
+            if prename not in sys.modules:
+                __import__(prename)
+                if not hasattr(sys.modules[prename], postname):
+                    setattr(sys.modules[prename], postname, mod)
+
+    return partdir, this_dir
+
+def __clone():
+    """ clone master version of autopath.py into all subdirs """
+    from os.path import join, walk
+    if not this_dir.endswith(join('pypy','tool')):
+        raise EnvironmentError("can only clone master version "
+                               "'%s'" % join(pypydir, 'tool',_myname))
+
+
+    def sync_walker(arg, dirname, fnames):
+        if _myname in fnames:
+            fn = join(dirname, _myname)
+            f = open(fn, 'rwb+')
+            try:
+                if f.read() == arg:
+                    print "checkok", fn
+                else:
+                    print "syncing", fn
+                    f = open(fn, 'w')
+                    f.write(arg)
+            finally:
+                f.close()
+    s = open(join(pypydir, 'tool', _myname), 'rb').read()
+    walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+    __clone()


From ericvrp at codespeak.net  Sun Jun 25 09:53:10 2006
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Sun, 25 Jun 2006 09:53:10 +0200 (CEST)
Subject: [pypy-svn] r29304 - in pypy/dist/pypy/translator/js/proxy/testme: .
	static/javascript
Message-ID: <20060625075310.AAD9810075@code0.codespeak.net>

Author: ericvrp
Date: Sun Jun 25 09:53:06 2006
New Revision: 29304

Modified:
   pypy/dist/pypy/translator/js/proxy/testme/controllers.py
   pypy/dist/pypy/translator/js/proxy/testme/servermessage.py
   pypy/dist/pypy/translator/js/proxy/testme/static/javascript/bnb.js
Log:
Let proxy generate alpha layer for png's and decouple polling from rendering.


Modified: pypy/dist/pypy/translator/js/proxy/testme/controllers.py
==============================================================================
--- pypy/dist/pypy/translator/js/proxy/testme/controllers.py	(original)
+++ pypy/dist/pypy/translator/js/proxy/testme/controllers.py	Sun Jun 25 09:53:06 2006
@@ -76,8 +76,13 @@
     def recv(self):
         #XXX hangs if not first sending CMSG_PING!
         sm   = self.serverMessage()
-        size = 10000 #XXX should really loop until all data is handled
-        data = sm.data + self.sessionSocket().recv(size)
+        data = sm.data
+        sock = self.sessionSocket()
+        while True:
+            try:
+                data += sock.recv(4096, socket.MSG_DONTWAIT)
+            except:    
+                break
         while sm.n_header_lines > 0 and '\n' in data:
             sm.n_header_lines -= 1
             header_line, data = data.split('\n',1)

Modified: pypy/dist/pypy/translator/js/proxy/testme/servermessage.py
==============================================================================
--- pypy/dist/pypy/translator/js/proxy/testme/servermessage.py	(original)
+++ pypy/dist/pypy/translator/js/proxy/testme/servermessage.py	Sun Jun 25 09:53:06 2006
@@ -38,7 +38,7 @@
     _def_icon_queue = {}
     base_gfx_dir = 'testme/static/images/'
     base_gfx_url = 'static/images/'
-    gfx_extension = 'gif'
+    gfx_extension = 'png'
 
     def __init__(self, base_gfx_dir = None):
         if base_gfx_dir:
@@ -93,9 +93,10 @@
         if len(rest) == 0:
             colorkey = None
         else:
-            colorkey = rest[0]
+            c = rest[0]
+            colorkey = (c & 255, (c >> 8) & 255, (c >> 16) & 255)
         #log('def_bitmap1 bitmap_code=%d, data=%d bytes, colorkey=%s' % (
-        #    bitmap_code, len(data), colokey))
+        #    bitmap_code, len(data), colorkey))
         gif_bitmap_filename = '%sbitmap%d.%s' % (self.gfx_dir, bitmap_code, self.gfx_extension)
         if exists(gif_bitmap_filename):
             #log('CACHED:%s' % gif_bitmap_filename)
@@ -117,14 +118,17 @@
                 raise BitmapCreationException('ERROR LOADING %s (%s)' % (
                     bitmap_filename, str(e)))
 
-            #create alpha layer that hopefully gets into the .gif...
-            #if colorkey is not None:
-            #    bitmap = bitmap.convert("RGBA")
-            #    pixel = bitmap.getpixel( (0,0) )
-            #    log('%s: colorkey=%s, pixel=%s' % (bitmap_filename, colorkey, str(pixel)))
-            #    colorkeyT = (1, 1, 1, 255)
-            #    alpha = [pixel == (1,1,1,255) for pixel in list(bitmap.getdata())]
-            #    bitmap.putalpha(alpha)
+            #create alpha layer (PIL export this correctly with png but not with gif)
+            if colorkey is not None:
+                bitmap = bitmap.convert("RGBA")
+                data   = bitmap.getdata()
+                c      = (colorkey[0], colorkey[1], colorkey[2], 255)
+                width, height = bitmap.size
+                for y in range(height): #this is slowish but gfx are cached, so...
+                    for x in range(width):
+                        p = data.getpixel((x,y))
+                        if p == c:
+                            data.putpixel((x,y), (0,0,0,0))
 
             try:
                 bitmap.save(gif_bitmap_filename)
@@ -194,7 +198,7 @@
         return messages
     
     def player_icon(self, player_id, icon_code):
-        log('player_icon player_id=%d, icon_code=%d' % (player_id, icon_code))
+        #log('player_icon player_id=%d, icon_code=%d' % (player_id, icon_code))
         return dict(type=PMSG_PLAYER_ICON, player_id=player_id, icon_code=icon_code)
 
     def player_join(self, player_id, client_is_self):
@@ -202,7 +206,7 @@
         return dict(type=PMSG_PLAYER_JOIN, player_id=player_id, client_is_self=client_is_self)
 
     def def_key(self, keyname, num, *icon_codes):
-        log('def_key keyname=%s, num=%d, icon_codes=%s' % (keyname, num, str(icon_codes)))
+        #log('def_key keyname=%s, num=%d, icon_codes=%s' % (keyname, num, str(icon_codes)))
         return dict(type=PMSG_DEF_KEY, keyname=keyname, num=num, icon_codes=icon_codes)
 
     def md5_file(self, fileid, protofilepath, offset, len_data, checksum):

Modified: pypy/dist/pypy/translator/js/proxy/testme/static/javascript/bnb.js
==============================================================================
--- pypy/dist/pypy/translator/js/proxy/testme/static/javascript/bnb.js	(original)
+++ pypy/dist/pypy/translator/js/proxy/testme/static/javascript/bnb.js	Sun Jun 25 09:53:06 2006
@@ -1,46 +1,62 @@
 function BnB() { //entrypoint to be called by body.onLoad
 	// init global data
-	playfield = DIV({'bgcolor':'red', 'width':42, 'height':42}); //updated with def_playfield
-	icon = {};
 	doc = currentDocument();
 	body = doc.body;
 
+	playfield = DIV({'bgcolor':'red', 'width':42, 'height':42}); //updated with def_playfield
+        max_images = 999;
+        images = [];
+        for (var n = 0;n < max_images;n++) { //why is firefox so F!@#King slow?
+            var img = IMG({
+                //'width':'0', 'height':'0',
+                'style':'position:absolute; top:-1000px; left:-1000px;'});
+            images.push(img);
+        }
+        replaceChildNodes(playfield, images);
+        appendChildNodes(body, playfield);
+            
+	icon = {};
         offsetx = 64;
         offsety = 64;
-        zoom = 1;
 
-        prev_sprites = [];
+        curr_sprites = [];  //current (most up-to-date) location of sprites
+        prev_sprites = [];  //previous rendered sprites
 
         spacebar     = 32;  //XXX hardcoded for now
         cursor_left  = 37;
         cursor_up    = 38;
         cursor_right = 39;
         cursor_down  = 40;
-        keycodes = [cursor_right, cursor_left, cursor_up, spacebar]
-        key_is_down = [false, false, false, false]
+        keycodes = [cursor_right, cursor_left, cursor_up, spacebar];
+        key_is_down = [false, false, false, false];
+        key_icon_codes = [];
+        player_icon_code = [];
+
+        stats = {
+            'starttime' : 0,
+            'n_received_inline_frames'   : 0,
+            'n_rendered_inline_frames'   : 0,
+            'n_rendered_dynamic_sprites' : 0
+            };
 
+        setupEventHandlers();
 	receiveData();
-        handleKeysEvents();
+        setInterval(renderSprites, 1000 / 25); //max fps
 }
 
 function BnBKeyDown(e) {
     var c = String.fromCharCode(e.charCode);
+
     if (c == 'a') {
         addPlayer(0);
         return;
     }
+
     if (c == 'r') {
         removePlayer(0);
         return;
     }
-    if (c == '-') {
-        newZoom(zoom / 2);
-        return;
-    }
-    if (c == '+') {
-        newZoom(zoom * 2);
-        return;
-    }
+
     for (var i = 0;i < 4;i++) {
         if (e.keyCode == keycodes[i]) {
             var player_id = 0;  //XXX hardcoded for now
@@ -77,82 +93,37 @@
     }
 }
 
-function handleKeysEvents() {
+function onUnload() {
+    //this doesn't get reached when the user presses the Escape key.
+    removePlayer(0);
+    return true;
+}
+
+function setupEventHandlers() {
     document.onkeydown = BnBKeyDown;
     document.onkeyup   = BnBKeyUp;
     document.onkeypress= BnBKeyDown;
-}
-
-function newZoom(z) {
-    for (var icon_code in icon) {
-        var ic = icon[icon_code];
-        ic.width  *= z / zoom;
-        ic.height *= z / zoom;
-    }
-    zoom = z;
-    prev_sprites = []; //force redraw
+    window.onunload = onUnload;
 }
 
 function BnBColorToHexString(c) {
-	var r = c;	//XXX should do the correct masking here
-	var g = c;
-	var b = c;
+	var r = c & 255;
+	var g = (c >> 8) & 255;
+	var b = (c >> 16) & 255;
 	return Color.fromRGB(r,g,b).toHexString();
 }
 
-function handleServerResponse(json_doc) {
-    //setTimeout(0, 'receiveData'); //do a new request a.s.a.p
-    receiveData();
-    for (var i in json_doc.messages) {
-        var msg = json_doc.messages[i];
-        if (msg.type == 'def_playfield') { //XXX refactor to helper functions
-            var bgcolor = BnBColorToHexString(msg.backcolor);
-            updateNodeAttributes(playfield,
-                {'bgcolor':bgcolor, 'width':msg.width, 'height':msg.height});
-            //replaceChildNodes(body, playfield);
-            body.setAttribute('bgcolor', bgcolor); //XXX hack!
-
-        } else if (msg.type == 'def_icon') {
-            icon[msg.icon_code] = msg;
-            icon[msg.icon_code].width  *= zoom;
-            icon[msg.icon_code].height *= zoom;
-
-        } else if (msg.type == 'inline_frame') { //msg.sounds, msg.sprites
-            if (!this.inline_frame_starttime) {
-                this.images = [];
-                this.max_images = 999;
-                for (var n = 0;n < this.max_images;n++) { //why is firefox so F!@#King slow?
-                    var img = IMG({
-                        'width':'0', 'height':'0',
-                        'style':'position:absolute; top:-1000px; left:0px;'});
-                    this.images.push(img);
-                }
-                //replaceChildNodes(playfield, this.images);
-                replaceChildNodes(body, this.images);
-
-                this.inline_frame_starttime = new Date();
-                this.n_inline_frames = 0;
-            } else {
-                this.n_inline_frames++;
-                var fps = 1000 / ((new Date() - this.inline_frame_starttime) / this.n_inline_frames);
-                document.title = fps + " fps, " +
-                    this.n_dynamic_sprites + "/" + prev_sprites.length;
-            }
+function renderSprites() {
 
             //XXX firefox isn't instant with changing img.src's!
             //Plus it is very slow when changing the .src attribute
             //So we might be better of keeping a list of animating images 
             //so we can just move those to the right location!
 
-            var sprite_data, icon_code, img, n, prev;
-            this.n_dynamic_sprites = 0;
-            for (n = 0;n < msg.sprites.length && n < this.max_images;n++) {
-                sprite_data = msg.sprites[n];
-                icon_code = sprite_data[0];
-                if (!(icon_code in icon)) {
-                    sprite_data[0] = -100; //force redraw when icon becomes avaliable
-                    continue;
-                }
+            var sprite_data, img, n, prev;
+            var n_dynamic = 0;
+            for (n = 0;n < curr_sprites.length && n < max_images;n++) {
+                sprite_data = curr_sprites[n];
                 if (n < prev_sprites.length) {
                     prev = prev_sprites[n];
                     if (sprite_data[0] == prev[0] && 
@@ -162,22 +133,63 @@
                 } else {
                     prev = [-200,-200,-200]; //always draw new sprites
                 }
-                this.n_dynamic_sprites++;
-                if (icon_code      != prev[0])
-                    this.images[n].src = icon[icon_code].filename;
-                this.images[n].width  = icon[icon_code].width;
-                this.images[n].height = icon[icon_code].height;
+                if (sprite_data[0] != prev[0])
+                    images[n].src = icon[sprite_data[0]].filename;
                 if (sprite_data[1] != prev[1])
-                    this.images[n].style.left = offsetx + sprite_data[1] * zoom + 'px'
+                    images[n].style.left = offsetx + sprite_data[1] + 'px';
                 if (sprite_data[2] != prev[2])
-                    this.images[n].style.top  = offsety + sprite_data[2] * zoom + 'px'
+                    images[n].style.top  = offsety + sprite_data[2] + 'px';
+                //images[n].width  = icon[sprite_data[0]].width;
+                //images[n].height = icon[sprite_data[0]].height;
+                n_dynamic++;
             }
             var n_max = prev_sprites.length;
-            if (n_max == 0) n_max = this.max_images;
+            if (n_max == 0) n_max = max_images;
             for (;n < n_max;n++) {
-                this.images[n].style.left = "-1000px";
+                images[n].style.left = "-1000px";
+            }
+            prev_sprites = curr_sprites;
+
+            if (n_dynamic > 0)
+                stats.n_rendered_dynamic_sprites = n_dynamic;
+            stats.n_rendered_inline_frames++;
+}
+
+function handleServerResponse(json_doc) {
+    receiveData();
+
+    for (var i in json_doc.messages) {
+        var msg = json_doc.messages[i];
+        if (msg.type == 'def_playfield') { //XXX refactor to helper functions
+            var bgcolor = BnBColorToHexString(msg.backcolor);
+            updateNodeAttributes(playfield,
+                {'bgcolor':bgcolor, 'width':msg.width, 'height':msg.height});
+            body.setAttribute('bgcolor', bgcolor); //XXX hack!
+
+        } else if (msg.type == 'def_key') {
+            if (msg.icon_codes.length > 0) {
+                key_icon_codes[msg.num] = msg.icon_codes;
             }
-            prev_sprites = msg.sprites;
+
+        } else if (msg.type == 'player_icon') {
+            player_icon_code[msg.player_id] = msg.icon_code;
+
+        } else if (msg.type == 'def_icon') {
+            icon[msg.icon_code] = msg;
+            //icon[msg.icon_code].image = new Image(); //preloading is too slow (too much data)
+            //icon[msg.icon_code].image.src = msg.filename; //note: it seems image.onload works!
+            
+        } else if (msg.type == 'inline_frame') { //msg.sounds, msg.sprites
+            if (!stats.starttime) 
+                stats.starttime = new Date();
+
+            stats.n_received_inline_frames++;
+            var t = new Date() - stats.starttime;
+            var fps = 1000 / (t / stats.n_rendered_inline_frames);
+            var ups = 1000 / (t / stats.n_received_inline_frames); //updates per second
+            document.title = fps + " fps, " + ups + " ups, " + stats.n_rendered_dynamic_sprites + "/" + prev_sprites.length;
+            curr_sprites = msg.sprites;
+
         } else {
             logWarning('unknown msg.type: ' + msg.type + ', msg: ' + items(msg));
         }


From ericvrp at codespeak.net  Sun Jun 25 11:15:16 2006
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Sun, 25 Jun 2006 11:15:16 +0200 (CEST)
Subject: [pypy-svn] r29305 - in pypy/dist/pypy/translator/js: demo/jsdemo
	proxy proxy/testme tools
Message-ID: <20060625091516.3F2CB10075@code0.codespeak.net>

Author: ericvrp
Date: Sun Jun 25 11:15:09 2006
New Revision: 29305

Modified:
   pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py
   pypy/dist/pypy/translator/js/proxy/README.txt
   pypy/dist/pypy/translator/js/proxy/testme/controllers.py
   pypy/dist/pypy/translator/js/tools/start_bnb.py
Log:
Fix image path. Better error handling. Fix missing import.
And starting to play with extendion the rpython script.


Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py	(original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py	Sun Jun 25 11:15:09 2006
@@ -7,7 +7,7 @@
 from pypy.translator.js.demo.jsdemo.controllers import Root
 from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc
 
-from pypy.translator.js.proxy.testme.servermessage import ServerMessage, PMSG_INLINE_FRAME
+from pypy.translator.js.proxy.testme.servermessage import log, ServerMessage, PMSG_INLINE_FRAME
 from pypy.translator.js.proxy.testme.msgstruct import *
 from cherrypy import session
 
@@ -29,9 +29,11 @@
     try:
         port = re.findall('value=".*"', urllib.urlopen('http://%s:8000' % host).read())[0]
     except IOError:
-        import sys
         log("ERROR: Can't connect to BnB server on %s:8000" % host)
         sys.exit()
+    except IndexError:
+        log("ERROR: Connected to BnB server but unable to detect a running game")
+        sys.exit()
     port = int(port[7:-1])
     
     _methods = {
@@ -41,7 +43,7 @@
     def serverMessage(self):
         sessionid = session['_id']
         if sessionid not in self._serverMessage:
-            self._serverMessage[sessionid] = ServerMessage('static/images')
+            self._serverMessage[sessionid] = ServerMessage('static/images/')
         return self._serverMessage[sessionid]
     
     @turbogears.expose(html="jsdemo.templates.bnb")

Modified: pypy/dist/pypy/translator/js/proxy/README.txt
==============================================================================
--- pypy/dist/pypy/translator/js/proxy/README.txt	(original)
+++ pypy/dist/pypy/translator/js/proxy/README.txt	Sun Jun 25 11:15:09 2006
@@ -1,4 +1,4 @@
-testme
+testme proxy for BnB
 
 This is a TurboGears (http://www.turbogears.org) project. It can be
-started by running the start-testme.py script.
\ No newline at end of file
+started by running the testme-start.py script.

Modified: pypy/dist/pypy/translator/js/proxy/testme/controllers.py
==============================================================================
--- pypy/dist/pypy/translator/js/proxy/testme/controllers.py	(original)
+++ pypy/dist/pypy/translator/js/proxy/testme/controllers.py	Sun Jun 25 11:15:09 2006
@@ -6,6 +6,7 @@
 import socket
 import urllib
 import re
+import sys
 from servermessage import ServerMessage, log, PMSG_INLINE_FRAME
 from random import random
 from md5 import md5
@@ -19,9 +20,11 @@
     try:
         port = re.findall('value=".*"', urllib.urlopen('http://%s:8000' % host).read())[0]
     except IOError:
-        import sys
         log("ERROR: Can't connect to BnB server on %s:8000" % host)
         sys.exit()
+    except IndexError:
+        log("ERROR: Connected to BnB server but unable to detect a running game")
+        sys.exit()
     port = int(port[7:-1])
     
     def serverMessage(self):

Modified: pypy/dist/pypy/translator/js/tools/start_bnb.py
==============================================================================
--- pypy/dist/pypy/translator/js/tools/start_bnb.py	(original)
+++ pypy/dist/pypy/translator/js/tools/start_bnb.py	Sun Jun 25 11:15:09 2006
@@ -41,6 +41,18 @@
 ##    fn = compile_function(mochikit, [], root = Root)
 ##    fn()
 
+class Stats(object):
+    """ Class containing some statistics
+    """
+    def __init__(self):
+        self.starttime = 0
+        self.n_received_inline_frames = 0
+        self.n_rendered_inline_frames = 0
+        self.n_rendered_dynamic_sprites = 0
+        self.n_sprites = 0 #why is inline frame broken up?
+
+stats = Stats()
+
 class SpriteContainer(object):
     """ Class containing all sprites
     """
@@ -104,6 +116,8 @@
         img = sc.get_sprite(msg['icon_code'])
         img.style.left = msg['x'] + 'px'
         img.style.top = msg['y'] + 'px'
+        stats.n_sprites += 1
+        get_document().title = str(stats.n_sprites) + " sprites"
     elif msg['type'] == 'end_frame':
         pass
         sc.revive()


From arigo at codespeak.net  Sun Jun 25 12:35:13 2006
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sun, 25 Jun 2006 12:35:13 +0200 (CEST)
Subject: [pypy-svn] r29307 - in pypy/dist/pypy/rpython: . lltypesystem
	lltypesystem/test
Message-ID: <20060625103513.1467E10070@code0.codespeak.net>

Author: arigo
Date: Sun Jun 25 12:35:09 2006
New Revision: 29307

Added:
   pypy/dist/pypy/rpython/lltypesystem/opimpl.py   (contents, props changed)
Modified:
   pypy/dist/pypy/rpython/llinterp.py
   pypy/dist/pypy/rpython/lltypesystem/lloperation.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py
   pypy/dist/pypy/rpython/rarithmetic.py
Log:
Refactor and clean up the execution of ll operations.  All 'canfold'
operations are implemented in a new opimpl.py, which is used both by
llinterp and by direct calls to the LLOps like:

    assert llop.int_add(Signed, 5, 6) == 11

The idea is that llop calls are used when constant-folding only, and can
raise TypeError if the operation is not foldable.  For general
execution, the llinterpreter is still needed.



Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py	(original)
+++ pypy/dist/pypy/rpython/llinterp.py	Sun Jun 25 12:35:09 2006
@@ -147,25 +147,19 @@
         raise ValueError, "couldn't match exception"
 
 
-# implementations of ops from flow.operation
-from pypy.objspace.flow.operation import FunctionByName
-opimpls = FunctionByName.copy()
-opimpls['is_true'] = bool
-
-ops_returning_a_bool = {'gt': True, 'ge': True,
-                        'lt': True, 'le': True,
-                        'eq': True, 'ne': True,
-                        'is_true': True}
-
 def checkptr(ptr):
-    return isinstance(lltype.typeOf(ptr), lltype.Ptr)
+    assert isinstance(lltype.typeOf(ptr), lltype.Ptr)
 
 def checkadr(addr):
-    return lltype.typeOf(addr) == llmemory.Address
+    assert lltype.typeOf(addr) is llmemory.Address
     
-def checkinst(inst):
+def is_inst(inst):
     return isinstance(lltype.typeOf(inst), (ootype.Instance, ootype.BuiltinType))
 
+def checkinst(inst):
+    assert is_inst(inst)
+
+
 class LLFrame(object):
     def __init__(self, graph, args, llinterpreter, f_back=None):
         assert not graph or isinstance(graph, FunctionGraph)
@@ -225,7 +219,10 @@
     def getoperationhandler(self, opname):
         ophandler = getattr(self, 'op_' + opname, None)
         if ophandler is None:
-            raise AssertionError, "cannot handle operation %r yet" %(opname,)
+            # try to import the operation from opimpl.py
+            from pypy.rpython.lltypesystem.opimpl import get_op_impl
+            ophandler = get_op_impl(opname)
+            LLFrame.ophandler = staticmethod(ophandler)
         return ophandler
     # _______________________________________________________
     # evaling functions
@@ -332,12 +329,7 @@
         elif operation.opname == 'indirect_call':
             assert isinstance(operation.args[0], Variable)
         vals = [self.getval(x) for x in operation.args]
-        # XXX these special cases DO pile up, do something better here
-        if operation.opname in ['cast_pointer', 'ooupcast', 'oodowncast',
-                                'cast_adr_to_ptr', 'cast_weakadr_to_ptr',
-                                'cast_int_to_ptr',
-                                'cast_opaque_ptr', 'unsafe_call',
-                                'cast_primitive']:
+        if getattr(ophandler, 'need_result_type', False):
             vals.insert(0, operation.result.concretetype)
         try:
             retval = ophandler(*vals)
@@ -428,9 +420,6 @@
     def op_keepalive(self, value):
         pass
 
-    def op_same_as(self, x):
-        return x
-
     def op_hint(self, x, hints):
         return x
 
@@ -527,6 +516,7 @@
         from pypy.translator.stackless.frame import storage_type
         assert storage_type(lltype.typeOf(result)) == TGT
         return lltype._cast_whatever(TGT, result)
+    op_unsafe_call.need_result_type = True
 
     def op_malloc(self, obj):
         if self.llinterpreter.gc is not None:
@@ -565,179 +555,22 @@
         self.heap.free(obj, flavor=flavor)
 
     def op_getfield(self, obj, field):
-        assert checkptr(obj)
+        checkptr(obj)
         # check the difference between op_getfield and op_getsubstruct:
         assert not isinstance(getattr(lltype.typeOf(obj).TO, field),
                               lltype.ContainerType)
         return getattr(obj, field)
 
-    def op_getsubstruct(self, obj, field):
-        assert checkptr(obj)
-        # check the difference between op_getfield and op_getsubstruct:
-        assert isinstance(getattr(lltype.typeOf(obj).TO, field),
-                          lltype.ContainerType)
-        return getattr(obj, field)
-
-    def op_getarraysubstruct(self, array, index):
-        assert checkptr(array)
-        result = array[index]
-        return result
-        # the diff between op_getarrayitem and op_getarraysubstruct
-        # is the same as between op_getfield and op_getsubstruct
-
-    def op_getarraysize(self, array):
-        #print array,type(array),dir(array)
-        assert isinstance(lltype.typeOf(array).TO, lltype.Array)
-        return len(array)
-
-    def op_cast_pointer(self, tp, obj):
-        return lltype.cast_pointer(tp, obj)
-
-    def op_cast_opaque_ptr(self, tp, obj):
-        return lltype.cast_opaque_ptr(tp, obj)
-
-    def op_ptr_eq(self, ptr1, ptr2):
-        assert checkptr(ptr1)
-        assert checkptr(ptr2)
-        return ptr1 == ptr2
-
-    def op_ptr_ne(self, ptr1, ptr2):
-        assert checkptr(ptr1)
-        assert checkptr(ptr2)
-        return ptr1 != ptr2
-
-    def op_ptr_nonzero(self, ptr1):
-        assert checkptr(ptr1)
-        return bool(ptr1)
-
-    def op_ptr_iszero(self, ptr1):
-        assert checkptr(ptr1)
-        return not bool(ptr1)
-
-    def op_direct_fieldptr(self, obj, field):
-        assert checkptr(obj)
-        assert isinstance(field, str)
-        return lltype.direct_fieldptr(obj, field)
-
-    def op_direct_arrayitems(self, obj):
-        assert checkptr(obj)
-        return lltype.direct_arrayitems(obj)
-
-    def op_direct_ptradd(self, obj, index):
-        assert checkptr(obj)
-        assert isinstance(index, int)
-        return lltype.direct_ptradd(obj, index)
-
-    def op_cast_primitive(self, TYPE, value):
-        assert isinstance(lltype.typeOf(value), lltype.Primitive)
-        return lltype.cast_primitive(TYPE, value)
+    def op_cast_int_to_ptr(self, RESTYPE, int1):
+        return lltype.cast_int_to_ptr(RESTYPE, int1)
+    op_cast_int_to_ptr.need_result_type = True
 
     def op_cast_ptr_to_int(self, ptr1):
-        assert checkptr(ptr1)
-        assert isinstance(lltype.typeOf(ptr1).TO, (lltype.Array, lltype.Struct))
+        checkptr(ptr1)
+        assert isinstance(lltype.typeOf(ptr1).TO, (lltype.Array, lltype.Struct)
+)
         return lltype.cast_ptr_to_int(ptr1)
 
-    def op_cast_int_to_ptr(self, tp, int1):
-        return lltype.cast_int_to_ptr(tp, int1)
-
-    def op_cast_ptr_to_adr(self, ptr):
-        assert checkptr(ptr)
-        return llmemory.cast_ptr_to_adr(ptr)
-
-    def op_cast_adr_to_ptr(self, TYPE, adr):
-        assert checkadr(adr)
-        return llmemory.cast_adr_to_ptr(adr, TYPE)
-
-    def op_cast_adr_to_int(self, adr):
-        assert checkadr(adr)
-        return llmemory.cast_adr_to_int(adr)
-
-    def op_cast_ptr_to_weakadr(self, ptr):
-        assert checkptr(ptr)
-        return llmemory.cast_ptr_to_weakadr(ptr)
-
-    def op_cast_weakadr_to_ptr(self, TYPE, wadr):
-        assert lltype.typeOf(wadr) == llmemory.WeakGcAddress
-        return llmemory.cast_weakadr_to_ptr(wadr, TYPE)
-
-    def op_cast_weakadr_to_int(self, wadr):
-        assert lltype.typeOf(wadr) == llmemory.WeakGcAddress
-        return wadr.cast_to_int()
-    
-    def op_cast_int_to_float(self, i):
-        assert type(i) is int
-        return float(i)
-
-    def op_cast_int_to_char(self, b):
-        assert type(b) is int
-        return chr(b)
-
-    def op_cast_bool_to_int(self, b):
-        assert type(b) is bool
-        return int(b)
-
-    def op_cast_bool_to_uint(self, b):
-        assert type(b) is bool
-        return r_uint(int(b))
-
-    def op_cast_bool_to_float(self, b):
-        assert type(b) is bool
-        return float(b)
-
-    def op_bool_not(self, b):
-        assert type(b) is bool
-        return not b
-
-    def op_cast_float_to_int(self, f):
-        assert type(f) is float
-        return ovfcheck(int(f))
-
-    def op_cast_float_to_uint(self, f):
-        assert type(f) is float
-        return r_uint(int(f))
-
-    def op_cast_char_to_int(self, b):
-        assert type(b) is str and len(b) == 1
-        return ord(b)
-
-    def op_cast_unichar_to_int(self, b):
-        assert type(b) is unicode and len(b) == 1
-        return ord(b)
-
-    def op_cast_int_to_unichar(self, b):
-        assert type(b) is int 
-        return unichr(b)
-
-    def op_cast_int_to_uint(self, b):
-        assert type(b) is int
-        return r_uint(b)
-
-    def op_cast_uint_to_int(self, b):
-        assert type(b) is r_uint
-        return intmask(b)
-
-    def op_cast_int_to_longlong(self, b):
-        assert type(b) is int
-        return r_longlong(b)
-
-    def op_truncate_longlong_to_int(self, b):
-        assert type(b) is r_longlong
-        assert -sys.maxint-1 <= b <= sys.maxint
-        return int(b)
-
-    def op_float_floor(self, b):
-        assert type(b) is float
-        return math.floor(b)
-
-    def op_float_fmod(self, b,c):
-        assert type(b) is float
-        assert type(c) is float
-        return math.fmod(b,c)
-
-    def op_float_pow(self, b,c):
-        assert type(b) is float
-        assert type(c) is float
-        return math.pow(b,c)
 
     def op_gc__collect(self):
         import gc
@@ -781,12 +614,12 @@
 
 
     # operations on pyobjects!
-    for opname in opimpls.keys():
+    for opname in lloperation.opimpls.keys():
         exec py.code.Source("""
         def op_%(opname)s(self, *pyobjs):
             for pyo in pyobjs:
                 assert lltype.typeOf(pyo) == lltype.Ptr(lltype.PyObject)
-            func = opimpls[%(opname)r]
+            func = lloperation.opimpls[%(opname)r]
             try:
                 pyo = func(*[pyo._obj.value for pyo in pyobjs])
             except Exception:
@@ -814,198 +647,98 @@
         return self.heap.raw_malloc_usage(size)
 
     def op_raw_free(self, addr):
-        assert checkadr(addr) 
+        checkadr(addr) 
         self.heap.raw_free(addr)
 
     def op_raw_memcopy(self, fromaddr, toaddr, size):
-        assert checkadr(fromaddr)
-        assert checkadr(toaddr)
+        checkadr(fromaddr)
+        checkadr(toaddr)
         self.heap.raw_memcopy(fromaddr, toaddr, size)
 
     def op_raw_load(self, addr, typ, offset):
-        assert checkadr(addr)
+        checkadr(addr)
         value = getattr(addr, str(typ).lower())[offset]
         assert lltype.typeOf(value) == typ
         return value
 
     def op_raw_store(self, addr, typ, offset, value):
-        assert checkadr(addr)
+        checkadr(addr)
         assert lltype.typeOf(value) == typ
         getattr(addr, str(typ).lower())[offset] = value
 
-    def op_adr_add(self, addr, offset):
-        assert checkadr(addr)
-        assert lltype.typeOf(offset) is lltype.Signed
-        return addr + offset
-
-    def op_adr_sub(self, addr, offset):
-        assert checkadr(addr)
-        assert lltype.typeOf(offset) is lltype.Signed
-        return addr - offset
-
-    def op_adr_delta(self, addr1, addr2):
-        assert checkadr(addr1)
-        assert checkadr(addr2)
-        return addr1 - addr2
-
-    for opname, op in (("eq", "=="), ("ne", "!="), ("le", "<="), ("lt", "<"),
-                       ("gt", ">"), ("ge", ">=")):
-        exec py.code.Source("""
-            def op_adr_%s(self, addr1, addr2):
-                checkadr(addr1)
-                checkadr(addr2)
-                return addr1 %s addr2""" % (opname, op)).compile()
-
-    # __________________________________________________________
-    # primitive operations
-
-    def setup_primitive_operations():
-        for typ in (float, int, r_uint, r_longlong, r_ulonglong):
-            typname = typ.__name__
-            optup = ('add', 'sub', 'mul', 'truediv', 'floordiv',
-                     'mod', 'gt', 'lt', 'ge', 'ne', 'le', 'eq',)
-            overflowing_operations = ('add', 'sub', 'mul', 'floordiv',
-                                      'mod', 'lshift')
-            if typ is r_uint:
-                opnameprefix = 'uint'
-            elif typ is r_longlong:
-                opnameprefix = 'llong'
-            elif typ is r_ulonglong:
-                opnameprefix = 'ullong'
-            else:
-                opnameprefix = typname
-            if typ is not float:
-                optup += 'and_', 'or_', 'lshift', 'rshift', 'xor'
-            for opname in optup:
-                assert opname in opimpls
-                if typ is float and opname == 'floordiv':
-                    continue    # 'floordiv' is for integer types
-                if typ is not float and opname == 'truediv':
-                    continue    # 'truediv' is for floats only
-                if typ is int and opname not in ops_returning_a_bool:
-                    adjust_result = 'intmask'
-                else:
-                    adjust_result = ''
-                pureopname = opname.rstrip('_')
-                yield """
-                    def op_%(opnameprefix)s_%(pureopname)s(self, x, y):
-                        assert isinstance(x, %(typname)s)
-                        assert isinstance(y, %(typname)s)
-                        func = opimpls[%(opname)r]
-                        return %(adjust_result)s(func(x, y))
-                """ % locals()
-
-                suffixes = []
-                if typ is not float:
-                    if opname in ('lshift', 'rshift'):
-                        suffixes.append(('_val', 'ValueError'))
-                    if opname in ('floordiv', 'mod'):
-                        suffixes.append(('_zer', 'ZeroDivisionError'))
-                    if typ is int and opname in overflowing_operations:
-                        for suffix1, exccls1 in suffixes[:]:
-                            suffixes.append(('_ovf'+suffix1,
-                                             '(OverflowError, %s)' % exccls1))
-                        suffixes.append(('_ovf', 'OverflowError'))
-
-                for suffix, exceptionclasses in suffixes:
-                    if '_ovf' in suffix:
-                        opname_ex = opname + '_ovf'
-                    else:
-                        opname_ex = opname
-                    yield """
-                        def op_%(opnameprefix)s_%(pureopname)s%(suffix)s(self, x, y):
-                            assert isinstance(x, %(typname)s)
-                            assert isinstance(y, %(typname)s)
-                            func = opimpls[%(opname_ex)r]
-                            try:
-                                return %(adjust_result)s(func(x, y))
-                            except %(exceptionclasses)s:
-                                self.make_llexception()
-                    """ % locals()
-            for opname in 'is_true', 'neg', 'abs', 'invert':
-                assert opname in opimpls
-                if typ is float and opname == 'invert':
-                    continue
-                if typ is int and opname not in ops_returning_a_bool:
-                    adjust_result = 'intmask'
-                else:
-                    adjust_result = ''
-                yield """
-                    def op_%(opnameprefix)s_%(opname)s(self, x):
-                        assert isinstance(x, %(typname)s)
-                        func = opimpls[%(opname)r]
-                        return %(adjust_result)s(func(x))
-                """ % locals()
-                if typ is int and opname in ('neg', 'abs'):
-                    opname += '_ovf'
-                    yield """
-                        def op_%(opnameprefix)s_%(opname)s(self, x):
-                            assert isinstance(x, %(typname)s)
-                            func = opimpls[%(opname)r]
-                            try:
-                                return %(adjust_result)s(func(x))
-                            except OverflowError:
-                                self.make_llexception()
-                    """ % locals()
-
-        for opname in ('gt', 'lt', 'ge', 'ne', 'le', 'eq'):
-            assert opname in opimpls
-            yield """
-                def op_char_%(opname)s(self, x, y):
-                    assert isinstance(x, str) and len(x) == 1
-                    assert isinstance(y, str) and len(y) == 1
-                    func = opimpls[%(opname)r]
-                    return func(x, y)
-            """ % locals()
-
-    for _src in setup_primitive_operations():
-        exec py.code.Source(_src).compile()
-        del _src
-    del setup_primitive_operations
-
     # ____________________________________________________________
+    # Overflow-detecting variants
 
-    original_int_add = op_int_add
-
-    def op_int_add(self, x, y):
-        if isinstance(x, llmemory.AddressOffset) or isinstance(y, llmemory.AddressOffset) :
-            return x + y
-        else:
-            return self.original_int_add(x, y)
-
-    original_int_add_ovf = op_int_add_ovf
-
-    def op_int_add_ovf(self, x, y):
-        if isinstance(x, llmemory.AddressOffset) or isinstance(y, llmemory.AddressOffset) :
-            return x + y
-        else:
-            return self.original_int_add_ovf(x, y)
+    def op_int_neg_ovf(self, x):
+        assert type(x) is int
+        try:
+            return ovfcheck(-x)
+        except OverflowError:
+            self.make_llexception()
 
-    original_int_mul = op_int_mul
+    def op_int_abs_ovf(self, x):
+        assert type(x) is int
+        try:
+            return ovfcheck(abs(x))
+        except OverflowError:
+            self.make_llexception()
 
-    def op_int_mul(self, x, y):
-        if isinstance(x, llmemory.AddressOffset):
-            return x * y
+    def _makefunc2(fn, operator, xtype, ytype=None):
+        import sys
+        d = sys._getframe(1).f_locals
+        if ytype is None:
+            ytype = xtype
+        if '_ovf' in fn:
+            checkfn = 'ovfcheck'
+        elif fn.startswith('op_int_'):
+            checkfn = 'intmask'
         else:
-            return self.original_int_mul(x, y)
+            checkfn = ''
+        exec py.code.Source("""
+        def %(fn)s(self, x, y):
+            assert isinstance(x, %(xtype)s)
+            assert isinstance(y, %(ytype)s)
+            try:
+                return %(checkfn)s(x %(operator)s y)
+            except (OverflowError, ValueError, ZeroDivisionError):
+                self.make_llexception()
+        """ % locals()).compile() in globals(), d
 
-    original_int_mul_ovf = op_int_mul_ovf
+    _makefunc2('op_int_add_ovf', '+', '(int, llmemory.AddressOffset)')
+    _makefunc2('op_int_mul_ovf', '*', '(int, llmemory.AddressOffset)', 'int')
+    _makefunc2('op_int_sub_ovf',          '-',  'int')
+    _makefunc2('op_int_floordiv_ovf',     '//', 'int')
+    _makefunc2('op_int_floordiv_zer',     '//', 'int')
+    _makefunc2('op_int_floordiv_ovf_zer', '//', 'int')
+    _makefunc2('op_int_mod_ovf',          '%',  'int')
+    _makefunc2('op_int_mod_zer',          '%',  'int')
+    _makefunc2('op_int_mod_ovf_zer',      '%',  'int')
+    _makefunc2('op_int_lshift_ovf',       '<<', 'int')
+    _makefunc2('op_int_lshift_val',       '<<', 'int')
+    _makefunc2('op_int_lshift_ovf_val',   '<<', 'int')
+    _makefunc2('op_int_rshift_val',       '>>', 'int')
+
+    _makefunc2('op_uint_floordiv_zer',    '//', 'r_uint')
+    _makefunc2('op_uint_mod_zer',         '%',  'r_uint')
+    _makefunc2('op_uint_lshift_val',      '<<', 'r_uint')
+    _makefunc2('op_uint_rshift_val',      '>>', 'r_uint')
+
+    _makefunc2('op_llong_floordiv_zer',   '//', 'r_longlong')
+    _makefunc2('op_llong_mod_zer',        '%',  'r_longlong')
+    _makefunc2('op_llong_lshift_val',     '<<', 'r_longlong')
+    _makefunc2('op_llong_rshift_val',     '>>', 'r_longlong')
+
+    _makefunc2('op_ullong_floordiv_zer',  '//', 'r_ulonglong')
+    _makefunc2('op_ullong_mod_zer',       '%',  'r_ulonglong')
+    _makefunc2('op_ullong_lshift_val',    '<<', 'r_ulonglong')
+    _makefunc2('op_ullong_rshift_val',    '>>', 'r_ulonglong')
 
-    def op_int_mul_ovf(self, x, y):
-        if isinstance(x, llmemory.AddressOffset):
-            return x * y
-        else:
-            return self.original_int_mul_ovf(x, y)
-
-    def op_unichar_eq(self, x, y):
-        assert isinstance(x, unicode) and len(x) == 1
-        assert isinstance(y, unicode) and len(y) == 1
-        return x == y
-
-    def op_unichar_ne(self, x, y):
-        assert isinstance(x, unicode) and len(x) == 1
-        assert isinstance(y, unicode) and len(y) == 1
-        return x != y
+    def op_cast_float_to_int(self, f):
+        assert type(f) is float
+        try:
+            return ovfcheck(int(f))
+        except OverflowError:
+            self.make_llexception()
 
     #Operation of ootype
 
@@ -1031,19 +764,19 @@
         return ootype.oonewcustomdict(DICT, sm_eq, sm_hash)
 
     def op_oosetfield(self, inst, name, value):
-        assert checkinst(inst)
+        checkinst(inst)
         assert isinstance(name, str)
         FIELDTYPE = lltype.typeOf(inst)._field_type(name)
         if FIELDTYPE != lltype.Void:
             setattr(inst, name, value)
 
     def op_oogetfield(self, inst, name):
-        assert checkinst(inst)
+        checkinst(inst)
         assert isinstance(name, str)
         return getattr(inst, name)
 
     def op_oosend(self, message, inst, *args):
-        assert checkinst(inst)
+        checkinst(inst)
         assert isinstance(message, str)
         bm = getattr(inst, message)
         inst = bm.inst
@@ -1055,17 +788,19 @@
 
     def op_ooupcast(self, INST, inst):
         return ootype.ooupcast(INST, inst)
+    op_ooupcast.need_result_type = True
     
     def op_oodowncast(self, INST, inst):
         return ootype.oodowncast(INST, inst)
+    op_oodowncast.need_result_type = True
 
     def op_oononnull(self, inst):
-        assert checkinst(inst)
+        checkinst(inst)
         return bool(inst)
 
     def op_oois(self, obj1, obj2):
-        if checkinst(obj1):
-            assert checkinst(obj2)
+        if is_inst(obj1):
+            checkinst(obj2)
             return obj1 == obj2   # NB. differently-typed NULLs must be equal
         elif isinstance(obj1, ootype._class):
             assert isinstance(obj2, ootype._class)

Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py	Sun Jun 25 12:35:09 2006
@@ -43,7 +43,23 @@
     __name__ = property(lambda self: 'llop_'+self.opname)
 
     def __call__(self, RESULTTYPE, *args):
-        raise TypeError, "llop is meant to be rtyped and not called direclty"
+        # llop is meant to be rtyped and not called directly, unless it is
+        # a canfold=True operation
+        fold = self.fold
+        if getattr(fold, 'need_result_type', False):
+            return fold(RESULTTYPE, *args)
+        else:
+            return fold(*args)
+
+    def fold(self, RESULTTYPE, *args):
+        if not self.canfold:
+            raise TypeError, "cannot constant-fold operation %r" % (
+                self.opname,)
+        from pypy.rpython.lltypesystem.opimpl import get_op_impl
+        # cache the implementation function into 'self'
+        self.fold = get_op_impl(self.opname)
+        return self(RESULTTYPE, *args)
+    fold.need_result_type = True
 
 
 def enum_ops_without_sideeffects(raising_is_ok=False):
@@ -258,7 +274,7 @@
     'cast_int_to_float':    LLOp(canfold=True),
     'cast_int_to_longlong': LLOp(canfold=True),
     'cast_uint_to_int':     LLOp(canfold=True),
-    'cast_float_to_int':    LLOp(canfold=True),
+    'cast_float_to_int':    LLOp(canraise=(OverflowError,)),
     'cast_float_to_uint':   LLOp(canfold=True),
     'truncate_longlong_to_int':LLOp(canfold=True),
 
@@ -374,11 +390,11 @@
 
 from pypy.objspace.flow.operation import FunctionByName
 opimpls = FunctionByName.copy()
-opimpls['is_true'] = True
-opimpls['simple_call'] = True
+opimpls['is_true'] = bool
 for opname in opimpls:
     LL_OPERATIONS[opname] = LLOp(canraise=(Exception,), pyobj=True)
-del opname, opimpls, FunctionByName
+LL_OPERATIONS['simple_call'] = LLOp(canraise=(Exception,), pyobj=True)
+del opname, FunctionByName
 
 # ____________________________________________________________
 # Post-processing

Added: pypy/dist/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/lltypesystem/opimpl.py	Sun Jun 25 12:35:09 2006
@@ -0,0 +1,332 @@
+import sys
+from pypy.tool.sourcetools import func_with_new_name
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem.lloperation import opimpls
+
+# ____________________________________________________________
+# Implementation of the 'canfold' operations
+
+
+# implementations of ops from flow.operation
+ops_returning_a_bool = {'gt': True, 'ge': True,
+                        'lt': True, 'le': True,
+                        'eq': True, 'ne': True,
+                        'is_true': True}
+ops_unary = {'is_true': True, 'neg': True, 'abs': True, 'invert': True}
+
+# global synonyms for some types
+from pypy.rpython.rarithmetic import intmask
+from pypy.rpython.rarithmetic import r_uint, r_longlong, r_ulonglong
+
+type_by_name = {
+    'int': int,
+    'float': float,
+    'uint': r_uint,
+    'llong': r_longlong,
+    'ullong': r_ulonglong,
+    }
+
+def no_op(x):
+    return x
+
+def get_primitive_op_src(fullopname):
+    assert '_' in fullopname, "%s: not a primitive op" % (fullopname,)
+    typname, opname = fullopname.split('_', 1)
+    if opname not in opimpls and (opname + '_') in opimpls:
+        func = opimpls[opname + '_']   # or_, and_
+    else:
+        assert opname in opimpls, "%s: not a primitive op" % (fullopname,)
+        func = opimpls[opname]
+
+    if typname == 'char':
+        # char_lt, char_eq, ...
+        def op_function(x, y):
+            if not isinstance(x, str) or len(x) != 1:
+                raise TypeError("%r arg must be a char, got %r instead" % (
+                    fullopname, typname, type(x).__name__))
+            if not isinstance(y, str) or len(y) != 1:
+                raise TypeError("%r arg must be a char, got %r instead" % (
+                    fullopname, typname, type(y).__name__))
+            return func(x, y)
+
+    else:
+        if typname == 'int' and opname not in ops_returning_a_bool:
+            adjust_result = intmask
+        else:
+            adjust_result = no_op
+        assert typname in type_by_name, "%s: not a primitive op" % (
+            fullopname,)
+        argtype = type_by_name[typname]
+
+        if opname in ops_unary:
+            def op_function(x):
+                if not isinstance(x, argtype):
+                    raise TypeError("%r arg must be %s, got %r instead" % (
+                        fullopname, typname, type(x).__name__))
+                return adjust_result(func(x))
+        else:
+            def op_function(x, y):
+                if not isinstance(x, argtype):
+                    raise TypeError("%r arg 1 must be %s, got %r instead" % (
+                        fullopname, typname, type(x).__name__))
+                if not isinstance(y, argtype):
+                    raise TypeError("%r arg 2 must be %s, got %r instead" % (
+                        fullopname, typname, type(y).__name__))
+                return adjust_result(func(x, y))
+
+    return func_with_new_name(op_function, 'op_' + fullopname)
+
+def checkptr(ptr):
+    if not isinstance(lltype.typeOf(ptr), lltype.Ptr):
+        raise TypeError("arg must be a pointer, got %r instead" % (
+            typeOf(ptr),))
+
+def checkadr(adr):
+    if lltype.typeOf(adr) is not llmemory.Address:
+        raise TypeError("arg must be an address, got %r instead" % (
+            typeOf(adr),))
+
+
+def op_ptr_eq(ptr1, ptr2):
+    checkptr(ptr1)
+    checkptr(ptr2)
+    return ptr1 == ptr2
+
+def op_ptr_ne(ptr1, ptr2):
+    checkptr(ptr1)
+    checkptr(ptr2)
+    return ptr1 != ptr2
+
+def op_ptr_nonzero(ptr1):
+    checkptr(ptr1)
+    return bool(ptr1)
+
+def op_ptr_iszero(ptr1):
+    checkptr(ptr1)
+    return not bool(ptr1)
+
+def op_getsubstruct(obj, field):
+    checkptr(obj)
+    # check the difference between op_getfield and op_getsubstruct:
+    assert isinstance(getattr(lltype.typeOf(obj).TO, field),
+                      lltype.ContainerType)
+    return getattr(obj, field)
+
+def op_getarraysubstruct(array, index):
+    checkptr(array)
+    result = array[index]
+    return result
+    # the diff between op_getarrayitem and op_getarraysubstruct
+    # is the same as between op_getfield and op_getsubstruct
+
+def op_getarraysize(array):
+    checkptr(array)
+    return len(array)
+
+def op_direct_fieldptr(obj, field):
+    checkptr(obj)
+    assert isinstance(field, str)
+    return lltype.direct_fieldptr(obj, field)
+
+def op_direct_arrayitems(obj):
+    checkptr(obj)
+    return lltype.direct_arrayitems(obj)
+
+def op_direct_ptradd(obj, index):
+    checkptr(obj)
+    assert isinstance(index, int)
+    return lltype.direct_ptradd(obj, index)
+
+
+def op_bool_not(b):
+    assert type(b) is bool
+    return not b
+
+def op_int_add(x, y):
+    assert isinstance(x, (int, llmemory.AddressOffset))
+    assert isinstance(y, (int, llmemory.AddressOffset))
+    return intmask(x + y)
+
+def op_int_mul(x, y):
+    assert isinstance(x, (int, llmemory.AddressOffset))
+    assert isinstance(y, int)
+    return intmask(x * y)
+
+
+def op_same_as(x):
+    return x
+
+def op_cast_primitive(TYPE, value):
+    assert isinstance(lltype.typeOf(value), lltype.Primitive)
+    return lltype.cast_primitive(TYPE, value)
+op_cast_primitive.need_result_type = True
+
+def op_cast_int_to_float(i):
+    assert type(i) is int
+    return float(i)
+
+def op_cast_int_to_char(b):
+    assert type(b) is int
+    return chr(b)
+
+def op_cast_bool_to_int(b):
+    assert type(b) is bool
+    return int(b)
+
+def op_cast_bool_to_uint(b):
+    assert type(b) is bool
+    return r_uint(int(b))
+
+def op_cast_bool_to_float(b):
+    assert type(b) is bool
+    return float(b)
+
+def op_cast_float_to_uint(f):
+    assert type(f) is float
+    return r_uint(int(f))
+
+def op_cast_char_to_int(b):
+    assert type(b) is str and len(b) == 1
+    return ord(b)
+
+def op_cast_unichar_to_int(b):
+    assert type(b) is unicode and len(b) == 1
+    return ord(b)
+
+def op_cast_int_to_unichar(b):
+    assert type(b) is int 
+    return unichr(b)
+
+def op_cast_int_to_uint(b):
+    assert type(b) is int
+    return r_uint(b)
+
+def op_cast_uint_to_int(b):
+    assert type(b) is r_uint
+    return intmask(b)
+
+def op_cast_int_to_longlong(b):
+    assert type(b) is int
+    return r_longlong(b)
+
+def op_truncate_longlong_to_int(b):
+    assert type(b) is r_longlong
+    assert -sys.maxint-1 <= b <= sys.maxint
+    return int(b)
+
+def op_float_floor(b):
+    assert type(b) is float
+    return math.floor(b)
+
+def op_float_fmod(b,c):
+    assert type(b) is float
+    assert type(c) is float
+    return math.fmod(b,c)
+
+def op_float_pow(b,c):
+    assert type(b) is float
+    assert type(c) is float
+    return math.pow(b,c)
+
+
+def op_cast_pointer(RESTYPE, obj):
+    checkptr(obj)
+    return lltype.cast_pointer(RESTYPE, obj)
+op_cast_pointer.need_result_type = True
+
+def op_cast_opaque_ptr(RESTYPE, obj):
+    checkptr(obj)
+    return lltype.cast_opaque_ptr(RESTYPE, obj)
+op_cast_opaque_ptr.need_result_type = True
+
+def op_cast_ptr_to_weakadr(ptr):
+    checkptr(ptr)
+    return llmemory.cast_ptr_to_weakadr(ptr)
+
+def op_cast_weakadr_to_ptr(TYPE, wadr):
+    assert lltype.typeOf(wadr) == llmemory.WeakGcAddress
+    return llmemory.cast_weakadr_to_ptr(wadr, TYPE)
+op_cast_weakadr_to_ptr.need_result_type = True
+
+def op_cast_weakadr_to_int(wadr):
+    assert lltype.typeOf(wadr) == llmemory.WeakGcAddress
+    return wadr.cast_to_int()
+
+def op_cast_ptr_to_adr(ptr):
+    checkptr(ptr)
+    return llmemory.cast_ptr_to_adr(ptr)
+
+def op_cast_adr_to_ptr(TYPE, adr):
+    checkadr(adr)
+    return llmemory.cast_adr_to_ptr(adr, TYPE)
+op_cast_adr_to_ptr.need_result_type = True
+
+def op_cast_adr_to_int(adr):
+    checkadr(adr)
+    return llmemory.cast_adr_to_int(adr)
+
+
+def op_unichar_eq(x, y):
+    assert isinstance(x, unicode) and len(x) == 1
+    assert isinstance(y, unicode) and len(y) == 1
+    return x == y
+
+def op_unichar_ne(x, y):
+    assert isinstance(x, unicode) and len(x) == 1
+    assert isinstance(y, unicode) and len(y) == 1
+    return x != y
+
+
+def op_adr_lt(addr1, addr2):
+    checkadr(addr1)
+    checkadr(addr2)
+    return addr1 < addr2
+
+def op_adr_le(addr1, addr2):
+    checkadr(addr1)
+    checkadr(addr2)
+    return addr1 <= addr2
+
+def op_adr_eq(addr1, addr2):
+    checkadr(addr1)
+    checkadr(addr2)
+    return addr1 == addr2
+
+def op_adr_ne(addr1, addr2):
+    checkadr(addr1)
+    checkadr(addr2)
+    return addr1 != addr2
+
+def op_adr_gt(addr1, addr2):
+    checkadr(addr1)
+    checkadr(addr2)
+    return addr1 > addr2
+
+def op_adr_ge(addr1, addr2):
+    checkadr(addr1)
+    checkadr(addr2)
+    return addr1 >= addr2
+
+def op_adr_add(addr, offset):
+    checkadr(addr)
+    assert lltype.typeOf(offset) is lltype.Signed
+    return addr + offset
+
+def op_adr_sub(addr, offset):
+    checkadr(addr)
+    assert lltype.typeOf(offset) is lltype.Signed
+    return addr - offset
+
+def op_adr_delta(addr1, addr2):
+    checkadr(addr1)
+    checkadr(addr2)
+    return addr1 - addr2
+
+# ____________________________________________________________
+
+def get_op_impl(opname):
+    # get the op_xxx() function from the globals above
+    try:
+        return globals()['op_' + opname]
+    except KeyError:
+        return get_primitive_op_src(opname)

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py	Sun Jun 25 12:35:09 2006
@@ -1,9 +1,8 @@
 from pypy.rpython.lltypesystem.lloperation import LL_OPERATIONS, llop
+from pypy.rpython.lltypesystem import lltype, opimpl
 from pypy.rpython.llinterp import LLFrame
 from pypy.rpython.test.test_llinterp import interpret
 
-# This tests that the LLInterpreter and the LL_OPERATIONS tables are in sync.
-
 LL_INTERP_OPERATIONS = [name[3:] for name in LLFrame.__dict__.keys()
                                  if name.startswith('op_')
 # Ignore OO operations for now
@@ -14,21 +13,37 @@
                                              name == 'op_runtimenew' or
                                              name.startswith('op_oo'))]
 
+# ____________________________________________________________
+
+def test_canfold_opimpl_complete():
+    for opname, llop in LL_OPERATIONS.items():
+        assert opname == llop.opname
+        if llop.canfold:
+            func = opimpl.get_op_impl(opname)
+            assert callable(func)
+
+def test_llop_fold():
+    assert llop.int_add(lltype.Signed, 10, 2) == 12
+    assert llop.int_add(lltype.Signed, -6, -7) == -13
+
+def test_llop_interp():
+    from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy
+    def llf(x, y):
+        return llop.int_add(lltype.Signed, x, y)
+    res = interpret(llf, [5, 7], policy=LowLevelAnnotatorPolicy())
+    assert res == 12
+
+# ___________________________________________________________________________
+# This tests that the LLInterpreter and the LL_OPERATIONS tables are in sync.
 
 def test_table_complete():
     for opname in LL_INTERP_OPERATIONS:
         assert opname in LL_OPERATIONS
 
 def test_llinterp_complete():
-    for opname in LL_OPERATIONS:
+    for opname, llop in LL_OPERATIONS.items():
+        if llop.canfold:
+            continue
         if opname.startswith('gc_x_'):
             continue   # ignore experimental stuff
         assert opname in LL_INTERP_OPERATIONS
-
-def test_llop():
-    from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy
-    from pypy.rpython.lltypesystem import lltype
-    def llf(x, y):
-        return llop.int_add(lltype.Signed, x, y)
-    res = interpret(llf, [5, 7], policy=LowLevelAnnotatorPolicy())
-    assert res == 12

Modified: pypy/dist/pypy/rpython/rarithmetic.py
==============================================================================
--- pypy/dist/pypy/rpython/rarithmetic.py	(original)
+++ pypy/dist/pypy/rpython/rarithmetic.py	Sun Jun 25 12:35:09 2006
@@ -29,7 +29,7 @@
 
 """
 import math
-from pypy.rpython import extregistry
+from pypy.rpython import extregistry, objectmodel
 
 # set up of machine internals
 _bits = 0
@@ -49,6 +49,8 @@
         return int(n)   # possibly bool->int
     if isinstance(n, unsigned_int):
         n = long(n)
+    elif isinstance(n, objectmodel.Symbolic):
+        return n        # assume Symbolics don't overflow
     n &= LONG_MASK
     if n >= LONG_TEST:
         n -= 2*LONG_TEST


From arigo at codespeak.net  Sun Jun 25 12:50:36 2006
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sun, 25 Jun 2006 12:50:36 +0200 (CEST)
Subject: [pypy-svn] r29308 - in pypy/dist/pypy/rpython/lltypesystem: . test
Message-ID: <20060625105036.C687310075@code0.codespeak.net>

Author: arigo
Date: Sun Jun 25 12:50:33 2006
New Revision: 29308

Modified:
   pypy/dist/pypy/rpython/lltypesystem/lloperation.py
   pypy/dist/pypy/rpython/lltypesystem/opimpl.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py
Log:
Allow constant-folding getfield and getarrayitem when 'immutable'.


Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py	Sun Jun 25 12:50:33 2006
@@ -52,12 +52,16 @@
             return fold(*args)
 
     def fold(self, RESULTTYPE, *args):
-        if not self.canfold:
-            raise TypeError, "cannot constant-fold operation %r" % (
-                self.opname,)
-        from pypy.rpython.lltypesystem.opimpl import get_op_impl
+        if self.canfold or self.opname in ('getfield', 'getarrayitem'):
+            from pypy.rpython.lltypesystem.opimpl import get_op_impl
+            op_impl = get_op_impl(self.opname)
+        else:
+            error = TypeError("cannot constant-fold operation %r" % (
+                self.opname,))
+            def op_impl(*args):
+                raise error
         # cache the implementation function into 'self'
-        self.fold = get_op_impl(self.opname)
+        self.fold = op_impl
         return self(RESULTTYPE, *args)
     fold.need_result_type = True
 

Modified: pypy/dist/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/opimpl.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/opimpl.py	Sun Jun 25 12:50:33 2006
@@ -322,6 +322,18 @@
     checkadr(addr2)
     return addr1 - addr2
 
+def op_getfield(p, name):
+    checkptr(p)
+    if not lltype.typeOf(p).TO._hints.get('immutable'):
+        raise TypeError("cannot fold getfield on mutable struct")
+    return getattr(p, name)
+
+def op_getarrayitem(p, index):
+    checkptr(p)
+    if not lltype.typeOf(p).TO._hints.get('immutable'):
+        raise TypeError("cannot fold getfield on mutable array")
+    return p[index]
+
 # ____________________________________________________________
 
 def get_op_impl(opname):

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py	Sun Jun 25 12:50:33 2006
@@ -1,3 +1,4 @@
+import py
 from pypy.rpython.lltypesystem.lloperation import LL_OPERATIONS, llop
 from pypy.rpython.lltypesystem import lltype, opimpl
 from pypy.rpython.llinterp import LLFrame
@@ -25,6 +26,14 @@
 def test_llop_fold():
     assert llop.int_add(lltype.Signed, 10, 2) == 12
     assert llop.int_add(lltype.Signed, -6, -7) == -13
+    S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True})
+    s1 = lltype.malloc(S1)
+    s1.x = 123
+    assert llop.getfield(lltype.Signed, s1, 'x') == 123
+    S2 = lltype.GcStruct('S2', ('x', lltype.Signed))
+    s2 = lltype.malloc(S2)
+    s2.x = 123
+    py.test.raises(TypeError, "llop.getfield(lltype.Signed, s2, 'x')")
 
 def test_llop_interp():
     from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy


From arigo at codespeak.net  Sun Jun 25 13:20:28 2006
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sun, 25 Jun 2006 13:20:28 +0200 (CEST)
Subject: [pypy-svn] r29310 -
	pypy/release/0.9.x/pypy/interpreter/stablecompiler
Message-ID: <20060625112028.1685110072@code0.codespeak.net>

Author: arigo
Date: Sun Jun 25 13:20:25 2006
New Revision: 29310

Modified:
   pypy/release/0.9.x/pypy/interpreter/stablecompiler/transformer.py
Log:
Backport r29294.


Modified: pypy/release/0.9.x/pypy/interpreter/stablecompiler/transformer.py
==============================================================================
--- pypy/release/0.9.x/pypy/interpreter/stablecompiler/transformer.py	(original)
+++ pypy/release/0.9.x/pypy/interpreter/stablecompiler/transformer.py	Sun Jun 25 13:20:25 2006
@@ -48,8 +48,8 @@
     setattr(symbol, name, value)
 
 # transforming is requiring a lot of recursion depth so make sure we have enough
-if sys.getrecursionlimit()<5000:
-    sys.setrecursionlimit(5000)
+if sys.getrecursionlimit()<2000:
+    sys.setrecursionlimit(2000)
 
 
 class WalkerError(StandardError):


From arigo at codespeak.net  Sun Jun 25 15:44:23 2006
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sun, 25 Jun 2006 15:44:23 +0200 (CEST)
Subject: [pypy-svn] r29316 - in pypy/dist/pypy: rpython/lltypesystem
	translator/backendopt translator/backendopt/test
Message-ID: <20060625134423.AB3831007A@code0.codespeak.net>

Author: arigo
Date: Sun Jun 25 15:44:18 2006
New Revision: 29316

Added:
   pypy/dist/pypy/translator/backendopt/constfold.py   (contents, props changed)
   pypy/dist/pypy/translator/backendopt/test/test_constfold.py   (contents, props changed)
Modified:
   pypy/dist/pypy/rpython/lltypesystem/lloperation.py
   pypy/dist/pypy/translator/backendopt/all.py
   pypy/dist/pypy/translator/backendopt/test/test_all.py
   pypy/dist/pypy/translator/backendopt/test/test_propagate.py
Log:
Experiment with a simple constant-folding backend-opt, based on calling
llop.opname().



Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py	Sun Jun 25 15:44:18 2006
@@ -47,11 +47,16 @@
         # a canfold=True operation
         fold = self.fold
         if getattr(fold, 'need_result_type', False):
-            return fold(RESULTTYPE, *args)
+            val = fold(RESULTTYPE, *args)
         else:
-            return fold(*args)
+            val = fold(*args)
+        if RESULTTYPE is not lltype.Void:
+            val = lltype.enforce(RESULTTYPE, val)
+        return val
 
     def fold(self, RESULTTYPE, *args):
+        global lltype                 #  <- lazy import hack, worth an XXX
+        from pypy.rpython.lltypesystem import lltype
         if self.canfold or self.opname in ('getfield', 'getarrayitem'):
             from pypy.rpython.lltypesystem.opimpl import get_op_impl
             op_impl = get_op_impl(self.opname)

Modified: pypy/dist/pypy/translator/backendopt/all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/all.py	(original)
+++ pypy/dist/pypy/translator/backendopt/all.py	Sun Jun 25 15:44:18 2006
@@ -3,6 +3,7 @@
 from pypy.translator.backendopt import inline
 from pypy.translator.backendopt.malloc import remove_simple_mallocs
 from pypy.translator.backendopt.propagate import propagate_all
+from pypy.translator.backendopt.constfold import constant_fold_graph
 from pypy.translator.backendopt.stat import print_statistics
 from pypy.translator.backendopt.merge_if_blocks import merge_if_blocks
 from pypy.translator import simplify
@@ -19,6 +20,7 @@
                                       mallocs=True,
                                       merge_if_blocks_to_switch=True,
                                       propagate=False,
+                                      constfold=False,
                                       heap2stack=False,
                                       clever_malloc_removal=False):
 
@@ -86,6 +88,10 @@
             print "after clever inlining and malloc removal"
             print_statistics(translator.graphs[0], translator)
 
+    if constfold:
+        for graph in graphs:
+            constant_fold_graph(graph)
+
     if propagate:
         assert graphs is translator.graphs  # XXX for now
         propagate_all(translator)

Added: pypy/dist/pypy/translator/backendopt/constfold.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/backendopt/constfold.py	Sun Jun 25 15:44:18 2006
@@ -0,0 +1,117 @@
+from pypy.objspace.flow.model import Constant, Variable, SpaceOperation
+from pypy.translator.backendopt.support import split_block_with_keepalive
+from pypy.translator.simplify import eliminate_empty_blocks
+from pypy.rpython.lltypesystem.lloperation import llop
+from pypy.rpython.lltypesystem import lltype
+
+
+def fold_op_list(operations, constants, exit_early=False):
+    newops = []
+    folded_count = 0
+    for spaceop in operations:
+        vargsmodif = False
+        vargs = []
+        args = []
+        for v in spaceop.args:
+            if isinstance(v, Constant):
+                args.append(v.value)
+            elif v in constants:
+                v = constants[v]
+                vargsmodif = True
+                args.append(v.value)
+            vargs.append(v)
+        if len(args) == len(vargs):
+            RESTYPE = spaceop.result.concretetype
+            op = getattr(llop, spaceop.opname)
+            try:
+                result = op(RESTYPE, *args)
+            except TypeError:
+                pass
+            else:
+                # success in folding this space operation
+                constants[spaceop.result] = Constant(result, RESTYPE)
+                folded_count += 1
+                continue
+        # failed to fold an operation, exit early if requested
+        if exit_early:
+            return folded_count
+        if vargsmodif:
+            spaceop = SpaceOperation(spaceop.opname, vargs, spaceop.result)
+        newops.append(spaceop)
+    # end
+    if exit_early:
+        return folded_count
+    else:
+        return newops
+
+def constant_fold_block(block):
+    constants = {}
+    block.operations = fold_op_list(block.operations, constants)
+    if constants:
+        if block.exitswitch in constants:
+            switch = constants[block.exitswitch].value
+            remaining_exits = [link for link in block.exits
+                                    if link.llexitcase == switch]
+            assert len(remaining_exits) == 1
+            remaining_exits[0].exitcase = None
+            remaining_exits[0].llexitcase = None
+            block.exitswitch = None
+            block.recloseblock(*remaining_exits)
+        for link in block.exits:
+            link.args = [constants.get(v, v) for v in link.args]
+
+def prepare_constant_fold_link(link, constants, splitblocks):
+    folded_count = fold_op_list(link.target.operations, constants,
+                                exit_early=True)
+    if folded_count > 0:
+        splits = splitblocks.setdefault(link.target, [])
+        splits.append((folded_count, link, constants))
+
+def rewire_links(splitblocks):
+    for block, splits in splitblocks.items():
+        # A splitting position is given by how many operations were
+        # folded with the knowledge of an incoming link's constant.
+        # Various incoming links may cause various splitting positions.
+        # We split the block gradually, starting from the end.
+        splits.sort()
+        splits.reverse()
+        for position, link, constants in splits:
+            if position == len(block.operations) and block.exitswitch is None:
+                # a split here would leave nothing in the 2nd part, so
+                # directly rewire the links
+                assert len(block.exits) == 1
+                splitlink = block.exits[0]
+            else:
+                # split the block at the given position
+                splitlink = split_block_with_keepalive(block, position)
+                assert block.exits == [splitlink]
+            # 'constants' maps some Variables of 'block' to Constants.
+            # Some input args of 'block' may be absent from 'constants'
+            # and must be fixed in the link to be passed directly from
+            # the origin of the link instead of via 'block'.
+            for v1, v2 in zip(link.args, link.target.inputargs):
+                constants.setdefault(v2, v1)
+            args = [constants.get(v, v) for v in splitlink.args]
+            link.args = args
+            link.target = splitlink.target
+
+
+def constant_fold_graph(graph):
+    # first fold inside the blocks
+    for block in graph.iterblocks():
+        if block.operations:
+            constant_fold_block(block)
+    # then fold along the links - a fixpoint process, because new links
+    # with new constants show up
+    while 1:
+        splitblocks = {}
+        for link in graph.iterlinks():
+            constants = {}
+            for v1, v2 in zip(link.args, link.target.inputargs):
+                if isinstance(v1, Constant):
+                    constants[v2] = v1
+            if constants:
+                prepare_constant_fold_link(link, constants, splitblocks)
+        if not splitblocks:
+            break   # finished
+        rewire_links(splitblocks)

Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_all.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_all.py	Sun Jun 25 15:44:18 2006
@@ -135,15 +135,17 @@
         c = [i for i in range(n2)]
         return 33 + big() + g(10)
 
-    t  = translateopt(idempotent, [int, int], raisingop2direct_call_all=True)
+    t  = translateopt(idempotent, [int, int], raisingop2direct_call_all=True,
+                      constfold=False)
     digest1 = md5digest(t)
 
     digest2 = md5digest(t)
     assert digest1 == digest2
 
-    #XXX Inlining is currently non-idempotent.
-    #    Maybe it just renames variables but it changes the graph in some way.
-    backend_optimizations(t, raisingop2direct_call_all=True, inline_threshold=0)
+    #XXX Inlining and constfold are currently non-idempotent.
+    #    Maybe they just renames variables but the graph changes in some way.
+    backend_optimizations(t, raisingop2direct_call_all=True,
+                          inline_threshold=0, constfold=False)
     digest3 = md5digest(t)
     assert digest1 == digest3
 

Added: pypy/dist/pypy/translator/backendopt/test/test_constfold.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/backendopt/test/test_constfold.py	Sun Jun 25 15:44:18 2006
@@ -0,0 +1,124 @@
+from pypy.objspace.flow.model import checkgraph, Constant
+from pypy.translator.translator import TranslationContext, graphof
+from pypy.rpython.llinterp import LLInterpreter
+from pypy.rpython.lltypesystem import lltype
+from pypy.translator.backendopt.constfold import constant_fold_graph
+from pypy import conftest
+
+def get_graph(fn, signature):
+    t = TranslationContext()
+    t.buildannotator().build_types(fn, signature)
+    t.buildrtyper().specialize()
+    graph = graphof(t, fn)
+    if conftest.option.view:
+        t.view()
+    return graph, t
+
+def check_graph(graph, args, expected_result, t):
+    if conftest.option.view:
+        t.view()
+    checkgraph(graph)
+    interp = LLInterpreter(t.rtyper)
+    res = interp.eval_graph(graph, args)
+    assert res == expected_result
+
+def summary(graph):
+    # return a summary of the instructions left in a graph
+    insns = {}
+    for block in graph.iterblocks():
+        for op in block.operations:
+            if op.opname != 'same_as':
+                insns[op.opname] = insns.get(op.opname, 0) + 1
+    return insns
+
+
+def test_simple():
+    S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True})
+    s1 = lltype.malloc(S1)
+    s1.x = 123
+    def g(y):
+        return y + 1
+    def fn():
+        return g(s1.x)
+
+    graph, t = get_graph(fn, [])
+    assert summary(graph) == {'getfield': 1, 'direct_call': 1}
+    constant_fold_graph(graph)
+    assert summary(graph) == {'direct_call': 1}
+    check_graph(graph, [], 124, t)
+
+
+def test_along_link():
+    S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True})
+    s1 = lltype.malloc(S1)
+    s1.x = 123
+    s2 = lltype.malloc(S1)
+    s2.x = 60
+    def fn(x):
+        if x:
+            x = s1.x
+        else:
+            x = s2.x
+        return x+1
+
+    graph, t = get_graph(fn, [int])
+    assert summary(graph) == {'int_is_true': 1,
+                              'getfield': 2,
+                              'int_add': 1}
+    constant_fold_graph(graph)
+    assert summary(graph) == {'int_is_true': 1}
+    check_graph(graph, [-1], 124, t)
+    check_graph(graph, [0], 61, t)
+
+
+def test_multiple_incoming_links():
+    S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True})
+    s1 = lltype.malloc(S1)
+    s1.x = 123
+    s2 = lltype.malloc(S1)
+    s2.x = 60
+    s3 = lltype.malloc(S1)
+    s3.x = 15
+    def fn(x):
+        y = x * 10
+        if x == 1:
+            x = s1.x
+        elif x == 2:
+            x = s2.x
+        elif x == 3:
+            x = s3.x
+            y = s1.x
+        return (x+1) + y
+
+    graph, t = get_graph(fn, [int])
+    constant_fold_graph(graph)
+    assert summary(graph) == {'int_mul': 1, 'int_eq': 3, 'int_add': 2}
+    for link in graph.iterlinks():
+        if Constant(139) in link.args:
+            break
+    else:
+        raise AssertionError("139 not found in the graph as a constant")
+    for i in range(4):
+        check_graph(graph, [i], fn(i), t)
+
+
+def test_fold_exitswitch():
+    S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True})
+    s1 = lltype.malloc(S1)
+    s1.x = 123
+    s2 = lltype.malloc(S1)
+    s2.x = 60
+    def fn(n):
+        if s1.x:
+            return n * 5
+        else:
+            return n - 7
+
+    graph, t = get_graph(fn, [int])
+    assert summary(graph) == {'getfield': 1,
+                              'int_is_true': 1,
+                              'int_mul': 1,
+                              'int_sub': 1}
+    constant_fold_graph(graph)
+    assert summary(graph) == {'int_mul': 1}
+    check_graph(graph, [12], 60, t)

Modified: pypy/dist/pypy/translator/backendopt/test/test_propagate.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_propagate.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_propagate.py	Sun Jun 25 15:44:18 2006
@@ -13,7 +13,7 @@
     t.buildrtyper().specialize()
     if all_opts:
         backend_optimizations(t, inline_threshold=inline_threshold,
-                              propagate=False,
+                              propagate=False, constfold=False,
                               raisingop2direct_call_all=False) 
     graph = graphof(t, fn)
     if conftest.option.view:


From arigo at codespeak.net  Sun Jun 25 16:51:49 2006
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sun, 25 Jun 2006 16:51:49 +0200 (CEST)
Subject: [pypy-svn] r29318 - in pypy/dist/pypy/objspace/std: . test
Message-ID: <20060625145149.9DB6A10079@code0.codespeak.net>

Author: arigo
Date: Sun Jun 25 16:51:45 2006
New Revision: 29318

Modified:
   pypy/dist/pypy/objspace/std/test/test_stringobject.py
   pypy/dist/pypy/objspace/std/test/test_unicodeobject.py
   pypy/dist/pypy/objspace/std/unicodeobject.py
Log:
Fix and test for  u''.split('separator').


Modified: pypy/dist/pypy/objspace/std/test/test_stringobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_stringobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_stringobject.py	Sun Jun 25 16:51:45 2006
@@ -135,6 +135,7 @@
 
     def test_split(self):
         assert "".split() == []
+        assert "".split('x') == ['']
         assert " ".split() == []
         assert "a".split() == ['a']
         assert "a".split("a", 1) == ['', '']

Modified: pypy/dist/pypy/objspace/std/test/test_unicodeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_unicodeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_unicodeobject.py	Sun Jun 25 16:51:45 2006
@@ -72,6 +72,7 @@
 
     def test_split(self):
         assert u"".split() == []
+        assert u"".split(u'x') == ['']
         assert u" ".split() == []
         assert u"a".split() == [u'a']
         assert u"a".split(u"a", 1) == [u'', u'']

Modified: pypy/dist/pypy/objspace/std/unicodeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/unicodeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/unicodeobject.py	Sun Jun 25 16:51:45 2006
@@ -696,8 +696,6 @@
         raise OperationError(space.w_ValueError,
                              space.wrap('empty separator'))
     parts = []
-    if len(self) == 0:
-        return space.newlist([])
     start = 0
     end = len(self)
     while maxsplit != 0:


From arigo at codespeak.net  Sun Jun 25 17:23:35 2006
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sun, 25 Jun 2006 17:23:35 +0200 (CEST)
Subject: [pypy-svn] r29319 - pypy/dist/pypy/module/sys
Message-ID: <20060625152335.EDFEE1007A@code0.codespeak.net>

Author: arigo
Date: Sun Jun 25 17:23:33 2006
New Revision: 29319

Modified:
   pypy/dist/pypy/module/sys/__init__.py
   pypy/dist/pypy/module/sys/state.py
Log:
Add a built-in:  sys.pypy_repr(x), which returns the interp-level repr
of its argument.  Probably works in compiled pypy-c too, but then it
will only show the interp-level class of x.



Modified: pypy/dist/pypy/module/sys/__init__.py
==============================================================================
--- pypy/dist/pypy/module/sys/__init__.py	(original)
+++ pypy/dist/pypy/module/sys/__init__.py	Sun Jun 25 17:23:33 2006
@@ -34,6 +34,7 @@
         'warnoptions'           : 'state.get(space).w_warnoptions', 
         'builtin_module_names'  : 'state.w_None',
         'pypy_getudir'          : 'state.pypy_getudir', 
+        'pypy_repr'             : 'state.pypy_repr',
 
         '_getframe'             : 'vm._getframe', 
         'setrecursionlimit'     : 'vm.setrecursionlimit', 

Modified: pypy/dist/pypy/module/sys/state.py
==============================================================================
--- pypy/dist/pypy/module/sys/state.py	(original)
+++ pypy/dist/pypy/module/sys/state.py	Sun Jun 25 17:23:33 2006
@@ -67,3 +67,7 @@
 # directly. 
 def pypy_getudir(space):
     return _pypy_getudir(space)
+
+
+def pypy_repr(space, w_object):
+    return space.wrap('%r' % (w_object,))


From arigo at codespeak.net  Sun Jun 25 17:51:29 2006
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sun, 25 Jun 2006 17:51:29 +0200 (CEST)
Subject: [pypy-svn] r29323 - in pypy/dist/pypy/objspace/std: . test
Message-ID: <20060625155129.BB2731007E@code0.codespeak.net>

Author: arigo
Date: Sun Jun 25 17:51:26 2006
New Revision: 29323

Added:
   pypy/dist/pypy/objspace/std/strsliceobject.py   (contents, props changed)
   pypy/dist/pypy/objspace/std/test/test_strsliceobject.py   (contents, props changed)
Modified:
   pypy/dist/pypy/objspace/std/model.py
   pypy/dist/pypy/objspace/std/stringobject.py
   pypy/dist/pypy/objspace/std/stringtype.py
Log:
Experimental (and turned off by default): W_StringSliceObject,
representing a slice of an RPython string.  Only a few operations are
implemented on it, but by automatic delegation to W_StringObject it
still works transparently.

I guess this should at least check how large the slice will be, and only
use W_StringSliceObject for "large enough" slices.



Modified: pypy/dist/pypy/objspace/std/model.py
==============================================================================
--- pypy/dist/pypy/objspace/std/model.py	(original)
+++ pypy/dist/pypy/objspace/std/model.py	Sun Jun 25 17:51:26 2006
@@ -9,6 +9,7 @@
 import pypy.interpreter.special
 
 WITHSMALLINT = False
+WITHSTRSLICE = False
 
 class StdTypeModel:
 
@@ -53,6 +54,8 @@
         from pypy.objspace.std import listobject
         from pypy.objspace.std import dictobject
         from pypy.objspace.std import stringobject
+        if WITHSTRSLICE:
+            from pypy.objspace.std import strsliceobject
         from pypy.objspace.std import typeobject
         from pypy.objspace.std import sliceobject
         from pypy.objspace.std import longobject
@@ -93,6 +96,8 @@
         self.typeorder[setobject.W_SetIterObject] = []
         if WITHSMALLINT:
             self.typeorder[smallintobject.W_SmallIntObject] = []
+        if WITHSTRSLICE:
+            self.typeorder[strsliceobject.W_StringSliceObject] = []
         for type in self.typeorder:
             self.typeorder[type].append((type, None))
 
@@ -140,6 +145,14 @@
          (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode),
             ]
 
+        if WITHSTRSLICE:
+            self.typeorder[strsliceobject.W_StringSliceObject] += [
+                (stringobject.W_StringObject,
+                                       strsliceobject.delegate_slice2str),
+                (unicodeobject.W_UnicodeObject,
+                                       strsliceobject.delegate_slice2unicode),
+                ]
+
         # put W_Root everywhere
         self.typeorder[W_Root] = []
         for type in self.typeorder:

Modified: pypy/dist/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stringobject.py	(original)
+++ pypy/dist/pypy/objspace/std/stringobject.py	Sun Jun 25 17:51:26 2006
@@ -11,8 +11,7 @@
 from pypy.objspace.std.noneobject import W_NoneObject
 from pypy.objspace.std.tupleobject import W_TupleObject
 
-# XXX consider reimplementing _value to be a list of characters
-#     instead of a plain string
+from pypy.objspace.std.stringtype import sliced
 
 
 class W_StringObject(W_Object):
@@ -846,7 +845,7 @@
         str = ""
     elif step == 1:
         assert start >= 0 and stop >= 0
-        str = s[start:stop]
+        return sliced(s, start, stop)
     else:
         str = "".join([s[start + i*step] for i in range(sl)])
     return W_StringObject(str)

Modified: pypy/dist/pypy/objspace/std/stringtype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stringtype.py	(original)
+++ pypy/dist/pypy/objspace/std/stringtype.py	Sun Jun 25 17:51:26 2006
@@ -3,6 +3,17 @@
 
 from sys import maxint
 
+from pypy.objspace.std.model import WITHSTRSLICE
+if WITHSTRSLICE:
+    def sliced(s, start, stop):
+        from pypy.objspace.std.strsliceobject import W_StringSliceObject
+        return W_StringSliceObject(s, start, stop)
+else:
+    def sliced(s, start, stop):
+        from pypy.objspace.std.stringobject import W_StringObject
+        return W_StringObject(s[start:stop])
+
+
 str_join    = SMM('join', 2,
                   doc='S.join(sequence) -> string\n\nReturn a string which is'
                       ' the concatenation of the strings in the\nsequence. '

Added: pypy/dist/pypy/objspace/std/strsliceobject.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/std/strsliceobject.py	Sun Jun 25 17:51:26 2006
@@ -0,0 +1,131 @@
+from pypy.objspace.std.objspace import *
+from pypy.objspace.std.stringobject import W_StringObject
+from pypy.objspace.std.unicodeobject import delegate_String2Unicode
+
+
+class W_StringSliceObject(W_Object):
+    from pypy.objspace.std.stringtype import str_typedef as typedef
+
+    def __init__(w_self, str, start, stop):
+        w_self.str = str
+        w_self.start = start
+        w_self.stop = stop
+
+    def force(w_self):
+        str = w_self.str[w_self.start:w_self.stop]
+        w_self.str = str
+        w_self.start = 0
+        w_self.stop = len(str)
+        return str
+
+    def __repr__(w_self):
+        """ representation for debugging purposes """
+        return "%s(%r[%d:%d])" % (w_self.__class__.__name__,
+                                  w_self.str, w_self.start, w_self.stop)
+
+
+registerimplementation(W_StringSliceObject)
+
+
+def delegate_slice2str(space, w_strslice):
+    return W_StringObject(w_strslice.force())
+
+def delegate_slice2unicode(space, w_strslice):
+    w_str = W_StringObject(w_strslice.force())
+    return delegate_String2Unicode(space, w_str)
+
+# ____________________________________________________________
+
+def contains__StringSlice_String(space, w_self, w_sub):
+    sub = w_sub._value
+    return space.newbool(w_self.str.find(sub, w_self.start, w_self.stop) >= 0)
+
+
+def _convert_idx_params(space, w_self, w_sub, w_start, w_end):
+    length = w_self.stop - w_self.start
+    sub = w_sub._value
+    w_start = slicetype.adapt_bound(space, w_start, space.wrap(length))
+    w_end = slicetype.adapt_bound(space, w_end, space.wrap(length))
+
+    start = space.int_w(w_start)
+    end = space.int_w(w_end)
+    assert start >= 0
+    assert end >= 0
+
+    return (w_self.str, sub, w_self.start + start, end)
+
+
+def str_find__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
+
+    (self, sub, start, end) =  _convert_idx_params(space, w_self, w_sub, w_start, w_end)
+    res = self.find(sub, start, end)
+    return space.wrap(res)
+
+def str_rfind__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
+
+    (self, sub, start, end) =  _convert_idx_params(space, w_self, w_sub, w_start, w_end)
+    res = self.rfind(sub, start, end)
+    return space.wrap(res)
+
+def str_index__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
+
+    (self, sub, start, end) =  _convert_idx_params(space, w_self, w_sub, w_start, w_end)
+    res = self.find(sub, start, end)
+    if res < 0:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("substring not found in string.index"))
+
+    return space.wrap(res)
+
+
+def str_rindex__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
+
+    (self, sub, start, end) =  _convert_idx_params(space, w_self, w_sub, w_start, w_end)
+    res = self.rfind(sub, start, end)
+    if res < 0:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("substring not found in string.rindex"))
+
+    return space.wrap(res)
+
+
+def str_w__StringSlice(space, w_str):
+    return w_str.force()
+
+
+def getitem__StringSlice_ANY(space, w_str, w_index):
+    ival = space.int_w(w_index)
+    slen = w_str.stop - w_str.start
+    if ival < 0:
+        ival += slen
+    if ival < 0 or ival >= slen:
+        exc = space.call_function(space.w_IndexError,
+                                  space.wrap("string index out of range"))
+        raise OperationError(space.w_IndexError, exc)
+    return W_StringObject(w_str.str[w_str.start + ival])
+
+def getitem__StringSlice_Slice(space, w_str, w_slice):
+    w = space.wrap
+    length = w_str.stop - w_str.start
+    start, stop, step, sl = w_slice.indices4(space, length)
+    if sl == 0:
+        str = ""
+    else:
+        s = w_str.str
+        start = w_str.start + start
+        if step == 1:
+            stop = w_str.start + stop
+            assert start >= 0 and stop >= 0
+            return W_StringSliceObject(s, start, stop)
+        else:
+            str = "".join([s[start + i*step] for i in range(sl)])
+    return W_StringObject(str)
+
+def len__StringSlice(space, w_str):
+    return space.wrap(w_str.stop - w_str.start)
+
+
+def str__StringSlice(space, w_str):
+    if type(w_str) is W_StringSliceObject:
+        return w_str
+    return W_StringSliceObject(w_str.str, w_str.start, w_str.stop)

Added: pypy/dist/pypy/objspace/std/test/test_strsliceobject.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/std/test/test_strsliceobject.py	Sun Jun 25 17:51:26 2006
@@ -0,0 +1,79 @@
+import autopath, py
+
+from pypy.objspace.std.model import WITHSTRSLICE
+if not WITHSTRSLICE:
+    py.test.skip("WITHSTRSLICE is not enabled")
+
+
+class AppTestStringObject:
+
+    def test_basic(self):
+        import sys
+        def slice(s): return (s*3)[len(s):-len(s)]
+        s = slice('0123456789')
+        assert len(s) == 10
+        assert s[5] == '5'
+        assert s[-2] == '8'
+        assert s[3:7] == '3456'
+        assert 'W_StringSliceObject' in sys.pypy_repr(s)
+        assert 'W_StringSliceObject' in sys.pypy_repr(s[3:7])
+
+    def test_find(self):
+        def slice(s): return (s*3)[len(s):-len(s)]
+        assert slice('abcdefghiabc').find('abc') == 0
+        assert slice('abcdefghiabc').find('abc', 1) == 9
+        assert slice('abcdefghiabc').find('def', 4) == -1
+
+    def test_index(self):
+        from sys import maxint
+        def slice(s): return (s*3)[len(s):-len(s)]
+        assert slice('abcdefghiabc').index('') == 0
+        assert slice('abcdefghiabc').index('def') == 3
+        assert slice('abcdefghiabc').index('abc') == 0
+        assert slice('abcdefghiabc').index('abc', 1) == 9
+        assert slice('abcdefghiabc').index('def', -4*maxint, 4*maxint) == 3
+        raises(ValueError, slice('abcdefghiabc').index, 'hib')
+        raises(ValueError, slice('abcdefghiab').index, 'abc', 1)
+        raises(ValueError, slice('abcdefghi').index, 'ghi', 8)
+        raises(ValueError, slice('abcdefghi').index, 'ghi', -1)
+        raises(TypeError, slice('abcdefghijklmn').index, 'abc', 0, 0.0)
+        raises(TypeError, slice('abcdefghijklmn').index, 'abc', -10.0, 30)
+
+    def test_rfind(self):
+        def slice(s): return (s*3)[len(s):-len(s)]
+        assert slice('abcdefghiabc').rfind('abc') == 9
+        assert slice('abcdefghiabc').rfind('') == 12
+        assert slice('abcdefghiabc').rfind('abcd') == 0
+        assert slice('abcdefghiabc').rfind('abcz') == -1
+
+    def test_rindex(self):
+        from sys import maxint
+        def slice(s): return (s*3)[len(s):-len(s)]
+        assert slice('abcdefghiabc').rindex('') == 12
+        assert slice('abcdefghiabc').rindex('def') == 3
+        assert slice('abcdefghiabc').rindex('abc') == 9
+        assert slice('abcdefghiabc').rindex('abc', 0, -1) == 0
+        assert slice('abcdefghiabc').rindex('abc', -4*maxint, 4*maxint) == 9
+        raises(ValueError, slice('abcdefghiabc').rindex, 'hib')
+        raises(ValueError, slice('defghiabc').rindex, 'def', 1)
+        raises(ValueError, slice('defghiabc').rindex, 'abc', 0, -1)
+        raises(ValueError, slice('abcdefghi').rindex, 'ghi', 0, 8)
+        raises(ValueError, slice('abcdefghi').rindex, 'ghi', 0, -1)
+        raises(TypeError, slice('abcdefghijklmn').rindex, 'abc', 0, 0.0)
+        raises(TypeError, slice('abcdefghijklmn').rindex, 'abc', -10.0, 30)
+
+    def test_contains(self):
+        def slice(s): return (s*3)[len(s):-len(s)]
+        assert '' in slice('abc')
+        assert 'a' in slice('abc')
+        assert 'ab' in slice('abc')
+        assert not 'd' in slice('abc')
+        raises(TypeError, slice('a').__contains__, 1)
+        
+    def test_hash(self):
+        # check that we have the same hash as CPython for at least 31 bits
+        # (but don't go checking CPython's special case -1)
+        # disabled: assert hash('') == 0 --- different special case
+        def slice(s): return (s*3)[len(s):-len(s)]
+        assert hash(slice('hello')) & 0x7fffffff == 0x347697fd
+        assert hash(slice('hello world!')) & 0x7fffffff == 0x2f0bb411


From arigo at codespeak.net  Sun Jun 25 17:57:38 2006
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sun, 25 Jun 2006 17:57:38 +0200 (CEST)
Subject: [pypy-svn] r29325 - pypy/dist/pypy/translator/backendopt
Message-ID: <20060625155738.017D010080@code0.codespeak.net>

Author: arigo
Date: Sun Jun 25 17:57:31 2006
New Revision: 29325

Modified:
   pypy/dist/pypy/translator/backendopt/constfold.py
Log:
Fix to avoid crashing on obscure unlisted operations.
This seems to produce a working pypy-c now.


Modified: pypy/dist/pypy/translator/backendopt/constfold.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/constfold.py	(original)
+++ pypy/dist/pypy/translator/backendopt/constfold.py	Sun Jun 25 17:57:31 2006
@@ -22,16 +22,20 @@
             vargs.append(v)
         if len(args) == len(vargs):
             RESTYPE = spaceop.result.concretetype
-            op = getattr(llop, spaceop.opname)
             try:
-                result = op(RESTYPE, *args)
-            except TypeError:
+                op = getattr(llop, spaceop.opname)
+            except AttributeError:
                 pass
             else:
-                # success in folding this space operation
-                constants[spaceop.result] = Constant(result, RESTYPE)
-                folded_count += 1
-                continue
+                try:
+                    result = op(RESTYPE, *args)
+                except TypeError:
+                    pass
+                else:
+                    # success in folding this space operation
+                    constants[spaceop.result] = Constant(result, RESTYPE)
+                    folded_count += 1
+                    continue
         # failed to fold an operation, exit early if requested
         if exit_early:
             return folded_count


From arigo at codespeak.net  Sun Jun 25 18:57:33 2006
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sun, 25 Jun 2006 18:57:33 +0200 (CEST)
Subject: [pypy-svn] r29327 - in pypy/dist/pypy: rpython/lltypesystem/test
	translator/backendopt translator/backendopt/test
Message-ID: <20060625165733.888411007A@code0.codespeak.net>

Author: arigo
Date: Sun Jun 25 18:57:30 2006
New Revision: 29327

Modified:
   pypy/dist/pypy/rpython/lltypesystem/test/test_rtagged.py
   pypy/dist/pypy/translator/backendopt/constfold.py
   pypy/dist/pypy/translator/backendopt/test/test_constfold.py
Log:
in constfold:
* shift keepalives at the end of blocks
* hack hack to turn indirect_calls into direct_calls

This allows constfold to pass the test_rtagged optimization check.



Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rtagged.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rtagged.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rtagged.py	Sun Jun 25 18:57:30 2006
@@ -163,7 +163,7 @@
     interp, graph = get_interpreter(fn, [-1000])
 
     t = interp.typer.annotator.translator
-    backend_optimizations(t, propagate=True)
+    backend_optimizations(t, constfold=True)
     if conftest.option.view:
         t.view()
 

Modified: pypy/dist/pypy/translator/backendopt/constfold.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/constfold.py	(original)
+++ pypy/dist/pypy/translator/backendopt/constfold.py	Sun Jun 25 18:57:30 2006
@@ -1,12 +1,14 @@
 from pypy.objspace.flow.model import Constant, Variable, SpaceOperation
 from pypy.translator.backendopt.support import split_block_with_keepalive
 from pypy.translator.simplify import eliminate_empty_blocks
+from pypy.translator.unsimplify import insert_empty_block
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rpython.lltypesystem import lltype
 
 
 def fold_op_list(operations, constants, exit_early=False):
     newops = []
+    keepalives = []
     folded_count = 0
     for spaceop in operations:
         vargsmodif = False
@@ -39,13 +41,27 @@
         # failed to fold an operation, exit early if requested
         if exit_early:
             return folded_count
-        if vargsmodif:
-            spaceop = SpaceOperation(spaceop.opname, vargs, spaceop.result)
-        newops.append(spaceop)
+        if spaceop.opname == 'keepalive':
+            if vargsmodif:
+                continue    # keepalive(constant) is not useful
+            keepalives.append(spaceop)
+        else:
+            if vargsmodif:
+                if (spaceop.opname == 'indirect_call'
+                    and isinstance(vargs[0], Constant)):
+                    spaceop = SpaceOperation('direct_call', vargs[:-1],
+                                             spaceop.result)
+                else:
+                    spaceop = SpaceOperation(spaceop.opname, vargs,
+                                             spaceop.result)
+            newops.append(spaceop)
     # end
     if exit_early:
         return folded_count
     else:
+        # move the keepalives to the end of the block, which makes the life
+        # of prepare_constant_fold_link() easier
+        newops.extend(keepalives)
         return newops
 
 def constant_fold_block(block):
@@ -64,11 +80,40 @@
         for link in block.exits:
             link.args = [constants.get(v, v) for v in link.args]
 
+
+def complete_constants(link, constants):
+    # 'constants' maps some Variables of 'block' to Constants.
+    # Some input args of 'block' may be absent from 'constants'
+    # and must be fixed in the link to be passed directly from
+    # the origin of the link instead of via 'block'.
+    for v1, v2 in zip(link.args, link.target.inputargs):
+        constants.setdefault(v2, v1)
+
 def prepare_constant_fold_link(link, constants, splitblocks):
-    folded_count = fold_op_list(link.target.operations, constants,
-                                exit_early=True)
+    block = link.target
+    folded_count = fold_op_list(block.operations, constants, exit_early=True)
+
+    if folded_count < len(block.operations):
+        nextop = block.operations[folded_count]
+        if (nextop is not None and nextop.opname == 'indirect_call'
+            and nextop.args[0] in constants):
+            # indirect_call -> direct_call
+            callargs = [constants[nextop.args[0]]]
+            constants1 = constants.copy()
+            complete_constants(link, constants1)
+            for v in nextop.args[1:-1]:
+                callargs.append(constants1.get(v, v))
+            v_result = Variable(nextop.result)
+            v_result.concretetype = nextop.result.concretetype
+            constants[nextop.result] = v_result
+            callop = SpaceOperation('direct_call', callargs, v_result)
+            newblock = insert_empty_block(None, link, [callop])
+            [link] = newblock.exits
+            assert link.target is block
+            folded_count += 1
+
     if folded_count > 0:
-        splits = splitblocks.setdefault(link.target, [])
+        splits = splitblocks.setdefault(block, [])
         splits.append((folded_count, link, constants))
 
 def rewire_links(splitblocks):
@@ -89,12 +134,7 @@
                 # split the block at the given position
                 splitlink = split_block_with_keepalive(block, position)
                 assert block.exits == [splitlink]
-            # 'constants' maps some Variables of 'block' to Constants.
-            # Some input args of 'block' may be absent from 'constants'
-            # and must be fixed in the link to be passed directly from
-            # the origin of the link instead of via 'block'.
-            for v1, v2 in zip(link.args, link.target.inputargs):
-                constants.setdefault(v2, v1)
+            complete_constants(link, constants)
             args = [constants.get(v, v) for v in splitlink.args]
             link.args = args
             link.target = splitlink.target
@@ -109,7 +149,7 @@
     # with new constants show up
     while 1:
         splitblocks = {}
-        for link in graph.iterlinks():
+        for link in list(graph.iterlinks()):
             constants = {}
             for v1, v2 in zip(link.args, link.target.inputargs):
                 if isinstance(v1, Constant):

Modified: pypy/dist/pypy/translator/backendopt/test/test_constfold.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_constfold.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_constfold.py	Sun Jun 25 18:57:30 2006
@@ -122,3 +122,31 @@
     constant_fold_graph(graph)
     assert summary(graph) == {'int_mul': 1}
     check_graph(graph, [12], 60, t)
+
+
+def xxx_test_later_along_link():
+    S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True})
+    s1 = lltype.malloc(S1)
+    s1.x = 123
+    s2 = lltype.malloc(S1)
+    s2.x = 60
+    def fn(x, y):
+        if x:
+            x = s1.x
+        else:
+            x = s2.x
+        y *= 2
+        return (x+1) - y
+
+    graph, t = get_graph(fn, [int, int])
+    assert summary(graph) == {'int_is_true': 1,
+                              'getfield': 2,
+                              'int_mul': 1,
+                              'int_add': 1,
+                              'int_sub': 1}
+    constant_fold_graph(graph)
+    assert summary(graph) == {'int_is_true': 1,
+                              'int_mul': 1,
+                              'int_sub': 1}
+    check_graph(graph, [-1], 124, t)
+    check_graph(graph, [0], 61, t)


From fijal at codespeak.net  Sun Jun 25 22:20:49 2006
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 25 Jun 2006 22:20:49 +0200 (CEST)
Subject: [pypy-svn] r29333 - pypy/extradoc/sprintinfo/post-ep2006
Message-ID: <20060625202049.DE8EB1007C@code0.codespeak.net>

Author: fijal
Date: Sun Jun 25 22:20:47 2006
New Revision: 29333

Modified:
   pypy/extradoc/sprintinfo/post-ep2006/people.txt
Log:
Added my timeline.


Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt
==============================================================================
--- pypy/extradoc/sprintinfo/post-ep2006/people.txt	(original)
+++ pypy/extradoc/sprintinfo/post-ep2006/people.txt	Sun Jun 25 22:20:47 2006
@@ -13,7 +13,7 @@
 Carl Friedrich Bolz  6-9th          CERN hostel 
 Guido Wesdorp        6-9th          CERN hostel 
 Holger Krekel        6-?            CERN hostel 
-Maciej Fijalkowski   ?              ? 
+Maciej Fijalkowski   6-9th          ? 
 Anders Chrigstroem   2/7 - 10/7     NH Geneva Airport
 Samuele Pedroni      2/7 - 10/7     NH Geneva Airport
 Christian Tismer     6-9th          ? 


From fijal at codespeak.net  Mon Jun 26 09:44:27 2006
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 26 Jun 2006 09:44:27 +0200 (CEST)
Subject: [pypy-svn] r29338 - in pypy/dist/pypy/translator: js js/demo/jsdemo
	js/demo/jsdemo/templates js/tools oosupport
Message-ID: <20060626074427.8EB3E1007A@code0.codespeak.net>

Author: fijal
Date: Mon Jun 26 09:44:24 2006
New Revision: 29338

Modified:
   pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py
   pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid
   pypy/dist/pypy/translator/js/jsbuiltin.py
   pypy/dist/pypy/translator/js/metavm.py
   pypy/dist/pypy/translator/js/tools/start_bnb.py
   pypy/dist/pypy/translator/oosupport/metavm.py
Log:
Added date() builtin. Added sprite management which leads to a little bit smoother animation.


Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py	(original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py	Mon Jun 26 09:44:24 2006
@@ -7,11 +7,11 @@
 from pypy.translator.js.demo.jsdemo.controllers import Root
 from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc
 
-from pypy.translator.js.proxy.testme.servermessage import log, ServerMessage, PMSG_INLINE_FRAME
+from pypy.translator.js.proxy.testme.servermessage import log, ServerMessage, PMSG_INLINE_FRAME, PMSG_DEF_ICON
 from pypy.translator.js.proxy.testme.msgstruct import *
 from cherrypy import session
 
-import re, time, sys, os, urllib, socket
+import re, time, sys, os, urllib, socket, copy
 
 class SortY(object):
     def __init__(self, data):
@@ -20,6 +20,55 @@
     def __cmp__(self, other):
         return cmp(self.data['y'], other.data['y'])
 
+
+class SpriteManager(object):
+    def __init__(self):
+        self.sprite_sets = {}
+        self.positions = {}
+        self.num = 0
+        self.next_pos = {}
+        self.last_seen = set()
+        self.seen = set()
+    
+    def def_icon(self, icon_code):
+        self.sprite_sets[icon_code] = []
+    
+    def get_sprite(self, icon_code, x, y):
+        try:
+            to_ret = self.positions[(icon_code, x, y)]
+            del self.positions[(icon_code, x, y)]
+            self.next_pos[(icon_code, x, y)] = to_ret
+            self.seen.add((icon_code, to_ret))
+            return "still", to_ret
+        except KeyError:
+            try:
+                try:
+                    to_ret = self.sprite_sets[icon_code].pop()
+                except KeyError:
+                    self.def_icon(icon_code)
+                    raise IndexError
+                self.next_pos[(icon_code, x, y)] = to_ret
+                self.seen.add((icon_code, to_ret))
+                return "move", to_ret
+            except IndexError:
+                next = self.num
+                self.num += 1
+                self.next_pos[(icon_code, x, y)] = next
+                self.seen.add((icon_code, next))
+                return "new", next
+    
+    def end_frame(self):
+        self.positions = copy.deepcopy(self.next_pos)
+        self.next_pos = {}
+        to_ret = []
+        #import pdb;pdb.set_trace()
+        for ic, i in self.last_seen - self.seen:
+            self.sprite_sets[ic].append(i)
+            to_ret.append(i)
+        self.last_seen = self.seen
+        self.seen = set()
+        return to_ret
+
 # Needed double inheritance for both server job
 # and semi-transparent communication proxy
 class BnbRoot(Root, BasicExternal):
@@ -40,6 +89,8 @@
         'get_message' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]})
     }
     
+    sm = SpriteManager()
+    
     def serverMessage(self):
         sessionid = session['_id']
         if sessionid not in self._serverMessage:
@@ -49,7 +100,7 @@
     @turbogears.expose(html="jsdemo.templates.bnb")
     def index(self):
         import time
-        self.last_frames = set()
+        self.new_sprites = 0
         return dict(now=time.ctime(), onload=self.jsname, code=self.jssource)
     
     def sessionSocket(self, close=False):
@@ -72,8 +123,13 @@
     def get_message(self):
         #XXX hangs if not first sending CMSG_PING!
         sm   = self.serverMessage()
-        size = 10000 #XXX should really loop until all data is handled
-        data = sm.data + self.sessionSocket().recv(size)
+        data = sm.data
+        sock = self.sessionSocket()
+        while True:
+            try:
+                data += sock.recv(4096, socket.MSG_DONTWAIT)
+            except:    
+                break
         while sm.n_header_lines > 0 and '\n' in data:
             sm.n_header_lines -= 1
             header_line, data = data.split('\n',1)
@@ -104,22 +160,23 @@
         #    log('MESSAGES:lenbefore=%d, inline_frames=%s, lenafter=%d' % (
         #        len_before, inline_frames, len(messages)))
         to_append = []
-        next_last = set()
-        keep_sprites = []
         for i, msg in enumerate(messages):
             if msg['type'] == PMSG_INLINE_FRAME:
                 for next in msg['sprites']:
-#                    if not next in self.last_frames:
-                        # sort them by y axis
-                    to_append.append(SortY({'type':'sprite', 'x':str(next[1]), 'y':str(next[2]), 'icon_code':str(next[0])}))
-                    #next_last.add(next)
+                    new_sprite, s_num = self.sm.get_sprite(*next)
+                    if new_sprite == 'new':
+                        #if self.new_sprites < 100:
+                        to_append.append({'type':'ns', 's':s_num, 'icon_code':str(next[0]), 'x':str(next[1]), 'y':str(next[2])})
+                        self.new_sprites += 1
+                    elif new_sprite == 'move':
+                        to_append.append({'type':'sm', 's':str(s_num), 'x':str(next[1]), 'y':str(next[2])})
                 del messages[i]
-        
-        self.last_frames = next_last
-        to_append.sort()
-        messages += [i.data for i in to_append]
-        
-        messages.append({'type':'end_frame'})
+
+        for i in self.sm.end_frame():
+            to_append.append({'type':'ds', 's':str(i)})
+        messages += to_append
+        #messages.append(to_append[0])
+        #print len(messages)
         return dict(messages=messages)
 
 BnbRootInstance = BnbRoot()

Modified: pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid	(original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid	Mon Jun 26 09:44:24 2006
@@ -3,6 +3,7 @@
 
     
     Bub'n'bros
+    
 
 
-  

This is a test!


-

Code:


-
-    ${code}
-  
+
+

This is a test!


+

Code:


+
+      ${code}
+    
+
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/templates/main.kid ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/templates/main.kid (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/main.kid Thu Jun 29 10:46:13 2006 @@ -21,10 +21,12 @@ -

This is a test!


-

Code:


-
-    ${code}
-  
+
+

This is a test!


+

Code:


+
+      ${code}
+    
+
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/templates/xmlhttp.kid ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/templates/xmlhttp.kid (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/xmlhttp.kid Thu Jun 29 10:46:13 2006 @@ -21,10 +21,12 @@ -

This is a test!


-

Code:


-
-    ${code}
-  
+
+

This is a test!


+

Code:


+
+      ${code}
+    
+
Modified: pypy/dist/pypy/translator/js/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/dom.py (original) +++ pypy/dist/pypy/translator/js/modules/dom.py Thu Jun 29 10:46:13 2006 @@ -77,6 +77,10 @@ def appendChild(self, elem): self.subnodes[elem.id] = elem + def removeChild(self, elem): + #del self.subnodes[elem.id] + pass + class Form(Node): pass Modified: pypy/dist/pypy/translator/js/tools/start_bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/tools/start_bnb.py (original) +++ pypy/dist/pypy/translator/js/tools/start_bnb.py Thu Jun 29 10:46:13 2006 @@ -213,12 +213,13 @@ #sc.revive() def session_dispatcher(msgs): - log("Something...") + #log("Something...") BnbRootInstance.get_message(bnb_dispatcher) def run_bnb(): def bnb(): - #get_document(). + genjsinfo = get_document().getElementById("genjsinfo") + get_document().body.removeChild(genjsinfo) createLoggingPane(True) log("keys: dd player, emove player and to walk around") BnbRootInstance.initialize_session(session_dispatcher) From arigo at codespeak.net Thu Jun 29 11:08:54 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 11:08:54 +0200 (CEST) Subject: [pypy-svn] r29479 - in pypy/dist/pypy/jit/timeshifter: . test Message-ID: <20060629090854.AE6E810071@code0.codespeak.net> Author: arigo Date: Thu Jun 29 11:08:51 2006 New Revision: 29479 Added: pypy/dist/pypy/jit/timeshifter/test/test_vlist.py (contents, props changed) Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py pypy/dist/pypy/jit/timeshifter/vlist.py Log: (arre, pedronis, arigo) Finish the simple virtual list example. Added support for same_as (duh). Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rtyper.py (original) +++ pypy/dist/pypy/jit/timeshifter/rtyper.py Thu Jun 29 11:08:51 2006 @@ -110,6 +110,10 @@ def translate_op_keepalive(self,hop): pass + def translate_op_same_as(self, hop): + [v] = hop.inputargs(hop.r_result) + return v + def translate_op_getfield(self, hop): if isinstance(hop.args_r[0], BlueRepr): return hop.args_r[0].timeshift_getfield(hop) @@ -246,7 +250,11 @@ args_s.insert(0, s_typedesc) ll_handler = oop_newlist else: - XXX - Later + typename, method = operation_name.split('.') + method = 'oop_%s_%s' % (typename, method) + vmodule = __import__('pypy.jit.timeshifter.v%s' % (typename,), + None, None, [method]) + ll_handler = getattr(vmodule, method) v_jitstate = hop.llops.getjitstate() return hop.llops.genmixlevelhelpercall(ll_handler, Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Thu Jun 29 11:08:51 2006 @@ -20,7 +20,6 @@ P_NOVIRTUAL = AnnotatorPolicy() P_NOVIRTUAL.novirtualcontainer = True -P_NOVIRTUAL.oopspec = True def getargtypes(annotator, values): return [annotation(annotator, x) for x in values] @@ -560,13 +559,3 @@ insns, res = timeshift(ll_function, [1], [], policy=P_NOVIRTUAL) assert res == 1 + 2 assert insns == {'int_is_true': 1, 'int_add': 1} - -def test_vlist(): - py.test.skip("in-progress") - def ll_function(): - lst = [] - lst.append(12) - return lst[0] - insns, res = timeshift(ll_function, [], [], policy=P_NOVIRTUAL) - assert res == 12 - assert insns == {} Added: pypy/dist/pypy/jit/timeshifter/test/test_vlist.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/jit/timeshifter/test/test_vlist.py Thu Jun 29 11:08:51 2006 @@ -0,0 +1,16 @@ +from pypy.annotation.policy import AnnotatorPolicy +from pypy.jit.timeshifter.test.test_timeshift import timeshift + +P_OOPSPEC = AnnotatorPolicy() +P_OOPSPEC.novirtualcontainer = True +P_OOPSPEC.oopspec = True + + +def test_vlist(): + def ll_function(): + lst = [] + lst.append(12) + return lst[0] + insns, res = timeshift(ll_function, [], [], policy=P_OOPSPEC) + assert res == 12 + assert insns == {} Modified: pypy/dist/pypy/jit/timeshifter/vlist.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/vlist.py (original) +++ pypy/dist/pypy/jit/timeshifter/vlist.py Thu Jun 29 11:08:51 2006 @@ -23,6 +23,21 @@ self.typedesc = typedesc self.item_boxes = [] + def enter_block(self, newblock, incoming, memo): + pass + + def force_runtime_container(self, jitstate): + pass + + def freeze(self, memo): + pass + + def copy(self, memo): + pass + + def replace(self, memo): + pass + def oop_newlist(jitstate, typedesc, lengthbox): assert lengthbox.is_constant() @@ -32,3 +47,13 @@ box = rvalue.PtrRedBox(typedesc.gv_ptrtype) box.content = vlist return box + +def oop_list_append(jitstate, selfbox, itembox): + assert isinstance(selfbox.content, VirtualList) + selfbox.content.item_boxes.append(itembox) + +def oop_list_getitem(jitstate, selfbox, indexbox): + assert isinstance(selfbox.content, VirtualList) + assert indexbox.is_constant() + index = rvalue.ll_getvalue(indexbox, lltype.Signed) + return selfbox.content.item_boxes[index] From arigo at codespeak.net Thu Jun 29 11:28:22 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 11:28:22 +0200 (CEST) Subject: [pypy-svn] r29481 - in pypy/dist/pypy/jit/timeshifter: . test Message-ID: <20060629092822.4999D10076@code0.codespeak.net> Author: arigo Date: Thu Jun 29 11:28:20 2006 New Revision: 29481 Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py pypy/dist/pypy/jit/timeshifter/test/test_vlist.py pypy/dist/pypy/jit/timeshifter/vlist.py Log: (arre, pedronis, arigo) Next test passes, by copying many methods from VirtualStruct to VirtualList. Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Thu Jun 29 11:28:20 2006 @@ -160,7 +160,7 @@ def __init__(self, typedesc): self.typedesc = typedesc - #self.fz_content initialized later + #self.fz_content_boxes initialized later def exactmatch(self, vstruct, outgoingvarboxes, memo): contmemo = memo.containers Modified: pypy/dist/pypy/jit/timeshifter/test/test_vlist.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/test/test_vlist.py (original) +++ pypy/dist/pypy/jit/timeshifter/test/test_vlist.py Thu Jun 29 11:28:20 2006 @@ -14,3 +14,19 @@ insns, res = timeshift(ll_function, [], [], policy=P_OOPSPEC) assert res == 12 assert insns == {} + +def test_enter_block(): + def ll_function(flag): + lst = [] + lst.append(flag) + lst.append(131) + if flag: + return lst[0] + else: + return lst[1] + insns, res = timeshift(ll_function, [6], [], policy=P_OOPSPEC) + assert res == 6 + assert insns == {'int_is_true': 1} + insns, res = timeshift(ll_function, [0], [], policy=P_OOPSPEC) + assert res == 131 + assert insns == {'int_is_true': 1} Modified: pypy/dist/pypy/jit/timeshifter/vlist.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/vlist.py (original) +++ pypy/dist/pypy/jit/timeshifter/vlist.py Thu Jun 29 11:28:20 2006 @@ -16,37 +16,92 @@ def _freeze_(self): return True + def ll_factory(self): + vlist = VirtualList(self) + box = rvalue.PtrRedBox(self.gv_ptrtype) + box.content = vlist + vlist.ownbox = box + return box + + +class FrozenVirtualList(AbstractContainer): + + def __init__(self, typedesc): + self.typedesc = typedesc + #self.fz_item_boxes initialized later + + def exactmatch(self, vlist, outgoingvarboxes, memo): + contmemo = memo.containers + if self in contmemo: + ok = vlist is contmemo[self] + if not ok: + outgoingvarboxes.append(vlist.ownbox) + return ok + if vlist in contmemo: + assert contmemo[vlist] is not self + outgoingvarboxes.append(vlist.ownbox) + return False + assert self.typedesc is vlist.typedesc + contmemo[self] = vlist + contmemo[vlist] = self + self_boxes = self.fz_item_boxes + vlist_boxes = vlist.item_boxes + fullmatch = True + for i in range(len(self_boxes)): + if not self_boxes[i].exactmatch(vlist_boxes[i], + outgoingvarboxes, + memo): + fullmatch = False + return fullmatch + class VirtualList(AbstractContainer): def __init__(self, typedesc): self.typedesc = typedesc self.item_boxes = [] + # self.ownbox = ... set in ll_factory def enter_block(self, newblock, incoming, memo): - pass + contmemo = memo.containers + if self not in contmemo: + contmemo[self] = None + for box in self.item_boxes: + box.enter_block(newblock, incoming, memo) def force_runtime_container(self, jitstate): - pass + assert 0 def freeze(self, memo): - pass + contmemo = memo.containers + try: + return contmemo[self] + except KeyError: + result = contmemo[self] = FrozenVirtualList(self.typedesc) + frozens = [box.freeze(memo) for box in self.item_boxes] + result.fz_item_boxes = frozens + return result def copy(self, memo): - pass + contmemo = memo.containers + try: + return contmemo[self] + except KeyError: + result = contmemo[self] = VirtualList(self.typedesc) + result.item_boxes = [box.copy(memo) + for box in self.item_boxes] + result.ownbox = self.ownbox.copy(memo) + return result def replace(self, memo): - pass + assert 0 def oop_newlist(jitstate, typedesc, lengthbox): assert lengthbox.is_constant() length = rvalue.ll_getvalue(lengthbox, lltype.Signed) assert length == 0 - vlist = VirtualList(typedesc) - box = rvalue.PtrRedBox(typedesc.gv_ptrtype) - box.content = vlist - return box + return typedesc.ll_factory() def oop_list_append(jitstate, selfbox, itembox): assert isinstance(selfbox.content, VirtualList) From arigo at codespeak.net Thu Jun 29 11:34:21 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 11:34:21 +0200 (CEST) Subject: [pypy-svn] r29482 - in pypy/dist/pypy/jit/timeshifter: . test Message-ID: <20060629093421.6704310078@code0.codespeak.net> Author: arigo Date: Thu Jun 29 11:34:19 2006 New Revision: 29482 Modified: pypy/dist/pypy/jit/timeshifter/test/test_vlist.py pypy/dist/pypy/jit/timeshifter/vlist.py Log: (arre, pedronis, arigo) Implemented a few more methods. Modified: pypy/dist/pypy/jit/timeshifter/test/test_vlist.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/test/test_vlist.py (original) +++ pypy/dist/pypy/jit/timeshifter/test/test_vlist.py Thu Jun 29 11:34:19 2006 @@ -30,3 +30,33 @@ insns, res = timeshift(ll_function, [0], [], policy=P_OOPSPEC) assert res == 131 assert insns == {'int_is_true': 1} + +def test_merge(): + def ll_function(flag): + lst = [] + if flag: + lst.append(flag) + else: + lst.append(131) + return lst[-1] + insns, res = timeshift(ll_function, [6], [], policy=P_OOPSPEC) + assert res == 6 + assert insns == {'int_is_true': 1} + insns, res = timeshift(ll_function, [0], [], policy=P_OOPSPEC) + assert res == 131 + assert insns == {'int_is_true': 1} + +def test_replace(): + def ll_function(flag): + lst = [] + if flag: + lst.append(12) + else: + lst.append(131) + return lst[-1] + insns, res = timeshift(ll_function, [6], [], policy=P_OOPSPEC) + assert res == 12 + assert insns == {'int_is_true': 1} + insns, res = timeshift(ll_function, [0], [], policy=P_OOPSPEC) + assert res == 131 + assert insns == {'int_is_true': 1} Modified: pypy/dist/pypy/jit/timeshifter/vlist.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/vlist.py (original) +++ pypy/dist/pypy/jit/timeshifter/vlist.py Thu Jun 29 11:34:19 2006 @@ -42,10 +42,13 @@ outgoingvarboxes.append(vlist.ownbox) return False assert self.typedesc is vlist.typedesc - contmemo[self] = vlist - contmemo[vlist] = self self_boxes = self.fz_item_boxes vlist_boxes = vlist.item_boxes + if len(self_boxes) != len(vlist_boxes): + outgoingvarboxes.append(vlist.ownbox) + return False + contmemo[self] = vlist + contmemo[vlist] = self fullmatch = True for i in range(len(self_boxes)): if not self_boxes[i].exactmatch(vlist_boxes[i], @@ -94,7 +97,12 @@ return result def replace(self, memo): - assert 0 + contmemo = memo.containers + if self not in contmemo: + contmemo[self] = None + for i in range(len(self.item_boxes)): + self.item_boxes[i] = self.item_boxes[i].replace(memo) + self.ownbox = self.ownbox.replace(memo) def oop_newlist(jitstate, typedesc, lengthbox): From cfbolz at codespeak.net Thu Jun 29 11:35:03 2006 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 29 Jun 2006 11:35:03 +0200 (CEST) Subject: [pypy-svn] r29483 - pypy/dist/pypy/doc Message-ID: <20060629093503.828E71007B@code0.codespeak.net> Author: cfbolz Date: Thu Jun 29 11:35:02 2006 New Revision: 29483 Modified: pypy/dist/pypy/doc/news.txt Log: add video news item. announcement to pypy-dev etc going out soonish Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Thu Jun 29 11:35:02 2006 @@ -15,6 +15,17 @@ .. _`iCalendar format`: webcal://pypycal.sabi.net///calendars/PyPy.ics .. _eventhistory: eventhistory.html +Release of PyPy video documentations +================================================================== + +The PyPy team is happy to announce that the first bunch of PyPy videos +can now be downloaded from: + +http://codespeak.net/pypy/dist/pypy/doc/video-index.html + +The videos introduce involved people and contain different talks, tutorials and +interviews and can be downloaded via bittorrent. **29th June 2006** + PyPy 0.9.0 ================================================================== From guido at codespeak.net Thu Jun 29 11:35:51 2006 From: guido at codespeak.net (guido at codespeak.net) Date: Thu, 29 Jun 2006 11:35:51 +0200 (CEST) Subject: [pypy-svn] r29484 - pypy/dist/pypy/doc Message-ID: <20060629093551.6203310081@code0.codespeak.net> Author: guido Date: Thu Jun 29 11:35:29 2006 New Revision: 29484 Modified: pypy/dist/pypy/doc/video-index.txt Log: More video descriptions. Modified: pypy/dist/pypy/doc/video-index.txt ============================================================================== --- pypy/dist/pypy/doc/video-index.txt (original) +++ pypy/dist/pypy/doc/video-index.txt Thu Jun 29 11:35:29 2006 @@ -75,6 +75,10 @@ PAL, 26 min, divx AVI +Holger Krekel explains more about the goals and history of PyPy, and the +structure and organisation behind it. Bea During describes the intricacies of +driving a distributed community in an agile way, and how to combine that with +the formalities required for EU funding. Introductory talk on PyPy ------------------------- @@ -90,6 +94,10 @@ PAL, 28 min, divx AVI +Michael Hudson talks about the basic building blocks of Python, the currently +available back-ends, and the status of PyPy in general. Christian Tismer takes +over to explain how co-routines can be used to implement things like +Stackless and Greenlets in PyPy. PyPy Architecture session ------------------------- @@ -105,6 +113,10 @@ PAL, 48 min, divx AVI +Holger Krekel and Armin Rigo talk about the basic implementation, +implementation level aspects and the translation toolchain. This +talk also gives an insight into how a developer works with these tools on +a daily basis, and pays special attention to flow graphs. Sprint tutorial --------------- From arigo at codespeak.net Thu Jun 29 12:24:02 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 12:24:02 +0200 (CEST) Subject: [pypy-svn] r29485 - in pypy/dist/pypy: jit/llabstractinterp rpython rpython/lltypesystem rpython/test Message-ID: <20060629102402.A8FCB1007B@code0.codespeak.net> Author: arigo Date: Thu Jun 29 12:24:00 2006 New Revision: 29485 Modified: pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py pypy/dist/pypy/jit/llabstractinterp/vlist.py pypy/dist/pypy/rpython/lltypesystem/rlist.py pypy/dist/pypy/rpython/rtyper.py pypy/dist/pypy/rpython/test/test_rlist.py Log: (pedronis, arre, arigo) Trying to make various op-generating interfaces converge. Modified: pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py ============================================================================== --- pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py (original) +++ pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py Thu Jun 29 12:24:00 2006 @@ -538,12 +538,15 @@ ls.link = cases[ls.exitcase] return b - def genop(self, opname, args, RESULT_TYPE): + def genop(self, opname, args, RESULT_TYPE=lltype.Void): return rgenop.genop(self.newblock, opname, args, rgenop.constTYPE(RESULT_TYPE)) def genconst(self, llvalue): return rgenop.genconst(llvalue) + + def genvoidconst(self, placeholder): + return rgenop.placeholder(placeholder) def binding(self, v): assert isinstance(v, (Constant, Variable)) Modified: pypy/dist/pypy/jit/llabstractinterp/vlist.py ============================================================================== --- pypy/dist/pypy/jit/llabstractinterp/vlist.py (original) +++ pypy/dist/pypy/jit/llabstractinterp/vlist.py Thu Jun 29 12:24:00 2006 @@ -41,7 +41,7 @@ def build_runtime_container(self, builder): items_v = [a.forcegenvarorconst(builder) for a in self.items_a] - v_result = self.T.list_builder(builder, items_v) + v_result = self.T.list_builder.build(builder, items_v) return v_result # ____________________________________________________________ Modified: pypy/dist/pypy/rpython/lltypesystem/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rlist.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rlist.py Thu Jun 29 12:24:00 2006 @@ -116,22 +116,21 @@ #self.c_dum_nocheck = inputconst(Void, dum_nocheck) #self.c_LIST = inputconst(Void, self.LIST) - def __call__(self, builder, items_v): + def build(self, llops, items_v): """Make the operations that would build a list containing the provided items.""" - from pypy.rpython import rgenop - c_newlist = builder.genconst(self.newlist_ptr) - c_len = builder.genconst(len(items_v)) - v_result = builder.genop('direct_call', - [c_newlist, rgenop.placeholder(self.LIST), c_len], - self.LISTPTR) - c_setitem_nonneg = builder.genconst(self.setitem_nonneg_ptr) - for i, v in enumerate(items_v): - c_i = builder.genconst(i) - builder.genop('direct_call', [c_setitem_nonneg, - rgenop.placeholder(dum_nocheck), - v_result, c_i, v], - Void) + c_newlist = llops.genconst(self.newlist_ptr) + c_len = llops.genconst(len(items_v)) + c_LIST = llops.genvoidconst(self.LIST) + v_result = llops.genop('direct_call', + [c_newlist, c_LIST, c_len], + self.LISTPTR) + c_setitem_nonneg = llops.genconst(self.setitem_nonneg_ptr) + for i in range(len(items_v)): + c_i = llops.genconst(i) + llops.genop('direct_call', [c_setitem_nonneg, + llops.genvoidconst(dum_nocheck), + v_result, c_i, items_v[i]]) return v_result def getlistptr(self): Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Thu Jun 29 12:24:00 2006 @@ -887,6 +887,12 @@ def gencapicall(self, cfnname, args_v, resulttype=None, **flags): return self.genexternalcall(cfnname, args_v, resulttype=resulttype, external="C", **flags) + def genconst(self, ll_value): + return inputconst(typeOf(ll_value), ll_value) + + def genvoidconst(self, placeholder): + return inputconst(Void, placeholder) + # _______________________________________________________________________ # this has the side-effect of registering the unary and binary operations # and the rtyper_chooserepr() methods Modified: pypy/dist/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rlist.py (original) +++ pypy/dist/pypy/rpython/test/test_rlist.py Thu Jun 29 12:24:00 2006 @@ -194,44 +194,19 @@ lst.append(42) return lst - from pypy.rpython import rgenop - from pypy.rpython.module import support - - class DummyBlockBuilder: - - def __init__(self): - self.newblock = rgenop.newblock() - self.bareblock = support.from_opaque_object(self.newblock.obj) - - def genop(self, opname, args, RESULT_TYPE): - return rgenop.genop(self.newblock, opname, args, - rgenop.constTYPE(RESULT_TYPE)) - - def genconst(self, llvalue): - return rgenop.genconst(llvalue) - - # inspection - def __getitem__(self, index): - return self.bareblock.operations[index] - - def __len__(self): - return len(self.bareblock.operations) - + from pypy.rpython.rtyper import LowLevelOpList for fn in [fixed_size_case, variable_size_case]: t = TranslationContext() t.buildannotator().build_types(fn, []) t.buildrtyper().specialize() LIST = t.graphs[0].getreturnvar().concretetype.TO - llop = DummyBlockBuilder() + llop = LowLevelOpList(None) v0 = Constant(42) v0.concretetype = Signed - opq_v0 = support.to_opaque_object(v0) v1 = Variable() v1.concretetype = Signed - opq_v1 = support.to_opaque_object(v1) - vr = LIST.list_builder(llop, [opq_v0, opq_v1]) - vr = rgenop.reveal(vr) + vr = LIST.list_builder.build(llop, [v0, v1]) assert len(llop) == 3 assert llop[0].opname == 'direct_call' assert len(llop[0].args) == 3 From ericvrp at codespeak.net Thu Jun 29 13:14:36 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 29 Jun 2006 13:14:36 +0200 (CEST) Subject: [pypy-svn] r29486 - in pypy/dist/pypy/translator/js: . demo/jsdemo proxy/testme test tools Message-ID: <20060629111436.4516810079@code0.codespeak.net> Author: ericvrp Date: Thu Jun 29 13:14:33 2006 New Revision: 29486 Modified: pypy/dist/pypy/translator/js/commproxy.py pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py pypy/dist/pypy/translator/js/proxy/testme/controllers.py pypy/dist/pypy/translator/js/test/test_typed.py pypy/dist/pypy/translator/js/tools/start_bnb.py Log: Player is now selectable. Fixed player_name controller method. And removal of some unused code. Modified: pypy/dist/pypy/translator/js/commproxy.py ============================================================================== --- pypy/dist/pypy/translator/js/commproxy.py (original) +++ pypy/dist/pypy/translator/js/commproxy.py Thu Jun 29 13:14:33 2006 @@ -10,10 +10,15 @@ var data,str; x = new XMLHttpRequest(); data = %(data)s; - str = "?" + str = "" for(i in data) { if (data[i]) { - str += i + "=" + data[i].toString() + ";"; + if (str.length == 0) { + str += "?"; + } else { + str += "&"; + } + str += i + "=" + data[i].toString(); } } logDebug('%(call)s'+str); @@ -44,10 +49,15 @@ %(class)s.prototype.%(method)s = function ( %(args)s ) { var data,str; data = %(data)s; - str = "?" + str = "" for(i in data) { //if (data[i]) { - str += i + "=" + data[i].toString() + ";"; + if (str.length == 0) { + str += "?"; + } else { + str += "&"; + } + str += i + "=" + data[i].toString(); //} } //logDebug('%(call)s'+str); Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py Thu Jun 29 13:14:33 2006 @@ -100,19 +100,9 @@ 'get_message' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), 'add_player' : MethodDesc( [('player_id', 0), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), 'remove_player': MethodDesc( [('player_id', 0), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), + 'player_name' : MethodDesc( [('player_id', 0), ('name', 'PyPy player'), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), 'key' : MethodDesc( [('player_id', 0), ('keynum', '0'), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), 'initialize_session' : MethodDesc( [('callback', (lambda : None))], {'aa':'bb'}), - -# 'add_player0' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), -# 'remove_player0': MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), - 'key0' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), - 'key1' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), - 'key2' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), - 'key3' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), - 'key4' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), - 'key5' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), - 'key6' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), - 'key7' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), } @@ -148,8 +138,9 @@ return dict(now=time.ctime(), onload=self.jsname, code=self.jssource) @turbogears.expose(format='json') - def player_name(self, name): - self.sessionSocket().send(message(CMSG_PLAYER_NAME, name)) + def player_name(self, player_id, name): + print "Changing player #%s name to %s" % (player_id, name) + self.sessionSocket().send(message(CMSG_PLAYER_NAME, int(player_id), name)) return self.get_message() @turbogears.expose(format='json') Modified: pypy/dist/pypy/translator/js/proxy/testme/controllers.py ============================================================================== --- pypy/dist/pypy/translator/js/proxy/testme/controllers.py (original) +++ pypy/dist/pypy/translator/js/proxy/testme/controllers.py Thu Jun 29 13:14:33 2006 @@ -56,8 +56,8 @@ return dict() @expose(format='json') - def player_name(self, name): - self.sessionSocket().send(message(CMSG_PLAYER_NAME, name)) + def player_name(self, player_id, name): + self.sessionSocket().send(message(CMSG_PLAYER_NAME, int(player_id), name)) return self.recv() @expose(format='json') Modified: pypy/dist/pypy/translator/js/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_typed.py (original) +++ pypy/dist/pypy/translator/js/test/test_typed.py Thu Jun 29 13:14:33 2006 @@ -260,7 +260,7 @@ f = compile_function(wrapper, [int]) assert f(42) -def test_str2int(): +def test_int2str(): def fn(i): return str(i) def wrapper(i): Modified: pypy/dist/pypy/translator/js/tools/start_bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/tools/start_bnb.py (original) +++ pypy/dist/pypy/translator/js/tools/start_bnb.py Thu Jun 29 13:14:33 2006 @@ -17,31 +17,13 @@ from pypy.translator.js.modules.mochikit import log, logWarning, createLoggingPane from pypy.translator.js.modules.dom import get_document, set_on_keydown, set_on_keyup from pypy.translator.js.modules.bltns import date +from pypy.translator.js.demo.jsdemo.bnb import BnbRootInstance import time import os os.chdir("../demo/jsdemo") -#if not conftest.option.browser: -# py.test.skip("Works only in browser (right now?)") - -from pypy.translator.js.demo.jsdemo.bnb import BnbRootInstance - -##def msg_dispatcher(data): -## for i in data['messages']: -## log(i['type']) -## BnbRootInstance.get_message(msg_dispatcher) -## -##def test_mochikit(): -## def mochikit(): -## createLoggingPane(True) -## BnbRootInstance.get_message(msg_dispatcher) -## -## from pypy.translator.js.proxy.testme.controllers import Root -## fn = compile_function(mochikit, [], root = Root) -## fn() - class Stats(object): """ Class containing some statistics """ @@ -64,6 +46,12 @@ stats = Stats() +class Player(object): + def __init__(self): + self.id = -1 + +player = Player() + class SpriteManager(object): def __init__(self): self.sprites = {} @@ -134,11 +122,6 @@ div.setAttribute('style', 'position:absolute; top:0px; left:0px') get_document().body.appendChild(div) elif msg['type'] == 'def_icon': -## img = get_document().createElement("img") -## img.setAttribute("src", msg["filename"]) -## img.setAttribute("style", 'position:absolute; left:0; top:0') -## img.setAttribute("id", msg["icon_code"]) -## get_document().getElementById("playfield").appendChild(img) sm.add_icon(msg['icon_code'], msg['filename']) elif msg['type'] == 'ns': sm.add_sprite(msg['s'], msg['icon_code'], msg['x'], msg['y']) @@ -157,28 +140,59 @@ # sm.show_sprite(msg['s']) +def addPlayer(player_id): + name = "player no. " + str(player_id) + #name = "player no. %d" % player_id + #File "/Users/eric/projects/pypy-dist/pypy/translator/js/jts.py", line 52, in lltype_to_cts + # raise NotImplementedError("Type %r" % (t,)) + # NotImplementedError: Type + prev_player_id = player.id + if player.id >= 0: + log("removing " + name) + BnbRootInstance.remove_player(player.id, bnb_dispatcher) + player.id = -1 + if player_id != prev_player_id: + log("adding " + name) + BnbRootInstance.add_player(player_id, bnb_dispatcher) + BnbRootInstance.player_name(player_id, name, bnb_dispatcher) + player.id = player_id + + def keydown(key): #c = chr(int(key.keyCode)).lower() #c = int(key.keyCode) c = key.keyCode - if c == '65': #ord('A'): - #BnbRootInstance.add_player0(bnb_dispatcher) - log("adding player") - BnbRootInstance.add_player(0, bnb_dispatcher) - elif c == '82': #ord('R'): - #BnbRootInstance.remove_player0(bnb_dispatcher) - BnbRootInstance.remove_player(0, bnb_dispatcher) + if c == '48': #ord('0'): + addPlayer(0) + elif c == '49': #ord('1'): #bwah. should really work on being able to cast to int + addPlayer(1) + elif c == '50': #ord('2'): + addPlayer(2) + elif c == '51': #ord('3'): + addPlayer(3) + elif c == '52': #ord('4'): + addPlayer(4) + elif c == '53': #ord('5'): + addPlayer(5) + elif c == '54': #ord('6'): + addPlayer(6) + elif c == '55': #ord('7'): + addPlayer(7) + elif c == '56': #ord('8'): + addPlayer(8) + elif c == '57': #ord('9'): + addPlayer(9) elif c == '68': #ord('D'): #right - BnbRootInstance.key0(bnb_dispatcher) + BnbRootInstance.key(player.id, 0, bnb_dispatcher) log('start right') elif c == '83': #ord('S'): #left - BnbRootInstance.key1(bnb_dispatcher) + BnbRootInstance.key(player.id, 1, bnb_dispatcher) log('start left') elif c == '69': #ord('E'): #up - BnbRootInstance.key2(bnb_dispatcher) + BnbRootInstance.key(player.id, 2, bnb_dispatcher) log('start up') elif c == '88': #ord('X'): #fire - BnbRootInstance.key3(bnb_dispatcher) + BnbRootInstance.key(player.id, 3, bnb_dispatcher) log('start fire') else: logWarning('unknown keydown: ' + c) @@ -186,19 +200,20 @@ def keyup(key): c = key.keyCode - if c in ('65', '82'): #Ignore A&R - pass + if c == '48' or c == '49' or c == '50' or c == '51' or c == '52' or\ + c == '53' or c == '54' or c == '55' or c == '56' or c == '57': #XXX c in (...) didn't work + pass #don't print warning elif c == '68': #ord('D'): #right - BnbRootInstance.key4(bnb_dispatcher) + BnbRootInstance.key(player.id, 4, bnb_dispatcher) log('stop right') elif c == '83': #ord('S'): #left - BnbRootInstance.key5(bnb_dispatcher) + BnbRootInstance.key(player.id, 5, bnb_dispatcher) log('stop left') elif c == '69': #ord('E'): #up - BnbRootInstance.key6(bnb_dispatcher) + BnbRootInstance.key(player.id, 6, bnb_dispatcher) log('stop up') elif c == '88': #ord('X'): #fire - BnbRootInstance.key7(bnb_dispatcher) + BnbRootInstance.key(player.id, 7, bnb_dispatcher) log('stop fire') else: logWarning('unknown keyup: ' + c) @@ -221,7 +236,7 @@ genjsinfo = get_document().getElementById("genjsinfo") get_document().body.removeChild(genjsinfo) createLoggingPane(True) - log("keys: dd player, emove player and to walk around") + log("keys: [0-9] to add a player, [esdx] to walk around") BnbRootInstance.initialize_session(session_dispatcher) set_on_keydown(keydown) set_on_keyup(keyup) From arigo at codespeak.net Thu Jun 29 15:40:50 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 15:40:50 +0200 (CEST) Subject: [pypy-svn] r29490 - in pypy/dist/pypy: jit/timeshifter jit/timeshifter/test rpython rpython/lltypesystem Message-ID: <20060629134050.D16C910076@code0.codespeak.net> Author: arigo Date: Thu Jun 29 15:40:47 2006 New Revision: 29490 Added: pypy/dist/pypy/jit/timeshifter/oop.py (contents, props changed) Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py pypy/dist/pypy/jit/timeshifter/rvalue.py pypy/dist/pypy/jit/timeshifter/test/test_vlist.py pypy/dist/pypy/jit/timeshifter/vlist.py pypy/dist/pypy/rpython/lltypesystem/rlist.py pypy/dist/pypy/rpython/rgenop.py Log: (arre, pedronis, arigo) Forcing lists, and more oopspec wacking to support falling back to the original operation in case of forced lists. Added: pypy/dist/pypy/jit/timeshifter/oop.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/jit/timeshifter/oop.py Thu Jun 29 15:40:47 2006 @@ -0,0 +1,71 @@ +from pypy.rpython.lltypesystem import lltype +from pypy.rpython import rgenop +from pypy.jit.timeshifter.rcontainer import cachedtype +from pypy.jit.timeshifter import rvalue + + +class Index: + def __init__(self, n): + self.n = n + + +class OopSpecDesc: + __metaclass__ = cachedtype + + def __init__(self, fnobj): + ll_func = fnobj._callable + FUNCTYPE = lltype.typeOf(fnobj) + nb_args = len(FUNCTYPE.ARGS) + + # parse the oopspec and fill in the arguments + operation_name, args = ll_func.oopspec.split('(', 1) + assert args.endswith(')') + args = args[:-1] + ',' # trailing comma to force tuple syntax + argnames = ll_func.func_code.co_varnames[:nb_args] + d = dict(zip(argnames, [Index(n) for n in range(nb_args)])) + self.argtuple = eval(args, d) + # end of rather XXX'edly hackish parsing + + self.argpositions = [] + for i, obj in enumerate(self.argtuple): + if isinstance(obj, Index): + self.argpositions.append(obj.n + 1) + else: + self.argpositions.append(0) + + for i in range(nb_args): + ARGTYPE = FUNCTYPE.ARGS[i] + assert ((i+1) in self.argpositions) == (ARGTYPE is not lltype.Void) + + self.args_gv = [rgenop.placeholder(None)] * nb_args + self.args_gv.insert(0, rgenop.genconst(fnobj._as_ptr())) + self.gv_result_type = rgenop.constTYPE(FUNCTYPE.RESULT) + self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.RESULT) + + if operation_name == 'newlist': + from pypy.jit.timeshifter.vlist import ListTypeDesc, oop_newlist + self.typedesc = ListTypeDesc(FUNCTYPE.RESULT.TO) + self.ll_handler = oop_newlist + else: + typename, method = operation_name.split('.') + method = 'oop_%s_%s' % (typename, method) + vmodule = __import__('pypy.jit.timeshifter.v%s' % (typename,), + None, None, [method]) + self.ll_handler = getattr(vmodule, method) + + def _freeze_(self): + return True + + def residual_call(self, jitstate, argboxes): + args_gv = self.args_gv[:] + argpositions = self.argpositions + for i in range(len(argpositions)): + pos = argpositions[i] + if pos > 0: + gv_arg = argboxes[i].getgenvar(jitstate) + args_gv[pos] = gv_arg + gv_result = rgenop.genop(jitstate.curblock, + 'direct_call', + args_gv, + self.gv_result_type) + return self.redboxbuilder(self.gv_result_type, gv_result) Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rtyper.py (original) +++ pypy/dist/pypy/jit/timeshifter/rtyper.py Thu Jun 29 15:40:47 2006 @@ -207,23 +207,16 @@ fnobj = c_func.value._obj if hasattr(fnobj._callable, 'oopspec'): hop.r_s_popfirstarg() - return self.handle_highlevel_operation(fnobj._callable, hop) + return self.handle_highlevel_operation(fnobj, hop) else: raise NotImplementedError("direct_call") - def handle_highlevel_operation(self, ll_func, hop): - # parse the oopspec and fill in the arguments - class Index: - def __init__(self, n): - self.n = n - operation_name, args = ll_func.oopspec.split('(', 1) - assert args.endswith(')') - args = args[:-1] + ',' # trailing comma to force tuple syntax - argnames = ll_func.func_code.co_varnames[:hop.nb_args] - d = dict(zip(argnames, [Index(n) for n in range(hop.nb_args)])) - argtuple = eval(args, d) + def handle_highlevel_operation(self, fnobj, hop): + from pypy.jit.timeshifter.oop import OopSpecDesc, Index + oopspecdesc = OopSpecDesc(fnobj) + args_v = [] - for obj in argtuple: + for obj in oopspecdesc.argtuple: if isinstance(obj, Index): hs = hop.args_s[obj.n] r_arg = self.getredrepr(originalconcretetype(hs)) @@ -231,7 +224,6 @@ else: v = hop.inputconst(self.getredrepr(lltype.typeOf(obj)), obj) args_v.append(v) - # end of rather XXX'edly hackish parsing ts = self.timeshifter args_s = [ts.s_RedBox] * len(args_v) @@ -241,26 +233,15 @@ else: s_result = ts.s_RedBox - if operation_name == 'newlist': - from pypy.jit.timeshifter.vlist import ListTypeDesc, oop_newlist - typedesc = ListTypeDesc(RESULT.TO) - c_typedesc = inputconst(lltype.Void, typedesc) - s_typedesc = ts.rtyper.annotator.bookkeeper.immutablevalue(typedesc) - args_v.insert(0, c_typedesc) - args_s.insert(0, s_typedesc) - ll_handler = oop_newlist - else: - typename, method = operation_name.split('.') - method = 'oop_%s_%s' % (typename, method) - vmodule = __import__('pypy.jit.timeshifter.v%s' % (typename,), - None, None, [method]) - ll_handler = getattr(vmodule, method) + c_oopspecdesc = hop.inputconst(lltype.Void, oopspecdesc) + s_oopspecdesc = ts.rtyper.annotator.bookkeeper.immutablevalue( + oopspecdesc) v_jitstate = hop.llops.getjitstate() - return hop.llops.genmixlevelhelpercall(ll_handler, - [ts.s_JITState] + args_s, - [v_jitstate] + args_v, - s_result) + return hop.llops.genmixlevelhelpercall(oopspecdesc.ll_handler, + [ts.s_JITState, s_oopspecdesc] + args_s, + [v_jitstate, c_oopspecdesc] + args_v, + s_result) class HintLowLevelOpList(LowLevelOpList): Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rvalue.py (original) +++ pypy/dist/pypy/jit/timeshifter/rvalue.py Thu Jun 29 15:40:47 2006 @@ -63,6 +63,23 @@ # XXX what about long longs? return IntRedBox +def redboxbuilder_void(gv_type, gv_value):return None +def redboxbuilder_int(gv_ptr, gv_value): return IntRedBox(gv_ptr, gv_value) +def redboxbuilder_dbl(gv_ptr, gv_value): return DoubleRedBox(gv_ptr, gv_value) +def redboxbuilder_ptr(gv_ptr, gv_value): return PtrRedBox(gv_ptr, gv_value) + +def ll_redboxbuilder(TYPE): + if TYPE is lltype.Void: + return redboxbuilder_void + elif isinstance(TYPE, lltype.Ptr): + return redboxbuilder_ptr + elif TYPE is lltype.Float: + return redboxbuilder_dbl + else: + assert isinstance(TYPE, lltype.Primitive) + # XXX what about long longs? + return redboxbuilder_int + def ll_fromvalue(value): "Make a constant RedBox from a low-level value." T = lltype.typeOf(value) Modified: pypy/dist/pypy/jit/timeshifter/test/test_vlist.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/test/test_vlist.py (original) +++ pypy/dist/pypy/jit/timeshifter/test/test_vlist.py Thu Jun 29 15:40:47 2006 @@ -60,3 +60,15 @@ insns, res = timeshift(ll_function, [0], [], policy=P_OOPSPEC) assert res == 131 assert insns == {'int_is_true': 1} + +def test_force(): + def ll_function(n): + lst = [] + lst.append(n) + if n: + lst.append(12) + return lst[-1] + insns, res = timeshift(ll_function, [6], [], policy=P_OOPSPEC) + assert res == 12 + insns, res = timeshift(ll_function, [0], [], policy=P_OOPSPEC) + assert res == 0 Modified: pypy/dist/pypy/jit/timeshifter/vlist.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/vlist.py (original) +++ pypy/dist/pypy/jit/timeshifter/vlist.py Thu Jun 29 15:40:47 2006 @@ -12,6 +12,8 @@ self.LISTPTR = lltype.Ptr(LIST) self.gv_type = rgenop.constTYPE(self.LIST) self.gv_ptrtype = rgenop.constTYPE(self.LISTPTR) + self.build_newlist = LIST.list_builder.build_newlist + self.build_setitem = LIST.list_builder.build_setitem def _freeze_(self): return True @@ -73,7 +75,16 @@ box.enter_block(newblock, incoming, memo) def force_runtime_container(self, jitstate): - assert 0 + typedesc = self.typedesc + boxes = self.item_boxes + self.item_boxes = None + llops = rgenop.LowLevelOpBuilder(jitstate.curblock) + gv_list = typedesc.build_newlist(llops, len(boxes)) + self.ownbox.genvar = gv_list + self.ownbox.content = None + for i in range(len(boxes)): + gv_item = boxes[i].getgenvar(jitstate) + typedesc.build_setitem(llops, gv_list, i, gv_item) def freeze(self, memo): contmemo = memo.containers @@ -105,18 +116,21 @@ self.ownbox = self.ownbox.replace(memo) -def oop_newlist(jitstate, typedesc, lengthbox): +def oop_newlist(jitstate, oopspecdesc, lengthbox): assert lengthbox.is_constant() length = rvalue.ll_getvalue(lengthbox, lltype.Signed) assert length == 0 - return typedesc.ll_factory() + return oopspecdesc.typedesc.ll_factory() -def oop_list_append(jitstate, selfbox, itembox): - assert isinstance(selfbox.content, VirtualList) - selfbox.content.item_boxes.append(itembox) - -def oop_list_getitem(jitstate, selfbox, indexbox): - assert isinstance(selfbox.content, VirtualList) - assert indexbox.is_constant() - index = rvalue.ll_getvalue(indexbox, lltype.Signed) - return selfbox.content.item_boxes[index] +def oop_list_append(jitstate, oopspecdesc, selfbox, itembox): + if isinstance(selfbox.content, VirtualList): + selfbox.content.item_boxes.append(itembox) + else: + oopspecdesc.residual_call(jitstate, [selfbox, itembox]) + +def oop_list_getitem(jitstate, oopspecdesc, selfbox, indexbox): + if isinstance(selfbox.content, VirtualList) and indexbox.is_constant(): + index = rvalue.ll_getvalue(indexbox, lltype.Signed) + return selfbox.content.item_boxes[index] + else: + return oopspecdesc.residual_call(jitstate, [selfbox, indexbox]) Modified: pypy/dist/pypy/rpython/lltypesystem/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rlist.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rlist.py Thu Jun 29 15:40:47 2006 @@ -106,32 +106,41 @@ self.LISTPTR = LISTPTR argtypes = [Signed] - fnptr = list_repr.rtyper.annotate_helper_fn(LIST.ll_newlist, argtypes) - self.newlist_ptr = fnptr + newlist_ptr = list_repr.rtyper.annotate_helper_fn(LIST.ll_newlist, + argtypes) bk = list_repr.rtyper.annotator.bookkeeper argtypes = [bk.immutablevalue(dum_nocheck), LISTPTR, Signed, ITEM] - fnptr = list_repr.rtyper.annotate_helper_fn(ll_setitem_nonneg, argtypes) - self.setitem_nonneg_ptr = fnptr + setitem_nonneg_ptr = list_repr.rtyper.annotate_helper_fn( + ll_setitem_nonneg, argtypes) #self.c_dum_nocheck = inputconst(Void, dum_nocheck) #self.c_LIST = inputconst(Void, self.LIST) - def build(self, llops, items_v): - """Make the operations that would build a list containing the - provided items.""" - c_newlist = llops.genconst(self.newlist_ptr) - c_len = llops.genconst(len(items_v)) - c_LIST = llops.genvoidconst(self.LIST) - v_result = llops.genop('direct_call', + def build_newlist(llops, length): + c_newlist = llops.genconst(newlist_ptr) + c_len = llops.genconst(length) + c_LIST = llops.genvoidconst(LIST) + return llops.genop('direct_call', [c_newlist, c_LIST, c_len], - self.LISTPTR) - c_setitem_nonneg = llops.genconst(self.setitem_nonneg_ptr) - for i in range(len(items_v)): - c_i = llops.genconst(i) + LISTPTR) + + def build_setitem(llops, v_list, index, v_item): + c_setitem_nonneg = llops.genconst(setitem_nonneg_ptr) + c_i = llops.genconst(index) llops.genop('direct_call', [c_setitem_nonneg, llops.genvoidconst(dum_nocheck), - v_result, c_i, items_v[i]]) - return v_result + v_list, c_i, v_item]) + + self.build_newlist = build_newlist + self.build_setitem = build_setitem + + def build(self, llops, items_v): + """Make the operations that would build a list containing the + provided items.""" + v_list = self.build_newlist(llops, len(items_v)) + for i, v in enumerate(items_v): + self.build_setitem(llops, v_list, i, v) + return v_list def getlistptr(self): list_repr = self.tmp_list_repr Modified: pypy/dist/pypy/rpython/rgenop.py ============================================================================== --- pypy/dist/pypy/rpython/rgenop.py (original) +++ pypy/dist/pypy/rpython/rgenop.py Thu Jun 29 15:40:47 2006 @@ -311,3 +311,18 @@ setannotation(constFieldName, s_ConstOrVar, specialize_as_constant=True) setannotation(constTYPE, s_ConstOrVar, specialize_as_constant=True) setannotation(placeholder, s_ConstOrVar, specialize_as_constant=True) + +# ____________________________________________________________ + +class LowLevelOpBuilder(object): + + def __init__(self, block): + self.block = block + + genconst = staticmethod(genconst) + genvoidconst = staticmethod(placeholder) + + def genop(self, opname, args_gv, RESULTTYPE=lltype.Void): + gv_result_type = constTYPE(RESULTTYPE) + return genop(self.block, opname, args_gv, gv_result_type) + genop._annspecialcase_ = 'specialize:arg(3)' From ericvrp at codespeak.net Thu Jun 29 18:10:59 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 29 Jun 2006 18:10:59 +0200 (CEST) Subject: [pypy-svn] r29498 - in pypy/dist/pypy/translator/js: demo/jsdemo proxy/testme Message-ID: <20060629161059.91A0510076@code0.codespeak.net> Author: ericvrp Date: Thu Jun 29 18:10:57 2006 New Revision: 29498 Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py pypy/dist/pypy/translator/js/proxy/testme/servermessage.py Log: close connection when idle for more than 5 seconds Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py Thu Jun 29 18:10:57 2006 @@ -107,6 +107,7 @@ def serverMessage(self): + self._closeIdleConnections() sessionid = session['_id'] if sessionid not in self._serverMessage: self._serverMessage[sessionid] = ServerMessage('static/images/') @@ -134,7 +135,6 @@ @turbogears.expose(html="jsdemo.templates.bnb") def index(self): - import time return dict(now=time.ctime(), onload=self.jsname, code=self.jssource) @turbogears.expose(format='json') @@ -206,6 +206,16 @@ sm.socket.close() del self._serverMessage[sessionid] + def _closeIdleConnections(self): + t = time.time() - 5.0 #5 seconds until considered idle + for sessionid, sm in self._serverMessage.items(): + if sm.last_active < t: + log("Close connection with sessionid %s because it was idle for %.1f seconds" % ( + sessionid, time.time() - sm.last_active)) + if sm.socket is not None: + sm.socket.close() + del self._serverMessage[sessionid] + @turbogears.expose(format="json") def initialize_session(self): self._close() Modified: pypy/dist/pypy/translator/js/proxy/testme/servermessage.py ============================================================================== --- pypy/dist/pypy/translator/js/proxy/testme/servermessage.py (original) +++ pypy/dist/pypy/translator/js/proxy/testme/servermessage.py Thu Jun 29 18:10:57 2006 @@ -8,6 +8,7 @@ from os.path import exists from md5 import md5 from struct import unpack +from time import time debug = True @@ -51,10 +52,12 @@ self.gfx_dir = self.base_gfx_dir #gets overwritten depending on playfield FnDesc self.gfx_url = self.base_gfx_url self.decompressobj = decompressobj().decompress + self.last_active = time() def dispatch(self, *values): #log('RECEIVED:%s(%d)' % (values[0], len(values[1:]))) + self.last_active = time() fn = self.MESSAGES.get(values[0]) if fn: try: From arigo at codespeak.net Thu Jun 29 18:25:14 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 18:25:14 +0200 (CEST) Subject: [pypy-svn] r29499 - in pypy/dist/pypy: objspace/flow translator/tool Message-ID: <20060629162514.1ECA810079@code0.codespeak.net> Author: arigo Date: Thu Jun 29 18:25:07 2006 New Revision: 29499 Modified: pypy/dist/pypy/objspace/flow/model.py pypy/dist/pypy/translator/tool/graphpage.py pypy/dist/pypy/translator/tool/make_dot.py pypy/dist/pypy/translator/tool/reftracker.py Log: (arre, arigo, a bit of pedronis) Improve graph viewing tools a bit: we can now say block.show() or link.show(), and the reftracker tries harder to give nice information. Modified: pypy/dist/pypy/objspace/flow/model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/model.py (original) +++ pypy/dist/pypy/objspace/flow/model.py Thu Jun 29 18:25:07 2006 @@ -41,6 +41,7 @@ class FunctionGraph(object): + __slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__'] def __init__(self, name, startblock, return_var=None): self.name = name # function name (possibly mangled already) @@ -162,6 +163,10 @@ __getstate__ = getstate_with_slots __setstate__ = setstate_with_slots + def show(self): + from pypy.translator.tool.graphpage import try_show + try_show(self) + class Block(object): __slots__ = """isstartblock inputargs operations exitswitch @@ -242,6 +247,10 @@ __getstate__ = getstate_with_slots __setstate__ = setstate_with_slots + def show(self): + from pypy.translator.tool.graphpage import try_show + try_show(self) + class Variable(object): __slots__ = ["_name", "_nr", "concretetype"] Modified: pypy/dist/pypy/translator/tool/graphpage.py ============================================================================== --- pypy/dist/pypy/translator/tool/graphpage.py (original) +++ pypy/dist/pypy/translator/tool/graphpage.py Thu Jun 29 18:25:07 2006 @@ -438,3 +438,40 @@ result = '%s__0x%x' % (getattr(obj, '__name__', ''), uid(obj)) cache[obj] = result return result + +# ____________________________________________________________ +# +# Helpers to try to show a graph when we only have a Block or a Link + +def try_show(obj): + if isinstance(obj, FunctionGraph): + obj.show() + elif isinstance(obj, Link): + try_show(obj.prevblock) + elif isinstance(obj, Block): + import gc + pending = [obj] # pending blocks + seen = {obj: True, None: True} + for x in pending: + for y in gc.get_referrers(x): + if isinstance(y, FunctionGraph): + y.show() + return + elif isinstance(y, Link): + block = y.prevblock + if block not in seen: + pending.append(block) + seen[block] = True + graph = IncompleteGraph(pending) + SingleGraphPage(graph).display() + else: + raise TypeError("try_show(%r object)" % (type(obj).__name__,)) + +class IncompleteGraph: + name = '(incomplete graph)' + + def __init__(self, bunch_of_blocks): + self.bunch_of_blocks = bunch_of_blocks + + def iterblocks(self): + return iter(self.bunch_of_blocks) Modified: pypy/dist/pypy/translator/tool/make_dot.py ============================================================================== --- pypy/dist/pypy/translator/tool/make_dot.py (original) +++ pypy/dist/pypy/translator/tool/make_dot.py Thu Jun 29 18:25:07 2006 @@ -82,12 +82,13 @@ def emit_subgraph(self, name, node): name = name.replace('.', '_') + '_' - self.blocks = {} + self.blocks = {id(None): '(None)'} self.func = None self.prefix = name self.enter_subgraph(name) self.visit_FunctionGraph(node) - traverse(self.visit, node) + for block in node.iterblocks(): + self.visit_Block(block) self.leave_subgraph() def blockname(self, block): @@ -98,10 +99,6 @@ self.blocks[i] = name = "%s_%d" % (self.prefix, len(self.blocks)) return name - def visit(self, obj): - if isinstance(obj, Block): - self.visit_Block(obj) - def visit_FunctionGraph(self, funcgraph): name = self.prefix # +'_'+funcgraph.name data = funcgraph.name @@ -117,7 +114,8 @@ self.emit_node(name, label=data, shape="box", fillcolor="green", style="filled") #('%(name)s [fillcolor="green", shape=box, label="%(data)s"];' % locals()) - self.emit_edge(name, self.blockname(funcgraph.startblock), 'startblock') + if hasattr(funcgraph, 'startblock'): + self.emit_edge(name, self.blockname(funcgraph.startblock), 'startblock') #self.emit_edge(name, self.blockname(funcgraph.returnblock), 'returnblock', style="dashed") def visit_Block(self, block): Modified: pypy/dist/pypy/translator/tool/reftracker.py ============================================================================== --- pypy/dist/pypy/translator/tool/reftracker.py (original) +++ pypy/dist/pypy/translator/tool/reftracker.py Thu Jun 29 18:25:07 2006 @@ -112,6 +112,13 @@ for k, v in o1.items(): if v is o2: slst.append('[%r]' % (k,)) + else: + for basetype in type(o1).__mro__: + for key, value in basetype.__dict__.items(): + if (type(value) is MemberDescriptorType or + type(value) is AttributeType): + if value.__get__(o1) is o2: + slst.append(str(key)) return ', '.join(slst) @@ -119,13 +126,27 @@ """Invoke a dot+pygame object reference tracker.""" page = RefTrackerPage([MARKER] + list(objs)) del objs + gc.collect() + gc.collect() page.display() +class _A(object): + __slots__ = 'a' +class _B(object): + pass +MemberDescriptorType = type(_A.a) +AttributeType = type(_B.__dict__['__dict__']) + + if __name__ == '__main__': try: sys.path.remove(os.getcwd()) except ValueError: pass + class A(object): + __slots__ = ['a'] d = {"lskjadldjslkj": "adjoiadoixmdoiemdwoi"} + a1 = A() + a1.a = d track(d) From arigo at codespeak.net Thu Jun 29 18:31:35 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 18:31:35 +0200 (CEST) Subject: [pypy-svn] r29500 - pypy/dist/pypy/rpython Message-ID: <20060629163135.A0C7610079@code0.codespeak.net> Author: arigo Date: Thu Jun 29 18:31:34 2006 New Revision: 29500 Modified: pypy/dist/pypy/rpython/llinterp.py Log: Make a symlink '/tmp/usession-/llinterp_trace.html' pointing to the latest (or currently) produced .html. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Thu Jun 29 18:31:34 2006 @@ -4,7 +4,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.objectmodel import ComputedIntSymbolic -import sys +import sys, os import math import py import traceback, cStringIO @@ -869,8 +869,20 @@ from pypy.tool.udir import udir n = Tracer.Counter Tracer.Counter += 1 - self.file = udir.join('llinterp_trace_%d.html' % n).open('w') + filename = 'llinterp_trace_%d.html' % n + self.file = udir.join(filename).open('w') print >> self.file, self.HEADER + + linkname = str(udir.join('llinterp_trace.html')) + try: + os.unlink(linkname) + except OSError: + pass + try: + os.symlink(filename, linkname) + except (AttributeError, OSError): + pass + self.count = 0 self.indentation = '' From arigo at codespeak.net Thu Jun 29 18:32:12 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 18:32:12 +0200 (CEST) Subject: [pypy-svn] r29501 - pypy/dist/pypy/rpython Message-ID: <20060629163212.D0C7610079@code0.codespeak.net> Author: arigo Date: Thu Jun 29 18:32:11 2006 New Revision: 29501 Modified: pypy/dist/pypy/rpython/annlowlevel.py Log: (arre, pedronis, arigo) A bug fix. See comments. Modified: pypy/dist/pypy/rpython/annlowlevel.py ============================================================================== --- pypy/dist/pypy/rpython/annlowlevel.py (original) +++ pypy/dist/pypy/rpython/annlowlevel.py Thu Jun 29 18:32:11 2006 @@ -184,6 +184,12 @@ def delayedconst(self, repr, obj): if repr.is_setup_delayed(): + # record the existence of this 'obj' for the bookkeeper - e.g. + # if 'obj' is an instance, this will populate the classdef with + # the prebuilt attribute values of the instance + bk = self.rtyper.annotator.bookkeeper + bk.immutablevalue(obj) + delayedptr = lltype._ptr(repr.lowleveltype, "delayed!") self.delayedconsts.append((delayedptr, repr, obj)) return delayedptr From arigo at codespeak.net Thu Jun 29 18:32:52 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 18:32:52 +0200 (CEST) Subject: [pypy-svn] r29502 - pypy/dist/pypy/jit/tl Message-ID: <20060629163252.279E010079@code0.codespeak.net> Author: arigo Date: Thu Jun 29 18:32:50 2006 New Revision: 29502 Modified: pypy/dist/pypy/jit/tl/tlr.py Log: (arre, pedronis, arigo) Cheat here with many hints. These should be reverted at some point. Modified: pypy/dist/pypy/jit/tl/tlr.py ============================================================================== --- pypy/dist/pypy/jit/tl/tlr.py (original) +++ pypy/dist/pypy/jit/tl/tlr.py Thu Jun 29 18:32:50 2006 @@ -19,11 +19,11 @@ opcode = hint(ord(bytecode[pc]), concrete=True) pc += 1 if opcode == MOV_A_R: - n = ord(bytecode[pc]) + n = ord(bytecode[pc]); hint(n, concrete=True) pc += 1 regs[n] = a elif opcode == MOV_R_A: - n = ord(bytecode[pc]) + n = ord(bytecode[pc]); hint(n, concrete=True) pc += 1 a = regs[n] elif opcode == JUMP_IF_A: @@ -32,16 +32,16 @@ if a: pc = target elif opcode == SET_A: - a = ord(bytecode[pc]) + a = ord(bytecode[pc]); hint(a, concrete=True) pc += 1 elif opcode == ADD_R_TO_A: - n = ord(bytecode[pc]) + n = ord(bytecode[pc]); hint(n, concrete=True) pc += 1 a += regs[n] elif opcode == RETURN_A: return a elif opcode == ALLOCATE: - n = ord(bytecode[pc]) + n = ord(bytecode[pc]); hint(n, concrete=True) pc += 1 regs = [0] * n elif opcode == NEG_A: From arigo at codespeak.net Thu Jun 29 18:35:12 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 18:35:12 +0200 (CEST) Subject: [pypy-svn] r29503 - in pypy/dist/pypy/jit: hintannotator timeshifter timeshifter/test Message-ID: <20060629163512.53AC510079@code0.codespeak.net> Author: arigo Date: Thu Jun 29 18:35:09 2006 New Revision: 29503 Added: pypy/dist/pypy/jit/timeshifter/test/test_tlr.py (contents, props changed) Modified: pypy/dist/pypy/jit/hintannotator/model.py pypy/dist/pypy/jit/timeshifter/oop.py pypy/dist/pypy/jit/timeshifter/rtimeshift.py pypy/dist/pypy/jit/timeshifter/rtyper.py pypy/dist/pypy/jit/timeshifter/timeshift.py pypy/dist/pypy/jit/timeshifter/vlist.py Log: (arre, pedronis, arigo) Added a test: the TLR interpreter. Lots of fixes, additions, and head-scratching to make it pass. Added minimal direct_call() support (all-green only). We have now turned the TLR interpreter into a compiler :-) Modified: pypy/dist/pypy/jit/hintannotator/model.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/model.py (original) +++ pypy/dist/pypy/jit/hintannotator/model.py Thu Jun 29 18:35:09 2006 @@ -149,6 +149,14 @@ class __extend__(SomeLLAbstractValue): + def define_unary(TYPE): + def var_unary(hs_v): + return SomeLLAbstractVariable(TYPE) + return var_unary + + int_neg = define_unary(lltype.Signed) + uint_is_true = int_is_true = define_unary(lltype.Bool) + def same_as(hs_v1): return hs_v1 Modified: pypy/dist/pypy/jit/timeshifter/oop.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/oop.py (original) +++ pypy/dist/pypy/jit/timeshifter/oop.py Thu Jun 29 18:35:09 2006 @@ -53,9 +53,6 @@ None, None, [method]) self.ll_handler = getattr(vmodule, method) - def _freeze_(self): - return True - def residual_call(self, jitstate, argboxes): args_gv = self.args_gv[:] argpositions = self.argpositions Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Thu Jun 29 18:35:09 2006 @@ -761,6 +761,7 @@ replace_memo = rvalue.copy_memo() for box in outgoingvarboxes: linkargs.append(box.getgenvar(jitstate)) + for box in outgoingvarboxes: if box.is_constant(): # constant boxes considered immutable: box = box.copy(replace_memo) # copy to avoid patching the original box.genvar = rgenop.geninputarg(newblock, box.gv_type) Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rtyper.py (original) +++ pypy/dist/pypy/jit/timeshifter/rtyper.py Thu Jun 29 18:35:09 2006 @@ -206,8 +206,17 @@ assert isinstance(c_func, flowmodel.Constant) fnobj = c_func.value._obj if hasattr(fnobj._callable, 'oopspec'): + # special-cased call, for things like list methods hop.r_s_popfirstarg() return self.handle_highlevel_operation(fnobj, hop) + elif (originalconcretetype(hop.s_result) is not lltype.Void and + isinstance(hop.r_result, GreenRepr)): + # green-returning call, for now (XXX) we assume it's an + # all-green function that we can just call + for r_arg in hop.args_r: + assert isinstance(r_arg, GreenRepr) + v = hop.genop('direct_call', hop.args_v, hop.r_result.lowleveltype) + return v else: raise NotImplementedError("direct_call") @@ -225,7 +234,19 @@ v = hop.inputconst(self.getredrepr(lltype.typeOf(obj)), obj) args_v.append(v) + # if the ll_handler() takes more arguments, it must be 'None' defaults. + # Pass them as constant Nones. ts = self.timeshifter + ll_handler = oopspecdesc.ll_handler + missing_args = ((ll_handler.func_code.co_argcount - 2) - + len(oopspecdesc.argtuple)) + assert missing_args >= 0 + if missing_args > 0: + assert (ll_handler.func_defaults[-missing_args:] == + (None,) * missing_args) + ll_None = lltype.nullptr(ts.r_RedBox.lowleveltype.TO) + args_v.extend([hop.llops.genconst(ll_None)] * missing_args) + args_s = [ts.s_RedBox] * len(args_v) RESULT = originalconcretetype(hop.s_result) if RESULT is lltype.Void: @@ -233,12 +254,12 @@ else: s_result = ts.s_RedBox - c_oopspecdesc = hop.inputconst(lltype.Void, oopspecdesc) - s_oopspecdesc = ts.rtyper.annotator.bookkeeper.immutablevalue( - oopspecdesc) - + s_oopspecdesc = ts.s_OopSpecDesc + ll_oopspecdesc = ts.annhelper.delayedconst(ts.r_OopSpecDesc, + oopspecdesc) + c_oopspecdesc = hop.llops.genconst(ll_oopspecdesc) v_jitstate = hop.llops.getjitstate() - return hop.llops.genmixlevelhelpercall(oopspecdesc.ll_handler, + return hop.llops.genmixlevelhelpercall(ll_handler, [ts.s_JITState, s_oopspecdesc] + args_s, [v_jitstate, c_oopspecdesc] + args_v, s_result) @@ -274,16 +295,11 @@ graph = self.timeshifter.annhelper.getgraph(function, args_s, s_result) self.record_extra_call(graph) # xxx - rtyper = self.timeshifter.rtyper - ARGS = [rtyper.getrepr(s_arg).lowleveltype for s_arg in args_s] - RESULT = rtyper.getrepr(s_result).lowleveltype - - F = lltype.FuncType(ARGS, RESULT) - - fptr = lltype.functionptr(F, graph.name, graph=graph) + c = self.timeshifter.annhelper.graph2const(graph) # build the 'direct_call' operation - c = inputconst(lltype.Ptr(F), fptr) + rtyper = self.timeshifter.rtyper + RESULT = rtyper.getrepr(s_result).lowleveltype return self.genop('direct_call', [c]+args_v, resulttype = RESULT) Added: pypy/dist/pypy/jit/timeshifter/test/test_tlr.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/jit/timeshifter/test/test_tlr.py Thu Jun 29 18:35:09 2006 @@ -0,0 +1,11 @@ +from pypy.rpython.lltypesystem.rstr import string_repr +from pypy.jit.timeshifter.test.test_timeshift import timeshift +from pypy.jit.timeshifter.test.test_vlist import P_OOPSPEC + +from pypy.jit.tl import tlr + + +def test_tlr(): + bytecode = string_repr.convert_const(tlr.SQUARE) + insns, res = timeshift(tlr.interpret, [bytecode, 9], [0], policy=P_OOPSPEC) + assert res == 81 Modified: pypy/dist/pypy/jit/timeshifter/timeshift.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/timeshift.py (original) +++ pypy/dist/pypy/jit/timeshifter/timeshift.py Thu Jun 29 18:35:09 2006 @@ -3,7 +3,7 @@ from pypy.objspace.flow import model as flowmodel from pypy.annotation import model as annmodel from pypy.annotation import listdef, dictdef -from pypy.jit.timeshifter import rvalue +from pypy.jit.timeshifter import rvalue, oop from pypy.jit.timeshifter.rtimeshift import JITState from pypy.rpython import rmodel, rgenop, annlowlevel from pypy.rpython.lltypesystem import rtuple, rlist, rdict @@ -26,6 +26,8 @@ self.s_JITState, self.r_JITState = self.s_r_instanceof(JITState) self.s_RedBox, self.r_RedBox = self.s_r_instanceof(rvalue.RedBox) + self.s_OopSpecDesc, self.r_OopSpecDesc = self.s_r_instanceof( + oop.OopSpecDesc) getrepr = self.rtyper.getrepr @@ -123,8 +125,14 @@ return self.latestexitindex def timeshift(self): - for graph in self.hannotator.translator.graphs: - self.timeshift_graph(graph) + # XXX in-progress: + ##for graph in self.hannotator.translator.graphs: + ## self.timeshift_graph(graph) + + # instead: + graph = self.hannotator.translator.graphs[0] + self.timeshift_graph(graph) + # Annotate and rType the helpers found during timeshifting self.annhelper.finish() Modified: pypy/dist/pypy/jit/timeshifter/vlist.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/vlist.py (original) +++ pypy/dist/pypy/jit/timeshifter/vlist.py Thu Jun 29 18:35:09 2006 @@ -15,11 +15,8 @@ self.build_newlist = LIST.list_builder.build_newlist self.build_setitem = LIST.list_builder.build_setitem - def _freeze_(self): - return True - - def ll_factory(self): - vlist = VirtualList(self) + def factory(self, length, itembox): + vlist = VirtualList(self, length, itembox) box = rvalue.PtrRedBox(self.gv_ptrtype) box.content = vlist vlist.ownbox = box @@ -62,10 +59,10 @@ class VirtualList(AbstractContainer): - def __init__(self, typedesc): + def __init__(self, typedesc, length=0, itembox=None): self.typedesc = typedesc - self.item_boxes = [] - # self.ownbox = ... set in ll_factory + self.item_boxes = [itembox] * length + # self.ownbox = ... set in factory() def enter_block(self, newblock, incoming, memo): contmemo = memo.containers @@ -116,11 +113,12 @@ self.ownbox = self.ownbox.replace(memo) -def oop_newlist(jitstate, oopspecdesc, lengthbox): - assert lengthbox.is_constant() - length = rvalue.ll_getvalue(lengthbox, lltype.Signed) - assert length == 0 - return oopspecdesc.typedesc.ll_factory() +def oop_newlist(jitstate, oopspecdesc, lengthbox, itembox=None): + if lengthbox.is_constant(): + length = rvalue.ll_getvalue(lengthbox, lltype.Signed) + if length == 0 or itembox is not None: + return oopspecdesc.typedesc.factory(length, itembox) + return oopspecdesc.residual_call(jitstate, [lengthbox, itembox]) def oop_list_append(jitstate, oopspecdesc, selfbox, itembox): if isinstance(selfbox.content, VirtualList): @@ -134,3 +132,10 @@ return selfbox.content.item_boxes[index] else: return oopspecdesc.residual_call(jitstate, [selfbox, indexbox]) + +def oop_list_setitem(jitstate, oopspecdesc, selfbox, indexbox, itembox): + if isinstance(selfbox.content, VirtualList) and indexbox.is_constant(): + index = rvalue.ll_getvalue(indexbox, lltype.Signed) + selfbox.content.item_boxes[index] = itembox + else: + oopspecdesc.residual_call(jitstate, [selfbox, indexbox, itembox]) From arigo at codespeak.net Thu Jun 29 18:53:36 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 18:53:36 +0200 (CEST) Subject: [pypy-svn] r29504 - in pypy/dist/pypy/jit: llabstractinterp/test tl tl/test Message-ID: <20060629165336.5DD2310076@code0.codespeak.net> Author: arigo Date: Thu Jun 29 18:53:34 2006 New Revision: 29504 Modified: pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py pypy/dist/pypy/jit/tl/test/test_tl.py pypy/dist/pypy/jit/tl/tl.py Log: ( " , " , " ) A flag to get a version of the TL without the recursive call. Modified: pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py ============================================================================== --- pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py (original) +++ pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py Thu Jun 29 18:53:34 2006 @@ -11,7 +11,7 @@ def setup_module(mod): t = TranslationContext() - t.buildannotator().build_types(tl.interp, [str, int]) + t.buildannotator().build_types(tl.interp, [str, int, bool]) rtyper = t.buildrtyper() rtyper.specialize() #inline.auto_inlining(t, 0.3) @@ -23,10 +23,12 @@ def jit_tl(code): interp = LLAbstractInterp() hints = {0: string_repr.convert_const(code), - 1: 0} + 1: 0, + 2: True} graph2 = interp.eval(graph1, hints) - result1 = llinterp.eval_graph(graph1, [string_repr.convert_const(code), 0]) + result1 = llinterp.eval_graph(graph1, [string_repr.convert_const(code), 0, + True]) result2 = llinterp.eval_graph(graph2, []) assert result1 == result2 Modified: pypy/dist/pypy/jit/tl/test/test_tl.py ============================================================================== --- pypy/dist/pypy/jit/tl/test/test_tl.py (original) +++ pypy/dist/pypy/jit/tl/test/test_tl.py Thu Jun 29 18:53:34 2006 @@ -48,7 +48,7 @@ def test_tl_translatable(): code = list2bytecode([PUSH,42, PUSH,100, ADD]) - fn = translate(interp, [str, int]) + fn = translate(interp, [str, int, bool]) assert interp(code) == fn(code) def test_swap(): Modified: pypy/dist/pypy/jit/tl/tl.py ============================================================================== --- pypy/dist/pypy/jit/tl/tl.py (original) +++ pypy/dist/pypy/jit/tl/tl.py Thu Jun 29 18:53:34 2006 @@ -11,7 +11,7 @@ t = -(-ord(c) & 0xff) return t -def interp(code='', pc=0): +def interp(code='', pc=0, support_calls=True): if not isinstance(code,str): raise TypeError("code '%s' should be a string" % str(code)) @@ -111,7 +111,7 @@ if stack.pop(): pc += hint(offset, forget=True) - elif opcode == CALL: + elif support_calls and opcode == CALL: offset = char2int(code[pc]) pc += 1 res = interp(code, pc + offset) From arigo at codespeak.net Thu Jun 29 18:59:23 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 18:59:23 +0200 (CEST) Subject: [pypy-svn] r29505 - in pypy/dist/pypy/jit: llabstractinterp/test tl tl/test Message-ID: <20060629165923.86DF510076@code0.codespeak.net> Author: arigo Date: Thu Jun 29 18:59:21 2006 New Revision: 29505 Modified: pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py pypy/dist/pypy/jit/tl/test/test_tl.py pypy/dist/pypy/jit/tl/tl.py Log: Revert r29504. Will do it differently. Modified: pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py ============================================================================== --- pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py (original) +++ pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py Thu Jun 29 18:59:21 2006 @@ -11,7 +11,7 @@ def setup_module(mod): t = TranslationContext() - t.buildannotator().build_types(tl.interp, [str, int, bool]) + t.buildannotator().build_types(tl.interp, [str, int]) rtyper = t.buildrtyper() rtyper.specialize() #inline.auto_inlining(t, 0.3) @@ -23,12 +23,10 @@ def jit_tl(code): interp = LLAbstractInterp() hints = {0: string_repr.convert_const(code), - 1: 0, - 2: True} + 1: 0} graph2 = interp.eval(graph1, hints) - result1 = llinterp.eval_graph(graph1, [string_repr.convert_const(code), 0, - True]) + result1 = llinterp.eval_graph(graph1, [string_repr.convert_const(code), 0]) result2 = llinterp.eval_graph(graph2, []) assert result1 == result2 Modified: pypy/dist/pypy/jit/tl/test/test_tl.py ============================================================================== --- pypy/dist/pypy/jit/tl/test/test_tl.py (original) +++ pypy/dist/pypy/jit/tl/test/test_tl.py Thu Jun 29 18:59:21 2006 @@ -48,7 +48,7 @@ def test_tl_translatable(): code = list2bytecode([PUSH,42, PUSH,100, ADD]) - fn = translate(interp, [str, int, bool]) + fn = translate(interp, [str, int]) assert interp(code) == fn(code) def test_swap(): Modified: pypy/dist/pypy/jit/tl/tl.py ============================================================================== --- pypy/dist/pypy/jit/tl/tl.py (original) +++ pypy/dist/pypy/jit/tl/tl.py Thu Jun 29 18:59:21 2006 @@ -11,7 +11,7 @@ t = -(-ord(c) & 0xff) return t -def interp(code='', pc=0, support_calls=True): +def interp(code='', pc=0): if not isinstance(code,str): raise TypeError("code '%s' should be a string" % str(code)) @@ -111,7 +111,7 @@ if stack.pop(): pc += hint(offset, forget=True) - elif support_calls and opcode == CALL: + elif opcode == CALL: offset = char2int(code[pc]) pc += 1 res = interp(code, pc + offset) From arigo at codespeak.net Thu Jun 29 19:14:54 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 19:14:54 +0200 (CEST) Subject: [pypy-svn] r29507 - in pypy/dist/pypy/jit: llabstractinterp/test timeshifter/test tl tl/test Message-ID: <20060629171454.0D3E310081@code0.codespeak.net> Author: arigo Date: Thu Jun 29 19:14:51 2006 New Revision: 29507 Added: pypy/dist/pypy/jit/timeshifter/test/test_tl.py (contents, props changed) Modified: pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py pypy/dist/pypy/jit/tl/opcode.py pypy/dist/pypy/jit/tl/test/test_tl.py pypy/dist/pypy/jit/tl/tl.py Log: (arre, pedronis, arigo) Modified the TL to take an input integer argument, available with a PUSHARG instruction. There are also now two variants of the TL, with or without the recursive call. Corresponding JIT test in-progress. Modified: pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py ============================================================================== --- pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py (original) +++ pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py Thu Jun 29 19:14:51 2006 @@ -11,7 +11,7 @@ def setup_module(mod): t = TranslationContext() - t.buildannotator().build_types(tl.interp, [str, int]) + t.buildannotator().build_types(tl.interp, [str, int, int]) rtyper = t.buildrtyper() rtyper.specialize() #inline.auto_inlining(t, 0.3) @@ -26,8 +26,9 @@ 1: 0} graph2 = interp.eval(graph1, hints) - result1 = llinterp.eval_graph(graph1, [string_repr.convert_const(code), 0]) - result2 = llinterp.eval_graph(graph2, []) + result1 = llinterp.eval_graph(graph1, [string_repr.convert_const(code), + 0, 0]) + result2 = llinterp.eval_graph(graph2, [0]) assert result1 == result2 Added: pypy/dist/pypy/jit/timeshifter/test/test_tl.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/jit/timeshifter/test/test_tl.py Thu Jun 29 19:14:51 2006 @@ -0,0 +1,15 @@ +from pypy.rpython.lltypesystem.rstr import string_repr +from pypy.jit.timeshifter.test.test_timeshift import timeshift +from pypy.jit.timeshifter.test.test_vlist import P_OOPSPEC + +from pypy.jit.tl import tl +from pypy.jit.tl.test.test_tl import FACTORIAL_SOURCE + + +def test_tl(): + import py; py.test.skip("in-progress") + code = tl.compile(FACTORIAL_SOURCE) + ll_code = string_repr.convert_const(code) + insns, res = timeshift(tl.interp_without_call, [ll_code, 0, 5], [0, 1], + policy=P_OOPSPEC) + assert res == 120 Modified: pypy/dist/pypy/jit/tl/opcode.py ============================================================================== --- pypy/dist/pypy/jit/tl/opcode.py (original) +++ pypy/dist/pypy/jit/tl/opcode.py Thu Jun 29 19:14:51 2006 @@ -31,6 +31,8 @@ opcode(20, "CALL") #1 operand offset opcode(21, "RETURN") -opcode(22, "INVALID") +opcode(22, "PUSHARG") + +opcode(23, "INVALID") del opcode Modified: pypy/dist/pypy/jit/tl/test/test_tl.py ============================================================================== --- pypy/dist/pypy/jit/tl/test/test_tl.py (original) +++ pypy/dist/pypy/jit/tl/test/test_tl.py Thu Jun 29 19:14:51 2006 @@ -48,7 +48,7 @@ def test_tl_translatable(): code = list2bytecode([PUSH,42, PUSH,100, ADD]) - fn = translate(interp, [str, int]) + fn = translate(interp, [str, int, int]) assert interp(code) == fn(code) def test_swap(): @@ -170,7 +170,7 @@ PUSH,2, RETURN, PUSH,4, PUSH,5, ADD, RETURN]) -def test_factorial(): +def test_factorial_seven(): code = compile(''' PUSH 1 # accumulator PUSH 7 # N @@ -197,7 +197,7 @@ res = interp(code) assert res == 5040 -def test_factorial_harder(): +def test_factorial_seven_harder(): code = compile(''' PUSH 1 # accumulator PUSH 7 # N @@ -225,3 +225,33 @@ ''') res = interp(code) assert res == 5040 + + +FACTORIAL_SOURCE = ''' + PUSH 1 # accumulator + PUSHARG + + start: + PICK 0 + PUSH 1 + LE + BR_COND exit + + SWAP + PICK 1 + MUL + SWAP + PUSH 1 + SUB + PUSH 1 + BR_COND start + + exit: + POP + RETURN + ''' + +def test_factorial_with_arg(): + code = compile(FACTORIAL_SOURCE) + res = interp(code, 0, 6) + assert res == 720 Modified: pypy/dist/pypy/jit/tl/tl.py ============================================================================== --- pypy/dist/pypy/jit/tl/tl.py (original) +++ pypy/dist/pypy/jit/tl/tl.py Thu Jun 29 19:14:51 2006 @@ -11,119 +11,130 @@ t = -(-ord(c) & 0xff) return t -def interp(code='', pc=0): - if not isinstance(code,str): - raise TypeError("code '%s' should be a string" % str(code)) - - code_len = len(code) - stack = [] - - while pc < code_len: - opcode = ord(code[pc]) - opcode = hint(opcode, concrete=True) - pc += 1 +def make_interp(supports_call): + def interp(code='', pc=0, inputarg=0): + if not isinstance(code,str): + raise TypeError("code '%s' should be a string" % str(code)) - if opcode == NOP: - pass + code_len = len(code) + stack = [] - elif opcode == PUSH: - stack.append( char2int(code[pc]) ) + while pc < code_len: + opcode = ord(code[pc]) + opcode = hint(opcode, concrete=True) pc += 1 - elif opcode == POP: - stack.pop() + if opcode == NOP: + pass - elif opcode == SWAP: - a, b = stack.pop(), stack.pop() - stack.append(a) - stack.append(b) - - elif opcode == ROLL: #rotate stack top to somewhere below - r = char2int(code[pc]) - if r < -1: - i = len(stack) + r - if i < 0: - raise IndexError - stack.insert( i, stack.pop() ) - elif r > 1: - i = len(stack) - r - if i < 0: - raise IndexError - stack.append(stack.pop(i)) - - pc += 1 + elif opcode == PUSH: + stack.append( char2int(code[pc]) ) + pc += 1 - elif opcode == PICK: - stack.append( stack[-1 - char2int(code[pc])] ) - pc += 1 + elif opcode == POP: + stack.pop() - elif opcode == PUT: - stack[-1 - char2int(code[pc])] = stack.pop() - pc += 1 + elif opcode == SWAP: + a, b = stack.pop(), stack.pop() + stack.append(a) + stack.append(b) - elif opcode == ADD: - a, b = stack.pop(), stack.pop() - stack.append( b + a ) - - elif opcode == SUB: - a, b = stack.pop(), stack.pop() - stack.append( b - a ) - - elif opcode == MUL: - a, b = stack.pop(), stack.pop() - stack.append( b * a ) - - elif opcode == DIV: - a, b = stack.pop(), stack.pop() - stack.append( b / a ) - - elif opcode == EQ: - a, b = stack.pop(), stack.pop() - stack.append( b == a ) - - elif opcode == NE: - a, b = stack.pop(), stack.pop() - stack.append( b != a ) - - elif opcode == LT: - a, b = stack.pop(), stack.pop() - stack.append( b < a ) - - elif opcode == LE: - a, b = stack.pop(), stack.pop() - stack.append( b <= a ) - - elif opcode == GT: - a, b = stack.pop(), stack.pop() - stack.append( b > a ) - - elif opcode == GE: - a, b = stack.pop(), stack.pop() - stack.append( b >= a ) - - elif opcode == BR_COND: - if stack.pop(): - pc += char2int(code[pc]) - pc += 1 + elif opcode == ROLL: #rotate stack top to somewhere below + r = char2int(code[pc]) + if r < -1: + i = len(stack) + r + if i < 0: + raise IndexError + stack.insert( i, stack.pop() ) + elif r > 1: + i = len(stack) - r + if i < 0: + raise IndexError + stack.append(stack.pop(i)) - elif opcode == BR_COND_STK: - offset = stack.pop() - if stack.pop(): - pc += hint(offset, forget=True) + pc += 1 - elif opcode == CALL: - offset = char2int(code[pc]) - pc += 1 - res = interp(code, pc + offset) - stack.append( res ) + elif opcode == PICK: + stack.append( stack[-1 - char2int(code[pc])] ) + pc += 1 + + elif opcode == PUT: + stack[-1 - char2int(code[pc])] = stack.pop() + pc += 1 + + elif opcode == ADD: + a, b = stack.pop(), stack.pop() + stack.append( b + a ) + + elif opcode == SUB: + a, b = stack.pop(), stack.pop() + stack.append( b - a ) + + elif opcode == MUL: + a, b = stack.pop(), stack.pop() + stack.append( b * a ) + + elif opcode == DIV: + a, b = stack.pop(), stack.pop() + stack.append( b / a ) + + elif opcode == EQ: + a, b = stack.pop(), stack.pop() + stack.append( b == a ) + + elif opcode == NE: + a, b = stack.pop(), stack.pop() + stack.append( b != a ) + + elif opcode == LT: + a, b = stack.pop(), stack.pop() + stack.append( b < a ) + + elif opcode == LE: + a, b = stack.pop(), stack.pop() + stack.append( b <= a ) + + elif opcode == GT: + a, b = stack.pop(), stack.pop() + stack.append( b > a ) + + elif opcode == GE: + a, b = stack.pop(), stack.pop() + stack.append( b >= a ) + + elif opcode == BR_COND: + if stack.pop(): + pc += char2int(code[pc]) + pc += 1 + + elif opcode == BR_COND_STK: + offset = stack.pop() + if stack.pop(): + pc += hint(offset, forget=True) + + elif supports_call and opcode == CALL: + offset = char2int(code[pc]) + pc += 1 + res = interp(code, pc + offset) + stack.append( res ) + + elif opcode == RETURN: + break + + elif opcode == PUSHARG: + stack.append( inputarg ) + + else: + raise RuntimeError("unknown opcode: " + str(opcode)) + + return stack[-1] + + return interp - elif opcode == RETURN: - break - else: - raise RuntimeError("unknown opcode: " + str(opcode)) +interp = make_interp(supports_call = True) +interp_without_call = make_interp(supports_call = False) - return stack[-1] def compile(code=''): bytecode = [] From arigo at codespeak.net Thu Jun 29 19:25:24 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 19:25:24 +0200 (CEST) Subject: [pypy-svn] r29508 - pypy/dist/pypy/jit/hintannotator/test Message-ID: <20060629172524.2F94A10083@code0.codespeak.net> Author: arigo Date: Thu Jun 29 19:25:22 2006 New Revision: 29508 Modified: pypy/dist/pypy/jit/hintannotator/test/test_annotator.py Log: Oups, forgot this. Modified: pypy/dist/pypy/jit/hintannotator/test/test_annotator.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/test/test_annotator.py (original) +++ pypy/dist/pypy/jit/hintannotator/test/test_annotator.py Thu Jun 29 19:25:22 2006 @@ -421,7 +421,7 @@ def test_hannotate_tl(): from pypy.jit.tl import tl - hannotate(tl.interp, [str, int], policy=P_OOPSPEC) + hannotate(tl.interp, [str, int, int], policy=P_OOPSPEC) def test_hannotate_plus_minus(): def ll_plus_minus(s, x, y): From arigo at codespeak.net Thu Jun 29 20:16:14 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 20:16:14 +0200 (CEST) Subject: [pypy-svn] r29509 - in pypy/dist/pypy/jit/hintannotator: . test Message-ID: <20060629181614.1E3E210076@code0.codespeak.net> Author: arigo Date: Thu Jun 29 20:16:12 2006 New Revision: 29509 Modified: pypy/dist/pypy/jit/hintannotator/model.py pypy/dist/pypy/jit/hintannotator/test/test_annotator.py Log: (arre, pedronis, arigo) Clean-ups and more operations support in hintannotator.model. Modified: pypy/dist/pypy/jit/hintannotator/model.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/model.py (original) +++ pypy/dist/pypy/jit/hintannotator/model.py Thu Jun 29 20:16:12 2006 @@ -1,7 +1,7 @@ from pypy.annotation import model as annmodel from pypy.annotation.pairtype import pair, pairtype from pypy.jit.hintannotator.bookkeeper import getbookkeeper -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, lloperation UNARY_OPERATIONS = """same_as hint getfield setfield getsubstruct getarraysize setarrayitem cast_pointer @@ -50,12 +50,14 @@ for p in self.read_positions: annotator.reflowfromposition(p) + class SomeLLAbstractValue(annmodel.SomeObject): def __init__(self, T): self.concretetype = T assert self.__class__ != SomeLLAbstractValue + class SomeLLAbstractConstant(SomeLLAbstractValue): def __init__(self, T, origins, eager_concrete=False): @@ -97,9 +99,11 @@ return None annotationcolor = property(annotationcolor) + class SomeLLAbstractVariable(SomeLLAbstractValue): pass + class SomeLLAbstractContainer(SomeLLAbstractValue): def __init__(self, contentdef): @@ -149,24 +153,18 @@ class __extend__(SomeLLAbstractValue): - def define_unary(TYPE): - def var_unary(hs_v): - return SomeLLAbstractVariable(TYPE) - return var_unary - - int_neg = define_unary(lltype.Signed) - uint_is_true = int_is_true = define_unary(lltype.Bool) - def same_as(hs_v1): return hs_v1 def hint(hs_v1, hs_flags): if hs_flags.const.get('variable', False): # only for testing purposes!!! - return SomeLLAbstractVariable(hs_c1.concretetype) + return SomeLLAbstractVariable(hs_v1.concretetype) if hs_flags.const.get('concrete', False): raise HintError("cannot make a concrete from %r" % (hs_v1,)) if hs_flags.const.get('forget', False): - XXX # not implemented + # turn a variable to a constant + origin = getbookkeeper().myorigin() + return SomeLLAbstractConstant(hs_v1.concretetype, {origin: True}) def getfield(hs_v1, hs_fieldname): S = hs_v1.concretetype.TO @@ -181,8 +179,25 @@ FIELD_TYPE = getattr(S, hs_fieldname.const) return SomeLLAbstractVariable(lltype.Ptr(FIELD_TYPE)) + def getarrayitem(hs_v1, hs_index): + ARRAY = hs_v1.concretetype.TO + return SomeLLAbstractVariable(ARRAY.OF) + + def setarrayitem(hs_v1, hs_index, hs_value): + pass + + def getarraysubstruct(hs_v1, hs_index): + ARRAY = hs_v1.concretetype.TO + return SomeLLAbstractVariable(lltype.Ptr(ARRAY.OF)) + + class __extend__(SomeLLAbstractConstant): + def same_as(hs_c1): + # this is here to prevent setup() below from adding a different + # version of same_as() + return hs_c1 + def hint(hs_c1, hs_flags): if hs_flags.const.get('variable', False): # only for testing purposes!!! return SomeLLAbstractVariable(hs_c1.concretetype) @@ -282,24 +297,7 @@ d = setadd(hs_c1.origins, getbookkeeper().myorigin()) return SomeLLAbstractConstant(lltype.Ptr(SUB_TYPE), d) - def getarraysize(hs_c1): - d = setadd(hs_c1.origins, getbookkeeper().myorigin()) - return SomeLLAbstractConstant(lltype.Signed, d) - def define_unary(TYPE): - def const_unary(hs_c1): - d = setadd(hs_c1.origins, getbookkeeper().myorigin()) - return SomeLLAbstractConstant(TYPE, d, eager_concrete=hs_c1.eager_concrete) - return const_unary - - cast_int_to_char = define_unary(lltype.Char) - - cast_uint_to_int = cast_bool_to_int = cast_char_to_int = int_neg = define_unary(lltype.Signed) - - cast_int_to_uint = define_unary(lltype.Unsigned) - - uint_is_true = int_is_true = define_unary(lltype.Bool) - class __extend__(SomeLLAbstractContainer): def setfield(hs_s1, hs_fieldname, hs_value): @@ -327,28 +325,13 @@ class __extend__(pairtype(SomeLLAbstractValue, SomeLLAbstractValue)): - def define_binary(TYPE): - def var_binary((hs_v1, hs_v2)): - return SomeLLAbstractVariable(TYPE) - return var_binary - - int_mul = int_mod = int_sub = int_add = define_binary(lltype.Signed) - int_floordiv = int_rshift = int_and = int_add - - uint_mul = uint_mod = uint_sub = uint_add = define_binary(lltype.Unsigned) - uint_floordiv = uint_rshift = uint_and = uint_add - - int_lt = int_le = int_ge = int_ne = int_gt = int_eq = define_binary(lltype.Bool) - uint_lt = uint_le = uint_ge = uint_ne = uint_gt = uint_eq = int_eq - - char_gt = char_lt = char_le = char_ge = char_eq = char_ne = int_eq - def getarrayitem((hs_v1, hs_v2)): return SomeLLAbstractVariable(hs_v1.concretetype.TO.OF) def union((hs_v1, hs_v2)): raise annmodel.UnionError("%s %s don't mix" % (hs_v1, hs_v2)) + class __extend__(pairtype(SomeLLAbstractVariable, SomeLLAbstractConstant), pairtype(SomeLLAbstractConstant, SomeLLAbstractVariable)): @@ -358,25 +341,8 @@ raise annmodel.UnionError("%s %s don't mix" % (hs_v1, hs_v2)) return SomeLLAbstractVariable(hs_v1.concretetype) -class __extend__(pairtype(SomeLLAbstractConstant, SomeLLAbstractConstant)): - - def define_binary(TYPE): - def const_binary((hs_c1, hs_c2)): - d = newset(hs_c1.origins, hs_c2.origins, - {getbookkeeper().myorigin(): True}) - return SomeLLAbstractConstant(TYPE, d, eager_concrete= hs_c1.eager_concrete or hs_c2.eager_concrete) - return const_binary - - int_mul = int_mod = int_sub = int_add = define_binary(lltype.Signed) - int_floordiv = int_rshift = int_and = int_add - - uint_mul = uint_mod = uint_sub = uint_add = define_binary(lltype.Unsigned) - uint_floordiv = uint_rshift = uint_and = uint_add - int_lt = int_le = int_ge = int_ne = int_gt = int_eq = define_binary(lltype.Bool) - uint_lt = uint_le = uint_ge = uint_ne = uint_gt = uint_eq = int_eq - - char_gt = char_lt = char_le = char_ge = char_eq = char_ne = int_eq +class __extend__(pairtype(SomeLLAbstractConstant, SomeLLAbstractConstant)): def union((hs_c1, hs_c2)): assert hs_c1.concretetype == hs_c2.concretetype @@ -393,22 +359,26 @@ else: return SomeLLAbstractVariable(READ_TYPE) + class __extend__(pairtype(SomeLLAbstractContainer, SomeLLAbstractContainer)): def union((hs_cont1, hs_cont2)): contentdef = hs_cont1.contentdef.union(hs_cont2.contentdef) return SomeLLAbstractContainer(contentdef) + class __extend__(pairtype(SomeLLAbstractContainer, SomeLLAbstractValue)): def union((hs_cont1, hs_val2)): hs_cont1.contentdef.mark_degenerated() assert hs_cont1.concretetype == hs_val2.concretetype return SomeLLAbstractVariable(hs_cont1.concretetype) + class __extend__(pairtype(SomeLLAbstractValue, SomeLLAbstractContainer)): def union((hs_val1, hs_cont2)): return pair(hs_cont2, hs_val1).union() + class __extend__(pairtype(SomeLLAbstractContainer, SomeLLAbstractConstant)): def getarrayitem((hs_a1, hs_index)): @@ -461,3 +431,47 @@ hs_result = handler(*args_hs) # which may raise NotImplementedError return hs_result + +# ____________________________________________________________ +# +# Register automatically simple operations + +def var_unary(hs_v, *rest_hs): + RESTYPE = getbookkeeper().current_op_concretetype() + return SomeLLAbstractVariable(RESTYPE) + +def var_binary((hs_v1, hs_v2), *rest_hs): + RESTYPE = getbookkeeper().current_op_concretetype() + return SomeLLAbstractVariable(RESTYPE) + +def const_unary(hs_c1): + bk = getbookkeeper() + d = setadd(hs_c1.origins, bk.myorigin()) + RESTYPE = bk.current_op_concretetype() + return SomeLLAbstractConstant(RESTYPE, d, + eager_concrete = hs_c1.eager_concrete) + +def const_binary((hs_c1, hs_c2)): + bk = getbookkeeper() + d = newset(hs_c1.origins, hs_c2.origins, {bk.myorigin(): True}) + RESTYPE = bk.current_op_concretetype() + return SomeLLAbstractConstant(RESTYPE, d, + eager_concrete = hs_c1.eager_concrete or + hs_c2.eager_concrete) + +def setup(oplist, ValueCls, var_fn, ConstantCls, const_fn): + for name in oplist: + llop = getattr(lloperation.llop, name) + if not llop.sideeffects: + if name not in ValueCls.__dict__: + setattr(ValueCls, name, var_fn) + if llop.canfold: + if name not in ConstantCls.__dict__: + setattr(ConstantCls, name, const_fn) +setup(UNARY_OPERATIONS, + SomeLLAbstractValue, var_unary, + SomeLLAbstractConstant, const_unary) +setup(BINARY_OPERATIONS, + pairtype(SomeLLAbstractValue, SomeLLAbstractValue), var_binary, + pairtype(SomeLLAbstractConstant, SomeLLAbstractConstant), const_binary) +del setup Modified: pypy/dist/pypy/jit/hintannotator/test/test_annotator.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/test/test_annotator.py (original) +++ pypy/dist/pypy/jit/hintannotator/test/test_annotator.py Thu Jun 29 20:16:12 2006 @@ -13,6 +13,10 @@ P_OOPSPEC = AnnotatorPolicy() P_OOPSPEC.oopspec = True +P_OOPSPEC_NOVIRTUAL = AnnotatorPolicy() +P_OOPSPEC_NOVIRTUAL.oopspec = True +P_OOPSPEC_NOVIRTUAL.novirtualcontainer = True + def hannotate(func, argtypes, policy=None, annotator=False, inline=None): # build the normal ll graphs for ll_function t = TranslationContext() @@ -140,7 +144,9 @@ def test_op_meet(): def meet(hs1, hs2): - HintBookkeeper(None).enter(None) + bk = HintBookkeeper(None) + bk.enter(None) + bk.current_op_concretetype = lambda: lltype.Signed # hack return pair(hs1, hs2).int_add() av1, av2 = SomeLLAbstractVariable(lltype.Signed), SomeLLAbstractVariable(lltype.Signed) cv1, cv2 = SomeLLAbstractConstant(lltype.Signed, {}, True), SomeLLAbstractConstant(lltype.Signed, {}, True) @@ -423,6 +429,10 @@ from pypy.jit.tl import tl hannotate(tl.interp, [str, int, int], policy=P_OOPSPEC) +def test_hannotate_tl_novirtual(): + from pypy.jit.tl import tl + hannotate(tl.interp, [str, int, int], policy=P_OOPSPEC_NOVIRTUAL) + def test_hannotate_plus_minus(): def ll_plus_minus(s, x, y): acc = x From arigo at codespeak.net Thu Jun 29 20:40:41 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 29 Jun 2006 20:40:41 +0200 (CEST) Subject: [pypy-svn] r29510 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20060629184041.D530F10078@code0.codespeak.net> Author: arigo Date: Thu Jun 29 20:40:39 2006 New Revision: 29510 Modified: pypy/dist/pypy/translator/backendopt/constfold.py pypy/dist/pypy/translator/backendopt/test/test_constfold.py Log: (arigo, bugged by pedronis) Keepalive fix in constfold.py. Modified: pypy/dist/pypy/translator/backendopt/constfold.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/constfold.py (original) +++ pypy/dist/pypy/translator/backendopt/constfold.py Thu Jun 29 20:40:39 2006 @@ -12,6 +12,7 @@ newops = [] keepalives = [] folded_count = 0 + first_sideeffect_index = None for spaceop in operations: vargsmodif = False vargs = [] @@ -24,13 +25,13 @@ vargsmodif = True args.append(v.value) vargs.append(v) - if len(args) == len(vargs): - RESTYPE = spaceop.result.concretetype - try: - op = getattr(llop, spaceop.opname) - except AttributeError: - pass - else: + try: + op = getattr(llop, spaceop.opname) + except AttributeError: + sideeffects = True + else: + if len(args) == len(vargs): + RESTYPE = spaceop.result.concretetype try: result = op(RESTYPE, *args) except TypeError: @@ -45,10 +46,11 @@ constants[spaceop.result] = Constant(result, RESTYPE) folded_count += 1 continue + sideeffects = op.sideeffects # failed to fold an operation, exit early if requested if exit_early: return folded_count - if spaceop.opname == 'keepalive': + if spaceop.opname == 'keepalive' and first_sideeffect_index is None: if vargsmodif: continue # keepalive(constant) is not useful keepalives.append(spaceop) @@ -61,6 +63,8 @@ else: spaceop = SpaceOperation(spaceop.opname, vargs, spaceop.result) + if sideeffects and first_sideeffect_index is None: + first_sideeffect_index = len(newops) newops.append(spaceop) # end if exit_early: @@ -68,11 +72,11 @@ else: # move the keepalives to the end of the block, which makes the life # of prepare_constant_fold_link() easier. Don't put them past the - # exception-raising operation, though. - if exc_catch: - exc_raising_op = newops.pop() - keepalives.append(exc_raising_op) - newops.extend(keepalives) + # exception-raising operation, though. There is also no point in + # moving them past the first sideeffect-ing operation. + if first_sideeffect_index is None: + first_sideeffect_index = len(newops) - exc_catch + newops[first_sideeffect_index:first_sideeffect_index] = keepalives return newops def constant_fold_block(block): Modified: pypy/dist/pypy/translator/backendopt/test/test_constfold.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_constfold.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_constfold.py Thu Jun 29 20:40:39 2006 @@ -2,6 +2,7 @@ from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.llinterp import LLInterpreter from pypy.rpython.lltypesystem import lltype +from pypy.rpython import objectmodel from pypy.translator.backendopt.constfold import constant_fold_graph from pypy import conftest @@ -130,6 +131,19 @@ check_graph(graph, [12], 12, t) +def test_malloc(): + S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True}) + def fn(): + s = lltype.malloc(S1) + s.x = 12 + objectmodel.keepalive_until_here(s) + return s.x + + graph, t = get_graph(fn, []) + constant_fold_graph(graph) + check_graph(graph, [], 12, t) + + def xxx_test_later_along_link(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True}) s1 = lltype.malloc(S1) From ericvrp at codespeak.net Thu Jun 29 22:00:23 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 29 Jun 2006 22:00:23 +0200 (CEST) Subject: [pypy-svn] r29511 - in pypy/dist/pypy/translator/js: modules tools Message-ID: <20060629200023.DF96210078@code0.codespeak.net> Author: ericvrp Date: Thu Jun 29 22:00:21 2006 New Revision: 29511 Modified: pypy/dist/pypy/translator/js/modules/bltns.py (props changed) pypy/dist/pypy/translator/js/tools/autopath.py (props changed) pypy/dist/pypy/translator/js/tools/start_bnb.py (props changed) Log: fixeol From antocuni at codespeak.net Fri Jun 30 00:19:18 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 00:19:18 +0200 (CEST) Subject: [pypy-svn] r29512 - pypy/dist/pypy/translator/cli/test Message-ID: <20060629221918.90A4610069@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 00:19:13 2006 New Revision: 29512 Modified: pypy/dist/pypy/translator/cli/test/test_oo.py Log: refactoring Modified: pypy/dist/pypy/translator/cli/test/test_oo.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_oo.py (original) +++ pypy/dist/pypy/translator/cli/test/test_oo.py Fri Jun 30 00:19:13 2006 @@ -1,13 +1,5 @@ -from pypy.translator.cli.test.runtest import check from pypy.translator.cli.test.runtest import CliTest -def test_oo(): - for name, func in globals().iteritems(): - if not name.startswith('oo_'): - continue - - yield check, func, [int, int], (42, 13) - class MyClass: INCREMENT = 1 @@ -38,6 +30,20 @@ return self.x - self.y +# helper functions +def call_method(obj): + return obj.compute() + +def init_and_compute(cls, x, y): + return cls(x, y).compute() + +def nonnull_helper(lst): + if lst is None: + return 1 + else: + return 2 + + class TestOO(CliTest): def test_indirect_call(self): def f(): @@ -66,55 +72,54 @@ return x(n) assert self.interpret(fn, [True, 42]) == 43 -# helper functions -def call_method(obj): - return obj.compute() - -def init_and_compute(cls, x, y): - return cls(x, y).compute() - -# test functions -def oo_compute(x, y): - obj = MyClass(x, y) - return obj.compute() - -def oo_compute_multiply(x, y): - obj = MyClass(x, y) - return obj.compute_and_multiply(2) - -def oo_inheritance(x, y): - obj = MyDerivedClass(x, y) - return obj.compute_and_multiply(2) - -def oo_liskov(x, y): - base = MyClass(x, y) - derived = MyDerivedClass(x, y) - return call_method(base) + call_method(derived) - -def oo_static_method(x, y): - base = MyClass(x, y) - derived = MyDerivedClass(x, y) - return base.static_meth(x,y) + derived.static_meth(x, y)\ - + MyClass.static_meth(x, y) + MyDerivedClass.static_meth(x, y) - -def oo_class_attribute(x, y): - base = MyClass(x, y) - derived = MyDerivedClass(x, y) - return base.class_attribute() + derived.class_attribute() - -def oo_runtimenew(x, y): - return init_and_compute(MyClass, x, y) + init_and_compute(MyDerivedClass, x, y) - -def nonnull_helper(lst): - if lst is None: - return 1 - else: - return 2 -def oo_nonnull(x, y): - return nonnull_helper([]) + nonnull_helper(None) + def test_compute(self): + def fn(x, y): + obj = MyClass(x, y) + return obj.compute() + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_compute_multiply(self): + def fn(x, y): + obj = MyClass(x, y) + return obj.compute_and_multiply(2) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_inheritance(self): + def fn(x, y): + obj = MyDerivedClass(x, y) + return obj.compute_and_multiply(2) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_liskov(self): + def fn(x, y): + base = MyClass(x, y) + derived = MyDerivedClass(x, y) + return call_method(base) + call_method(derived) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_static_method(self): + def fn(x, y): + base = MyClass(x, y) + derived = MyDerivedClass(x, y) + return base.static_meth(x,y) + derived.static_meth(x, y)\ + + MyClass.static_meth(x, y) + MyDerivedClass.static_meth(x, y) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_class_attribute(self): + def fn(x, y): + base = MyClass(x, y) + derived = MyDerivedClass(x, y) + return base.class_attribute() + derived.class_attribute() + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_runtimenew(self): + def fn(x, y): + return init_and_compute(MyClass, x, y) + init_and_compute(MyDerivedClass, x, y) + assert self.interpret(fn, [42, 13]) == fn(42, 13) + + def test_nonnull(self): + def fn(x, y): + return nonnull_helper([]) + nonnull_helper(None) + assert self.interpret(fn, [42, 13]) == fn(42, 13) -if __name__ == '__main__': - from pypy.translator.cli import conftest - conftest.option.wd = True - check(oo_liskov, [int, int], (42, 13)) From antocuni at codespeak.net Fri Jun 30 00:35:23 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 00:35:23 +0200 (CEST) Subject: [pypy-svn] r29513 - pypy/dist/pypy/translator/cli Message-ID: <20060629223523.9B3271006E@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 00:35:19 2006 New Revision: 29513 Modified: pypy/dist/pypy/translator/cli/ilgenerator.py Log: CLI classes can be 'sealed' Modified: pypy/dist/pypy/translator/cli/ilgenerator.py ============================================================================== --- pypy/dist/pypy/translator/cli/ilgenerator.py (original) +++ pypy/dist/pypy/translator/cli/ilgenerator.py Fri Jun 30 00:35:19 2006 @@ -53,11 +53,15 @@ def end_namespace(self): self.code.closeblock() - def begin_class(self, name, base = None): + def begin_class(self, name, base = None, sealed = False): if base is None: base = '[mscorlib]System.Object' + if sealed: + s = 'sealed' + else: + s = '' - self.code.writeline('.class public %s extends %s' % (name, base)) + self.code.writeline('.class public %s %s extends %s' % (s, name, base)) self.code.openblock() def end_class(self): From antocuni at codespeak.net Fri Jun 30 00:36:21 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 00:36:21 +0200 (CEST) Subject: [pypy-svn] r29514 - pypy/dist/pypy/translator/cli Message-ID: <20060629223621.50FCF1006E@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 00:36:17 2006 New Revision: 29514 Modified: pypy/dist/pypy/translator/cli/database.py Log: Microsoft .NET wants delegate types to be sealed Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Fri Jun 30 00:36:17 2006 @@ -92,7 +92,7 @@ def gen_delegate_types(self, ilasm): for TYPE, name in self.delegates.iteritems(): - ilasm.begin_class(name, '[mscorlib]System.MulticastDelegate') + ilasm.begin_class(name, '[mscorlib]System.MulticastDelegate', sealed=True) ilasm.begin_function('.ctor', [('object', "'object'"), ('native int', "'method'")], 'void', From antocuni at codespeak.net Fri Jun 30 00:37:49 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 00:37:49 +0200 (CEST) Subject: [pypy-svn] r29515 - pypy/dist/pypy/translator/cli Message-ID: <20060629223749.A40ED1006E@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 00:37:45 2006 New Revision: 29515 Modified: pypy/dist/pypy/translator/cli/cts.py Log: Check for 'include_type' for delegates too, else Microsoft ilasm complains. Modified: pypy/dist/pypy/translator/cli/cts.py ============================================================================== --- pypy/dist/pypy/translator/cli/cts.py (original) +++ pypy/dist/pypy/translator/cli/cts.py Fri Jun 30 00:37:45 2006 @@ -88,7 +88,10 @@ name = self.db.pending_record(t) return self.__class(name, include_class) elif isinstance(t, ootype.StaticMethod): - return self.db.record_delegate_type(t) + res = self.db.record_delegate_type(t) + if include_class: + res = 'class ' + res + return res elif isinstance(t, ootype.List): item_type = self.lltype_to_cts(t._ITEMTYPE) if item_type == 'void': # special case: List of Void From antocuni at codespeak.net Fri Jun 30 00:40:37 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 00:40:37 +0200 (CEST) Subject: [pypy-svn] r29516 - pypy/dist/pypy/translator/cli Message-ID: <20060629224037.0CC171006E@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 00:40:33 2006 New Revision: 29516 Modified: pypy/dist/pypy/translator/cli/cts.py Log: Use the existing __class method instead of duplicate code. Modified: pypy/dist/pypy/translator/cli/cts.py ============================================================================== --- pypy/dist/pypy/translator/cli/cts.py (original) +++ pypy/dist/pypy/translator/cli/cts.py Fri Jun 30 00:40:33 2006 @@ -88,10 +88,8 @@ name = self.db.pending_record(t) return self.__class(name, include_class) elif isinstance(t, ootype.StaticMethod): - res = self.db.record_delegate_type(t) - if include_class: - res = 'class ' + res - return res + delegate = self.db.record_delegate_type(t) + return self.__class(delegate, include_class) elif isinstance(t, ootype.List): item_type = self.lltype_to_cts(t._ITEMTYPE) if item_type == 'void': # special case: List of Void From antocuni at codespeak.net Fri Jun 30 00:42:02 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 00:42:02 +0200 (CEST) Subject: [pypy-svn] r29517 - pypy/dist/pypy/translator/cli Message-ID: <20060629224202.4C1D21006E@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 00:41:58 2006 New Revision: 29517 Modified: pypy/dist/pypy/translator/cli/cts.py Log: check include_class for PYPY_LIST_OF_VOID, too. Modified: pypy/dist/pypy/translator/cli/cts.py ============================================================================== --- pypy/dist/pypy/translator/cli/cts.py (original) +++ pypy/dist/pypy/translator/cli/cts.py Fri Jun 30 00:41:58 2006 @@ -93,7 +93,7 @@ elif isinstance(t, ootype.List): item_type = self.lltype_to_cts(t._ITEMTYPE) if item_type == 'void': # special case: List of Void - return PYPY_LIST_OF_VOID + return self.__class(PYPY_LIST_OF_VOID, include_class) return self.__class(PYPY_LIST % item_type, include_class) elif isinstance(t, ootype.Dict): key_type = self.lltype_to_cts(t._KEYTYPE) From antocuni at codespeak.net Fri Jun 30 01:02:22 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 01:02:22 +0200 (CEST) Subject: [pypy-svn] r29518 - pypy/dist/pypy/translator/cli Message-ID: <20060629230222.E36DD10075@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 01:02:18 2006 New Revision: 29518 Modified: pypy/dist/pypy/translator/cli/class_.py Log: It could happen that first argument of a method of a class is annotated with the tyoe of a subclass: in this case don't render the method, else there would be a type mismatch. Modified: pypy/dist/pypy/translator/cli/class_.py ============================================================================== --- pypy/dist/pypy/translator/cli/class_.py (original) +++ pypy/dist/pypy/translator/cli/class_.py Fri Jun 30 01:02:18 2006 @@ -1,3 +1,4 @@ +from pypy.rpython.ootypesystem import ootype from pypy.translator.cli.node import Node from pypy.translator.cli.cts import CTS @@ -55,6 +56,15 @@ # lazy import to avoid circular dependencies #import pypy.translator.cli.function as function for m_name, m_meth in self.classdef._methods.iteritems(): + args = m_meth.graph.getargs() + + # if the first argument of the method is a strict subclass + # of this class, then this method is not really used by + # the class: don't render it, else there would be a type + # mismatch. + SELF = args[0].concretetype + if SELF is not self.classdef and ootype.isSubclass(SELF, self.classdef): + continue f = self.db.function_class(self.db, m_meth.graph, m_name, is_method = True) f.render(ilasm) From antocuni at codespeak.net Fri Jun 30 01:10:57 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 01:10:57 +0200 (CEST) Subject: [pypy-svn] r29519 - pypy/dist/pypy/translator/cli Message-ID: <20060629231057.9129610075@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 01:10:53 2006 New Revision: 29519 Modified: pypy/dist/pypy/translator/cli/cts.py Log: Prepend 'class' to StringBuilder typename, to make Microsoft ilasm happy. Modified: pypy/dist/pypy/translator/cli/cts.py ============================================================================== --- pypy/dist/pypy/translator/cli/cts.py (original) +++ pypy/dist/pypy/translator/cli/cts.py Fri Jun 30 01:10:53 2006 @@ -32,7 +32,7 @@ ootype.UniChar: 'char', ootype.Class: 'class [mscorlib]System.Type', ootype.String: 'string', - ootype.StringBuilder: PYPY_STRING_BUILDER, + ootype.StringBuilder: 'class ' + PYPY_STRING_BUILDER, # maps generic types to their ordinal ootype.List.SELFTYPE_T: 'class ' + (PYPY_LIST % '!0'), From antocuni at codespeak.net Fri Jun 30 01:20:07 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 01:20:07 +0200 (CEST) Subject: [pypy-svn] r29520 - pypy/dist/pypy/translator/cli Message-ID: <20060629232007.5AB1710075@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 01:20:02 2006 New Revision: 29520 Modified: pypy/dist/pypy/translator/cli/record.py Log: Don't try to render Void items when converting record to string. Modified: pypy/dist/pypy/translator/cli/record.py ============================================================================== --- pypy/dist/pypy/translator/cli/record.py (original) +++ pypy/dist/pypy/translator/cli/record.py Fri Jun 30 01:20:02 2006 @@ -1,5 +1,6 @@ import string +from pypy.rpython.ootypesystem import ootype from pypy.translator.cli.node import Node from pypy.translator.cli.cts import CTS @@ -72,6 +73,8 @@ 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)) From rxe at codespeak.net Fri Jun 30 03:30:26 2006 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 30 Jun 2006 03:30:26 +0200 (CEST) Subject: [pypy-svn] r29521 - pypy/dist/pypy/objspace/cpy/test Message-ID: <20060630013026.8418910076@code0.codespeak.net> Author: rxe Date: Fri Jun 30 03:30:10 2006 New Revision: 29521 Modified: pypy/dist/pypy/objspace/cpy/test/test_typedef.py Log: Banged my head against a wall for an entire day - can anyone help me please! :-) Seems like we have trouble specializing wrap() if there is more than user defined class to wrap. Modified: pypy/dist/pypy/objspace/cpy/test/test_typedef.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/test/test_typedef.py (original) +++ pypy/dist/pypy/objspace/cpy/test/test_typedef.py Fri Jun 30 03:30:10 2006 @@ -1,4 +1,5 @@ import py +import py.test from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef @@ -52,6 +53,31 @@ assert type(res).__name__ == 'MyType' +def test_get_blackboxes(): + py.test.skip("a bug with specialize:wrap?") + W_MyType.typedef = TypeDef("MyType") + + class W_MyType2(Wrappable): + def __init__(self, space, x=1): + self.space = space + self.x = x + W_MyType2.typedef = TypeDef("MyType2") + space = CPyObjSpace() + + def make_mytype(n): + if n: + return space.wrap(W_MyType2(space)) + else: + return space.wrap(W_MyType(space)) + fn = compile(make_mytype, [int], + annotatorpolicy = CPyAnnotatorPolicy(space)) + + res = fn(1, expected_extra_mallocs=1) + assert type(res).__name__ == 'MyType' + res = fn(0, expected_extra_mallocs=1) + assert type(res).__name__ == 'MyType2' + + def test_blackbox(): W_MyType.typedef = TypeDef("MyType") space = CPyObjSpace() From ericvrp at codespeak.net Fri Jun 30 09:32:48 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 30 Jun 2006 09:32:48 +0200 (CEST) Subject: [pypy-svn] r29522 - in pypy/dist/pypy/translator/js: demo/jsdemo tools Message-ID: <20060630073248.DEEB010075@code0.codespeak.net> Author: ericvrp Date: Fri Jun 30 09:32:46 2006 New Revision: 29522 Added: pypy/dist/pypy/translator/js/demo/jsdemo/msgstruct.py - copied unchanged from r29470, pypy/dist/pypy/translator/js/proxy/testme/msgstruct.py pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py - copied unchanged from r29498, pypy/dist/pypy/translator/js/proxy/testme/servermessage.py Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py pypy/dist/pypy/translator/js/tools/start_bnb.py Log: Refactor to use files from the demo directory only (no longer from proxy). Prefend 'random' (non-update) messages to start a new request-response loop. Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py Fri Jun 30 09:32:46 2006 @@ -7,8 +7,9 @@ from pypy.translator.js.demo.jsdemo.controllers import Root from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc -from pypy.translator.js.proxy.testme.servermessage import log, ServerMessage, PMSG_INLINE_FRAME, PMSG_DEF_ICON -from pypy.translator.js.proxy.testme.msgstruct import * +from pypy.translator.js.demo.jsdemo.servermessage import log, ServerMessage,\ + PMSG_INLINE_FRAME, PMSG_DEF_ICON +from pypy.translator.js.demo.jsdemo.msgstruct import * from cherrypy import session import re, time, sys, os, urllib, socket, copy, md5, random @@ -139,27 +140,26 @@ @turbogears.expose(format='json') def player_name(self, player_id, name): - print "Changing player #%s name to %s" % (player_id, name) + log("Changing player #%s name to %s" % (player_id, name)) self.sessionSocket().send(message(CMSG_PLAYER_NAME, int(player_id), name)) - return self.get_message() + return dict() @turbogears.expose(format='json') def add_player(self, player_id): - print "Adding player" - print player_id + log("Adding player " + player_id) self.sessionSocket().send(message(CMSG_ADD_PLAYER, int(player_id))) - return self.get_message() + return dict() @turbogears.expose(format='json') def remove_player(self, player_id): - print player_id + log("Remove player " + player_id) self.sessionSocket().send(message(CMSG_REMOVE_PLAYER, int(player_id))) - return self.get_message() + return dict() @turbogears.expose(format='json') def key(self, player_id, keynum): self.sessionSocket().send(message(CMSG_KEY, int(player_id), int(keynum))) - return self.get_message() + return dict() @turbogears.expose(format='json') def key0(self): @@ -224,7 +224,7 @@ sessionid = session['_id'] self._serverMessage[sessionid] = ServerMessage('static/images/') self._spriteManagers[sessionid] = SpriteManager() - return dict() + return dict(messages=[]) @turbogears.expose(format="json") def get_message(self): @@ -308,7 +308,7 @@ sprite_manager.end_frame() messages += to_append #messages.append(to_append[0]) - #print len(messages) + #log(len(messages)) return dict(messages=messages) BnbRootInstance = BnbRoot() Modified: pypy/dist/pypy/translator/js/tools/start_bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/tools/start_bnb.py (original) +++ pypy/dist/pypy/translator/js/tools/start_bnb.py Fri Jun 30 09:32:46 2006 @@ -149,12 +149,12 @@ prev_player_id = player.id if player.id >= 0: log("removing " + name) - BnbRootInstance.remove_player(player.id, bnb_dispatcher) + BnbRootInstance.remove_player(player.id, ignore_dispatcher) player.id = -1 if player_id != prev_player_id: log("adding " + name) - BnbRootInstance.add_player(player_id, bnb_dispatcher) - BnbRootInstance.player_name(player_id, name, bnb_dispatcher) + BnbRootInstance.add_player(player_id, ignore_dispatcher) + BnbRootInstance.player_name(player_id, name, ignore_dispatcher) player.id = player_id @@ -183,16 +183,16 @@ elif c == '57': #ord('9'): addPlayer(9) elif c == '68': #ord('D'): #right - BnbRootInstance.key(player.id, 0, bnb_dispatcher) + BnbRootInstance.key(player.id, 0, ignore_dispatcher) log('start right') elif c == '83': #ord('S'): #left - BnbRootInstance.key(player.id, 1, bnb_dispatcher) + BnbRootInstance.key(player.id, 1, ignore_dispatcher) log('start left') elif c == '69': #ord('E'): #up - BnbRootInstance.key(player.id, 2, bnb_dispatcher) + BnbRootInstance.key(player.id, 2, ignore_dispatcher) log('start up') elif c == '88': #ord('X'): #fire - BnbRootInstance.key(player.id, 3, bnb_dispatcher) + BnbRootInstance.key(player.id, 3, ignore_dispatcher) log('start fire') else: logWarning('unknown keydown: ' + c) @@ -204,20 +204,22 @@ c == '53' or c == '54' or c == '55' or c == '56' or c == '57': #XXX c in (...) didn't work pass #don't print warning elif c == '68': #ord('D'): #right - BnbRootInstance.key(player.id, 4, bnb_dispatcher) + BnbRootInstance.key(player.id, 4, ignore_dispatcher) log('stop right') elif c == '83': #ord('S'): #left - BnbRootInstance.key(player.id, 5, bnb_dispatcher) + BnbRootInstance.key(player.id, 5, ignore_dispatcher) log('stop left') elif c == '69': #ord('E'): #up - BnbRootInstance.key(player.id, 6, bnb_dispatcher) + BnbRootInstance.key(player.id, 6, ignore_dispatcher) log('stop up') elif c == '88': #ord('X'): #fire - BnbRootInstance.key(player.id, 7, bnb_dispatcher) + BnbRootInstance.key(player.id, 7, ignore_dispatcher) log('stop fire') else: logWarning('unknown keyup: ' + c) +def ignore_dispatcher(msgs): + pass def bnb_dispatcher(msgs): BnbRootInstance.get_message(bnb_dispatcher) @@ -226,7 +228,7 @@ stats.register_frame() get_document().title = str(stats.n_sprites) + " sprites " + str(stats.fps) #sc.revive() - + def session_dispatcher(msgs): #log("Something...") BnbRootInstance.get_message(bnb_dispatcher) From ericvrp at codespeak.net Fri Jun 30 09:50:57 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 30 Jun 2006 09:50:57 +0200 (CEST) Subject: [pypy-svn] r29524 - pypy/dist/pypy/translator/js/proxy Message-ID: <20060630075057.BCB4710078@code0.codespeak.net> Author: ericvrp Date: Fri Jun 30 09:50:55 2006 New Revision: 29524 Removed: pypy/dist/pypy/translator/js/proxy/ Log: Refactor because this is now replaced by the code in demo/jsdemo. (moved to /user/ericvrp/js/proxy) From arigo at codespeak.net Fri Jun 30 10:55:53 2006 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 30 Jun 2006 10:55:53 +0200 (CEST) Subject: [pypy-svn] r29526 - in pypy/dist/pypy/objspace/cpy: . test Message-ID: <20060630085553.3189110076@code0.codespeak.net> Author: arigo Date: Fri Jun 30 10:55:52 2006 New Revision: 29526 Modified: pypy/dist/pypy/objspace/cpy/objspace.py pypy/dist/pypy/objspace/cpy/test/test_typedef.py pypy/dist/pypy/objspace/cpy/typedef.py Log: Oups oups oups. Wrong specialization caused troubles in programs with more than one TypeDef, or other similar things. This is a tentative fix. Modified: pypy/dist/pypy/objspace/cpy/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/objspace.py (original) +++ pypy/dist/pypy/objspace/cpy/objspace.py Fri Jun 30 10:55:52 2006 @@ -6,6 +6,7 @@ from pypy.interpreter.function import Function from pypy.interpreter.typedef import GetSetProperty from pypy.rpython.rarithmetic import r_uint +from pypy.rpython.objectmodel import we_are_translated class CPyObjSpace(baseobjspace.ObjSpace): @@ -41,14 +42,15 @@ def wrap(self, x): if isinstance(x, baseobjspace.Wrappable): - x = x.__spacebind__(self) - # special cases - if isinstance(x, Function): - from pypy.objspace.cpy.function import FunctionCache - return self.fromcache(FunctionCache).getorbuild(x) - if isinstance(x, GetSetProperty): - from pypy.objspace.cpy.property import PropertyCache - return self.fromcache(PropertyCache).getorbuild(x) + # special cases, only when bootstrapping + if not we_are_translated(): + x = x.__spacebind__(self) + if isinstance(x, Function): + from pypy.objspace.cpy.function import FunctionCache + return self.fromcache(FunctionCache).getorbuild(x) + if isinstance(x, GetSetProperty): + from pypy.objspace.cpy.property import PropertyCache + return self.fromcache(PropertyCache).getorbuild(x) # normal case from pypy.objspace.cpy.typedef import rpython2cpython return rpython2cpython(self, x) @@ -66,7 +68,7 @@ # in the format string, but it's that someone is calling space.wrap() # on a strange object. raise TypeError("wrap(%r)" % (x,)) - wrap._annspecialcase_ = "specialize:wrap" + wrap._annspecialcase_ = "specialize:argtype(1)" def unwrap(self, w_obj): assert isinstance(w_obj, W_Object) Modified: pypy/dist/pypy/objspace/cpy/test/test_typedef.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/test/test_typedef.py (original) +++ pypy/dist/pypy/objspace/cpy/test/test_typedef.py Fri Jun 30 10:55:52 2006 @@ -54,7 +54,6 @@ def test_get_blackboxes(): - py.test.skip("a bug with specialize:wrap?") W_MyType.typedef = TypeDef("MyType") class W_MyType2(Wrappable): @@ -72,10 +71,10 @@ fn = compile(make_mytype, [int], annotatorpolicy = CPyAnnotatorPolicy(space)) - res = fn(1, expected_extra_mallocs=1) + res2 = fn(1, expected_extra_mallocs=1) + assert type(res2).__name__ == 'MyType2' + res = fn(0, expected_extra_mallocs=2) assert type(res).__name__ == 'MyType' - res = fn(0, expected_extra_mallocs=1) - assert type(res).__name__ == 'MyType2' def test_blackbox(): Modified: pypy/dist/pypy/objspace/cpy/typedef.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/typedef.py (original) +++ pypy/dist/pypy/objspace/cpy/typedef.py Fri Jun 30 10:55:52 2006 @@ -6,6 +6,8 @@ from pypy.objspace.cpy.capi import * from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import Wrappable, SpaceCache +from pypy.interpreter.function import Function +from pypy.interpreter.typedef import GetSetProperty from pypy.rpython.objectmodel import we_are_translated from pypy.rpython.rcpy import CPyTypeInterface, cpy_export, cpy_import from pypy.rpython.rcpy import cpy_typeobject @@ -41,6 +43,7 @@ init_rpython_data(w_x, x) return w_x rpython2cpython.allow_someobjects = True +rpython2cpython._annspecialcase_ = "specialize:argtype(1)" def cpython2rpython_raw(space, w_obj): "NOT_RPYTHON." @@ -83,6 +86,9 @@ self.wrappedtypes = {} def build(cache, typedef): + if typedef in (Function.typedef, GetSetProperty.typedef): + raise ValueError("cannot wrap at run-time an interpreter object " + "of type %r" % (typedef.name,)) space = cache.space objects = {} for name, value in typedef.rawdict.items(): From ericvrp at codespeak.net Fri Jun 30 11:32:06 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 30 Jun 2006 11:32:06 +0200 (CEST) Subject: [pypy-svn] r29527 - pypy/dist/pypy/translator/js/tools Message-ID: <20060630093206.40B3E10076@code0.codespeak.net> Author: ericvrp Date: Fri Jun 30 11:32:03 2006 New Revision: 29527 Modified: pypy/dist/pypy/translator/js/tools/start_bnb.py Log: Added code to detect when (response) messages arrive out of order. Cleaned up logging pane output. Modified: pypy/dist/pypy/translator/js/tools/start_bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/tools/start_bnb.py (original) +++ pypy/dist/pypy/translator/js/tools/start_bnb.py Fri Jun 30 11:32:03 2006 @@ -24,6 +24,10 @@ os.chdir("../demo/jsdemo") +def logKey(msg): + #log(msg) + pass + class Stats(object): """ Class containing some statistics """ @@ -49,6 +53,7 @@ class Player(object): def __init__(self): self.id = -1 + self.prev_count = 0 player = Player() @@ -135,9 +140,18 @@ sm.end_clean_sprites() elif msg['type'] == 'show_sprite': sm.show_sprite(msg['s'], msg['icon_code'], msg['x'], msg['y']) - #elif msg['type'] == 'ss': # sm.show_sprite(msg['s']) + elif msg['type'] == 'player_icon' or msg['type'] == 'def_key' or \ + msg['type'] == 'player_join' or msg['type'] == 'player_kill': + pass #ignore + elif msg['type'] == 'count': + count = int(msg['n']) + if count != player.prev_count + 1: + logWarning("incorrect response order, expected " + str(player.prev_count+1) + ' got ' + str(count)) + player.prev_count = count + else: + logWarning('unknown message type: ' + msg['type']) def addPlayer(player_id): @@ -148,11 +162,11 @@ # NotImplementedError: Type prev_player_id = player.id if player.id >= 0: - log("removing " + name) + #log("removing " + name) BnbRootInstance.remove_player(player.id, ignore_dispatcher) player.id = -1 if player_id != prev_player_id: - log("adding " + name) + #log("adding " + name) BnbRootInstance.add_player(player_id, ignore_dispatcher) BnbRootInstance.player_name(player_id, name, ignore_dispatcher) player.id = player_id @@ -184,16 +198,16 @@ addPlayer(9) elif c == '68': #ord('D'): #right BnbRootInstance.key(player.id, 0, ignore_dispatcher) - log('start right') + logKey('start right') elif c == '83': #ord('S'): #left BnbRootInstance.key(player.id, 1, ignore_dispatcher) - log('start left') + logKey('start left') elif c == '69': #ord('E'): #up BnbRootInstance.key(player.id, 2, ignore_dispatcher) - log('start up') + logKey('start up') elif c == '88': #ord('X'): #fire BnbRootInstance.key(player.id, 3, ignore_dispatcher) - log('start fire') + logKey('start fire') else: logWarning('unknown keydown: ' + c) @@ -205,16 +219,16 @@ pass #don't print warning elif c == '68': #ord('D'): #right BnbRootInstance.key(player.id, 4, ignore_dispatcher) - log('stop right') + logKey('stop right') elif c == '83': #ord('S'): #left BnbRootInstance.key(player.id, 5, ignore_dispatcher) - log('stop left') + logKey('stop left') elif c == '69': #ord('E'): #up BnbRootInstance.key(player.id, 6, ignore_dispatcher) - log('stop up') + logKey('stop up') elif c == '88': #ord('X'): #fire BnbRootInstance.key(player.id, 7, ignore_dispatcher) - log('stop fire') + logKey('stop fire') else: logWarning('unknown keyup: ' + c) @@ -227,10 +241,8 @@ process_message(msg) stats.register_frame() get_document().title = str(stats.n_sprites) + " sprites " + str(stats.fps) - #sc.revive() def session_dispatcher(msgs): - #log("Something...") BnbRootInstance.get_message(bnb_dispatcher) def run_bnb(): @@ -238,7 +250,7 @@ genjsinfo = get_document().getElementById("genjsinfo") get_document().body.removeChild(genjsinfo) createLoggingPane(True) - log("keys: [0-9] to add a player, [esdx] to walk around") + log("keys: [0-9] to select player, [esdx] to walk around") BnbRootInstance.initialize_session(session_dispatcher) set_on_keydown(keydown) set_on_keyup(keyup) From ericvrp at codespeak.net Fri Jun 30 11:40:00 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 30 Jun 2006 11:40:00 +0200 (CEST) Subject: [pypy-svn] r29529 - pypy/dist/pypy/translator/js/demo/jsdemo Message-ID: <20060630094000.CC5761007B@code0.codespeak.net> Author: ericvrp Date: Fri Jun 30 11:39:58 2006 New Revision: 29529 Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py Log: missed these files from the previous checkin Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py Fri Jun 30 11:39:58 2006 @@ -222,9 +222,10 @@ #force new session id to restart a game! session['_id'] = md5.md5(str(random.random())).hexdigest() sessionid = session['_id'] - self._serverMessage[sessionid] = ServerMessage('static/images/') + sm = ServerMessage('static/images/') + self._serverMessage[sessionid] = sm self._spriteManagers[sessionid] = SpriteManager() - return dict(messages=[]) + return dict() @turbogears.expose(format="json") def get_message(self): @@ -243,7 +244,7 @@ #log('RECEIVED HEADER LINE: %s' % header_line) #log('RECEIVED DATA CONTAINS %d BYTES' % len(data)) - messages = [] + messages = [ {'type':'count', 'n':sm.count()} ] while data: values, data = decodemessage(data) if not values: Modified: pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py Fri Jun 30 11:39:58 2006 @@ -28,6 +28,7 @@ PMSG_DEF_ICON = "def_icon" PMSG_PLAYER_ICON = "player_icon" PMSG_PLAYER_JOIN = "player_join" +PMSG_PLAYER_KILL = "player_kill" PMSG_DEF_KEY = "def_key" PMSG_INLINE_FRAME = "inline_frame" @@ -53,7 +54,11 @@ self.gfx_url = self.base_gfx_url self.decompressobj = decompressobj().decompress self.last_active = time() + self._count = 0 + def count(self): + self._count += 1 + return self._count def dispatch(self, *values): #log('RECEIVED:%s(%d)' % (values[0], len(values[1:]))) @@ -210,6 +215,10 @@ log('player_join player_id=%d, client_is_self=%d' % (player_id, client_is_self)) return dict(type=PMSG_PLAYER_JOIN, player_id=player_id, client_is_self=client_is_self) + def player_kill(self, player_id): + log('player_kill player_id=%d' % player_id) + return dict(type=PMSG_PLAYER_KILL, player_id=player_id) + def def_key(self, keyname, num, *icon_codes): #log('def_key keyname=%s, num=%d, icon_codes=%s' % (keyname, num, str(icon_codes))) return dict(type=PMSG_DEF_KEY, keyname=keyname, num=num, icon_codes=icon_codes) @@ -261,6 +270,7 @@ MSG_DEF_ICON : def_icon, MSG_PLAYER_ICON : player_icon, MSG_PLAYER_JOIN : player_join, + MSG_PLAYER_KILL : player_kill, MSG_DEF_KEY : def_key, MSG_MD5_FILE : md5_file, MSG_INLINE_FRAME : inline_frame, From adim at codespeak.net Fri Jun 30 12:57:48 2006 From: adim at codespeak.net (adim at codespeak.net) Date: Fri, 30 Jun 2006 12:57:48 +0200 (CEST) Subject: [pypy-svn] r29530 - pypy/extradoc/sprintinfo/post-ep2006 Message-ID: <20060630105748.03A5B10076@code0.codespeak.net> Author: adim Date: Fri Jun 30 12:57:46 2006 New Revision: 29530 Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt Log: update sprint attendants list Modified: pypy/extradoc/sprintinfo/post-ep2006/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/post-ep2006/people.txt (original) +++ pypy/extradoc/sprintinfo/post-ep2006/people.txt Fri Jun 30 12:57:46 2006 @@ -22,6 +22,10 @@ Eric van Riet Paap 2-9th CERN Hostel Lawrence Oluyede 6-9th CERN Hostel Alexander Schremmer 6-9th CERN Hostel +Aurelien Campeas 6-8th ? +Alexandre Fayolle 6-8th ? +Ludovic Aubry 6-8th ? +David Douard 6-8th ? ==================== ============== ===================== People on the following list were present at previous sprints: @@ -31,8 +35,6 @@ ==================== ============== ===================== Christian Tismer ? ? Jacob Hallen ? ? -Aurelien Campeas ? ? -Alexandre Fayolle ? ? Lene Wagner ? ? Amaury Forgeot d'Arc ? ? Valentino Volonghi ? ? From antocuni at codespeak.net Fri Jun 30 14:59:10 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 14:59:10 +0200 (CEST) Subject: [pypy-svn] r29533 - pypy/dist/pypy/translator/cli Message-ID: <20060630125910.EF6D910077@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 14:58:58 2006 New Revision: 29533 Modified: pypy/dist/pypy/translator/cli/class_.py pypy/dist/pypy/translator/cli/database.py pypy/dist/pypy/translator/cli/function.py pypy/dist/pypy/translator/cli/record.py Log: Add __ne__ when there is an __eq__ Modified: pypy/dist/pypy/translator/cli/class_.py ============================================================================== --- pypy/dist/pypy/translator/cli/class_.py (original) +++ pypy/dist/pypy/translator/cli/class_.py Fri Jun 30 14:58:58 2006 @@ -18,6 +18,9 @@ def __eq__(self, other): return self.classdef == other.classdef + def __ne__(self, other): + return not self == other + def is_root(classdef): return classdef._superclass is None is_root = staticmethod(is_root) Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Fri Jun 30 14:58:58 2006 @@ -203,6 +203,12 @@ ilasm.opcode('ldsfld %s %s' % (cts_type, name)) load = staticmethod(load) + def __eq__(self, other): + raise NotImplementedError + + def __ne__(self, other): + return not self == other + def get_name(self): pass Modified: pypy/dist/pypy/translator/cli/function.py ============================================================================== --- pypy/dist/pypy/translator/cli/function.py (original) +++ pypy/dist/pypy/translator/cli/function.py Fri Jun 30 14:58:58 2006 @@ -40,6 +40,9 @@ def __eq__(self, other): return self.graph == other.graph + def __ne__(self, other): + return not self == other + def _is_return_block(self, block): return (not block.exits) and len(block.inputargs) == 1 Modified: pypy/dist/pypy/translator/cli/record.py ============================================================================== --- pypy/dist/pypy/translator/cli/record.py (original) +++ pypy/dist/pypy/translator/cli/record.py Fri Jun 30 14:58:58 2006 @@ -28,6 +28,9 @@ def __eq__(self, other): return self.record == other.record + def __ne__(self, other): + return not self == other + def get_name(self): return self.name From antocuni at codespeak.net Fri Jun 30 16:08:21 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 16:08:21 +0200 (CEST) Subject: [pypy-svn] r29534 - pypy/dist/pypy/rpython/ootypesystem/test Message-ID: <20060630140821.989F310081@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 16:08:16 2006 New Revision: 29534 Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py Log: Added a failing test. Basically, if we modify the Record after its hash has already been computed, we might obtain two objects that compare equal but hash differently. Disabling the caching in LowLevelType.__hash__ fix the test, but I think it's not what we want. Adding the following __hash__ to ootype.Record also fix the test, but I'm not sure if it's correct, especially with recursive structures: def __hash__(self): return hash(self._fields) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py Fri Jun 30 16:08:16 2006 @@ -38,3 +38,14 @@ t.a = 1 t.b = 2 assert ooidentityhash(t) != ooidentityhash(t2) + +import py +def test_hash(): + #py.test.skip("LowLevelType.__hash__ bug waiting to be fixed") + T1 = Record({"item0": Signed, "item1": Signed}) + T2 = Record({"item0": Signed}) + + hash(T2) # compute the hash, it will stored in __cached_hash + T2._add_fields({"item1": Signed}) # modify the object + assert T1 == T2 + assert hash(T1) == hash(T2) From antocuni at codespeak.net Fri Jun 30 16:09:29 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 16:09:29 +0200 (CEST) Subject: [pypy-svn] r29535 - pypy/dist/pypy/rpython/ootypesystem/test Message-ID: <20060630140929.7782F10085@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 16:09:25 2006 New Revision: 29535 Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py Log: forgot to skip the test. Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_oorecord.py Fri Jun 30 16:09:25 2006 @@ -41,7 +41,7 @@ import py def test_hash(): - #py.test.skip("LowLevelType.__hash__ bug waiting to be fixed") + py.test.skip("LowLevelType.__hash__ bug waiting to be fixed") T1 = Record({"item0": Signed, "item1": Signed}) T2 = Record({"item0": Signed}) From antocuni at codespeak.net Fri Jun 30 16:19:39 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 16:19:39 +0200 (CEST) Subject: [pypy-svn] r29536 - in pypy/dist/pypy/translator/cli: . test Message-ID: <20060630141939.E3E9010085@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 16:19:34 2006 New Revision: 29536 Modified: pypy/dist/pypy/translator/cli/database.py pypy/dist/pypy/translator/cli/test/test_rpython.py Log: The workaround in LowLevelDatabase is not for a gencli bug, but for an ootype.Record bug (see revision r29534): the problem is related to hashing, so using a set doesn't fix it, we need a list for ensuring that __eq__ is called. Don't skip a test that no longer fails. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Fri Jun 30 16:19:34 2006 @@ -30,7 +30,7 @@ self.delegates = {} # StaticMethod --> type_name self.const_names = set() self.name_count = 0 - self._recorded_records = set() # XXX: temporary hack + self._recorded_records = [] # XXX: temporary hack def next_count(self): self.name_count += 1 @@ -45,7 +45,7 @@ def pending_record(self, record): r = Record(self, record) if r not in self._recorded_records: # XXX: temporary hack - self._recorded_records.add(r) + self._recorded_records.append(r) self.pending_node(r) return r.get_name() Modified: pypy/dist/pypy/translator/cli/test/test_rpython.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_rpython.py (original) +++ pypy/dist/pypy/translator/cli/test/test_rpython.py Fri Jun 30 16:19:34 2006 @@ -65,9 +65,6 @@ test_constant_tuple_contains2 = test_constant_tuple_contains test_constant_unichar_tuple_contains = test_constant_tuple_contains - def test_inst_tuple_add_getitem(self): - py.test.skip("Need to fix pending nodes rendering") - class TestCliString(CliTest, BaseTestRstr): def test_char_isxxx(self): From antocuni at codespeak.net Fri Jun 30 16:23:07 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 16:23:07 +0200 (CEST) Subject: [pypy-svn] r29537 - pypy/dist/pypy/translator/cli/test Message-ID: <20060630142307.B1CC810088@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 16:23:03 2006 New Revision: 29537 Modified: pypy/dist/pypy/translator/cli/test/test_rpython.py Log: Don't skip two tests that no longer fails Modified: pypy/dist/pypy/translator/cli/test/test_rpython.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_rpython.py (original) +++ pypy/dist/pypy/translator/cli/test/test_rpython.py Fri Jun 30 16:23:03 2006 @@ -31,14 +31,8 @@ def test_call_memoized_cache(self): py.test.skip("gencli doesn't support recursive constants, yet") - def test_multiple_specialized_functions(self): - py.test.skip("CLI doesn't support string, yet") - def test_specialized_method_of_frozen(self): - py.test.skip("CLI doesn't support string, yet") - - def test_specialized_method(self): - py.test.skip("CLI doesn't support string, yet") + py.test.skip("waiting to be fixed") class TestCliList(CliTest, BaseTestRlist): From ericvrp at codespeak.net Fri Jun 30 17:04:54 2006 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 30 Jun 2006 17:04:54 +0200 (CEST) Subject: [pypy-svn] r29538 - in pypy/dist/pypy/translator/js/demo: . jsdemo Message-ID: <20060630150454.CE8801008B@code0.codespeak.net> Author: ericvrp Date: Fri Jun 30 17:04:53 2006 New Revision: 29538 Modified: pypy/dist/pypy/translator/js/demo/dev.cfg pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py Log: Fix gfx mismatches after server restart by using the hexdigest as filename instead of the server supplied bitmap and icon codes. Modified: pypy/dist/pypy/translator/js/demo/dev.cfg ============================================================================== --- pypy/dist/pypy/translator/js/demo/dev.cfg (original) +++ pypy/dist/pypy/translator/js/demo/dev.cfg Fri Jun 30 17:04:53 2006 @@ -34,6 +34,7 @@ server.logToScreen=False server.environment="production" #"development" +#server.environment="development" #autoreload.package="testme" autoreload.on = False Modified: pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py Fri Jun 30 17:04:53 2006 @@ -4,11 +4,10 @@ import PIL.Image from zlib import decompressobj, decompress from urllib import quote -from os import mkdir from os.path import exists -from md5 import md5 from struct import unpack from time import time +import md5 debug = True @@ -37,6 +36,7 @@ class ServerMessage: _md5_file = {} + _bitmap2hexdigits={} _def_icon_queue = {} base_gfx_dir = 'testme/static/images/' base_gfx_url = 'static/images/' @@ -82,13 +82,8 @@ def def_playfield(self, width, height, backcolor, FnDesc): #log('def_playfield width=%s, height=%s, backcolor=%s, FnDesc=%s' % (\ # width, height, backcolor, FnDesc)) - hexdigest = md5(FnDesc).hexdigest() - self.gfx_dir = self.base_gfx_dir + hexdigest + '/' - self.gfx_url = self.base_gfx_url + hexdigest + '/' - try: - mkdir(self.gfx_dir) - except OSError: - pass + self.gfx_dir = self.base_gfx_dir + self.gfx_url = self.base_gfx_url return dict(type=PMSG_DEF_PLAYFIELD, width=width, height=height, backcolor=backcolor, FnDesc=FnDesc) @@ -107,17 +102,21 @@ colorkey = (c & 255, (c >> 8) & 255, (c >> 16) & 255) #log('def_bitmap1 bitmap_code=%d, data=%d bytes, colorkey=%s' % ( # bitmap_code, len(data), colorkey)) - gif_bitmap_filename = '%sbitmap%d.%s' % (self.gfx_dir, bitmap_code, self.gfx_extension) - if exists(gif_bitmap_filename): - #log('CACHED:%s' % gif_bitmap_filename) + + try: + decompressed_data = decompress(data) + except Exception, e: + raise BitmapCreationException('ERROR UNCOMPRESSING DATA FOR %s (%s)' % ( + bitmap_filename, str(e))) + hexdigits = md5.new(decompressed_data).hexdigest() + self._bitmap2hexdigits[bitmap_code] = hexdigits + + gfx_bitmap_filename = '%s%s.%s' % (self.gfx_dir, hexdigits, self.gfx_extension) + if exists(gfx_bitmap_filename): + #log('CACHED:%s' % gfx_bitmap_filename) pass else: - bitmap_filename = '%sbitmap%d.ppm' % (self.gfx_dir, bitmap_code) - try: - decompressed_data = decompress(data) - except Exception, e: - raise BitmapCreationException('ERROR UNCOMPRESSING DATA FOR %s (%s)' % ( - bitmap_filename, str(e))) + bitmap_filename = '%s%s.ppm' % (self.gfx_dir, hexdigits) f = open(bitmap_filename, 'wb') f.write(decompressed_data) f.close() @@ -141,17 +140,19 @@ data.putpixel((x,y), (0,0,0,0)) try: - bitmap.save(gif_bitmap_filename) - log('SAVED:%s' % gif_bitmap_filename) + bitmap.save(gfx_bitmap_filename) + log('SAVED:%s' % gfx_bitmap_filename) except IOError: raise BitmapCreationException('ERROR SAVING %s (%s)' % ( - gif_bitmap_filename, str(e))) + gfx_bitmap_filename, str(e))) def def_bitmap2(self, bitmap_code, fileid, *rest): #log('def_bitmap2: bitmap_code=%d, fileid=%d, colorkey=%s' % (bitmap_code, fileid, rest)) - gif_bitmap_filename = '%sbitmap%d.%s' % (self.gfx_dir, bitmap_code, self.gfx_extension) - if exists(gif_bitmap_filename): - #log('SKIP DATA_REQUEST:%s' % gif_bitmap_filename) + hexdigits = self._md5_file[fileid]['hexdigits'] + self._bitmap2hexdigits[bitmap_code] = hexdigits + gfx_bitmap_filename = '%s%s.%s' % (self.gfx_dir, hexdigits, self.gfx_extension) + if exists(gfx_bitmap_filename): + #log('SKIP DATA_REQUEST:%s' % gfx_bitmap_filename) pass else: self._md5_file[fileid]['bitmap_code'] = bitmap_code @@ -160,14 +161,17 @@ size = self._md5_file[fileid]['len_data'] msg = message(CMSG_DATA_REQUEST, fileid, position, size) self.socket.send(msg) - log('DATA_REQUEST:%s' % gif_bitmap_filename) + log('DATA_REQUEST:fileid=%d(pos=%d,size=%d):%s' % ( + fileid, position, size, gfx_bitmap_filename)) def def_icon(self, bitmap_code, icon_code, x,y,w,h, *rest): #log('def_icon bitmap_code=%s, icon_code=%s, x=%s, y=%s, w=%s, h=%s, alpha=%s' %\ # (bitmap_code, icon_code, x,y,w,h, rest) #ignore alpha (bubbles) - bitmap_filename = '%sbitmap%d.%s' % (self.gfx_dir, bitmap_code, self.gfx_extension) - icon_filename = '%sicon%d.%s' % (self.gfx_dir, icon_code, self.gfx_extension) + hexdigits = self._bitmap2hexdigits[bitmap_code] + bitmap_filename = '%s%s.%s' % (self.gfx_dir, hexdigits, self.gfx_extension) + icon_filename = '%s%s_%d_%d_%d_%d.%s' % ( + self.gfx_dir, hexdigits, x, y, w, h, self.gfx_extension) if exists(icon_filename): #log('CACHED:%s' % icon_filename) pass @@ -185,11 +189,13 @@ self._def_icon_queue[bitmap_code].append((icon_code, x, y, w, h, rest)) return - filename = '%sicon%d.%s' % (self.gfx_url, icon_code, self.gfx_extension) + filename = '%s%s_%d_%d_%d_%d.%s' % ( + self.gfx_url, hexdigits, x, y, w, h, self.gfx_extension) return dict(type=PMSG_DEF_ICON, icon_code=icon_code, filename=filename, width=w, height=h) def zpatch_file(self, fileid, position, data): #response to CMSG_DATA_REQUEST #log('zpatch_file fileid=%d, position=%d, len(data)=%d' % (fileid, position, len(data))) + bitmap_code = self._md5_file[fileid]['bitmap_code'] colorkey = self._md5_file[fileid]['colorkey'] try: @@ -212,11 +218,11 @@ return dict(type=PMSG_PLAYER_ICON, player_id=player_id, icon_code=icon_code) def player_join(self, player_id, client_is_self): - log('player_join player_id=%d, client_is_self=%d' % (player_id, client_is_self)) + #log('player_join player_id=%d, client_is_self=%d' % (player_id, client_is_self)) return dict(type=PMSG_PLAYER_JOIN, player_id=player_id, client_is_self=client_is_self) def player_kill(self, player_id): - log('player_kill player_id=%d' % player_id) + #log('player_kill player_id=%d' % player_id) return dict(type=PMSG_PLAYER_KILL, player_id=player_id) def def_key(self, keyname, num, *icon_codes): @@ -224,13 +230,19 @@ return dict(type=PMSG_DEF_KEY, keyname=keyname, num=num, icon_codes=icon_codes) def md5_file(self, fileid, protofilepath, offset, len_data, checksum): - #log('md5_file fileid=%d, protofilepath=%s, offset=%d, len_data=%d, checksum=...' % ( - # fileid, protofilepath, offset, len_data)) + hd = '0123456789abcdef' + hexdigits = '' + for c in checksum: + i = ord(c) + hexdigits = hexdigits + hd[i >> 4] + hd[i & 15] + #log('md5_file fileid=%d, protofilepath=%s, offset=%d, len_data=%d, hexdigits=%s' % ( + # fileid, protofilepath, offset, len_data, hexdigits)) self._md5_file[fileid] = { 'protofilepath' : protofilepath, 'offset' : offset, 'len_data' : len_data, 'checksum' : checksum, + 'hexdigits' : hexdigits, } def inline_frame(self, data): From antocuni at codespeak.net Fri Jun 30 22:03:33 2006 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 30 Jun 2006 22:03:33 +0200 (CEST) Subject: [pypy-svn] r29540 - pypy/dist/pypy/translator/cli Message-ID: <20060630200333.A907210076@code0.codespeak.net> Author: antocuni Date: Fri Jun 30 22:03:27 2006 New Revision: 29540 Modified: pypy/dist/pypy/translator/cli/database.py pypy/dist/pypy/translator/cli/function.py pypy/dist/pypy/translator/cli/record.py Log: Don't store the _name attribute in the record, because it breaks the cached hash. For now we recalc the name every time, in future we might consider to cache it somewhere. The work-around for the broken hash issue is no longer needed. Modified: pypy/dist/pypy/translator/cli/database.py ============================================================================== --- pypy/dist/pypy/translator/cli/database.py (original) +++ pypy/dist/pypy/translator/cli/database.py Fri Jun 30 22:03:27 2006 @@ -30,7 +30,6 @@ self.delegates = {} # StaticMethod --> type_name self.const_names = set() self.name_count = 0 - self._recorded_records = [] # XXX: temporary hack def next_count(self): self.name_count += 1 @@ -44,9 +43,7 @@ def pending_record(self, record): r = Record(self, record) - if r not in self._recorded_records: # XXX: temporary hack - self._recorded_records.append(r) - self.pending_node(r) + self.pending_node(r) return r.get_name() def pending_node(self, node): @@ -67,6 +64,10 @@ def class_name(self, classdef): return self.classes.get(classdef, None) + def get_record_name(self, RECORD): + r = Record(self, RECORD) + return r.get_name() # TODO: cache the result? + def record_const(self, value): if value in self.consts: const = self.consts[value] Modified: pypy/dist/pypy/translator/cli/function.py ============================================================================== --- pypy/dist/pypy/translator/cli/function.py (original) +++ pypy/dist/pypy/translator/cli/function.py Fri Jun 30 22:03:27 2006 @@ -285,8 +285,11 @@ def function_signature(self, graph): return self.cts.graph_to_signature(graph, False) - def class_name(self, ooinstance): - return ooinstance._name + def class_name(self, TYPE): + if isinstance(TYPE, ootype.Instance): + return TYPE._name + elif isinstance(TYPE, ootype.Record): + return self.db.get_record_name(TYPE) def emit(self, instr, *args): self.ilasm.opcode(instr, *args) Modified: pypy/dist/pypy/translator/cli/record.py ============================================================================== --- pypy/dist/pypy/translator/cli/record.py (original) +++ pypy/dist/pypy/translator/cli/record.py Fri Jun 30 22:03:27 2006 @@ -20,7 +20,6 @@ self.name = '__'.join(name) assert ':' not in self.name - record._name = self.name def __hash__(self): return hash(self.record)