You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(107) |
Dec
(67) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(76) |
Feb
(125) |
Mar
(72) |
Apr
(13) |
May
(18) |
Jun
(12) |
Jul
(129) |
Aug
(47) |
Sep
(1) |
Oct
(36) |
Nov
(128) |
Dec
(124) |
2002 |
Jan
(59) |
Feb
|
Mar
(14) |
Apr
(14) |
May
(72) |
Jun
(9) |
Jul
(3) |
Aug
(5) |
Sep
(18) |
Oct
(65) |
Nov
(28) |
Dec
(12) |
2003 |
Jan
(10) |
Feb
(2) |
Mar
(4) |
Apr
(33) |
May
(21) |
Jun
(9) |
Jul
(29) |
Aug
(34) |
Sep
(4) |
Oct
(8) |
Nov
(15) |
Dec
(4) |
2004 |
Jan
(26) |
Feb
(12) |
Mar
(11) |
Apr
(9) |
May
(7) |
Jun
|
Jul
(5) |
Aug
|
Sep
(3) |
Oct
(7) |
Nov
(1) |
Dec
(10) |
2005 |
Jan
(2) |
Feb
(72) |
Mar
(16) |
Apr
(39) |
May
(48) |
Jun
(97) |
Jul
(57) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(100) |
Dec
(24) |
2006 |
Jan
(15) |
Feb
(34) |
Mar
(33) |
Apr
(31) |
May
(79) |
Jun
(64) |
Jul
(41) |
Aug
(64) |
Sep
(31) |
Oct
(46) |
Nov
(55) |
Dec
(37) |
2007 |
Jan
(32) |
Feb
(61) |
Mar
(11) |
Apr
(58) |
May
(46) |
Jun
(30) |
Jul
(94) |
Aug
(93) |
Sep
(86) |
Oct
(69) |
Nov
(125) |
Dec
(177) |
2008 |
Jan
(169) |
Feb
(97) |
Mar
(74) |
Apr
(113) |
May
(120) |
Jun
(334) |
Jul
(215) |
Aug
(237) |
Sep
(72) |
Oct
(189) |
Nov
(126) |
Dec
(160) |
2009 |
Jan
(180) |
Feb
(45) |
Mar
(98) |
Apr
(140) |
May
(151) |
Jun
(71) |
Jul
(107) |
Aug
(119) |
Sep
(73) |
Oct
(121) |
Nov
(14) |
Dec
(6) |
2010 |
Jan
(13) |
Feb
(9) |
Mar
(10) |
Apr
(64) |
May
(3) |
Jun
(16) |
Jul
(7) |
Aug
(23) |
Sep
(17) |
Oct
(37) |
Nov
(5) |
Dec
(8) |
2011 |
Jan
(10) |
Feb
(11) |
Mar
(77) |
Apr
(11) |
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <cg...@us...> - 2009-01-24 20:11:04
|
Revision: 5971 http://jython.svn.sourceforge.net/jython/?rev=5971&view=rev Author: cgroves Date: 2009-01-24 20:10:59 +0000 (Sat, 24 Jan 2009) Log Message: ----------- Run the java import * test from a sub-interpreter to allow regrtest to be run with python.cachedir.skip=true Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py Added Paths: ----------- trunk/jython/Lib/test/import_star_from_java.py Added: trunk/jython/Lib/test/import_star_from_java.py =================================================================== --- trunk/jython/Lib/test/import_star_from_java.py (rev 0) +++ trunk/jython/Lib/test/import_star_from_java.py 2009-01-24 20:10:59 UTC (rev 5971) @@ -0,0 +1,4 @@ +from java.util.regex import * + +p = Pattern.compile("foo") +assert p.flags() == 0 Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2009-01-24 18:02:37 UTC (rev 5970) +++ trunk/jython/Lib/test/test_java_integration.py 2009-01-24 20:10:59 UTC (rev 5971) @@ -21,10 +21,6 @@ from org.python.core.util import FileUtil from org.python.tests import BeanImplementation, Child, Listenable, CustomizableMapHolder -#Just for test_import_star -#java.util.regex was chosen for its small number of classes to reduce the pollution. -from java.util.regex import * - class InstantiationTest(unittest.TestCase): def test_cant_instantiate_abstract(self): self.assertRaises(TypeError, Component) @@ -417,9 +413,8 @@ self.assertEquals(None, m.nonexistent, "Nonexistent fields should be passed on to the Map") def test_import_star(self): - #Depends on "from java.util.regex import *" at the top. - x = Pattern.compile("foo") - self.assertEquals(x.flags(), 0) + self.assertEquals(subprocess.call([sys.executable, + test_support.findfile("import_star_from_java.py")]), 0) def test_main(): test_support.run_unittest(InstantiationTest, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-24 18:02:40
|
Revision: 5970 http://jython.svn.sourceforge.net/jython/?rev=5970&view=rev Author: zyasoft Date: 2009-01-24 18:02:37 +0000 (Sat, 24 Jan 2009) Log Message: ----------- Supports throwing exceptions into generators. Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyBytecode.java Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-24 16:47:59 UTC (rev 5969) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-24 18:02:37 UTC (rev 5970) @@ -193,10 +193,15 @@ if (f.f_exits == null || f.f_blockstate[0] == 0) { return "[]"; } - StringBuilder buf = new StringBuilder(); - for (int i = 0; i < f.f_blockstate[0]; i++) { + StringBuilder buf = new StringBuilder("["); + int len = f.f_blockstate[0]; + for (int i = 0; i < len; i++) { buf.append(f.f_exits[i].toString()); + if (i < len - 1) { + buf.append(", "); + } } + buf.append("]"); return buf.toString(); } @@ -239,53 +244,53 @@ PyObject retval = null; ThreadState ts = Py.getThreadState(); // XXX - change interpret to pass through from PyFrame since our ts will never change - // this may work: detach setting/getting anything in the frame to improve performance, instead do this - // in a shadow version of the frame that we copy back to + // XXX - optimization opportunities + // 1. consider detaching the setting/getting of frame fields to improve performance, instead do this + // in a shadow version of the frame that we copy back to on entry/exit and downcalls System.err.println("Entry with " + f.f_lasti + " into " + co_code.length); if (f.f_lasti >= co_code.length) { -// f.f_lasti = -1; -// return Py.None; - throw Py.StopIteration(""); + throw Py.SystemError(""); } next_instr = f.f_lasti; - // check if we have been thrown an exception in the generatorinput, this - // is roughly the same as -// if (throwflag) { /* support for generator.throw() */ -// why = WHY_EXCEPTION; -// goto on_error; -// } - - // the restore stack aspets should occur ONLY after a yield + // the restore stack aspects should occur ONLY after a yield + boolean checkGeneratorInput = false; if (f.f_savedlocals != null) { for (int i = 0; i < f.f_savedlocals.length; i++) { PyObject v = (PyObject) (f.f_savedlocals[i]); stack.push(v); } - Object generatorInput = f.getGeneratorInput(); - if (generatorInput instanceof PyException) { - throw (PyException)generatorInput; - } - stack.push((PyObject)generatorInput); // put the generator input in here + checkGeneratorInput = true; f.f_savedlocals = null; } while (count < maxCount) { // XXX - replace with while(true) - opcode = co_code[next_instr]; - if (opcode > Opcode.HAVE_ARGUMENT) { - next_instr += 2; - oparg = (co_code[next_instr] << 8) + co_code[next_instr - 1]; - } - print_debug(count, next_instr, opcode, oparg, stack, f); + try { - count += 1; - next_instr += 1; - f.f_lasti = next_instr; // should have no worries about needing co_lnotab, just keep this current + if (checkGeneratorInput) { + checkGeneratorInput = false; + Object generatorInput = f.getGeneratorInput(); + if (generatorInput instanceof PyException) { + throw (PyException) generatorInput; + } + stack.push((PyObject) generatorInput); + } - try { + opcode = co_code[next_instr]; + if (opcode > Opcode.HAVE_ARGUMENT) { + next_instr += 2; + oparg = (co_code[next_instr] << 8) + co_code[next_instr - 1]; + } + print_debug(count, next_instr, opcode, oparg, stack, f); + + count += 1; + next_instr += 1; + f.f_lasti = next_instr; // should have no worries about needing co_lnotab, just keep this current + + switch (opcode) { case Opcode.NOP: break; @@ -307,15 +312,15 @@ break; case Opcode.ROT_TWO: - stack.rotN(2); + stack.rot(2); break; case Opcode.ROT_THREE: - stack.rotN(3); + stack.rot(3); break; case Opcode.ROT_FOUR: - stack.rotN(4); + stack.rot(4); break; case Opcode.DUP_TOP: @@ -324,7 +329,7 @@ case Opcode.DUP_TOPX: { if (oparg == 2 || oparg == 3) { - stack.dupN(oparg); + stack.dup(oparg); } else { throw Py.RuntimeError("invalid argument to DUP_TOPX" + " (bytecode corruption?)"); @@ -1094,9 +1099,8 @@ if (b.b_type == Opcode.SETUP_EXCEPT) { exc.normalize(); } - stack.push(Py.None); // XXX - x3 to conform with CPython's calling convention, which - stack.push(Py.None); // stores the type, val, tb separately on the stack - stack.push(new PyStackException(exc)); + stack.push(new PyStackException(exc)); // x3 to conform with CPython's calling convention, which + stack.dup(2); // stores the type, val, tb separately on the stack } else { if (why == Why.RETURN || why == Why.CONTINUE) { stack.push(retval); @@ -1125,7 +1129,6 @@ } else { // store the stack in the frame for reentry from the yield; f.f_savedlocals = stack.popN(stack.size()); - // also need to add support for checking the generatorinput etc } f.f_lasti = next_instr; // need to update on function entry, etc @@ -1134,6 +1137,10 @@ ", stack: " + stack.toString() + ", blocks: " + stringify_blocks(f)); + if (why == why.EXCEPTION) { + throw ts.exception; + } + if ((co_flags & CO_GENERATOR) != 0 && why == Why.RETURN && retval == Py.None) { f.f_lasti = -1; } @@ -1259,7 +1266,7 @@ stack.add(top()); } - void dupN(int n) { + void dup(int n) { PyObject v = top(); for (int i = 0; i < n; i++) { stack.add(v); @@ -1275,7 +1282,7 @@ return ret; } - void rotN(int n) { + void rot(int n) { int end = stack.size(); List<PyObject> lastN = stack.subList(end - n, end); Collections.rotate(lastN, n); @@ -1308,8 +1315,8 @@ @Override public String toString() { - return "[" + getOpname().__getitem__(Py.newInteger(b_type)) + "," + - b_handler + "," + b_level + "]"; + return "<" + getOpname().__getitem__(Py.newInteger(b_type)) + "," + + b_handler + "," + b_level + ">"; } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-24 16:48:04
|
Revision: 5969 http://jython.svn.sourceforge.net/jython/?rev=5969&view=rev Author: zyasoft Date: 2009-01-24 16:47:59 +0000 (Sat, 24 Jan 2009) Log Message: ----------- Added support for basic coroutines (no support for throw) and generator expressions. Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyBytecode.java Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-24 04:36:06 UTC (rev 5968) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-24 16:47:59 UTC (rev 5969) @@ -200,8 +200,9 @@ return buf.toString(); } - private static void print_debug(int count, int next_instr, int opcode, int oparg, PyStack stack, PyFrame f) { - System.err.println(count + "," + f.f_lasti + "> opcode: " + + private void print_debug(int count, int next_instr, int opcode, int oparg, PyStack stack, PyFrame f) { + System.err.println(co_name + ":" + + count + "," + f.f_lasti + "> opcode: " + getOpname().__getitem__(Py.newInteger(opcode)) + (opcode > Opcode.HAVE_ARGUMENT ? ", oparg: " + oparg : "") + ", stack: " + stack.toString() + @@ -257,18 +258,22 @@ // goto on_error; // } + // the restore stack aspets should occur ONLY after a yield if (f.f_savedlocals != null) { for (int i = 0; i < f.f_savedlocals.length; i++) { PyObject v = (PyObject) (f.f_savedlocals[i]); stack.push(v); } - stack.push(Py.None); // put the generator input in here + Object generatorInput = f.getGeneratorInput(); + if (generatorInput instanceof PyException) { + throw (PyException)generatorInput; + } + stack.push((PyObject)generatorInput); // put the generator input in here f.f_savedlocals = null; } while (count < maxCount) { // XXX - replace with while(true) - opcode = co_code[next_instr]; if (opcode > Opcode.HAVE_ARGUMENT) { next_instr += 2; @@ -662,16 +667,6 @@ case Opcode.YIELD_VALUE: retval = stack.pop(); - // need to implement something like this when we reenter after a yield -// code.invokevirtual("org/python/core/PyFrame", "getGeneratorInput", "()" + $obj); -// code.dup(); -// code.instanceof_("org/python/core/PyException"); -// Label done2 = new Label(); -// code.ifeq(done2); -// code.checkcast("java/lang/Throwable"); -// code.athrow(); -// code.label(done2); -// code.checkcast("org/python/core/PyObject"); why = Why.YIELD; break; @@ -910,7 +905,7 @@ break; case Opcode.JUMP_ABSOLUTE: - next_instr = oparg - 1; // XXX - continue to a label is probably much better + next_instr = oparg; // XXX - continue to a label is probably much better break; case Opcode.GET_ITER: { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-24 04:36:09
|
Revision: 5968 http://jython.svn.sourceforge.net/jython/?rev=5968&view=rev Author: zyasoft Date: 2009-01-24 04:36:06 +0000 (Sat, 24 Jan 2009) Log Message: ----------- Added support for keyword args, *arg, and **kwarg calling conventions. Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyBytecode.java Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-24 02:49:52 UTC (rev 5967) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-24 04:36:06 UTC (rev 5968) @@ -1,7 +1,6 @@ package org.python.core; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -31,6 +30,8 @@ public final String[] co_names; public final int co_stacksize; // ignored, probably shouldn't be public final PyObject[] co_lnotab; // ignored + private final static int CALL_FLAG_VAR = 1; + private final static int CALL_FLAG_KW = 2; // follows new.code's interface public PyBytecode(int argcount, int nlocals, int stacksize, int flags, @@ -997,62 +998,28 @@ case Opcode.CALL_FUNCTION: { int na = oparg & 0xff; int nk = (oparg >> 8) & 0xff; - int n = na + 2 * nk; - PyObject args[] = stack.popN(na); - PyObject callable = stack.pop(); - System.err.println("__call__:" + callable + "," + Arrays.toString(args)); - stack.push(callable.__call__(args)); + if (nk == 0) { + call_function(na, stack); + } else { + call_function(na, nk, stack); + } break; } -// -// case CALL_FUNCTION_VAR: -// case CALL_FUNCTION_KW: -// case CALL_FUNCTION_VAR_KW: -// { -// int na = oparg & 0xff; -// int nk = (oparg>>8) & 0xff; -// int flags = (opcode - CALL_FUNCTION) & 3; -// int n = na + 2 * nk; -// PyObject **pfunc, *func, **sp; -// PCALL(PCALL_ALL); -// if (flags & CALL_FLAG_VAR) -// n++; -// if (flags & CALL_FLAG_KW) -// n++; -// pfunc = stack_pointer - n - 1; -// func = *pfunc; -// -// if (PyMethod_Check(func) -// && PyMethod_GET_SELF(func) != NULL) { -// PyObject *self = PyMethod_GET_SELF(func); -// Py_INCREF(self); -// func = PyMethod_GET_FUNCTION(func); -// Py_INCREF(func); -// Py_DECREF(*pfunc); -// *pfunc = self; -// na++; -// n++; -// } else -// Py_INCREF(func); -// sp = stack_pointer; -// READ_TIMESTAMP(intr0); -// x = ext_do_call(func, &sp, flags, na, nk); -// READ_TIMESTAMP(intr1); -// stack_pointer = sp; -// Py_DECREF(func); -// -// while (stack_pointer > pfunc) { -// w = POP(); -// Py_DECREF(w); -// } -// PUSH(x); -// if (x != NULL) -// continue; -// break; -// } -// + case Opcode.CALL_FUNCTION_VAR: + case Opcode.CALL_FUNCTION_KW: + case Opcode.CALL_FUNCTION_VAR_KW: { + int na = oparg & 0xff; + int nk = (oparg >> 8) & 0xff; + int flags = (opcode - Opcode.CALL_FUNCTION) & 3; + call_function(na, nk, + (flags & CALL_FLAG_VAR) != 0, + (flags & CALL_FLAG_KW) != 0, + stack); + break; + } + case Opcode.MAKE_FUNCTION: { PyCode code = (PyCode) stack.pop(); PyObject[] defaults = stack.popN(oparg); @@ -1179,6 +1146,90 @@ return retval; } + private static void call_function(int na, PyStack stack) { + switch (na) { + case 0: { + PyObject callable = stack.pop(); + stack.push(callable.__call__()); + break; + } + case 1: { + PyObject arg = stack.pop(); + PyObject callable = stack.pop(); + stack.push(callable.__call__(arg)); + break; + } + case 2: { + PyObject arg1 = stack.pop(); + PyObject arg0 = stack.pop(); + PyObject callable = stack.pop(); + stack.push(callable.__call__(arg0, arg1)); + break; + } + case 3: { + PyObject arg2 = stack.pop(); + PyObject arg1 = stack.pop(); + PyObject arg0 = stack.pop(); + PyObject callable = stack.pop(); + stack.push(callable.__call__(arg0, arg1, arg2)); + break; + } + case 4: { + PyObject arg3 = stack.pop(); + PyObject arg2 = stack.pop(); + PyObject arg1 = stack.pop(); + PyObject arg0 = stack.pop(); + PyObject callable = stack.pop(); + stack.push(callable.__call__(arg0, arg1, arg2, arg3)); + break; + } + default: { + PyObject args[] = stack.popN(na); + PyObject callable = stack.pop(); + stack.push(callable.__call__(args)); + } + } + } + + private static void call_function(int na, int nk, PyStack stack) { + int n = na + nk * 2; + PyObject params[] = stack.popN(n); + PyObject callable = stack.pop(); + + PyObject args[] = new PyObject[na + nk]; + String keywords[] = new String[nk]; + int i; + for (i = 0; i < na; i++) { + args[i] = params[i]; + } + for (int j = 0; i < n; i += 2, j++) { + keywords[j] = params[i].toString(); + args[na + j] = params[i + 1]; + } + stack.push(callable.__call__(args, keywords)); + } + + private static void call_function(int na, int nk, boolean var, boolean kw, PyStack stack) { + int n = na + nk * 2; + PyObject kwargs = kw ? stack.pop() : null; + PyObject starargs = var ? stack.pop() : null; + PyObject params[] = stack.popN(n); + PyObject callable = stack.pop(); + + PyObject args[] = new PyObject[na + nk]; + String keywords[] = new String[nk]; + int i; + for (i = 0; i < na; i++) { + args[i] = params[i]; + } + for (int j = 0; i < n; i += 2, j++) { + keywords[j] = params[i].toString(); + args[na + j] = params[i + 1]; + + } + stack.push(callable._callextra(args, keywords, starargs, kwargs)); + } + // XXX - perhaps add support for max stack size (presumably from co_stacksize) // and capacity hints private class PyStack { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-24 02:49:56
|
Revision: 5967 http://jython.svn.sourceforge.net/jython/?rev=5967&view=rev Author: zyasoft Date: 2009-01-24 02:49:52 +0000 (Sat, 24 Jan 2009) Log Message: ----------- Now supports generators, via the standard PyGenerator protocol. Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyBytecode.java Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-24 00:17:40 UTC (rev 5966) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-24 02:49:52 UTC (rev 5967) @@ -240,7 +240,15 @@ // this may work: detach setting/getting anything in the frame to improve performance, instead do this // in a shadow version of the frame that we copy back to + System.err.println("Entry with " + f.f_lasti + " into " + co_code.length); + if (f.f_lasti >= co_code.length) { +// f.f_lasti = -1; +// return Py.None; + throw Py.StopIteration(""); + } + next_instr = f.f_lasti; + // check if we have been thrown an exception in the generatorinput, this // is roughly the same as // if (throwflag) { /* support for generator.throw() */ @@ -250,7 +258,7 @@ if (f.f_savedlocals != null) { for (int i = 0; i < f.f_savedlocals.length; i++) { - PyObject v = (PyObject)(f.f_savedlocals[i]); + PyObject v = (PyObject) (f.f_savedlocals[i]); stack.push(v); } stack.push(Py.None); // put the generator input in here @@ -267,7 +275,7 @@ } print_debug(count, next_instr, opcode, oparg, stack, f); - count += 1; + count += 1; next_instr += 1; f.f_lasti = next_instr; // should have no worries about needing co_lnotab, just keep this current @@ -544,73 +552,40 @@ break; } -// -// case SLICE+0: -// case SLICE+1: -// case SLICE+2: -// case SLICE+3: -// if ((opcode-SLICE) & 2) -// w = POP(); -// else -// w = NULL; -// if ((opcode-SLICE) & 1) -// v = POP(); -// else -// v = NULL; -// u = TOP(); -// x = apply_slice(u, v, w); -// Py_DECREF(u); -// Py_XDECREF(v); -// Py_XDECREF(w); -// SET_TOP(x); -// if (x != NULL) continue; -// break; -// -// case Opcode.STORE_SLICE+0: -// case Opcode.STORE_SLICE+1: -// case Opcode.STORE_SLICE+2: -// case Opcode.STORE_SLICE+3: -// if (((opcode - Opcode.STORE_SLICE) & 2) !=0) { -// -// } -// w = POP(); -// else -// w = NULL; -// if ((opcode-STORE_SLICE) & 1) -// v = POP(); -// else -// v = NULL; -// u = POP(); -// t = POP(); -// err = assign_slice(u, v, w, t); /* u[v:w] = t */ -// Py_DECREF(t); -// Py_DECREF(u); -// Py_XDECREF(v); -// Py_XDECREF(w); -// if (err == 0) continue; -// break; -// -// case DELETE_SLICE+0: -// case DELETE_SLICE+1: -// case DELETE_SLICE+2: -// case DELETE_SLICE+3: -// if ((opcode-DELETE_SLICE) & 2) -// w = POP(); -// else -// w = NULL; -// if ((opcode-DELETE_SLICE) & 1) -// v = POP(); -// else -// v = NULL; -// u = POP(); -// err = assign_slice(u, v, w, (PyObject *)NULL); -// /* del u[v:w] */ -// Py_DECREF(u); -// Py_XDECREF(v); -// Py_XDECREF(w); -// if (err == 0) continue; -// break; -// + case Opcode.SLICE + 0: + case Opcode.SLICE + 1: + case Opcode.SLICE + 2: + case Opcode.SLICE + 3: { + PyObject stop = (((opcode - Opcode.SLICE) & 2) != 0) ? stack.pop() : null; + PyObject start = (((opcode - Opcode.SLICE) & 1) != 0) ? stack.pop() : null; + PyObject obj = stack.pop(); + stack.push(obj.__getslice__(start, stop)); + break; + } + + case Opcode.STORE_SLICE + 0: + case Opcode.STORE_SLICE + 1: + case Opcode.STORE_SLICE + 2: + case Opcode.STORE_SLICE + 3: { + PyObject stop = (((opcode - Opcode.SLICE) & 2) != 0) ? stack.pop() : null; + PyObject start = (((opcode - Opcode.SLICE) & 1) != 0) ? stack.pop() : null; + PyObject obj = stack.pop(); + PyObject value = stack.pop(); + obj.__setslice__(start, stop, value); + break; + } + + case Opcode.DELETE_SLICE + 0: + case Opcode.DELETE_SLICE + 1: + case Opcode.DELETE_SLICE + 2: + case Opcode.DELETE_SLICE + 3: { + PyObject stop = (((opcode - Opcode.SLICE) & 2) != 0) ? stack.pop() : null; + PyObject start = (((opcode - Opcode.SLICE) & 1) != 0) ? stack.pop() : null; + PyObject obj = stack.pop(); + obj.__delslice__(start, stop); + break; + } + case Opcode.STORE_SUBSCR: { PyObject key = stack.pop(); PyObject obj = stack.pop(); @@ -979,61 +954,46 @@ case Opcode.SETUP_FINALLY: pushBlock(f, new PyTryBlock(opcode, next_instr + oparg, stack.size())); break; -// -// case WITH_CLEANUP: -// { -// /* TOP is the context.__exit__ bound method. -// Below that are 1-3 values indicating how/why -// we entered the finally clause: -// - SECOND = None -// - (SECOND, THIRD) = (WHY_{RETURN,CONTINUE}), retval -// - SECOND = WHY_*; no retval below it -// - (SECOND, THIRD, FOURTH) = exc_info() -// In the last case, we must call -// TOP(SECOND, THIRD, FOURTH) -// otherwise we must call -// TOP(None, None, None) -// -// In addition, if the stack represents an exception, -// *and* the function call returns a 'true' value, we -// "zap" this information, to prevent END_FINALLY from -// re-raising the exception. (But non-local gotos -// should still be resumed.) -// */ -// -// x = TOP(); -// u = SECOND(); -// if (PyInt_Check(u) || u == Py_None) { -// u = v = w = Py_None; -// } -// else { -// v = THIRD(); -// w = FOURTH(); -// } -// /* XXX Not the fastest way to call it... */ -// x = PyObject_CallFunctionObjArgs(x, u, v, w, NULL); -// if (x == NULL) -// break; /* Go to error exit */ -// if (u != Py_None && PyObject_IsTrue(x)) { -// /* There was an exception and a true return */ -// Py_DECREF(x); -// x = TOP(); /* Again */ -// STACKADJ(-3); -// Py_INCREF(Py_None); -// SET_TOP(Py_None); -// Py_DECREF(x); -// Py_DECREF(u); -// Py_DECREF(v); -// Py_DECREF(w); -// } else { -// /* Let END_FINALLY do its thing */ -// Py_DECREF(x); -// x = POP(); -// Py_DECREF(x); -// } -// break; -// } -// + + case Opcode.WITH_CLEANUP: { + /* TOP is the context.__exit__ bound method. + Below that are 1-3 values indicating how/why + we entered the finally clause: + - SECOND = None + - (SECOND, THIRD) = (WHY_{RETURN,CONTINUE}), retval + - SECOND = WHY_*; no retval below it + - (SECOND, THIRD, FOURTH) = exc_info() + In the last case, we must call + TOP(SECOND, THIRD, FOURTH) + otherwise we must call + TOP(None, None, None) + + In addition, if the stack represents an exception, + *and* the function call returns a 'true' value, we + "zap" this information, to prevent END_FINALLY from + re-raising the exception. (But non-local gotos + should still be resumed.) + */ + PyObject exit = stack.top(); + PyObject u = stack.top(2); + PyObject v; + PyObject w; + if (u == Py.None || u instanceof PyStackWhy) { + u = v = w = Py.None; + } else { + v = stack.top(3); + w = stack.top(4); + } + PyObject x = exit.__call__(u, v, w); + if (u != Py.None && x.__nonzero__()) { + stack.popN(4); + stack.push(Py.None); + } else { + stack.pop(); + } + break; + } + case Opcode.CALL_FUNCTION: { int na = oparg & 0xff; int nk = (oparg >> 8) & 0xff; @@ -1110,21 +1070,14 @@ break; } -// case BUILD_SLICE: -// if (oparg == 3) -// w = POP(); -// else -// w = NULL; -// v = POP(); -// u = TOP(); -// x = PySlice_New(u, v, w); -// Py_DECREF(u); -// Py_DECREF(v); -// Py_XDECREF(w); -// SET_TOP(x); -// if (x != NULL) continue; -// break; -// + case Opcode.BUILD_SLICE: { + PyObject step = oparg == 3 ? stack.pop() : null; + PyObject stop = stack.pop(); + PyObject start = stack.pop(); + stack.push(new PySlice(start, stop, step)); + break; + } + case Opcode.EXTENDED_ARG: opcode = co_code[next_instr++]; next_instr += 2; @@ -1197,7 +1150,7 @@ if (why != Why.NOT) { break; } - + } // end-while of the instruction loop if (why != Why.YIELD) { @@ -1210,13 +1163,19 @@ } else { // store the stack in the frame for reentry from the yield; f.f_savedlocals = stack.popN(stack.size()); - // also need to add support for checking the generatorinput etc + // also need to add support for checking the generatorinput etc } f.f_lasti = next_instr; // need to update on function entry, etc + System.err.println(count + "," + f.f_lasti + "> Returning from " + why + ": " + retval + ", stack: " + stack.toString() + ", blocks: " + stringify_blocks(f)); + + if ((co_flags & CO_GENERATOR) != 0 && why == Why.RETURN && retval == Py.None) { + f.f_lasti = -1; + } + return retval; } @@ -1234,6 +1193,10 @@ return stack.get(stack.size() - 1); } + PyObject top(int n) { + return stack.get(stack.size() - n); + } + PyObject pop() { return stack.remove(stack.size() - 1); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-01-24 00:17:44
|
Revision: 5966 http://jython.svn.sourceforge.net/jython/?rev=5966&view=rev Author: pjenvey Date: 2009-01-24 00:17:40 +0000 (Sat, 24 Jan 2009) Log Message: ----------- merge from: http://svn.python.org/projects/python/branches/release25-maint/Lib/platform.py -c 66214 Modified Paths: -------------- trunk/jython/Lib/platform.py Modified: trunk/jython/Lib/platform.py =================================================================== --- trunk/jython/Lib/platform.py 2009-01-23 23:40:46 UTC (rev 5965) +++ trunk/jython/Lib/platform.py 2009-01-24 00:17:40 UTC (rev 5966) @@ -794,7 +794,7 @@ filepath = _abspath(filepath) while os.path.islink(filepath): filepath = os.path.normpath( - os.path.join(filepath,os.readlink(filepath))) + os.path.join(os.path.dirname(filepath),os.readlink(filepath))) return filepath def _syscmd_uname(option,default=''): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-01-23 23:40:54
|
Revision: 5965 http://jython.svn.sourceforge.net/jython/?rev=5965&view=rev Author: pjenvey Date: 2009-01-23 23:40:46 +0000 (Fri, 23 Jan 2009) Log Message: ----------- more java.lang.Strings to regular str instead of unicode Modified Paths: -------------- trunk/jython/Lib/os.py trunk/jython/Lib/platform.py Modified: trunk/jython/Lib/os.py =================================================================== --- trunk/jython/Lib/os.py 2009-01-23 15:30:09 UTC (rev 5964) +++ trunk/jython/Lib/os.py 2009-01-23 23:40:46 UTC (rev 5965) @@ -83,9 +83,9 @@ """ os_name = sys.registry.getProperty('python.os') if os_name: - return str(os_name) + return asPyString(os_name) - os_name = str(java.lang.System.getProperty('os.name')) + os_name = asPyString(java.lang.System.getProperty('os.name')) os_type = None for type, (patterns, shell_commands) in _os_map.iteritems(): for pattern in patterns: Modified: trunk/jython/Lib/platform.py =================================================================== --- trunk/jython/Lib/platform.py 2009-01-23 15:30:09 UTC (rev 5964) +++ trunk/jython/Lib/platform.py 2009-01-23 23:40:46 UTC (rev 5965) @@ -624,8 +624,9 @@ def _java_getprop(name,default): from java.lang import System + from org.python.core.Py import newString try: - return System.getProperty(name) + return newString(System.getProperty(name)) except: return default This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-23 15:30:34
|
Revision: 5964 http://jython.svn.sourceforge.net/jython/?rev=5964&view=rev Author: zyasoft Date: 2009-01-23 15:30:09 +0000 (Fri, 23 Jan 2009) Log Message: ----------- Basic generators are almost supported. Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyBytecode.java Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-23 15:22:27 UTC (rev 5963) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-23 15:30:09 UTC (rev 5964) @@ -8,16 +8,22 @@ public class PyBytecode extends PyBaseCode { // for debugging - static int count = 0; // total number of opcodes run - final static int maxCount = 900; // less than my buffer on iterm - static PyObject opname; + private int count = 0; // total number of opcodes run + private int maxCount = 900; // less than my buffer on iterm + private static PyObject opname; - static synchronized PyObject getOpname() { + private static synchronized PyObject getOpname() { if (opname == null) { opname = __builtin__.__import__("dis").__getattr__("opname"); } return opname; } + + public PyObject _debug(int maxCount) { + this.maxCount = maxCount; + return Py.None; + } + // end debugging public final static int CO_MAXBLOCKS = 20; // same as in CPython public final char[] co_code; // to avoid sign issues @@ -193,7 +199,7 @@ return buf.toString(); } - private static void print_debug(int next_instr, int opcode, int oparg, PyStack stack, PyFrame f) { + private static void print_debug(int count, int next_instr, int opcode, int oparg, PyStack stack, PyFrame f) { System.err.println(count + "," + f.f_lasti + "> opcode: " + getOpname().__getitem__(Py.newInteger(opcode)) + (opcode > Opcode.HAVE_ARGUMENT ? ", oparg: " + oparg : "") + @@ -229,28 +235,41 @@ int oparg = 0; /* Current opcode argument, if any */ Why why = Why.NOT; PyObject retval = null; - ThreadState ts = Py.getThreadState(); // XXX - change interpret to pass through from PyFrame + ThreadState ts = Py.getThreadState(); // XXX - change interpret to pass through from PyFrame since our ts will never change - // need to support something like this, but perhaps we can get this from the frame itself? + // this may work: detach setting/getting anything in the frame to improve performance, instead do this + // in a shadow version of the frame that we copy back to + + next_instr = f.f_lasti; + // check if we have been thrown an exception in the generatorinput, this + // is roughly the same as // if (throwflag) { /* support for generator.throw() */ // why = WHY_EXCEPTION; // goto on_error; // } + if (f.f_savedlocals != null) { + for (int i = 0; i < f.f_savedlocals.length; i++) { + PyObject v = (PyObject)(f.f_savedlocals[i]); + stack.push(v); + } + stack.push(Py.None); // put the generator input in here + f.f_savedlocals = null; + } + while (count < maxCount) { // XXX - replace with while(true) - next_instr += 1; - // this may work: detach setting anything in the frame to improve performance, instead do this - // in a shadow version of the frame that we copy back to - f.f_lasti = next_instr; // should have no worries about needing co_lnotab, just keep this current + opcode = co_code[next_instr]; if (opcode > Opcode.HAVE_ARGUMENT) { next_instr += 2; oparg = (co_code[next_instr] << 8) + co_code[next_instr - 1]; } - print_debug(next_instr, opcode, oparg, stack, f); + print_debug(count, next_instr, opcode, oparg, stack, f); - count += 1; + count += 1; + next_instr += 1; + f.f_lasti = next_instr; // should have no worries about needing co_lnotab, just keep this current try { switch (opcode) { @@ -1128,7 +1147,11 @@ ts.exception = pye; } - // do some trace handling here + if (why == Why.YIELD) { + break; + } + + // do some trace handling here, but for now just convert to EXCEPTION if (why == Why.RERAISE) { why = Why.EXCEPTION; } @@ -1156,7 +1179,7 @@ if (b.b_type == Opcode.SETUP_EXCEPT) { exc.normalize(); } - stack.push(Py.None); // XXX - x3 to conform with CPython which + stack.push(Py.None); // XXX - x3 to conform with CPython's calling convention, which stack.push(Py.None); // stores the type, val, tb separately on the stack stack.push(new PyStackException(exc)); } else { @@ -1174,15 +1197,26 @@ if (why != Why.NOT) { break; } + + } // end-while of the instruction loop + + if (why != Why.YIELD) { + while (stack.size() > 0) { + stack.pop(); + } + if (why != Why.RETURN) { + retval = Py.None; + } + } else { + // store the stack in the frame for reentry from the yield; + f.f_savedlocals = stack.popN(stack.size()); + // also need to add support for checking the generatorinput etc } - assert (why != Why.YIELD); - while (stack.size() > 0) { - stack.pop(); - } - if (why != Why.RETURN) { - retval = Py.None; - } + f.f_lasti = next_instr; // need to update on function entry, etc + System.err.println(count + "," + f.f_lasti + "> Returning from " + why + ": " + retval + + ", stack: " + stack.toString() + + ", blocks: " + stringify_blocks(f)); return retval; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-23 15:22:30
|
Revision: 5963 http://jython.svn.sourceforge.net/jython/?rev=5963&view=rev Author: fwierzbicki Date: 2009-01-23 15:22:27 +0000 (Fri, 23 Jan 2009) Log Message: ----------- Some cleanup. Modified Paths: -------------- trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/SysPackageManager.java Modified: trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/SysPackageManager.java =================================================================== --- trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/SysPackageManager.java 2009-01-23 04:40:26 UTC (rev 5962) +++ trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/SysPackageManager.java 2009-01-23 15:22:27 UTC (rev 5963) @@ -3,23 +3,6 @@ package org.python.core.packagecache; -import org.python.core.imp; -import org.python.core.Py; -import org.python.core.PyJavaPackage; -import org.python.core.PyList; -import org.python.core.PyObject; -import org.python.core.PyString; -import org.python.core.PyStringMap; -import org.python.core.PySystemState; -import org.python.core.util.RelativeFile; - -import java.util.Properties; -import java.util.StringTokenizer; -import java.io.*; - -import org.python.core.Options; -import org.python.util.Generic; - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; @@ -28,6 +11,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Modifier; @@ -37,21 +21,39 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Properties; +import java.util.StringTokenizer; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import org.python.core.Options; +import org.python.core.Py; +import org.python.core.PyJavaPackage; +import org.python.core.PyList; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PyStringMap; +import org.python.core.PySystemState; +import org.python.core.imp; +import org.python.core.util.RelativeFile; +import org.python.util.Generic; /** * System package manager. Used by org.python.core.PySystemState. */ public class SysPackageManager implements PackageManager { - /* from PathPackageManager constructor */ - public PyList searchPath; - /* from old PackageManager */ - public PyJavaPackage topLevelPackage; + private PyList searchPath; + private PyJavaPackage topLevelPackage; + private boolean indexModified; + + private Map<String,JarXEntry> jarfiles; + + // for default cache (local fs based) impl + private File cachedir; + protected void message(String msg) { Py.writeMessage("*sys-package-mgr*", msg); } @@ -179,7 +181,7 @@ PyList basic = basicDoDir(jpkg, instantiate, exclpkgs); PyList ret = new PyList(); - doDir(this.searchPath, ret, jpkg, instantiate, exclpkgs); + doDir(this.getSearchPath(), ret, jpkg, instantiate, exclpkgs); PySystemState system = Py.getSystemState(); @@ -199,7 +201,7 @@ * @return true if pkg exists */ public boolean packageExists(String pkg, String name) { - if (packageExists(this.searchPath, pkg, name)) { + if (packageExists(this.getSearchPath(), pkg, name)) { return true; } @@ -245,6 +247,34 @@ return false; } + /** + * @return the searchPath + */ + public PyList getSearchPath() { + return searchPath; + } + + /** + * @param searchPath the searchPath to set + */ + public void setSearchPath(PyList searchPath) { + this.searchPath = searchPath; + } + + /** + * @return the topLevelPackage + */ + public PyJavaPackage getTopLevelPackage() { + return topLevelPackage; + } + + /** + * @param topLevelPackage the topLevelPackage to set + */ + public void setTopLevelPackage(PyJavaPackage topLevelPackage) { + this.topLevelPackage = topLevelPackage; + } + class PackageExistsFileFilter implements FilenameFilter { private boolean java; @@ -366,9 +396,9 @@ public void addDirectory(File dir) { try { if (dir.getPath().length() == 0) { - this.searchPath.append(Py.EmptyString); + this.getSearchPath().append(Py.EmptyString); } else { - this.searchPath.append(new PyString(dir.getCanonicalPath())); + this.getSearchPath().append(new PyString(dir.getCanonicalPath())); } } catch (IOException e) { warning("skipping bad directory, '" + dir + "'"); @@ -435,10 +465,6 @@ return (acc & Modifier.PUBLIC) != Modifier.PUBLIC; } - private boolean indexModified; - - private Map<String,JarXEntry> jarfiles; - private static String listToString(List<String> list) { int n = list.size(); StringBuilder ret = new StringBuilder(); @@ -709,7 +735,7 @@ packs.put(packageName, classes); } } catch (EOFException eof) { - ; + //ignore } istream.close(); @@ -762,7 +788,7 @@ this.jarfiles.put(jarcanon, new JarXEntry(cachefile, mtime)); } } catch (EOFException eof) { - ; + //ignore } istream.close(); } catch (IOException ioe) { @@ -906,10 +932,6 @@ new FileOutputStream(cachefile))); } - // for default cache (local fs based) impl - - private File cachedir; - /** * Initialize off-the-shelf (default) local file-system cache impl. Must be * called before {@link #initCache}. cachedir is the cache repository @@ -986,7 +1008,7 @@ } public PyObject lookupName(String name) { - PyObject top = this.topLevelPackage; + PyObject top = this.getTopLevelPackage(); do { int dot = name.indexOf('.'); String firstName = name; @@ -1017,7 +1039,7 @@ */ public PyJavaPackage makeJavaPackage(String name, String classes, String jarfile) { - PyJavaPackage p = this.topLevelPackage; + PyJavaPackage p = this.getTopLevelPackage(); if (name.length() != 0) p = p.addPackage(name, jarfile); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-23 04:40:32
|
Revision: 5962 http://jython.svn.sourceforge.net/jython/?rev=5962&view=rev Author: zyasoft Date: 2009-01-23 04:40:26 +0000 (Fri, 23 Jan 2009) Log Message: ----------- Added support for try/except and try/finally blocks (and their combination). Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyBytecode.java Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-23 01:03:39 UTC (rev 5961) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-23 04:40:26 UTC (rev 5962) @@ -82,7 +82,6 @@ return new PyList(members); } - private void throwReadonly(String name) { for (int i = 0; i < __members__.length; i++) { if (__members__[i] == name) { @@ -145,24 +144,48 @@ }; - private Why do_raise() { - throw new UnsupportedOperationException("Not yet implemented"); - } + // to enable why's to be stored on a PyStack + private class PyStackWhy extends PyObject { - private Why do_raise(PyObject type) { - throw new UnsupportedOperationException("Not yet implemented"); + Why why; + + PyStackWhy(Why why) { + this.why = why; + } + + @Override + public String toString() { + return why.toString(); + } } - private Why do_raise(PyObject type, PyObject value) { - throw new UnsupportedOperationException("Not yet implemented"); + private class PyStackException extends PyObject { + + PyException exception; + + PyStackException(PyException exception) { + this.exception = exception; + } + + @Override + public String toString() { + return exception.toString(); + } } - private Why do_raise(PyObject type, PyObject value, PyObject traceback) { - throw new UnsupportedOperationException("Not yet implemented"); + private static Why do_raise(ThreadState ts, PyObject type, PyObject value, PyTraceback traceback) { + PyException pye = type == null ? ts.exception : new PyException(type, value, traceback); + if (traceback == null) { + return Why.EXCEPTION; + } else { + return Why.RERAISE; + } } private static String stringify_blocks(PyFrame f) { - if (f.f_exits == null) return "[]"; + if (f.f_exits == null || f.f_blockstate[0] == 0) { + return "[]"; + } StringBuilder buf = new StringBuilder(); for (int i = 0; i < f.f_blockstate[0]; i++) { buf.append(f.f_exits[i].toString()); @@ -175,9 +198,29 @@ getOpname().__getitem__(Py.newInteger(opcode)) + (opcode > Opcode.HAVE_ARGUMENT ? ", oparg: " + oparg : "") + ", stack: " + stack.toString() + - ", blocks: " + stringify_blocks(f)); + ", blocks: " + stringify_blocks(f)); } + private static PyTryBlock popBlock(PyFrame f) { + return (PyTryBlock) (f.f_exits[--f.f_blockstate[0]]); + } + + private static void pushBlock(PyFrame f, PyTryBlock block) { + if (f.f_exits == null) { // allocate in the frame where they can fit! consider supporting directly in the frame + f.f_exits = new PyObject[CO_MAXBLOCKS]; // f_blockstack in CPython - a simple ArrayList might be best + f.f_blockstate = new int[]{0}; // f_iblock in CPython - f_blockstate is likely go away soon + } + f.f_exits[f.f_blockstate[0]++] = block; + } + + private boolean blocksLeft(PyFrame f) { + if (f.f_exits != null) { + return f.f_blockstate[0] > 0; + } else { + return false; + } + } + @Override protected PyObject interpret(PyFrame f) { final PyStack stack = new PyStack(); @@ -186,10 +229,19 @@ int oparg = 0; /* Current opcode argument, if any */ Why why = Why.NOT; PyObject retval = null; + ThreadState ts = Py.getThreadState(); // XXX - change interpret to pass through from PyFrame + // need to support something like this, but perhaps we can get this from the frame itself? +// if (throwflag) { /* support for generator.throw() */ +// why = WHY_EXCEPTION; +// goto on_error; +// } + while (count < maxCount) { // XXX - replace with while(true) next_instr += 1; + // this may work: detach setting anything in the frame to improve performance, instead do this + // in a shadow version of the frame that we copy back to f.f_lasti = next_instr; // should have no worries about needing co_lnotab, just keep this current opcode = co_code[next_instr]; if (opcode > Opcode.HAVE_ARGUMENT) { @@ -237,7 +289,7 @@ stack.dup(); break; - case Opcode.DUP_TOPX: + case Opcode.DUP_TOPX: { if (oparg == 2 || oparg == 3) { stack.dupN(oparg); } else { @@ -245,6 +297,7 @@ " (bytecode corruption?)"); } break; + } case Opcode.UNARY_POSITIVE: stack.push(stack.pop().__pos__()); @@ -578,25 +631,25 @@ switch (oparg) { case 3: { - PyObject tb = stack.pop(); + PyTraceback tb = (PyTraceback) (stack.pop()); PyObject value = stack.pop(); PyObject type = stack.pop(); - why = do_raise(type, value, tb); + why = do_raise(ts, type, value, tb); break; } case 2: { PyObject value = stack.pop(); PyObject type = stack.pop(); - why = do_raise(type, value); + why = do_raise(ts, type, value, null); break; } case 1: { PyObject type = stack.pop(); - why = do_raise(type); + why = do_raise(ts, type, null, null); break; } case 0: - why = do_raise(); + why = do_raise(ts, null, null, null); break; default: throw Py.SystemError("bad RAISE_VARARGS oparg"); @@ -644,39 +697,31 @@ break; } - case Opcode.POP_BLOCK: - { - PyTryBlock b = (PyTryBlock) (f.f_exits[--f.f_blockstate[0]]); - while (stack.size() > b.b_level) { - stack.pop(); + case Opcode.POP_BLOCK: { + PyTryBlock b = popBlock(f); + while (stack.size() > b.b_level) { + stack.pop(); + } + break; + } + + case Opcode.END_FINALLY: { + PyObject v = stack.pop(); + if (v instanceof PyStackWhy) { + why = ((PyStackWhy) v).why; + assert (why != Why.YIELD); + if (why == Why.RETURN || why == Why.CONTINUE) { + retval = stack.pop(); } + } else if ((v instanceof PyStackException) || (v instanceof PyString)) { + ts.exception = ((PyStackException) v).exception; + why = Why.RERAISE; + } else if (v != Py.None) { + throw Py.SystemError("'finally' pops bad exception"); } break; -// -// case END_FINALLY: -// v = POP(); -// if (PyInt_Check(v)) { -// why = (enum why_code) PyInt_AS_LONG(v); -// assert(why != WHY_YIELD); -// if (why == WHY_RETURN || -// why == WHY_CONTINUE) -// retval = POP(); -// } -// else if (PyExceptionClass_Check(v) || PyString_Check(v)) { -// w = POP(); -// u = POP(); -// PyErr_Restore(v, w, u); -// why = WHY_RERAISE; -// break; -// } -// else if (v != Py_None) { -// PyErr_SetString(PyExc_SystemError, -// "'finally' pops bad exception"); -// why = WHY_EXCEPTION; -// } -// Py_DECREF(v); -// break; -// + } + case Opcode.BUILD_CLASS: { PyObject methods = stack.pop(); PyObject bases[] = (new PyTuple(stack.pop())).getArray(); @@ -804,7 +849,12 @@ stack.push(a._isnot(b)); break; case Opcode.PyCmp_EXC_MATCH: - stack.push(Py.newBoolean(Py.matchException(new PyException(a), b))); + if (a instanceof PyStackException) { + PyException pye = ((PyStackException) a).exception; + stack.push(Py.newBoolean(Py.matchException(pye, b))); + } else { + stack.push(Py.newBoolean(Py.matchException(new PyException(a), b))); + } break; } @@ -907,14 +957,9 @@ case Opcode.SETUP_LOOP: case Opcode.SETUP_EXCEPT: - case Opcode.SETUP_FINALLY: { - if (f.f_exits == null) { // allocate in the frame where they can fit! consider supporting directly in the frame - f.f_exits = new PyObject[CO_MAXBLOCKS]; // f_blockstack in CPython - a simple ArrayList might be best - f.f_blockstate = new int[]{0}; // f_iblock in CPython - } - f.f_exits[f.f_blockstate[0]++] = new PyTryBlock(opcode, next_instr + oparg, stack.size()); + case Opcode.SETUP_FINALLY: + pushBlock(f, new PyTryBlock(opcode, next_instr + oparg, stack.size())); break; - } // // case WITH_CLEANUP: // { @@ -1078,22 +1123,67 @@ } // end switch } // end try catch (Throwable t) { - // wrap so we can consume with our try block handling PyException pye = Py.JavaError(t); - // XXX - but since that hasn't been written, for now just rethrow in wrapped form - throw pye; + why = Why.EXCEPTION; + ts.exception = pye; } + // do some trace handling here + if (why == Why.RERAISE) { + why = Why.EXCEPTION; + } - // process why, blocks - switch (why) { - case RETURN: - return retval; - default: + while (why != Why.NOT && blocksLeft(f)) { + PyTryBlock b = popBlock(f); + assert (why != Why.YIELD); + if (b.b_type == Opcode.SETUP_LOOP && why == Why.CONTINUE) { + pushBlock(f, b); + why = Why.NOT; + next_instr = retval.asInt(); break; + } + while (stack.size() > b.b_level) { + stack.pop(); + } + if (b.b_type == Opcode.SETUP_LOOP && why == Why.BREAK) { + why = Why.NOT; + next_instr = b.b_handler; + break; + } + if (b.b_type == Opcode.SETUP_FINALLY || (b.b_type == Opcode.SETUP_EXCEPT && why == Why.EXCEPTION)) { + if (why == Why.EXCEPTION) { + PyException exc = ts.exception; + if (b.b_type == Opcode.SETUP_EXCEPT) { + exc.normalize(); + } + stack.push(Py.None); // XXX - x3 to conform with CPython which + stack.push(Py.None); // stores the type, val, tb separately on the stack + stack.push(new PyStackException(exc)); + } else { + if (why == Why.RETURN || why == Why.CONTINUE) { + stack.push(retval); + } + stack.push(Py.newString(why.name())); // XXX - hack! + } + why = Why.NOT; + next_instr = b.b_handler; + break; + } + } // unwindstack + + if (why != Why.NOT) { + break; } - } // end while - return Py.None; // should never get here, just for debugging + } + assert (why != Why.YIELD); + while (stack.size() > 0) { + stack.pop(); + } + if (why != Why.RETURN) { + retval = Py.None; + } + + return retval; } // XXX - perhaps add support for max stack size (presumably from co_stacksize) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-23 01:03:41
|
Revision: 5961 http://jython.svn.sourceforge.net/jython/?rev=5961&view=rev Author: fwierzbicki Date: 2009-01-23 01:03:39 +0000 (Fri, 23 Jan 2009) Log Message: ----------- Over-ride pyset in PyTuple so our tuples go back to being immutable. Fixes http://bugs.jython.org/issue1242. Modified Paths: -------------- trunk/jython/Lib/test/test_tuple.py trunk/jython/src/org/python/core/PyTuple.java Modified: trunk/jython/Lib/test/test_tuple.py =================================================================== --- trunk/jython/Lib/test/test_tuple.py 2009-01-22 20:20:59 UTC (rev 5960) +++ trunk/jython/Lib/test/test_tuple.py 2009-01-23 01:03:39 UTC (rev 5961) @@ -88,6 +88,12 @@ self.assertEqual(repr(a0), "()") self.assertEqual(repr(a2), "(0, 1, 2)") + def test_setitem(self): + #This test is equivalent to (1,2)[0] = 0 which was briefly broken in + #Jython 2.5b2 + import operator + self.assertRaises(TypeError, operator.setitem, (1,2), 0, 0) + def test_main(): test_support.run_unittest(TupleTest) Modified: trunk/jython/src/org/python/core/PyTuple.java =================================================================== --- trunk/jython/src/org/python/core/PyTuple.java 2009-01-22 20:20:59 UTC (rev 5960) +++ trunk/jython/src/org/python/core/PyTuple.java 2009-01-23 01:03:39 UTC (rev 5961) @@ -384,4 +384,9 @@ } return super.unsupportedopMessage(op, o2); } + + public void pyset(int index, PyObject value) { + throw Py.TypeError("'tuple' object does not support item assignment"); + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-22 20:21:09
|
Revision: 5960 http://jython.svn.sourceforge.net/jython/?rev=5960&view=rev Author: fwierzbicki Date: 2009-01-22 20:20:59 +0000 (Thu, 22 Jan 2009) Log Message: ----------- Make PackageManager an interface and combine the impl into SysPackageManager. Modified Paths: -------------- trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/PackageManager.java trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/SysPackageManager.java Removed Paths: ------------- trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/CachedJarsPackageManager.java trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/PathPackageManager.java Deleted: trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/CachedJarsPackageManager.java =================================================================== --- trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/CachedJarsPackageManager.java 2009-01-22 19:50:18 UTC (rev 5959) +++ trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/CachedJarsPackageManager.java 2009-01-22 20:20:59 UTC (rev 5960) @@ -1,596 +0,0 @@ -// Copyright (c) Corporation for National Research Initiatives -// Copyright 2000 Samuele Pedroni - -package org.python.core.packagecache; - -import org.python.core.Options; -import org.python.util.Generic; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.EOFException; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Modifier; -import java.net.URL; -import java.net.URLConnection; -import java.security.AccessControlException; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -/** - * Abstract package manager that gathers info about statically known classes - * from a set of jars. This info can be eventually cached. Off-the-shelf this - * class offers a local file-system based cache impl. - */ -public abstract class CachedJarsPackageManager extends PackageManager { - - /** - * Message log method - hook. This default impl does nothing. - * - * @param msg message text - */ - protected void message(String msg) { - } - - /** - * Warning log method - hook. This default impl does nothing. - * - * @param warn warning text - */ - protected void warning(String warn) { - } - - /** - * Comment log method - hook. This default impl does nothing. - * - * @param msg message text - */ - protected void comment(String msg) { - } - - /** - * Debug log method - hook. This default impl does nothing. - * - * @param msg message text - */ - protected void debug(String msg) { - } - - /** - * Filter class/pkg by name helper method - hook. The default impl. is used - * by {@link #addJarToPackages} in order to filter out classes whose name - * contains '$' (e.g. inner classes,...). Should be used or overriden by - * derived classes too. Also to be used in {@link #doDir}. - * - * @param name class/pkg name - * @param pkg if true, name refers to a pkg - * @return true if name must be filtered out - */ - protected boolean filterByName(String name, boolean pkg) { - return name.indexOf('$') != -1; - } - - /** - * Filter class by access perms helper method - hook. The default impl. is - * used by {@link #addJarToPackages} in order to filter out non-public - * classes. Should be used or overriden by derived classes too. Also to be - * used in {@link #doDir}. Access perms can be read with - * {@link #checkAccess}. - * - * @param name class name - * @param acc class access permissions as int - * @return true if name must be filtered out - */ - protected boolean filterByAccess(String name, int acc) { - return (acc & Modifier.PUBLIC) != Modifier.PUBLIC; - } - - private boolean indexModified; - - private Map<String,JarXEntry> jarfiles; - - private static String listToString(List<String> list) { - int n = list.size(); - StringBuilder ret = new StringBuilder(); - for (int i = 0; i < n; i++) { - ret.append(list.get(i)); - if (i < n - 1) { - ret.append(","); - } - } - return ret.toString(); - } - - // Add a single class from zipFile to zipPackages - // Only add valid, public classes - private void addZipEntry(Map<String, List<String>[]> zipPackages, ZipEntry entry, - ZipInputStream zip) throws IOException { - String name = entry.getName(); - // System.err.println("entry: "+name); - if (!name.endsWith(".class")) { - return; - } - - char sep = '/'; - int breakPoint = name.lastIndexOf(sep); - if (breakPoint == -1) { - breakPoint = name.lastIndexOf('\\'); - sep = '\\'; - } - - String packageName; - if (breakPoint == -1) { - packageName = ""; - } else { - packageName = name.substring(0, breakPoint).replace(sep, '.'); - } - - String className = name.substring(breakPoint + 1, name.length() - 6); - - if (filterByName(className, false)) { - return; - } - - List<String>[] vec = zipPackages.get(packageName); - if (vec == null) { - vec = new List[] { Generic.list(), Generic.list() }; - zipPackages.put(packageName, vec); - } - int access = checkAccess(zip); - if ((access != -1) && !filterByAccess(name, access)) { - vec[0].add(className); - } else { - vec[1].add(className); - } - } - - // Extract all of the packages in a single jarfile - private Map<String, String> getZipPackages(InputStream jarin) throws IOException { - Map<String, List<String>[]> zipPackages = Generic.map(); - - ZipInputStream zip = new ZipInputStream(jarin); - - ZipEntry entry; - while ((entry = zip.getNextEntry()) != null) { - addZipEntry(zipPackages, entry, zip); - zip.closeEntry(); - } - - // Turn each vector into a comma-separated String - Map<String, String> transformed = Generic.map(); - for (String key : zipPackages.keySet()) { - List<String>[] vec = zipPackages.get(key); - String classes = listToString(vec[0]); - if (vec[1].size() > 0) { - classes += '@' + listToString(vec[1]); - } - transformed.put(key, classes); - } - - return transformed; - } - - /** - * Gathers classes info from jar specified by jarurl URL. Eventually just - * using previously cached info. Eventually updated info is not cached. - * Persistent cache storage access goes through inOpenCacheFile() and - * outCreateCacheFile(). - */ - public void addJarToPackages(java.net.URL jarurl) { - addJarToPackages(jarurl, null, false); - } - - /** - * Gathers classes info from jar specified by jarurl URL. Eventually just - * using previously cached info. Eventually updated info is (re-)cached if - * param cache is true. Persistent cache storage access goes through - * inOpenCacheFile() and outCreateCacheFile(). - */ - public void addJarToPackages(URL jarurl, boolean cache) { - addJarToPackages(jarurl, null, cache); - } - - /** - * Gathers classes info from jar specified by File jarfile. Eventually just - * using previously cached info. Eventually updated info is not cached. - * Persistent cache storage access goes through inOpenCacheFile() and - * outCreateCacheFile(). - */ - public void addJarToPackages(File jarfile) { - addJarToPackages(null, jarfile, false); - } - - /** - * Gathers classes info from jar specified by File jarfile. Eventually just - * using previously cached info. Eventually updated info is (re-)cached if - * param cache is true. Persistent cache storage access goes through - * inOpenCacheFile() and outCreateCacheFile(). - */ - public void addJarToPackages(File jarfile, boolean cache) { - addJarToPackages(null, jarfile, cache); - } - - private void addJarToPackages(URL jarurl, File jarfile, boolean cache) { - try { - boolean caching = this.jarfiles != null; - - URLConnection jarconn = null; - boolean localfile = true; - - if (jarfile == null) { - jarconn = jarurl.openConnection(); - // This is necessary because 'file:' url-connections - // return always 0 through getLastModified (bug?). - // And in order to handle localfiles (from urls too) - // uniformly. - if (jarconn.getURL().getProtocol().equals("file")) { - // ??pending: need to use java2 URLDecoder.decode? - String jarfilename = jarurl.getFile(); - jarfilename = jarfilename.replace('/', File.separatorChar); - jarfile = new File(jarfilename); - } else { - localfile = false; - } - } - - if (localfile && !jarfile.exists()) { - return; - } - - Map<String, String> zipPackages = null; - - long mtime = 0; - String jarcanon = null; - JarXEntry entry = null; - boolean brandNew = false; - - if (caching) { - - if (localfile) { - mtime = jarfile.lastModified(); - jarcanon = jarfile.getCanonicalPath(); - } else { - mtime = jarconn.getLastModified(); - jarcanon = jarurl.toString(); - } - - entry = this.jarfiles.get(jarcanon); - - if ((entry == null || !(new File(entry.cachefile).exists())) - && cache) { - message("processing new jar, '" + jarcanon + "'"); - - String jarname; - if (localfile) { - jarname = jarfile.getName(); - } else { - jarname = jarurl.getFile(); - int slash = jarname.lastIndexOf('/'); - if (slash != -1) - jarname = jarname.substring(slash + 1); - } - jarname = jarname.substring(0, jarname.length() - 4); - - entry = new JarXEntry(jarname); - this.jarfiles.put(jarcanon, entry); - - brandNew = true; - } - - if (mtime != 0 && entry != null && entry.mtime == mtime) { - zipPackages = readCacheFile(entry, jarcanon); - } - - } - - if (zipPackages == null) { - caching = caching && cache; - - if (caching) { - this.indexModified = true; - if (entry.mtime != 0) { - message("processing modified jar, '" + jarcanon + "'"); - } - entry.mtime = mtime; - } - - InputStream jarin; - if (jarconn == null) { - jarin = new BufferedInputStream( - new FileInputStream(jarfile)); - } else { - jarin = jarconn.getInputStream(); - } - - zipPackages = getZipPackages(jarin); - - if (caching) { - writeCacheFile(entry, jarcanon, zipPackages, brandNew); - } - } - - addPackages(zipPackages, jarcanon); - } catch (IOException ioe) { - // silently skip any bad directories - warning("skipping bad jar, '" - + (jarfile != null ? jarfile.toString() : jarurl.toString()) - + "'"); - } - - } - - private void addPackages(Map<String,String> zipPackages, String jarfile) { - for (Entry<String,String> entry : zipPackages.entrySet()) { - String pkg = entry.getKey(); - String classes = entry.getValue(); - - int idx = classes.indexOf('@'); - if (idx >= 0 && Options.respectJavaAccessibility) { - classes = classes.substring(0, idx); - } - - makeJavaPackage(pkg, classes, jarfile); - } - } - - // Read in cache file storing package info for a single .jar - // Return null and delete this cachefile if it is invalid - private Map<String, String> readCacheFile(JarXEntry entry, String jarcanon) { - String cachefile = entry.cachefile; - long mtime = entry.mtime; - - debug("reading cache, '" + jarcanon + "'"); - - try { - DataInputStream istream = inOpenCacheFile(cachefile); - String old_jarcanon = istream.readUTF(); - long old_mtime = istream.readLong(); - if ((!old_jarcanon.equals(jarcanon)) || (old_mtime != mtime)) { - comment("invalid cache file: " + cachefile + ", " + jarcanon - + ":" + old_jarcanon + ", " + mtime + ":" + old_mtime); - deleteCacheFile(cachefile); - return null; - } - Map<String, String> packs = Generic.map(); - try { - while (true) { - String packageName = istream.readUTF(); - String classes = istream.readUTF(); - packs.put(packageName, classes); - } - } catch (EOFException eof) { - ; - } - istream.close(); - - return packs; - } catch (IOException ioe) { - // if (cachefile.exists()) cachefile.delete(); - return null; - } - } - - // Write a cache file storing package info for a single .jar - private void writeCacheFile(JarXEntry entry, String jarcanon, - Map<String,String> zipPackages, boolean brandNew) { - try { - DataOutputStream ostream = outCreateCacheFile(entry, brandNew); - ostream.writeUTF(jarcanon); - ostream.writeLong(entry.mtime); - comment("rewriting cachefile for '" + jarcanon + "'"); - - for (String packageName : zipPackages.keySet()) { - String classes = zipPackages.get(packageName); - ostream.writeUTF(packageName); - ostream.writeUTF(classes); - } - ostream.close(); - } catch (IOException ioe) { - warning("can't write cache file for '" + jarcanon + "'"); - } - } - - /** - * Initializes cache. Eventually reads back cache index. Index persistent - * storage is accessed through inOpenIndex(). - */ - protected void initCache() { - this.indexModified = false; - this.jarfiles = Generic.map(); - - try { - DataInputStream istream = inOpenIndex(); - if (istream == null) { - return; - } - - try { - while (true) { - String jarcanon = istream.readUTF(); - String cachefile = istream.readUTF(); - long mtime = istream.readLong(); - this.jarfiles.put(jarcanon, new JarXEntry(cachefile, mtime)); - } - } catch (EOFException eof) { - ; - } - istream.close(); - } catch (IOException ioe) { - warning("invalid index file"); - } - - } - - /** - * Write back cache index. Index persistent storage is accessed through - * outOpenIndex(). - */ - public void saveCache() { - if (jarfiles == null || !indexModified) { - return; - } - - indexModified = false; - - comment("writing modified index file"); - - try { - DataOutputStream ostream = outOpenIndex(); - for (Entry<String,JarXEntry> entry : jarfiles.entrySet()) { - String jarcanon = entry.getKey(); - JarXEntry xentry = entry.getValue(); - ostream.writeUTF(jarcanon); - ostream.writeUTF(xentry.cachefile); - ostream.writeLong(xentry.mtime); - } - ostream.close(); - } catch (IOException ioe) { - warning("can't write index file"); - } - } - - // hooks for changing cache storage - - /** - * To pass a cachefile id by ref. And for internal use. See - * outCreateCacheFile - */ - public static class JarXEntry extends Object { - /** cachefile id */ - public String cachefile; - - public long mtime; - - public JarXEntry(String cachefile) { - this.cachefile = cachefile; - } - - public JarXEntry(String cachefile, long mtime) { - this.cachefile = cachefile; - this.mtime = mtime; - } - - } - - /** - * Open cache index for reading from persistent storage - hook. Must Return - * null if this is absent. This default impl is part of the off-the-shelf - * local file-system cache impl. Can be overriden. - */ - protected DataInputStream inOpenIndex() throws IOException { - File indexFile = new File(this.cachedir, "packages.idx"); - - if (!indexFile.exists()) { - return null; - } - - DataInputStream istream = new DataInputStream(new BufferedInputStream( - new FileInputStream(indexFile))); - - return istream; - } - - /** - * Open cache index for writing back to persistent storage - hook. This - * default impl is part of the off-the-shelf local file-system cache impl. - * Can be overriden. - */ - protected DataOutputStream outOpenIndex() throws IOException { - File indexFile = new File(this.cachedir, "packages.idx"); - - return new DataOutputStream(new BufferedOutputStream( - new FileOutputStream(indexFile))); - } - - /** - * Open cache file for reading from persistent storage - hook. This default - * impl is part of the off-the-shelf local file-system cache impl. Can be - * overriden. - */ - protected DataInputStream inOpenCacheFile(String cachefile) - throws IOException { - return new DataInputStream(new BufferedInputStream(new FileInputStream( - cachefile))); - } - - /** - * Delete (invalidated) cache file from persistent storage - hook. This - * default impl is part of the off-the-shelf local file-system cache impl. - * Can be overriden. - */ - protected void deleteCacheFile(String cachefile) { - new File(cachefile).delete(); - } - - /** - * Create/open cache file for rewriting back to persistent storage - hook. - * If create is false, cache file is supposed to exist and must be opened - * for rewriting, entry.cachefile is a valid cachefile id. If create is - * true, cache file must be created. entry.cachefile is a flat jarname to be - * used to produce a valid cachefile id (to be put back in entry.cachefile - * on exit). This default impl is part of the off-the-shelf local - * file-system cache impl. Can be overriden. - */ - protected DataOutputStream outCreateCacheFile(JarXEntry entry, - boolean create) throws IOException { - File cachefile = null; - - if (create) { - int index = 1; - String suffix = ""; - String jarname = entry.cachefile; - while (true) { - cachefile = new File(this.cachedir, jarname + suffix + ".pkc"); - // System.err.println("try cachefile: "+cachefile); - if (!cachefile.exists()) { - break; - } - suffix = "$" + index; - index += 1; - } - entry.cachefile = cachefile.getCanonicalPath(); - } else - cachefile = new File(entry.cachefile); - - return new DataOutputStream(new BufferedOutputStream( - new FileOutputStream(cachefile))); - } - - // for default cache (local fs based) impl - - private File cachedir; - - /** - * Initialize off-the-shelf (default) local file-system cache impl. Must be - * called before {@link #initCache}. cachedir is the cache repository - * directory, this is eventually created. Returns true if dir works. - */ - protected boolean useCacheDir(File aCachedir1) { - if (aCachedir1 == null) { - return false; - } - try { - if(!aCachedir1.isDirectory() && aCachedir1.mkdirs() == false) { - warning("can't create package cache dir, '" + aCachedir1 + "'"); - return false; - } - } catch(AccessControlException ace) { - warning("The java security manager isn't allowing access to the package cache dir, '" + aCachedir1 + "'"); - return false; - } - - this.cachedir = aCachedir1; - - return true; - } - -} Modified: trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/PackageManager.java =================================================================== --- trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/PackageManager.java 2009-01-22 19:50:18 UTC (rev 5959) +++ trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/PackageManager.java 2009-01-22 20:20:59 UTC (rev 5960) @@ -11,37 +11,17 @@ import java.io.EOFException; -/** - * Abstract package manager. - */ -public abstract class PackageManager extends Object { +public interface PackageManager { - public PyJavaPackage topLevelPackage; + Class findClass(String pkg, String name, String reason); - public PackageManager() { - this.topLevelPackage = new PyJavaPackage("", this); - } + Class findClass(String pkg, String name); - abstract public Class findClass(String pkg, String name, String reason); + void notifyPackageImport(String pkg, String name); - public Class findClass(String pkg, String name) { - return findClass(pkg, name, "java class"); - } + boolean packageExists(String pkg, String name); - public void notifyPackageImport(String pkg, String name) { - } - /** - * Dynamically check if pkg.name exists as java pkg in the controlled - * hierarchy. Should be overriden. - * - * @param pkg parent pkg name - * @param name candidate name - * @return true if pkg exists - */ - public abstract boolean packageExists(String pkg, String name); - - /** * Reports the specified package content names. Should be overriden. Used by * {@link PyJavaPackage#__dir__} and {@link PyJavaPackage#fillDir}. * @@ -50,8 +30,7 @@ * @param instantiate if true then instatiate reported names in package dict * @param exclpkgs exclude packages (just when instantiate is false) */ - public abstract PyList doDir(PyJavaPackage jpkg, boolean instantiate, - boolean exclpkgs); + PyList doDir(PyJavaPackage jpkg, boolean instantiate, boolean exclpkgs); /** * Append a directory to the list of directories searched for java packages @@ -59,7 +38,7 @@ * * @param dir A directory. */ - public abstract void addDirectory(java.io.File dir); + void addDirectory(java.io.File dir); /** * Append a directory to the list of directories searched for java packages @@ -67,7 +46,7 @@ * * @param dir A directory name. */ - public abstract void addJarDir(String dir, boolean cache); + void addJarDir(String dir, boolean cache); /** * Append a jar file to the list of locations searched for java packages and @@ -75,78 +54,11 @@ * * @param jarfile A directory name. */ - public abstract void addJar(String jarfile, boolean cache); + void addJar(String jarfile, boolean cache); - /** - * Basic helper implementation of {@link #doDir}. It merges information - * from jpkg {@link PyJavaPackage#clsSet} and {@link PyJavaPackage#__dict__}. - */ - protected PyList basicDoDir(PyJavaPackage jpkg, boolean instantiate, - boolean exclpkgs) { - PyStringMap dict = jpkg.__dict__; - PyStringMap cls = jpkg.clsSet; + PyObject lookupName(String name); - if (!instantiate) { - PyList ret = cls.keys(); - - PyList dictKeys = dict.keys(); - - for (int i = 0; i < dictKeys.__len__(); i++) { - PyObject name = dictKeys.pyget(i); - if (!cls.has_key(name)) { - if (exclpkgs && dict.get(name) instanceof PyJavaPackage) - continue; - ret.append(name); - } - } - - return ret; - } - - - for (PyObject pyname : cls.keys().asIterable()) { - if (!dict.has_key(pyname)) { - String name = pyname.toString(); - jpkg.addClass(name, Py.findClass(jpkg.__name__ + "." + name)); - } - } - - return dict.keys(); - } - /** - * Helper merging list2 into list1. Returns list1. - */ - protected PyList merge(PyList list1, PyList list2) { - for (int i = 0; i < list2.__len__(); i++) { - PyObject name = list2.pyget(i); - list1.append(name); - } - - return list1; - } - - public PyObject lookupName(String name) { - PyObject top = this.topLevelPackage; - do { - int dot = name.indexOf('.'); - String firstName = name; - String lastName = null; - if (dot != -1) { - firstName = name.substring(0, dot); - lastName = name.substring(dot + 1, name.length()); - } - firstName = firstName.intern(); - top = top.__findattr__(firstName); - if (top == null) - return null; - // ??pending: test for jpkg/jclass? - name = lastName; - } while (name != null); - return top; - } - - /** * Creates package/updates statically known classes info. Uses * {@link PyJavaPackage#addPackage(java.lang.String, java.lang.String) }, * {@link PyJavaPackage#addPlaceholders}. @@ -156,85 +68,5 @@ * @param jarfile involved jarfile; can be null * @return created/updated package */ - public PyJavaPackage makeJavaPackage(String name, String classes, - String jarfile) { - PyJavaPackage p = this.topLevelPackage; - if (name.length() != 0) - p = p.addPackage(name, jarfile); - - if (classes != null) - p.addPlaceholders(classes); - - return p; - } - - /** - * Check that a given stream is a valid Java .class file. And return its - * access permissions as an int. - */ - static protected int checkAccess(java.io.InputStream cstream) - throws java.io.IOException { - java.io.DataInputStream istream = new java.io.DataInputStream(cstream); - - try { - int magic = istream.readInt(); - if (magic != 0xcafebabe) { - return -1; - } - } catch (EOFException eof) { - //Empty or 1 byte file. - return -1; - } - //int minor = - istream.readShort(); - //int major = - istream.readShort(); - - // Check versions??? - // System.out.println("magic: "+magic+", "+major+", "+minor); - int nconstants = istream.readShort(); - for (int i = 1; i < nconstants; i++) { - int cid = istream.readByte(); - // System.out.println(""+i+" : "+cid); - switch (cid) { - case 7: - istream.skipBytes(2); - break; - case 9: - case 10: - case 11: - istream.skipBytes(4); - break; - case 8: - istream.skipBytes(2); - break; - case 3: - case 4: - istream.skipBytes(4); - break; - case 5: - case 6: - istream.skipBytes(8); - i++; - break; - case 12: - istream.skipBytes(4); - break; - case 1: - // System.out.println("utf: "+istream.readUTF()+";"); - int slength = istream.readUnsignedShort(); - istream.skipBytes(slength); - break; - default: - // System.err.println("unexpected cid: "+cid+", "+i+", "+ - // nconstants); - // for (int j=0; j<10; j++) - // System.err.print(", "+istream.readByte()); - // System.err.println(); - return -1; - } - } - return istream.readShort(); - } - + PyJavaPackage makeJavaPackage(String name, String classes, String jarfile); } Deleted: trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/PathPackageManager.java =================================================================== --- trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/PathPackageManager.java 2009-01-22 19:50:18 UTC (rev 5959) +++ trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/PathPackageManager.java 2009-01-22 20:20:59 UTC (rev 5960) @@ -1,237 +0,0 @@ -// Copyright (c) Corporation for National Research Initiatives -// Copyright 2000 Samuele Pedroni - -package org.python.core.packagecache; - -import org.python.core.imp; -import org.python.core.Py; -import org.python.core.PyJavaPackage; -import org.python.core.PyList; -import org.python.core.PyString; -import org.python.core.util.RelativeFile; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FilenameFilter; -import java.io.IOException; - -/** - * Path package manager. Gathering classes info dynamically from a set of - * directories in path {@link #searchPath}, and statically from a set of jars, - * like {@link CachedJarsPackageManager}. - */ -public abstract class PathPackageManager extends CachedJarsPackageManager { - - public PyList searchPath; - - public PathPackageManager() { - this.searchPath = new PyList(); - } - - /** - * Helper for {@link #packageExists(java.lang.String,java.lang.String)}. - * Scans for package pkg.name the directories in path. - */ - protected boolean packageExists(PyList path, String pkg, String name) { - String child = pkg.replace('.', File.separatorChar) + File.separator - + name; - - for (int i = 0; i < path.__len__(); i++) { - String dir = path.pyget(i).__str__().toString(); - - File f = new RelativeFile(dir, child); - if (f.isDirectory() && imp.caseok(f, name)) { - /* - * Figure out if we have a directory a mixture of python and - * java or just an empty directory (which means Java) or a - * directory with only Python source (which means Python). - */ - PackageExistsFileFilter m = new PackageExistsFileFilter(); - f.listFiles(m); - boolean exists = m.packageExists(); - if (exists) { - Py.writeComment("import", "java package as '" - + f.getAbsolutePath() + "'"); - } - return exists; - } - } - return false; - } - - class PackageExistsFileFilter implements FilenameFilter { - private boolean java; - - private boolean python; - - public boolean accept(File dir, String name) { - if(name.endsWith(".py") || name.endsWith("$py.class") || name.endsWith("$_PyInner.class")) { - python = true; - }else if (name.endsWith(".class")) { - java = true; - } - return false; - } - - public boolean packageExists() { - if (this.python && !this.java) { - return false; - } - return true; - } - } - - /** - * Helper for {@link #doDir(PyJavaPackage,boolean,boolean)}. Scans for - * package jpkg content over the directories in path. Add to ret the founded - * classes/pkgs. Filter out classes using {@link #filterByName},{@link #filterByAccess}. - */ - protected void doDir(PyList path, PyList ret, PyJavaPackage jpkg, - boolean instantiate, boolean exclpkgs) { - String child = jpkg.__name__.replace('.', File.separatorChar); - - for (int i = 0; i < path.__len__(); i++) { - String dir = path.pyget(i).__str__().toString(); - if (dir.length() == 0) { - dir = null; - } - - File childFile = new File(dir, child); - - String[] list = childFile.list(); - if (list == null) { - continue; - } - - doList: for (int j = 0; j < list.length; j++) { - String jname = list[j]; - - File cand = new File(childFile, jname); - - int jlen = jname.length(); - - boolean pkgCand = false; - - if (cand.isDirectory()) { - if (!instantiate && exclpkgs) { - continue; - } - pkgCand = true; - } else { - if (!jname.endsWith(".class")) { - continue; - } - jlen -= 6; - } - - jname = jname.substring(0, jlen); - PyString name = new PyString(jname); - - if (filterByName(jname, pkgCand)) { - continue; - } - - // for opt maybe we should some hash-set for ret - if (jpkg.__dict__.has_key(name) || jpkg.clsSet.has_key(name) - || ret.__contains__(name)) { - continue; - } - - if (!Character.isJavaIdentifierStart(jname.charAt(0))) { - continue; - } - - for (int k = 1; k < jlen; k++) { - if (!Character.isJavaIdentifierPart(jname.charAt(k))) { - continue doList; - } - } - - if (!pkgCand) { - try { - int acc = checkAccess(new BufferedInputStream( - new FileInputStream(cand))); - if ((acc == -1) || filterByAccess(jname, acc)) { - continue; - } - } catch (IOException e) { - continue; - } - } - - if (instantiate) { - if (pkgCand) { - jpkg.addPackage(jname); - } else { - jpkg.addClass(jname, Py.findClass(jpkg.__name__ + "." + jname)); - } - } - - ret.append(name); - - } - } - - } - - /** - * Add directory dir (if exists) to {@link #searchPath}. - */ - public void addDirectory(File dir) { - try { - if (dir.getPath().length() == 0) { - this.searchPath.append(Py.EmptyString); - } else { - this.searchPath.append(new PyString(dir.getCanonicalPath())); - } - } catch (IOException e) { - warning("skipping bad directory, '" + dir + "'"); - } - } - - // ??pending: - // Uses simply split and not a StringTokenizer+trim to adhere to - // sun jvm parsing of classpath. - // E.g. "a;" is parsed by sun jvm as a, ""; the latter is interpreted - // as cwd. jview trims and cwd is per default in classpath. - // The logic here should work for both(...). Need to distinguish? - // This code does not avoid duplicates in searchPath. - // Should cause no problem (?). - - /** - * Adds "classpath" entry. Calls {@link #addDirectory} if path refers to a - * dir, {@link #addJarToPackages(java.io.File, boolean)} with param cache - * true if path refers to a jar. - */ - public void addClassPath(String path) { - PyList paths = new PyString(path).split(java.io.File.pathSeparator); - - for (int i = 0; i < paths.__len__(); i++) { - String entry = paths.pyget(i).toString(); - if (entry.endsWith(".jar") || entry.endsWith(".zip")) { - addJarToPackages(new File(entry), true); - } else { - File dir = new File(entry); - if (entry.length() == 0 || dir.isDirectory()) { - addDirectory(dir); - } - } - } - } - - public PyList doDir(PyJavaPackage jpkg, boolean instantiate, - boolean exclpkgs) { - PyList basic = basicDoDir(jpkg, instantiate, exclpkgs); - PyList ret = new PyList(); - - doDir(this.searchPath, ret, jpkg, instantiate, exclpkgs); - - return merge(basic, ret); - } - - public boolean packageExists(String pkg, String name) { - return packageExists(this.searchPath, pkg, name); - } - -} Modified: trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/SysPackageManager.java =================================================================== --- trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/SysPackageManager.java 2009-01-22 19:50:18 UTC (rev 5959) +++ trunk/sandbox/wierzbicki/jlr_experiment/src/org/python/core/packagecache/SysPackageManager.java 2009-01-22 20:20:59 UTC (rev 5960) @@ -3,20 +3,55 @@ package org.python.core.packagecache; +import org.python.core.imp; import org.python.core.Py; import org.python.core.PyJavaPackage; import org.python.core.PyList; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PyStringMap; import org.python.core.PySystemState; +import org.python.core.util.RelativeFile; import java.util.Properties; import java.util.StringTokenizer; import java.io.*; +import org.python.core.Options; +import org.python.util.Generic; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Modifier; +import java.net.URL; +import java.net.URLConnection; +import java.security.AccessControlException; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + + /** * System package manager. Used by org.python.core.PySystemState. */ -public class SysPackageManager extends PathPackageManager { +public class SysPackageManager implements PackageManager { + /* from PathPackageManager constructor */ + public PyList searchPath; + + /* from old PackageManager */ + public PyJavaPackage topLevelPackage; + protected void message(String msg) { Py.writeMessage("*sys-package-mgr*", msg); } @@ -34,6 +69,12 @@ } public SysPackageManager(File cachedir, Properties registry) { + /* from PathPackageManager constructor */ + this.searchPath = new PyList(); + + /* from old PackageManager constructor */ + this.topLevelPackage = new PyJavaPackage("", this); + if (useCacheDir(cachedir)) { initCache(); findAllPackages(registry); @@ -119,7 +160,7 @@ } public Class findClass(String pkg, String name) { - Class c = super.findClass(pkg, name); + Class c = findClass(pkg, name, "java class"); if (c != null) { Py.writeComment("import", "'" + name + "' as java class"); } @@ -149,6 +190,14 @@ return merge(basic, ret); } + /** + * Dynamically check if pkg.name exists as java pkg in the controlled + * hierarchy. Should be overriden. + * + * @param pkg parent pkg name + * @param name candidate name + * @return true if pkg exists + */ public boolean packageExists(String pkg, String name) { if (packageExists(this.searchPath, pkg, name)) { return true; @@ -164,4 +213,888 @@ return false; } + + /** + * Helper for {@link #packageExists(java.lang.String,java.lang.String)}. + * Scans for package pkg.name the directories in path. + */ + protected boolean packageExists(PyList path, String pkg, String name) { + String child = pkg.replace('.', File.separatorChar) + File.separator + + name; + + for (int i = 0; i < path.__len__(); i++) { + String dir = path.pyget(i).__str__().toString(); + + File f = new RelativeFile(dir, child); + if (f.isDirectory() && imp.caseok(f, name)) { + /* + * Figure out if we have a directory a mixture of python and + * java or just an empty directory (which means Java) or a + * directory with only Python source (which means Python). + */ + PackageExistsFileFilter m = new PackageExistsFileFilter(); + f.listFiles(m); + boolean exists = m.packageExists(); + if (exists) { + Py.writeComment("import", "java package as '" + + f.getAbsolutePath() + "'"); + } + return exists; + } + } + return false; + } + + class PackageExistsFileFilter implements FilenameFilter { + private boolean java; + + private boolean python; + + public boolean accept(File dir, String name) { + if(name.endsWith(".py") || name.endsWith("$py.class") || name.endsWith("$_PyInner.class")) { + python = true; + }else if (name.endsWith(".class")) { + java = true; + } + return false; + } + + public boolean packageExists() { + if (this.python && !this.java) { + return false; + } + return true; + } + } + + /** + * Helper for {@link #doDir(PyJavaPackage,boolean,boolean)}. Scans for + * package jpkg content over the directories in path. Add to ret the founded + * classes/pkgs. Filter out classes using {@link #filterByName},{@link #filterByAccess}. + */ + protected void doDir(PyList path, PyList ret, PyJavaPackage jpkg, + boolean instantiate, boolean exclpkgs) { + String child = jpkg.__name__.replace('.', File.separatorChar); + + for (int i = 0; i < path.__len__(); i++) { + String dir = path.pyget(i).__str__().toString(); + if (dir.length() == 0) { + dir = null; + } + + File childFile = new File(dir, child); + + String[] list = childFile.list(); + if (list == null) { + continue; + } + + doList: for (int j = 0; j < list.length; j++) { + String jname = list[j]; + + File cand = new File(childFile, jname); + + int jlen = jname.length(); + + boolean pkgCand = false; + + if (cand.isDirectory()) { + if (!instantiate && exclpkgs) { + continue; + } + pkgCand = true; + } else { + if (!jname.endsWith(".class")) { + continue; + } + jlen -= 6; + } + + jname = jname.substring(0, jlen); + PyString name = new PyString(jname); + + if (filterByName(jname, pkgCand)) { + continue; + } + + // for opt maybe we should some hash-set for ret + if (jpkg.__dict__.has_key(name) || jpkg.clsSet.has_key(name) + || ret.__contains__(name)) { + continue; + } + + if (!Character.isJavaIdentifierStart(jname.charAt(0))) { + continue; + } + + for (int k = 1; k < jlen; k++) { + if (!Character.isJavaIdentifierPart(jname.charAt(k))) { + continue doList; + } + } + + if (!pkgCand) { + try { + int acc = checkAccess(new BufferedInputStream( + new FileInputStream(cand))); + if ((acc == -1) || filterByAccess(jname, acc)) { + continue; + } + } catch (IOException e) { + continue; + } + } + + if (instantiate) { + if (pkgCand) { + jpkg.addPackage(jname); + } else { + jpkg.addClass(jname, Py.findClass(jpkg.__name__ + "." + jname)); + } + } + + ret.append(name); + + } + } + + } + + /** + * Add directory dir (if exists) to {@link #searchPath}. + */ + public void addDirectory(File dir) { + try { + if (dir.getPath().length() == 0) { + this.searchPath.append(Py.EmptyString); + } else { + this.searchPath.append(new PyString(dir.getCanonicalPath())); + } + } catch (IOException e) { + warning("skipping bad directory, '" + dir + "'"); + } + } + + // ??pending: + // Uses simply split and not a StringTokenizer+trim to adhere to + // sun jvm parsing of classpath. + // E.g. "a;" is parsed by sun jvm as a, ""; the latter is interpreted + // as cwd. jview trims and cwd is per default in classpath. + // The logic here should work for both(...). Need to distinguish? + // This code does not avoid duplicates in searchPath. + // Should cause no problem (?). + + /** + * Adds "classpath" entry. Calls {@link #addDirectory} if path refers to a + * dir, {@link #addJarToPackages(java.io.File, boolean)} with param cache + * true if path refers to a jar. + */ + public void addClassPath(String path) { + PyList paths = new PyString(path).split(java.io.File.pathSeparator); + + for (int i = 0; i < paths.__len__(); i++) { + String entry = paths.pyget(i).toString(); + if (entry.endsWith(".jar") || entry.endsWith(".zip")) { + addJarToPackages(new File(entry), true); + } else { + File dir = new File(entry); + if (entry.length() == 0 || dir.isDirectory()) { + addDirectory(dir); + } + } + } + } + + //Copied from CachedJarsPackageManager + /** + * Filter class/pkg by name helper method - hook. The default impl. is used + * by {@link #addJarToPackages} in order to filter out classes whose name + * contains '$' (e.g. inner classes,...). Should be used or overriden by + * derived classes too. Also to be used in {@link #doDir}. + * + * @param name class/pkg name + * @param pkg if true, name refers to a pkg + * @return true if name must be filtered out + */ + protected boolean filterByName(String name, boolean pkg) { + return name.indexOf('$') != -1; + } + + /** + * Filter class by access perms helper method - hook. The default impl. is + * used by {@link #addJarToPackages} in order to filter out non-public + * classes. Should be used or overriden by derived classes too. Also to be + * used in {@link #doDir}. Access perms can be read with + * {@link #checkAccess}. + * + * @param name class name + * @param acc class access permissions as int + * @return true if name must be filtered out + */ + protected boolean filterByAccess(String name, int acc) { + return (acc & Modifier.PUBLIC) != Modifier.PUBLIC; + } + + private boolean indexModified; + + private Map<String,JarXEntry> jarfiles; + + private static String listToString(List<String> list) { + int n = list.size(); + StringBuilder ret = new StringBuilder(); + for (int i = 0; i < n; i++) { + ret.append(list.get(i)); + if (i < n - 1) { + ret.append(","); + } + } + return ret.toString(); + } + + // Add a single class from zipFile to zipPackages + // Only add valid, public classes + private void addZipEntry(Map<String, List<String>[]> zipPackages, ZipEntry entry, + ZipInputStream zip) throws IOException { + String name = entry.getName(); + // System.err.println("entry: "+name); + if (!name.endsWith(".class")) { + return; + } + + char sep = '/'; + int breakPoint = name.lastIndexOf(sep); + if (breakPoint == -1) { + breakPoint = name.lastIndexOf('\\'); + sep = '\\'; + } + + String packageName; + if (breakPoint == -1) { + packageName = ""; + } else { + packageName = name.substring(0, breakPoint).replace(sep, '.'); + } + + String className = name.substring(breakPoint + 1, name.length() - 6); + + if (filterByName(className, false)) { + return; + } + + List<String>[] vec = zipPackages.get(packageName); + if (vec == null) { + vec = new List[] { Generic.list(), Generic.list() }; + zipPackages.put(packageName, vec); + } + int access = checkAccess(zip); + if ((access != -1) && !filterByAccess(name, access)) { + vec[0].add(className); + } else { + vec[1].add(className); + } + } + + // Extract all of the packages in a single jarfile + private Map<String, String> getZipPackages(InputStream jarin) throws IOException { + Map<String, List<String>[]> zipPackages = Generic.map(); + + ZipInputStream zip = new ZipInputStream(jarin); + + ZipEntry entry; + while ((entry = zip.getNextEntry()) != null) { + addZipEntry(zipPackages, entry, zip); + zip.closeEntry(); + } + + // Turn each vector into a comma-separated String + Map<String, String> transformed = Generic.map(); + for (String key : zipPackages.keySet()) { + List<String>[] vec = zipPackages.get(key); + String classes = listToString(vec[0]); + if (vec[1].size() > 0) { + classes += '@' + listToString(vec[1]); + } + transformed.put(key, classes); + } + + return transformed; + } + + /** + * Gathers classes info from jar specified by jarurl URL. Eventually just + * using previously cached info. Eventually updated info is not cached. + * Persistent cache storage access goes through inOpenCacheFile() and + * outCreateCacheFile(). + */ + public void addJarToPackages(java.net.URL jarurl) { + addJarToPackages(jarurl, null, false); + } + + /** + * Gathers classes info from jar specified by jarurl URL. Eventually just + * using previously cached info. Eventually updated info is (re-)cached if + * param cache is true. Persistent cache storage access goes through + * inOpenCacheFile() and outCreateCacheFile(). + */ + public void addJarToPackages(URL jarurl, boolean cache) { + addJarToPackages(jarurl, null, cache); + } + + /** + * Gathers classes info from jar specified by File jarfile. Eventually just + * using previously cached info. Eventually updated info is not cached. + * Persistent cache storage access goes through inOpenCacheFile() and + * outCreateCacheFile(). + */ + public void addJarToPackages(File jarfile) { + addJarToPackages(null, jarfile, false); + } + + /** + * Gathers classes info from jar specified by File jarfile. Eventually just + * using previously cached info. Eventually updated info is (re-)cached if + * param cache is true. Persistent cache storage access goes through + * inOpenCacheFile() and outCreateCacheFile(). + */ + public void addJarToPackages(File jarfile, boolean cache) { + addJarToPackages(null, jarfile, cache); + } + + private void addJarToPackages(URL jarurl, File jarfile, boolean cache) { + try { + boolean caching = this.jarfiles != null; + + URLConnection jarconn = null; + boolean localfile = true; + + if (jarfile == null) { + jarconn = jarurl.openConnection(); + // This is necessary because 'file:' url-connections + // return always 0 through getLastModified (bug?). + // And in order to handle localfiles (from urls too) + // uniformly. + if (jarconn.getURL().getProtocol().equals("file")) { + // ??pending: need to use java2 URLDecoder.decode? + String jarfilename = jarurl.getFile(); + jarfilename = jarfilename.replace('/', File.separatorChar); + jarfile = new File(jarfilename); + } else { + localfile = false; + } + } + + if (localfile && !jarfile.exists()) { + return; + } + + Map<String, String> zipPackages = null; + + long mtime = 0; + String jarcanon = null; + JarXEntry entry = null; + boolean brandNew = false; + + if (caching) { + + if (localfile) { + mtime = jarfile.lastModified(); + jarcanon = jarfile.getCanonicalPath(); + } else { + mtime = jarconn.getLastModified(); + jarcanon = jarurl.toString(); + } + + entry = this.jarfiles.get(jarcanon); + + if ((entry == null || !(new File(entry.cachefile).exists())) + && cache) { + message("processing new jar, '" + jarcanon + "'"); + + String jarname; + if (localfile) { + jarname = jarfile.getName(); + } else { + jarname = jarurl.getFile(); + int slash = jarname.lastIndexOf('/'); + if (slash != -1) + jarname = jarname.substring(slash + 1); + } + jarname = jarname.substring(0, jarname.length() - 4); + + entry = new JarXEntry(jarname); + this.jarfiles.put(jarcanon, entry); + + brandNew = true; + } + + if (mtime != 0 && entry != null && entry.mtime == mtime) { + zipPackages = readCacheFile(entry, jarcanon); + } + + } + + if (zipPackages == null) { + caching = caching && cache; + + if (caching) { + this.indexModified = true; + if (entry.mtime != 0) { + message("processing modified jar, '" + jarcanon + "'"); + } + entry.mtime = mtime; + } + + InputStream jarin; + if (jarconn == null) { + jarin = new BufferedInputStream( + new FileInputStream(jarfile)); + } else { + jarin = jarconn.getInputStream(); + } + + zipPackages = getZipPackages(jarin); + + if (caching) { + writeCacheFile(entry, jarcanon, zipPackages, brandNew); + } + } + + addPackages(zipPackages, jarcanon); + } catch (IOException ioe) { + // silently skip any bad directories + warning("skipping bad jar, '" + + (jarfile != null ? jarfile.toString() : jarurl.toString()) + + "'"); + } + + } + + private void addPackages(Map<String,String> zipPackages, String jarfile) { + for (Entry<String,String> entry : zipPackages.entrySet()) { + String pkg = entry.getKey(); + String classes = entry.getValue(); + + int idx = classes.indexOf('@'); + if (idx >= 0 && Options.respectJavaAccessibility) { + classes = classes.substring(0, idx); + } + + makeJavaPackage(pkg, classes, jarfile); + } + } + + // Read in cache file storing package info for a single .jar + // Return null and delete this cachefile if it is invalid + private Map<String, String> readCacheFile(JarXEntry entry, String jarcanon) { + String cachefile = entry.cachefile; + long mtime = entry.mtime; + + debug("reading cache, '" + jarcanon + "'"); + + try { + DataInputStream istream = inOpenCacheFile(cachefile); + String old_jarcanon = istream.readUTF(); + long old_mtime = istream.readLong(); + if ((!old_jarcanon.equals(jarcanon)) || (old_mtime != mtime)) { + comment("invalid cache file: " + cachefile + ", " + jarcanon + + ":" + old_jarcanon + ", " + mtime + ":" + old_mtime); + deleteCacheFile(cachefile); + return null; + } + Map<String, String> packs = Generic.map(); + try { + while (true) { + String packageName = istream.readUTF(); + String classes = istream.readUTF(); + packs.put(packageName, classes); + } + } catch (EOFException eof) { + ; + } + istream.close(); + + return packs; + } catch (IOException ioe) { + // if (cachefile.exists()) cachefile.delete(); + return null; + } + } + + // Write a cache file storing package info for a single .jar + private void writeCacheFile(JarXEntry entry, String jarcanon, + Map<String,String> zipPackages, boolean brandNew) { + try { + DataOutputStream ostream = outCreateCacheFile(entry, brandNew); + ostream.writeUTF(jarcanon); + ostream.writeLong(entry.mtime); + comment("rewriting cachefile for '" + jarcanon + "'"); + + for (String packageName : zipPackages.keySet()) { + String classes = zipPackages.get(packageName); + ostream.writeUTF(packageName); + ostream.writeUTF(classes); + } + ostream.close(); + } catch (IOException ioe) { + warning("can't write cache file for '" + jarcanon + "'"); + } + } + + /** + * Initializes cache. Eventually r... [truncated message content] |
From: <cg...@us...> - 2009-01-22 19:50:23
|
Revision: 5959 http://jython.svn.sourceforge.net/jython/?rev=5959&view=rev Author: cgroves Date: 2009-01-22 19:50:18 +0000 (Thu, 22 Jan 2009) Log Message: ----------- Expose rich comparision methods on Java classes implementing Comparable Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py trunk/jython/src/org/python/core/PyJavaType.java Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2009-01-22 04:38:25 UTC (rev 5958) +++ trunk/jython/Lib/test/test_java_integration.py 2009-01-22 19:50:18 UTC (rev 5959) @@ -7,9 +7,10 @@ from test import test_support -from java.lang import (ExceptionInInitializerError, String, Runnable, System, Runtime, Math, Byte) +from java.lang import (ClassCastException, ExceptionInInitializerError, String, Runnable, System, + Runtime, Math, Byte) from java.math import BigDecimal, BigInteger -from java.io import (FileInputStream, FileNotFoundException, FileOutputStream, FileWriter, +from java.io import (File, FileInputStream, FileNotFoundException, FileOutputStream, FileWriter, OutputStreamWriter, UnsupportedEncodingException) from java.util import ArrayList, Date, HashMap, Hashtable, StringTokenizer, Vector @@ -350,6 +351,39 @@ for i in v: pass + def test_comparable_delegation(self): + first_file = File("a") + first_date = Date(100) + for a, b, c in [(first_file, File("b"), File("c")), (first_date, Date(1000), Date())]: + self.assertTrue(a.compareTo(b) < 0) + self.assertEquals(-1, cmp(a, b)) + self.assertTrue(a.compareTo(c) < 0) + self.assertEquals(-1, cmp(a, c)) + self.assertEquals(0, a.compareTo(a)) + self.assertEquals(0, cmp(a, a)) + self.assertTrue(b.compareTo(a) > 0) + self.assertEquals(1, cmp(b, a)) + self.assertTrue(c.compareTo(b) > 0) + self.assertEquals(1, cmp(c, b)) + self.assertTrue(a < b) + self.assertTrue(a <= a) + self.assertTrue(b > a) + self.assertTrue(c >= a) + self.assertTrue(a != b) + l = [b, c, a] + self.assertEquals(a, min(l)) + self.assertEquals(c, max(l)) + l.sort() + self.assertEquals([a, b, c], l) + # Check that we fall back to the default comparison(class name) instead of using compareTo + # on non-Comparable types + self.assertRaises(ClassCastException, first_file.compareTo, first_date) + self.assertEquals(-1, cmp(first_file, first_date)) + self.assertTrue(first_file < first_date) + self.assertTrue(first_file <= first_date) + self.assertTrue(first_date > first_file) + self.assertTrue(first_date >= first_file) + class SecurityManagerTest(unittest.TestCase): def test_nonexistent_import_with_security(self): policy = test_support.findfile("python_home.policy") Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2009-01-22 04:38:25 UTC (rev 5958) +++ trunk/jython/src/org/python/core/PyJavaType.java 2009-01-22 19:50:18 UTC (rev 5959) @@ -402,6 +402,14 @@ return proxy.equals(oAsJava) ? Py.True : Py.False; } }); + addMethod(new PyBuiltinMethodNarrow("__ne__", 1) { + @Override + public PyObject __call__(PyObject o) { + Object proxy = self.getJavaProxy(); + Object oAsJava = o.__tojava__(proxy.getClass()); + return !proxy.equals(oAsJava) ? Py.True : Py.False; + } + }); addMethod(new PyBuiltinMethodNarrow("__hash__") { @Override public PyObject __call__() { @@ -415,6 +423,32 @@ } }); } + if(forClass == Comparable.class) { + addMethod(new ComparableMethod("__lt__", 1) { + @Override + protected boolean getResult(int comparison) { + return comparison < 0; + } + }); + addMethod(new ComparableMethod("__le__", 1) { + @Override + protected boolean getResult(int comparison) { + return comparison <= 0; + } + }); + addMethod(new ComparableMethod("__gt__", 1) { + @Override + protected boolean getResult(int comparison) { + return comparison > 0; + } + }); + addMethod(new ComparableMethod("__ge__", 1) { + @Override + protected boolean getResult(int comparison) { + return comparison >= 0; + } + }); + } } /** @@ -559,6 +593,25 @@ } } + private static abstract class ComparableMethod extends PyBuiltinMethodNarrow { + protected ComparableMethod(String name, int numArgs) { + super(name, numArgs); + } + @Override + public PyObject __call__(PyObject arg) { + Object asjava = arg.__tojava__(Object.class); + int compare; + try { + compare = ((Comparable<Object>)self.getJavaProxy()).compareTo(asjava); + } catch(ClassCastException classCast) { + return Py.NotImplemented; + } + return getResult(compare) ? Py.True : Py.False; + } + + protected abstract boolean getResult(int comparison); + } + private static Map<Class<?>, PyBuiltinMethod[]> getCollectionProxies() { if (collectionProxies == null) { collectionProxies = Generic.map(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-22 04:38:29
|
Revision: 5958 http://jython.svn.sourceforge.net/jython/?rev=5958&view=rev Author: fwierzbicki Date: 2009-01-22 04:38:25 +0000 (Thu, 22 Jan 2009) Log Message: ----------- Branch to experiment with the extracted jlr package cache. Added Paths: ----------- trunk/sandbox/wierzbicki/jlr_experiment/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-22 04:16:49
|
Revision: 5957 http://jython.svn.sourceforge.net/jython/?rev=5957&view=rev Author: fwierzbicki Date: 2009-01-22 04:16:47 +0000 (Thu, 22 Jan 2009) Log Message: ----------- Thanks to Marc Downie for this patch that fixes http://bugs.jython.org/issue1230 importing with '*' from java packages does not work with 2.5b1. Also added a test to test_java_integration.py. Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py trunk/jython/src/org/python/core/packagecache/PackageManager.java trunk/jython/src/org/python/core/packagecache/PathPackageManager.java Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2009-01-22 02:21:08 UTC (rev 5956) +++ trunk/jython/Lib/test/test_java_integration.py 2009-01-22 04:16:47 UTC (rev 5957) @@ -20,6 +20,10 @@ from org.python.core.util import FileUtil from org.python.tests import BeanImplementation, Child, Listenable, CustomizableMapHolder +#Just for test_import_star +#java.util.regex was chosen for its small number of classes to reduce the pollution. +from java.util.regex import * + class InstantiationTest(unittest.TestCase): def test_cant_instantiate_abstract(self): self.assertRaises(TypeError, Component) @@ -378,6 +382,10 @@ self.assertEquals(7, m.initial) self.assertEquals(None, m.nonexistent, "Nonexistent fields should be passed on to the Map") + def test_import_star(self): + #Depends on "from java.util.regex import *" at the top. + x = Pattern.compile("foo") + self.assertEquals(x.flags(), 0) def test_main(): test_support.run_unittest(InstantiationTest, Modified: trunk/jython/src/org/python/core/packagecache/PackageManager.java =================================================================== --- trunk/jython/src/org/python/core/packagecache/PackageManager.java 2009-01-22 02:21:08 UTC (rev 5956) +++ trunk/jython/src/org/python/core/packagecache/PackageManager.java 2009-01-22 04:16:47 UTC (rev 5957) @@ -107,7 +107,7 @@ for (PyObject pyname : cls.keys().asIterable()) { if (!dict.has_key(pyname)) { String name = pyname.toString(); - jpkg.addClass(name, Py.findClass(name)); + jpkg.addClass(name, Py.findClass(jpkg.__name__ + "." + name)); } } Modified: trunk/jython/src/org/python/core/packagecache/PathPackageManager.java =================================================================== --- trunk/jython/src/org/python/core/packagecache/PathPackageManager.java 2009-01-22 02:21:08 UTC (rev 5956) +++ trunk/jython/src/org/python/core/packagecache/PathPackageManager.java 2009-01-22 04:16:47 UTC (rev 5957) @@ -164,7 +164,7 @@ if (pkgCand) { jpkg.addPackage(jname); } else { - jpkg.addClass(jname, Py.findClass(jname)); + jpkg.addClass(jname, Py.findClass(jpkg.__name__ + "." + jname)); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-22 02:21:14
|
Revision: 5956 http://jython.svn.sourceforge.net/jython/?rev=5956&view=rev Author: fwierzbicki Date: 2009-01-22 02:21:08 +0000 (Thu, 22 Jan 2009) Log Message: ----------- Fix for http://bugs.jython.org/issue1239. When jars where added to sys.path, they did not always trigger package caching, leading to unexpected import failures. This is Charlie Grove's fix, which was much better than mine. Modified Paths: -------------- trunk/jython/Lib/test/test_classpathimporter.py trunk/jython/src/org/python/core/SyspathJavaLoader.java trunk/jython/src/org/python/core/imp.java Added Paths: ----------- trunk/jython/Lib/test/bug1239.jar Added: trunk/jython/Lib/test/bug1239.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/Lib/test/bug1239.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/jython/Lib/test/test_classpathimporter.py =================================================================== --- trunk/jython/Lib/test/test_classpathimporter.py 2009-01-21 23:32:55 UTC (rev 5955) +++ trunk/jython/Lib/test/test_classpathimporter.py 2009-01-22 02:21:08 UTC (rev 5956) @@ -37,6 +37,17 @@ sys.path = ['__pyclasspath__/Lib'] self.setClassLoaderAndCheck("classimport_Lib.jar", "__pyclasspath__/Lib") + # I don't like the checked in jar file bug1239.jar. The *one* thing I + # liked about the tests in bugtests/ is that you could create a java file, + # compile it, jar it and destroy the jar when done. Maybe when we move to + # JDK 6 and can use JSR-199 to do runtime compiling, we can go back to + # that. Anyway, see http://bugs.jython.org/issue1239. In short, jars added + # with sys.path.append where not getting scanned if they start with a top + # level package we already have, like the "org" in org.python.* + def test_bug1239(self): + sys.path.append("Lib/test/bug1239.jar") + import org.test403javapackage.test403 + def test_main(): test_support.run_unittest(ClasspathImporterTestCase) Modified: trunk/jython/src/org/python/core/SyspathJavaLoader.java =================================================================== --- trunk/jython/src/org/python/core/SyspathJavaLoader.java 2009-01-21 23:32:55 UTC (rev 5955) +++ trunk/jython/src/org/python/core/SyspathJavaLoader.java 2009-01-22 02:21:08 UTC (rev 5956) @@ -50,7 +50,7 @@ PyList path = sys.path; for (int i = 0; i < path.__len__(); i++) { - PyObject entry = path.__getitem__(i); + PyObject entry = replacePathItem(sys, i, path); if (entry instanceof SyspathArchive) { SyspathArchive archive = (SyspathArchive) entry; ZipEntry ze = archive.getEntry(entryRes); @@ -65,8 +65,7 @@ } String dir = sys.getPath(entry.__str__().toString()); try { - return new BufferedInputStream(new FileInputStream(new File( - dir, res))); + return new BufferedInputStream(new FileInputStream(new File(dir, res))); } catch (IOException e) { continue; } @@ -75,11 +74,28 @@ return null; } + static PyObject replacePathItem(PySystemState sys, int idx, PyList paths) { + PyObject path = paths.__getitem__(idx); + if (path instanceof SyspathArchive) { + // already an archive + return path; + } + + try { + // this has the side affect of adding the jar to the PackageManager during the + // initialization of the SyspathArchive + path = new SyspathArchive(sys.getPath(path.toString())); + } catch (Exception e) { + return path; + } + paths.__setitem__(idx, path); + return path; + } + // override from abstract base class - protected Class loadClass(String name, boolean resolve) + protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { - // First, if the Python runtime system has a default class loader, - // defer to it. + // First, if the Python runtime system has a default class loader, defer to it. PySystemState sys = Py.getSystemState(); ClassLoader classLoader = sys.getClassLoader(); if (classLoader != null) { @@ -97,44 +113,43 @@ return Class.forName(name, true, ClassLoader.getSystemClassLoader()); } catch(ClassNotFoundException e) {} - Class c = findLoadedClass(name); + Class<?> c = findLoadedClass(name); if(c != null) { return c; } PyList path = sys.path; for(int i = 0; i < path.__len__(); i++) { - InputStream fis = null; - File file = null; - int size = 0; - PyObject entry = path.__getitem__(i); + + InputStream fis; + int size; + PyObject entry = replacePathItem(sys, i, path); if(entry instanceof SyspathArchive) { SyspathArchive archive = (SyspathArchive)entry; String entryname = name.replace('.', SLASH_CHAR) + ".class"; ZipEntry ze = archive.getEntry(entryname); - if(ze != null) { - try { - fis = archive.getInputStream(ze); - size = (int)ze.getSize(); - } catch(IOException exc) { - ; - } + if(ze == null) { + continue; } + try { + fis = archive.getInputStream(ze); + size = (int)ze.getSize(); + } catch (IOException exc) { + continue; + } } else { String dir = entry.__str__().toString(); - file = getFile(dir, name); - if(file != null) { - size = (int)file.length(); - try { - fis = new FileInputStream(file); - } catch(FileNotFoundException e) { - ; - } + File file = getFile(dir, name); + if (file == null) { + continue; } + size = (int)file.length(); + try { + fis = new FileInputStream(file); + } catch (FileNotFoundException e) { + continue; + } } - if(fis == null) { - continue; - } try { byte[] buffer = new byte[size]; int nread = 0; @@ -143,14 +158,12 @@ } fis.close(); return loadClassFromBytes(name, buffer); - } catch(IOException e) { - continue; + } catch (IOException e) { + } finally { try { fis.close(); - } catch(IOException e) { - continue; - } + } catch (IOException e) {} } } @@ -173,9 +186,9 @@ return new RelativeFile(dir, accum + ".class"); } - private Class loadClassFromBytes(String name, byte[] data) { + private Class<?> loadClassFromBytes(String name, byte[] data) { // System.err.println("loadClassFromBytes("+name+", byte[])"); - Class c = defineClass(name, data, 0, data.length); + Class<?> c = defineClass(name, data, 0, data.length); resolveClass(c); Compiler.compileClass(c); return c; Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2009-01-21 23:32:55 UTC (rev 5955) +++ trunk/jython/src/org/python/core/imp.java 2009-01-22 02:21:08 UTC (rev 5956) @@ -318,41 +318,12 @@ return importer; } - static PyObject replacePathItem(PySystemState sys, PyObject path) { - if (path instanceof SyspathArchive) { - // already an archive - return null; - } - - try { - // this has the side affect of adding the jar to the PackageManager - // during the initialization of the SyspathArchive - return new SyspathArchive(sys.getPath(path.toString())); - } catch (Exception e) { - return null; - } - } - static PyObject find_module(String name, String moduleName, PyList path) { PyObject loader = Py.None; PySystemState sys = Py.getSystemState(); PyObject metaPath = sys.meta_path; - /* - * Needed to convert all entries on the path to SyspathArchives if - * necessary. - */ - PyList ppath = path == null ? sys.path : path; - for (int i = 0; i < ppath.__len__(); i++) { - PyObject p = ppath.__getitem__(i); - PyObject q = replacePathItem(sys, p); - if (q == null) { - continue; - } - ppath.__setitem__(i, q); - } - for (PyObject importer : metaPath.asIterable()) { PyObject findModule = importer.__getattr__("find_module"); loader = findModule.__call__(new PyObject[] { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-01-21 23:32:59
|
Revision: 5955 http://jython.svn.sourceforge.net/jython/?rev=5955&view=rev Author: cgroves Date: 2009-01-21 23:32:55 +0000 (Wed, 21 Jan 2009) Log Message: ----------- Add a jython initializer service. If META-INF/services/org.python.core.JythonInitializer is on the classpath, the class named in that file will be instantiated and used in Jython's initialization. This is useful when Jython is initialized by a library outside of your control, but some customization still needs to be done to Jython's environment. I promise not to add a JythonFactory or a JythonFactoryFactory. Modified Paths: -------------- trunk/jython/build.xml trunk/jython/src/org/python/core/PySystemState.java trunk/jython/src/org/python/core/ThreadStateMapping.java Added Paths: ----------- trunk/jython/Lib/test/check_for_initializer_in_syspath.py trunk/jython/Lib/test/test_jython_initializer.py trunk/jython/src/org/python/core/JythonInitializer.java trunk/jython/tests/data/ trunk/jython/tests/data/initializer/ trunk/jython/tests/data/initializer/META-INF/ trunk/jython/tests/data/initializer/META-INF/services/ trunk/jython/tests/data/initializer/META-INF/services/org.python.core.JythonInitializer trunk/jython/tests/data/initializer/SyspathAppendingInitializer.java Added: trunk/jython/Lib/test/check_for_initializer_in_syspath.py =================================================================== --- trunk/jython/Lib/test/check_for_initializer_in_syspath.py (rev 0) +++ trunk/jython/Lib/test/check_for_initializer_in_syspath.py 2009-01-21 23:32:55 UTC (rev 5955) @@ -0,0 +1,2 @@ +import sys +assert "/from_SyspathAppendingInitializer_with_love" in sys.path Added: trunk/jython/Lib/test/test_jython_initializer.py =================================================================== --- trunk/jython/Lib/test/test_jython_initializer.py (rev 0) +++ trunk/jython/Lib/test/test_jython_initializer.py 2009-01-21 23:32:55 UTC (rev 5955) @@ -0,0 +1,17 @@ +import unittest +import subprocess +import sys +from test import test_support + +class TestUsingInitializer(unittest.TestCase): + def test_syspath_initializer(self): + fn = test_support.findfile("check_for_initializer_in_syspath.py") + ret = subprocess.Popen([sys.executable, fn], + env={"CLASSPATH":"tests/data/initializer"}).wait() + self.assertEquals(0, ret) + +def test_main(): + test_support.run_unittest(TestUsingInitializer) + +if __name__ == "__main__": + test_main() Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-01-21 21:26:50 UTC (rev 5954) +++ trunk/jython/build.xml 2009-01-21 23:32:55 UTC (rev 5955) @@ -482,7 +482,17 @@ nowarn="${nowarn}"> <classpath refid="test.classpath" /> </javac> + <javac srcdir="tests/data/initializer" + destdir="tests/data/initializer" + target="${jdk.target.version}" + source="${jdk.source.version}" + debug="${debug}" + deprecation="${deprecation}" + nowarn="${nowarn}"> + <classpath refid="test.classpath" /> + </javac> + <copy file="${source.dir}/org/python/modules/ucnhash.dat" todir="${compile.dir}/org/python/modules" preservelastmodified="true" /> Added: trunk/jython/src/org/python/core/JythonInitializer.java =================================================================== --- trunk/jython/src/org/python/core/JythonInitializer.java (rev 0) +++ trunk/jython/src/org/python/core/JythonInitializer.java 2009-01-21 23:32:55 UTC (rev 5955) @@ -0,0 +1,35 @@ +package org.python.core; + +import java.util.Properties; + +import org.python.core.adapter.ExtensiblePyObjectAdapter; + +/** + * A service for initializing Jython without explicitly calling {@link PySystemState#initialize}. If + * a file META-INF/services/org.python.core.JythonInitializer is on the classpath, Jython will + * instantiate the class named in that file and use it in Jython's initialization. The given class + * must be an implementation of this interface with a no-arg constructor. + * + * @see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">Java + Service Providers</a> + */ +public interface JythonInitializer { + + /** + * Called from {@link PySystemState#initialize} with the full set of initialization arguments. + * Implementations may modify or replace the given arguments, and must call + * {@link PySystemState#doInitialize}. + * + * @param argv + * - The command line arguments the jython interpreter was started with, or an empty + * array if jython wasn't started directly from the command line. + * @param classLoader + * - The classloader to be used by sys, or null if no sys-specific classloader was + * specified + */ + void initialize(Properties preProperties, + Properties postProperties, + String[] argv, + ClassLoader classLoader, + ExtensiblePyObjectAdapter adapter); +} Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2009-01-21 21:26:50 UTC (rev 5954) +++ trunk/jython/src/org/python/core/PySystemState.java 2009-01-21 23:32:55 UTC (rev 5955) @@ -1,11 +1,16 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; +import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.net.URL; import java.net.URLDecoder; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; import java.security.AccessControlException; import java.util.Map; import java.util.Properties; @@ -539,9 +544,6 @@ Py.writeError("systemState", "trying to reinitialize registry"); return; } - if (preProperties == null) { - preProperties = getBaseProperties(); - } registry = preProperties; String prefix = findRoot(preProperties, postProperties, jarFileName); @@ -572,9 +574,7 @@ } } catch (SecurityException e) { } - if (postProperties != null) { - registry.putAll(postProperties); - } + registry.putAll(postProperties); if (standalone) { // set default standalone property (if not yet set) if (!registry.containsKey(PYTHON_CACHEDIR_SKIP)) { @@ -642,6 +642,116 @@ if (initialized) { return; } + if (preProperties == null) { + preProperties = getBaseProperties(); + } + if (postProperties == null) { + postProperties = new Properties(); + } + try { + ClassLoader context = Thread.currentThread().getContextClassLoader(); + if (context != null) { + if (initialize(preProperties, postProperties, argv, classLoader, adapter, context)) { + return; + } + } else { + Py.writeDebug("initializer", "Context class loader null, skipping"); + } + ClassLoader sysStateLoader = PySystemState.class.getClassLoader(); + if (sysStateLoader != null) { + if (initialize(preProperties, + postProperties, + argv, + classLoader, + adapter, + sysStateLoader)) { + return; + } + } else { + Py.writeDebug("initializer", "PySystemState.class class loader null, skipping"); + } + } catch (UnsupportedCharsetException e) { + Py.writeWarning("initializer", "Unable to load the UTF-8 charset to read an initializer definition"); + e.printStackTrace(System.err); + } catch (SecurityException e) { + // Must be running in a security environment that doesn't allow access to the class + // loader + } catch (Exception e) { + Py.writeWarning("initializer", + "Unexpected exception thrown while trying to use initializer service"); + e.printStackTrace(System.err); + } + doInitialize(preProperties, postProperties, argv, classLoader, adapter); + } + + private static final String INITIALIZER_SERVICE = + "META-INF/services/org.python.core.JythonInitializer"; + + /** + * Attempts to read a SystemStateInitializer service from the given classloader, instantiate it, + * and initialize with it. + * + * @throws UnsupportedCharsetException + * if unable to load UTF-8 to read a service definition + * @return true if a service is found and successfully initializes. + */ + private static boolean initialize(Properties pre, + Properties post, + String[] argv, + ClassLoader sysClassLoader, + ExtensiblePyObjectAdapter adapter, + ClassLoader initializerClassLoader) { + InputStream in = initializerClassLoader.getResourceAsStream(INITIALIZER_SERVICE); + if (in == null) { + Py.writeDebug("initializer", "'" + INITIALIZER_SERVICE + "' not found on " + initializerClassLoader); + return false; + } + BufferedReader r = new BufferedReader(new InputStreamReader(in, Charset.forName("UTF-8"))); + String className; + try { + className = r.readLine(); + } catch (IOException e) { + Py.writeWarning("initializer", "Failed reading '" + INITIALIZER_SERVICE + "' from " + + initializerClassLoader); + e.printStackTrace(System.err); + return false; + } + Class<?> initializer; + try { + initializer = initializerClassLoader.loadClass(className); + } catch (ClassNotFoundException e) { + Py.writeWarning("initializer", "Specified initializer class '" + className + + "' not found, continuing"); + return false; + } + try { + ((JythonInitializer)initializer.newInstance()).initialize(pre, + post, + argv, + sysClassLoader, + adapter); + } catch (Exception e) { + Py.writeWarning("initializer", "Failed initializing with class '" + className + + "', continuing"); + e.printStackTrace(System.err); + return false; + } + if (!initialized) { + Py.writeWarning("initializer", "Initializer '" + className + + "' failed to call doInitialize, using default initialization"); + } + return initialized; + } + + + public static synchronized PySystemState doInitialize(Properties preProperties, + Properties postProperties, + String[] argv, + ClassLoader classLoader, + ExtensiblePyObjectAdapter adapter) { + if (initialized) { + return Py.defaultSystemState; + } initialized = true; Py.setAdapter(adapter); boolean standalone = false; @@ -663,11 +773,13 @@ // Finish up standard Python initialization... Py.defaultSystemState = new PySystemState(); Py.setSystemState(Py.defaultSystemState); - if (classLoader != null) + if (classLoader != null) { Py.defaultSystemState.setClassLoader(classLoader); + } Py.initClassExceptions(getDefaultBuiltins()); // Make sure that Exception classes have been loaded new PySyntaxError("", 1, 1, "", ""); + return Py.defaultSystemState; } private static void initStaticFields() { Modified: trunk/jython/src/org/python/core/ThreadStateMapping.java =================================================================== --- trunk/jython/src/org/python/core/ThreadStateMapping.java 2009-01-21 21:26:50 UTC (rev 5954) +++ trunk/jython/src/org/python/core/ThreadStateMapping.java 2009-01-21 23:32:55 UTC (rev 5955) @@ -9,10 +9,13 @@ return ts; } + Thread t = Thread.currentThread(); - if (newSystemState == null) { Py.writeDebug("threadstate", "no current system state"); + if (Py.defaultSystemState == null) { + PySystemState.initialize(); + } newSystemState = Py.defaultSystemState; } Property changes on: trunk/jython/tests/data/initializer ___________________________________________________________________ Added: svn:ignore + SyspathAppendingInitializer.class Added: trunk/jython/tests/data/initializer/META-INF/services/org.python.core.JythonInitializer =================================================================== --- trunk/jython/tests/data/initializer/META-INF/services/org.python.core.JythonInitializer (rev 0) +++ trunk/jython/tests/data/initializer/META-INF/services/org.python.core.JythonInitializer 2009-01-21 23:32:55 UTC (rev 5955) @@ -0,0 +1 @@ +SyspathAppendingInitializer Added: trunk/jython/tests/data/initializer/SyspathAppendingInitializer.java =================================================================== --- trunk/jython/tests/data/initializer/SyspathAppendingInitializer.java (rev 0) +++ trunk/jython/tests/data/initializer/SyspathAppendingInitializer.java 2009-01-21 23:32:55 UTC (rev 5955) @@ -0,0 +1,18 @@ +import java.util.Properties; +import org.python.core.JythonInitializer; +import org.python.core.Py; +import org.python.core.PySystemState; +import org.python.core.adapter.ExtensiblePyObjectAdapter; + +public class SyspathAppendingInitializer implements JythonInitializer { + public void initialize(Properties preProperties, + Properties postProperties, + String[] argv, + ClassLoader classLoader, + ExtensiblePyObjectAdapter adapter) { + postProperties.put(PySystemState.PYTHON_CACHEDIR_SKIP, "true"); + PySystemState defaultState = + PySystemState.doInitialize(preProperties, postProperties, argv, classLoader, adapter); + defaultState.path.append(Py.newString("/from_SyspathAppendingInitializer_with_love")); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-01-21 21:26:59
|
Revision: 5954 http://jython.svn.sourceforge.net/jython/?rev=5954&view=rev Author: cgroves Date: 2009-01-21 21:26:50 +0000 (Wed, 21 Jan 2009) Log Message: ----------- Turn includeJavaStackInExceptions on by default as it was always done in previous versions. Modified Paths: -------------- trunk/jython/src/org/python/compiler/JavaMaker.java trunk/jython/src/org/python/core/Options.java trunk/jython/src/org/python/util/jython.java Modified: trunk/jython/src/org/python/compiler/JavaMaker.java =================================================================== --- trunk/jython/src/org/python/compiler/JavaMaker.java 2009-01-21 20:47:19 UTC (rev 5953) +++ trunk/jython/src/org/python/compiler/JavaMaker.java 2009-01-21 21:26:50 UTC (rev 5954) @@ -46,13 +46,12 @@ super.addProxy(); // _initProxy method - Code code = classfile.addMethod("__initProxy__", - "([Ljava/lang/Object;)V", Modifier.PUBLIC); + Code code = classfile.addMethod("__initProxy__", "([Ljava/lang/Object;)V", Modifier.PUBLIC); code.visitVarInsn(ALOAD, 0); code.visitLdcInsn(pythonModule); code.visitLdcInsn(pythonClass); - + code.visitVarInsn(ALOAD, 1); code.visitMethodInsn(INVOKESTATIC, "org/python/core/Py", "initProxy", "(" + $pyProxy + $str + $str + $objArr + ")V"); code.visitInsn(RETURN); Modified: trunk/jython/src/org/python/core/Options.java =================================================================== --- trunk/jython/src/org/python/core/Options.java 2009-01-21 20:47:19 UTC (rev 5953) +++ trunk/jython/src/org/python/core/Options.java 2009-01-21 21:26:50 UTC (rev 5954) @@ -21,7 +21,7 @@ * trace in addition to the Python traceback. This can slow raising * considerably. */ - public static boolean includeJavaStackInExceptions = false; + public static boolean includeJavaStackInExceptions = true; /** * When true, python exception raised in overridden methods will be shown on @@ -63,7 +63,7 @@ * A directory where the dynamically generated classes are written. Nothing is * ever read from here, it is only for debugging purposes. */ - public static String proxyDebugDirectory = null; + public static String proxyDebugDirectory; /** * If true, Jython will use the first module found on sys.path where java Modified: trunk/jython/src/org/python/util/jython.java =================================================================== --- trunk/jython/src/org/python/util/jython.java 2009-01-21 20:47:19 UTC (rev 5953) +++ trunk/jython/src/org/python/util/jython.java 2009-01-21 21:26:50 UTC (rev 5954) @@ -7,6 +7,7 @@ import java.io.InputStream; import java.nio.charset.Charset; import java.util.List; +import java.util.Properties; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -131,8 +132,7 @@ } // Setup the basic python system state from these options - PySystemState.initialize(PySystemState.getBaseProperties(), - opts.properties, opts.argv); + PySystemState.initialize(PySystemState.getBaseProperties(), opts.properties, opts.argv); // Now create an interpreter InteractiveConsole interp = newInterpreter(); @@ -339,7 +339,7 @@ public boolean fixInteractive; public boolean help, version; public String[] argv; - public java.util.Properties properties; + public Properties properties; public String command; public List<String> warnoptions = Generic.list(); public String encoding; @@ -351,7 +351,7 @@ jar = fixInteractive = false; interactive = notice = true; runModule = false; - properties = new java.util.Properties(); + properties = new Properties(); help = version = false; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-01-21 20:47:33
|
Revision: 5953 http://jython.svn.sourceforge.net/jython/?rev=5953&view=rev Author: cgroves Date: 2009-01-21 20:47:19 +0000 (Wed, 21 Jan 2009) Log Message: ----------- Break out the compile method for use in subclasses Modified Paths: -------------- trunk/jython/src/org/python/util/JycompileAntTask.java Modified: trunk/jython/src/org/python/util/JycompileAntTask.java =================================================================== --- trunk/jython/src/org/python/util/JycompileAntTask.java 2009-01-21 05:02:29 UTC (rev 5952) +++ trunk/jython/src/org/python/util/JycompileAntTask.java 2009-01-21 20:47:19 UTC (rev 5953) @@ -10,6 +10,10 @@ import org.python.core.imp; import org.python.modules._py_compile; +/** + * Compiles all python files in a directory to bytecode, and writes them to another directory, + * possibly the same one. + */ public class JycompileAntTask extends GlobMatchingTask { @Override @@ -31,21 +35,30 @@ compiledFilePath += "/__init__"; } File compiled = new File(destDir, compiledFilePath + "$py.class"); - byte[] bytes; - try { - bytes = imp.compileSource(name, src); - } catch (PyException pye) { - pye.printStackTrace(); - throw new BuildException("Compile failed; see the compiler error output for details."); - } - File dir = compiled.getParentFile(); - if (!dir.exists() && !compiled.getParentFile().mkdirs()) { - throw new BuildException("Unable to make directory for compiled file: " + compiled); - } - imp.cacheCompiledSource(src.getAbsolutePath(), compiled.getAbsolutePath(), bytes); + compile(src, compiled, name); } } + /** + * Compiles the python file <code>src</code> to bytecode filling in <code>moduleName</code> as + * its name, and stores it in <code>compiled</code>. This is called by process for every file + * that's compiled, so subclasses can override this method to affect or track the compilation. + */ + protected void compile(File src, File compiled, String moduleName) { + byte[] bytes; + try { + bytes = imp.compileSource(moduleName, src); + } catch (PyException pye) { + pye.printStackTrace(); + throw new BuildException("Compile failed; see the compiler error output for details."); + } + File dir = compiled.getParentFile(); + if (!dir.exists() && !compiled.getParentFile().mkdirs()) { + throw new BuildException("Unable to make directory for compiled file: " + compiled); + } + imp.cacheCompiledSource(src.getAbsolutePath(), compiled.getAbsolutePath(), bytes); + } + protected String getFrom() { return "*.py"; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-21 05:02:31
|
Revision: 5952 http://jython.svn.sourceforge.net/jython/?rev=5952&view=rev Author: zyasoft Date: 2009-01-21 05:02:29 +0000 (Wed, 21 Jan 2009) Log Message: ----------- Fixed binary and inplace bytecodes to use the proper methods. Added block support to support iteration. Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyBytecode.java Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-20 19:29:17 UTC (rev 5951) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-21 05:02:29 UTC (rev 5952) @@ -4,7 +4,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; public class PyBytecode extends PyBaseCode { @@ -20,7 +19,7 @@ return opname; } // end debugging - + public final static int CO_MAXBLOCKS = 20; // same as in CPython public final char[] co_code; // to avoid sign issues public final PyObject[] co_consts; public final String[] co_names; @@ -83,6 +82,7 @@ return new PyList(members); } + private void throwReadonly(String name) { for (int i = 0; i < __members__.length; i++) { if (__members__[i] == name) { @@ -161,6 +161,23 @@ throw new UnsupportedOperationException("Not yet implemented"); } + private static String stringify_blocks(PyFrame f) { + if (f.f_exits == null) return "[]"; + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < f.f_blockstate[0]; i++) { + buf.append(f.f_exits[i].toString()); + } + return buf.toString(); + } + + private static void print_debug(int next_instr, int opcode, int oparg, PyStack stack, PyFrame f) { + System.err.println(count + "," + f.f_lasti + "> opcode: " + + getOpname().__getitem__(Py.newInteger(opcode)) + + (opcode > Opcode.HAVE_ARGUMENT ? ", oparg: " + oparg : "") + + ", stack: " + stack.toString() + + ", blocks: " + stringify_blocks(f)); + } + @Override protected PyObject interpret(PyFrame f) { final PyStack stack = new PyStack(); @@ -172,15 +189,15 @@ while (count < maxCount) { // XXX - replace with while(true) - f.f_lasti = next_instr++; // should have no worries about needing co_lnotab, just keep this current + next_instr += 1; + f.f_lasti = next_instr; // should have no worries about needing co_lnotab, just keep this current opcode = co_code[next_instr]; if (opcode > Opcode.HAVE_ARGUMENT) { next_instr += 2; oparg = (co_code[next_instr] << 8) + co_code[next_instr - 1]; - System.err.println(count + "," + next_instr + "> opcode: " + getOpname().__getitem__(Py.newInteger(opcode)) + ", oparg: " + oparg + ", stack: " + stack.toString()); - } else { - System.err.println(count + "," + next_instr + "> opcode: " + getOpname().__getitem__(Py.newInteger(opcode)) + ", stack: " + stack.toString()); } + print_debug(next_instr, opcode, oparg, stack, f); + count += 1; try { @@ -252,14 +269,14 @@ case Opcode.BINARY_POWER: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__pow__(b)); + stack.push(a._pow(b)); break; } case Opcode.BINARY_MULTIPLY: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__mul__(b)); + stack.push(a._mul(b)); break; } @@ -268,9 +285,9 @@ PyObject a = stack.pop(); if ((co_flags & CO_FUTUREDIVISION) == 0) { - stack.push(a.__div__(b)); + stack.push(a._div(b)); } else { - stack.push(a.__truediv__(b)); + stack.push(a._truediv(b)); } break; } @@ -278,35 +295,35 @@ case Opcode.BINARY_TRUE_DIVIDE: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__truediv__(b)); + stack.push(a._truediv(b)); break; } case Opcode.BINARY_FLOOR_DIVIDE: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__floordiv__(b)); + stack.push(a._floordiv(b)); break; } case Opcode.BINARY_MODULO: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__mod__(b)); + stack.push(a._mod(b)); break; } case Opcode.BINARY_ADD: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__add__(b)); + stack.push(a._add(b)); break; } case Opcode.BINARY_SUBTRACT: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__sub__(b)); + stack.push(a._sub(b)); break; } @@ -320,21 +337,21 @@ case Opcode.BINARY_LSHIFT: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__lshift__(b)); + stack.push(a._lshift(b)); break; } case Opcode.BINARY_RSHIFT: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__rshift__(b)); + stack.push(a._rshift(b)); break; } case Opcode.BINARY_AND: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__and__(b)); + stack.push(a._and(b)); break; } @@ -342,14 +359,14 @@ case Opcode.BINARY_XOR: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__xor__(b)); + stack.push(a._xor(b)); break; } case Opcode.BINARY_OR: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__or__(b)); + stack.push(a._or(b)); break; } @@ -370,7 +387,7 @@ case Opcode.INPLACE_MULTIPLY: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__imul__(b)); + stack.push(a._imul(b)); break; } @@ -378,9 +395,9 @@ PyObject b = stack.pop(); PyObject a = stack.pop(); if ((co_flags & CO_FUTUREDIVISION) == 0) { - stack.push(a.__idiv__(b)); + stack.push(a._idiv(b)); } else { - stack.push(a.__itruediv__(b)); + stack.push(a._itruediv(b)); } break; } @@ -388,70 +405,70 @@ case Opcode.INPLACE_TRUE_DIVIDE: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__itruediv__(b)); + stack.push(a._itruediv(b)); break; } case Opcode.INPLACE_FLOOR_DIVIDE: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__ifloordiv__(b)); + stack.push(a._ifloordiv(b)); break; } case Opcode.INPLACE_MODULO: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__imod__(b)); + stack.push(a._imod(b)); break; } case Opcode.INPLACE_ADD: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__iadd__(b)); + stack.push(a._iadd(b)); break; } case Opcode.INPLACE_SUBTRACT: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__isub__(b)); + stack.push(a._isub(b)); break; } case Opcode.INPLACE_LSHIFT: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__ilshift__(b)); + stack.push(a._ilshift(b)); break; } case Opcode.INPLACE_RSHIFT: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__irshift__(b)); + stack.push(a._irshift(b)); break; } case Opcode.INPLACE_AND: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__iand__(b)); + stack.push(a._iand(b)); break; } case Opcode.INPLACE_XOR: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__ixor__(b)); + stack.push(a._ixor(b)); break; } case Opcode.INPLACE_OR: { PyObject b = stack.pop(); PyObject a = stack.pop(); - stack.push(a.__ior__(b)); + stack.push(a._ior(b)); break; } @@ -597,6 +614,16 @@ case Opcode.YIELD_VALUE: retval = stack.pop(); + // need to implement something like this when we reenter after a yield +// code.invokevirtual("org/python/core/PyFrame", "getGeneratorInput", "()" + $obj); +// code.dup(); +// code.instanceof_("org/python/core/PyException"); +// Label done2 = new Label(); +// code.ifeq(done2); +// code.checkcast("java/lang/Throwable"); +// code.athrow(); +// code.label(done2); +// code.checkcast("org/python/core/PyObject"); why = Why.YIELD; break; @@ -617,15 +644,14 @@ break; } -// case POP_BLOCK: -// { -// PyTryBlock *b = PyFrame_BlockPop(f); -// while (STACK_LEVEL() > b->b_level) { -// v = POP(); -// Py_DECREF(v); -// } -// } -// continue; + case Opcode.POP_BLOCK: + { + PyTryBlock b = (PyTryBlock) (f.f_exits[--f.f_blockstate[0]]); + while (stack.size() > b.b_level) { + stack.pop(); + } + } + break; // // case END_FINALLY: // v = POP(); @@ -839,7 +865,7 @@ break; case Opcode.JUMP_ABSOLUTE: - next_instr = oparg; + next_instr = oparg - 1; // XXX - continue to a label is probably much better break; case Opcode.GET_ITER: { @@ -855,7 +881,9 @@ try { PyObject x = it.__iternext__(); if (x != null) { + stack.push(it); stack.push(x); + break; } } catch (PyException pye) { if (!Py.matchException(pye, Py.StopIteration)) { @@ -876,17 +904,18 @@ why = Why.CONTINUE; } break; + + case Opcode.SETUP_LOOP: + case Opcode.SETUP_EXCEPT: + case Opcode.SETUP_FINALLY: { + if (f.f_exits == null) { // allocate in the frame where they can fit! consider supporting directly in the frame + f.f_exits = new PyObject[CO_MAXBLOCKS]; // f_blockstack in CPython - a simple ArrayList might be best + f.f_blockstate = new int[]{0}; // f_iblock in CPython + } + f.f_exits[f.f_blockstate[0]++] = new PyTryBlock(opcode, next_instr + oparg, stack.size()); + break; + } // -// case SETUP_LOOP: -// case SETUP_EXCEPT: -// case SETUP_FINALLY: -// /* NOTE: If you add any new block-setup opcodes that are not try/except/finally -// handlers, you may need to update the PyGen_NeedsFinalizing() function. */ -// -// PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg, -// STACK_LEVEL()); -// continue; -// // case WITH_CLEANUP: // { // /* TOP is the context.__exit__ bound method. @@ -1069,7 +1098,7 @@ // XXX - perhaps add support for max stack size (presumably from co_stacksize) // and capacity hints - class PyStack { + private class PyStack { final List<PyObject> stack; @@ -1119,11 +1148,37 @@ Collections.rotate(lastN, n); } + int size() { + return stack.size(); + } + @Override public String toString() { return stack.toString(); } } + + private class PyTryBlock extends PyObject { // purely to sit on top of the existing PyFrame in f_exits!!! + + int b_type; /* what kind of block this is */ + + int b_handler; /* where to jump to find handler */ + + int b_level; /* value stack level to pop to */ + + + PyTryBlock(int type, int handler, int level) { + b_type = type; + b_handler = handler; + b_level = level; + } + + @Override + public String toString() { + return "[" + getOpname().__getitem__(Py.newInteger(b_type)) + "," + + b_handler + "," + b_level + "]"; + } + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2009-01-20 19:29:20
|
Revision: 5951 http://jython.svn.sourceforge.net/jython/?rev=5951&view=rev Author: leosoto Date: 2009-01-20 19:29:17 +0000 (Tue, 20 Jan 2009) Log Message: ----------- Use the new getcwdu on POSIXHandler, to avoid unnecesary conversions from unicode to bytestring. Also added getcwdu to os.__all__ Modified Paths: -------------- trunk/jython/Lib/os.py Modified: trunk/jython/Lib/os.py =================================================================== --- trunk/jython/Lib/os.py 2009-01-20 18:28:03 UTC (rev 5950) +++ trunk/jython/Lib/os.py 2009-01-20 19:29:17 UTC (rev 5951) @@ -30,8 +30,8 @@ 'O_RDWR', 'O_SYNC', 'O_TRUNC', 'O_WRONLY', 'R_OK', 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'W_OK', 'X_OK', '_exit', 'access', 'altsep', 'chdir', 'chmod', 'close', 'curdir', 'defpath', - 'environ', 'error', 'fdopen', 'getcwd', 'getegid', 'getenv', - 'geteuid', 'getgid', 'getlogin', 'getlogin', 'getpgrp', + 'environ', 'error', 'fdopen', 'getcwd', 'getcwdu', 'getegid', + 'getenv','geteuid', 'getgid', 'getlogin', 'getlogin', 'getpgrp', 'getpid', 'getppid', 'getuid', 'isatty', 'linesep', 'listdir', 'lseek', 'lstat', 'makedirs', 'mkdir', 'name', 'open', 'pardir', 'path', 'pathsep', 'popen', 'popen2', 'popen3', 'popen4', @@ -118,7 +118,7 @@ def isVerbose(self): return False def getCurrentWorkingDirectory(self): - return File(getcwd()) + return File(getcwdu()) def getEnv(self): return ['%s=%s' % (key, val) for key, val in environ.iteritems()] def getInputStream(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-20 18:28:06
|
Revision: 5950 http://jython.svn.sourceforge.net/jython/?rev=5950&view=rev Author: zyasoft Date: 2009-01-20 18:28:03 +0000 (Tue, 20 Jan 2009) Log Message: ----------- Added os.getcwdu. This fixes #1219 (necessary for Django 1.0.2 support), but not the larger question of better Unicode handling in the os module, specifically around os.path. Modified Paths: -------------- trunk/jython/Lib/os.py Modified: trunk/jython/Lib/os.py =================================================================== --- trunk/jython/Lib/os.py 2009-01-20 13:56:46 UTC (rev 5949) +++ trunk/jython/Lib/os.py 2009-01-20 18:28:03 UTC (rev 5950) @@ -251,6 +251,13 @@ """ return asPyString(sys.getCurrentWorkingDir()) +def getcwdu(): + """getcwd() -> path + + Return a unicode string representing the current working directory. + """ + return sys.getCurrentWorkingDir() + def chdir(path): """chdir(path) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-20 13:56:50
|
Revision: 5949 http://jython.svn.sourceforge.net/jython/?rev=5949&view=rev Author: zyasoft Date: 2009-01-20 13:56:46 +0000 (Tue, 20 Jan 2009) Log Message: ----------- Initial commit. Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyFrame.java branches/pbcvm/src/org/python/core/PyFunction.java branches/pbcvm/src/org/python/core/PyTableCode.java Added Paths: ----------- branches/pbcvm/src/org/python/core/Opcode.java branches/pbcvm/src/org/python/core/PyBaseCode.java branches/pbcvm/src/org/python/core/PyBytecode.java Added: branches/pbcvm/src/org/python/core/Opcode.java =================================================================== --- branches/pbcvm/src/org/python/core/Opcode.java (rev 0) +++ branches/pbcvm/src/org/python/core/Opcode.java 2009-01-20 13:56:46 UTC (rev 5949) @@ -0,0 +1,172 @@ +package org.python.core; + +// derived from CPython 2.5.2 Include/opcode.h + +public class Opcode { + + public static final int POP_TOP = 1; + public static final int ROT_TWO = 2; + public static final int ROT_THREE = 3; + public static final int DUP_TOP = 4; + public static final int ROT_FOUR = 5; + public static final int NOP = 9; + public static final int UNARY_POSITIVE = 10; + public static final int UNARY_NEGATIVE = 11; + public static final int UNARY_NOT = 12; + public static final int UNARY_CONVERT = 13; + public static final int UNARY_INVERT = 15; + public static final int LIST_APPEND = 18; + public static final int BINARY_POWER = 19; + public static final int BINARY_MULTIPLY = 20; + public static final int BINARY_DIVIDE = 21; + public static final int BINARY_MODULO = 22; + public static final int BINARY_ADD = 23; + public static final int BINARY_SUBTRACT = 24; + public static final int BINARY_SUBSCR = 25; + public static final int BINARY_FLOOR_DIVIDE = 26; + public static final int BINARY_TRUE_DIVIDE = 27; + public static final int INPLACE_FLOOR_DIVIDE = 28; + public static final int INPLACE_TRUE_DIVIDE = 29; + public static final int SLICE = 30; + /* Also uses 31-33 */ + public static final int STORE_SLICE = 40; + /* Also uses 41-43 */ + public static final int DELETE_SLICE = 50; + /* Also uses 51-53 */ + public static final int INPLACE_ADD = 55; + public static final int INPLACE_SUBTRACT = 56; + public static final int INPLACE_MULTIPLY = 57; + public static final int INPLACE_DIVIDE = 58; + public static final int INPLACE_MODULO = 59; + public static final int STORE_SUBSCR = 60; + public static final int DELETE_SUBSCR = 61; + public static final int BINARY_LSHIFT = 62; + public static final int BINARY_RSHIFT = 63; + public static final int BINARY_AND = 64; + public static final int BINARY_XOR = 65; + public static final int BINARY_OR = 66; + public static final int INPLACE_POWER = 67; + public static final int GET_ITER = 68; + public static final int PRINT_EXPR = 70; + public static final int PRINT_ITEM = 71; + public static final int PRINT_NEWLINE = 72; + public static final int PRINT_ITEM_TO = 73; + public static final int PRINT_NEWLINE_TO = 74; + public static final int INPLACE_LSHIFT = 75; + public static final int INPLACE_RSHIFT = 76; + public static final int INPLACE_AND = 77; + public static final int INPLACE_XOR = 78; + public static final int INPLACE_OR = 79; + public static final int BREAK_LOOP = 80; + public static final int WITH_CLEANUP = 81; + public static final int LOAD_LOCALS = 82; + public static final int RETURN_VALUE = 83; + public static final int IMPORT_STAR = 84; + public static final int EXEC_STMT = 85; + public static final int YIELD_VALUE = 86; + public static final int POP_BLOCK = 87; + public static final int END_FINALLY = 88; + public static final int BUILD_CLASS = 89; + public static final int HAVE_ARGUMENT = 90; /* Opcodes from here have an argument: */ + + public static final int STORE_NAME = 90; /* Index in name list */ + + public static final int DELETE_NAME = 91; /* "" */ + + public static final int UNPACK_SEQUENCE = 92; /* Number of sequence items */ + + public static final int FOR_ITER = 93; + public static final int STORE_ATTR = 95; /* Index in name list */ + + public static final int DELETE_ATTR = 96; /* "" */ + + public static final int STORE_GLOBAL = 97; /* "" */ + + public static final int DELETE_GLOBAL = 98; /* "" */ + + public static final int DUP_TOPX = 99; /* number of items to duplicate */ + + public static final int LOAD_CONST = 100; /* Index in const list */ + + public static final int LOAD_NAME = 101; /* Index in name list */ + + public static final int BUILD_TUPLE = 102; /* Number of tuple items */ + + public static final int BUILD_LIST = 103; /* Number of list items */ + + public static final int BUILD_MAP = 104; /* Always zero for now */ + + public static final int LOAD_ATTR = 105; /* Index in name list */ + + public static final int COMPARE_OP = 106; /* Comparison operator */ + + public static final int IMPORT_NAME = 107; /* Index in name list */ + + public static final int IMPORT_FROM = 108; /* Index in name list */ + + public static final int JUMP_FORWARD = 110; /* Number of bytes to skip */ + + public static final int JUMP_IF_FALSE = 111; /* "" */ + + public static final int JUMP_IF_TRUE = 112; /* "" */ + + public static final int JUMP_ABSOLUTE = 113; /* Target byte offset from beginning of code */ + + public static final int LOAD_GLOBAL = 116; /* Index in name list */ + + public static final int CONTINUE_LOOP = 119; /* Start of loop (absolute) */ + + public static final int SETUP_LOOP = 120; /* Target address (absolute) */ + + public static final int SETUP_EXCEPT = 121; /* "" */ + + public static final int SETUP_FINALLY = 122; /* "" */ + + public static final int LOAD_FAST = 124; /* Local variable number */ + + public static final int STORE_FAST = 125; /* Local variable number */ + + public static final int DELETE_FAST = 126; /* Local variable number */ + + public static final int RAISE_VARARGS = 130; /* Number of raise arguments (1, 2 or 3) */ + /* CALL_FUNCTION_XXX opcodes defined below depend on this definition */ + + public static final int CALL_FUNCTION = 131; /* #args + (#kwargs<<8) */ + + public static final int MAKE_FUNCTION = 132; /* #defaults */ + + public static final int BUILD_SLICE = 133; /* Number of items */ + + public static final int MAKE_CLOSURE = 134; /* #free vars */ + + public static final int LOAD_CLOSURE = 135; /* Load free variable from closure */ + + public static final int LOAD_DEREF = 136; /* Load and dereference from closure cell */ + + public static final int STORE_DEREF = 137; /* Store into cell */ + + /* The next 3 opcodes must be contiguous and satisfy + (CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1 */ + public static final int CALL_FUNCTION_VAR = 140; /* #args + (#kwargs<<8) */ + + public static final int CALL_FUNCTION_KW = 141; /* #args + (#kwargs<<8) */ + + public static final int CALL_FUNCTION_VAR_KW = 142; /* #args + (#kwargs<<8) */ + + /* Support for opargs more than 16 bits long */ + public static final int EXTENDED_ARG = 143; + + // comparison opcodes (on the oparg), just put in this class too + public static final int PyCmp_LT = 0; + public static final int PyCmp_LE = 1; + public static final int PyCmp_EQ = 2; + public static final int PyCmp_NE = 3; + public static final int PyCmp_GT = 4; + public static final int PyCmp_GE = 5; + public static final int PyCmp_IN = 6; + public static final int PyCmp_NOT_IN = 7; + public static final int PyCmp_IS = 8; + public static final int PyCmp_IS_NOT = 9; + public static final int PyCmp_EXC_MATCH = 10; + +} Added: branches/pbcvm/src/org/python/core/PyBaseCode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBaseCode.java (rev 0) +++ branches/pbcvm/src/org/python/core/PyBaseCode.java 2009-01-20 13:56:46 UTC (rev 5949) @@ -0,0 +1,314 @@ +// Copyright (c) Corporation for National Research Initiatives +package org.python.core; + +import org.python.modules._systemrestart; + +public abstract class PyBaseCode extends PyCode { + + public int co_argcount; + int nargs; + public int co_firstlineno = -1; + public String co_varnames[]; + public String co_cellvars[]; + public int jy_npurecell; // internal: jython specific + public String co_freevars[]; + public String co_filename; + public int co_flags; + public int co_nlocals; + public boolean varargs, varkwargs; + + final public static int CO_OPTIMIZED = 0x0001; + //final public static int CO_NEWLOCALS = 0x0002 + final public static int CO_VARARGS = 0x0004; + final public static int CO_VARKEYWORDS = 0x0008; + final public static int CO_GENERATOR = 0x0020; + + // these are defined in __future__.py + final public static int CO_NESTED = 0x0010; + final public static int CO_GENERATOR_ALLOWED = 0x0; + final public static int CO_FUTUREDIVISION = 0x2000; + final public static int CO_FUTURE_ABSOLUTE_IMPORT = 0x4000; + final public static int CO_WITH_STATEMENT = 0x8000; + + //XXX: I'm not positive that this is the right place for these constants. + final public static int PyCF_SOURCE_IS_UTF8 = 0x0100; + final public static int PyCF_DONT_IMPLY_DEDENT = 0x0200; + final public static int PyCF_ONLY_AST = 0x0400; + + final public static int CO_ALL_FEATURES = PyCF_DONT_IMPLY_DEDENT|PyCF_ONLY_AST| + PyCF_SOURCE_IS_UTF8|CO_NESTED| + CO_GENERATOR_ALLOWED| CO_FUTUREDIVISION| + CO_FUTURE_ABSOLUTE_IMPORT|CO_WITH_STATEMENT; + + + public boolean hasFreevars() { + return co_freevars != null && co_freevars.length > 0; + } + + public PyObject call(PyFrame frame, PyObject closure) { +// System.err.println("tablecode call: "+co_name); + ThreadState ts = Py.getThreadState(); + if (ts.systemState == null) { + ts.systemState = Py.defaultSystemState; + } + //System.err.println("got ts: "+ts+", "+ts.systemState); + + // Cache previously defined exception + PyException previous_exception = ts.exception; + + // Push frame + frame.f_back = ts.frame; + if (frame.f_builtins == null) { + if (frame.f_back != null) { + frame.f_builtins = frame.f_back.f_builtins; + } else { + //System.err.println("ts: "+ts); + //System.err.println("ss: "+ts.systemState); + frame.f_builtins = PySystemState.builtins; + } + } + // nested scopes: setup env with closure + // this should only be done once, so let the frame take care of it + frame.setupEnv((PyTuple)closure); + + ts.frame = frame; + + // Handle trace function for debugging + if (ts.tracefunc != null) { + frame.f_lineno = co_firstlineno; + frame.tracefunc = ts.tracefunc.traceCall(frame); + } + + // Handle trace function for profiling + if (ts.profilefunc != null) { + ts.profilefunc.traceCall(frame); + } + + PyObject ret; + try { + ret = interpret(frame); + } catch (Throwable t) { + // Convert exceptions that occured in Java code to PyExceptions + PyException pye = Py.JavaError(t); + pye.tracebackHere(frame); + + frame.f_lasti = -1; + + if (frame.tracefunc != null) { + frame.tracefunc.traceException(frame, pye); + } + if (ts.profilefunc != null) { + ts.profilefunc.traceException(frame, pye); + } + + // Rethrow the exception to the next stack frame + ts.exception = previous_exception; + ts.frame = ts.frame.f_back; + throw pye; + } + + if (frame.tracefunc != null) { + frame.tracefunc.traceReturn(frame, ret); + } + // Handle trace function for profiling + if (ts.profilefunc != null) { + ts.profilefunc.traceReturn(frame, ret); + } + + // Restore previously defined exception + ts.exception = previous_exception; + + ts.frame = ts.frame.f_back; + + // Check for interruption, which is used for restarting the interpreter + // on Jython + if (Thread.currentThread().isInterrupted()) { + throw new PyException(_systemrestart.SystemRestart); + } + return ret; + } + + public PyObject call(PyObject globals, PyObject[] defaults, + PyObject closure) + { + if (co_argcount != 0 || varargs || varkwargs) + return call(Py.EmptyObjects, Py.NoKeywords, globals, defaults, + closure); + PyFrame frame = new PyFrame(this, globals); + if ((co_flags & CO_GENERATOR) != 0) { + return new PyGenerator(frame, closure); + } + return call(frame, closure); + } + + public PyObject call(PyObject arg1, PyObject globals, PyObject[] defaults, + PyObject closure) + { + if (co_argcount != 1 || varargs || varkwargs) + return call(new PyObject[] {arg1}, + Py.NoKeywords, globals, defaults, closure); + PyFrame frame = new PyFrame(this, globals); + frame.f_fastlocals[0] = arg1; + if ((co_flags & CO_GENERATOR) != 0) { + return new PyGenerator(frame, closure); + } + return call(frame, closure); + } + + public PyObject call(PyObject arg1, PyObject arg2, PyObject globals, + PyObject[] defaults, PyObject closure) + { + if (co_argcount != 2 || varargs || varkwargs) + return call(new PyObject[] {arg1, arg2}, + Py.NoKeywords, globals, defaults, closure); + PyFrame frame = new PyFrame(this, globals); + frame.f_fastlocals[0] = arg1; + frame.f_fastlocals[1] = arg2; + if ((co_flags & CO_GENERATOR) != 0) { + return new PyGenerator(frame, closure); + } + return call(frame, closure); + } + + public PyObject call(PyObject arg1, PyObject arg2, PyObject arg3, + PyObject globals, PyObject[] defaults, + PyObject closure) + { + if (co_argcount != 3 || varargs || varkwargs) + return call(new PyObject[] {arg1, arg2, arg3}, + Py.NoKeywords, globals, defaults, closure); + PyFrame frame = new PyFrame(this, globals); + frame.f_fastlocals[0] = arg1; + frame.f_fastlocals[1] = arg2; + frame.f_fastlocals[2] = arg3; + if ((co_flags & CO_GENERATOR) != 0) { + return new PyGenerator(frame, closure); + } + return call(frame, closure); + } + + public PyObject call(PyObject self, PyObject args[], + String keywords[], PyObject globals, + PyObject[] defaults, PyObject closure) + { + PyObject[] os = new PyObject[args.length+1]; + os[0] = self; + System.arraycopy(args, 0, os, 1, args.length); + return call(os, keywords, globals, defaults, closure); + } + + public PyObject call(PyObject args[], String kws[], PyObject globals, PyObject[] defs, + PyObject closure) { + PyFrame frame = new PyFrame(this, globals); + int argcount = args.length - kws.length; + int defcount = defs != null ? defs.length : 0; + PyObject[] fastlocals = frame.f_fastlocals; + + if (co_argcount > 0 || (varargs || varkwargs)) { + int i; + int n = argcount; + PyObject kwdict = null; + if (varkwargs) { + kwdict = new PyDictionary(); + i = co_argcount; + if (varargs) { + i++; + } + fastlocals[i] = kwdict; + } + if (argcount > co_argcount) { + if (!varargs) { + String msg = String.format("%.200s() takes %s %d %sargument%s (%d given)", + co_name, + defcount > 0 ? "at most" : "exactly", + co_argcount, + kws.length > 0 ? "non-keyword " : "", + co_argcount == 1 ? "" : "s", + argcount); + throw Py.TypeError(msg); + } + n = co_argcount; + } + + System.arraycopy(args, 0, fastlocals, 0, n); + + if (varargs) { + PyObject[] u = new PyObject[argcount - n]; + System.arraycopy(args, n, u, 0, argcount - n); + PyObject uTuple = new PyTuple(u); + fastlocals[co_argcount] = uTuple; + } + for (i = 0; i < kws.length; i++) { + String keyword = kws[i]; + PyObject value = args[i + argcount]; + int j; + // XXX: keywords aren't PyObjects, can't ensure strings + //if (keyword == null || keyword.getClass() != PyString.class) { + // throw Py.TypeError(String.format("%.200s() keywords must be strings", + // co_name)); + //} + for (j = 0; j < co_argcount; j++) { + if (co_varnames[j].equals(keyword)) { + break; + } + } + if (j >= co_argcount) { + if (kwdict == null) { + throw Py.TypeError(String.format("%.200s() got an unexpected keyword " + + "argument '%.400s'", + co_name, keyword)); + } + kwdict.__setitem__(keyword, value); + } else { + if (fastlocals[j] != null) { + throw Py.TypeError(String.format("%.200s() got multiple values for " + + "keyword argument '%.400s'", + co_name, keyword)); + } + fastlocals[j] = value; + } + } + if (argcount < co_argcount) { + int m = co_argcount - defcount; + for (i = argcount; i < m; i++) { + if (fastlocals[i] == null) { + String msg = + String.format("%.200s() takes %s %d %sargument%s (%d given)", + co_name, (varargs || defcount > 0) ? + "at least" : "exactly", + m, kws.length > 0 ? "non-keyword " : "", + m == 1 ? "" : "s", i); + throw Py.TypeError(msg); + } + } + if (n > m) { + i = n - m; + } else { + i = 0; + } + for (; i < defcount; i++) { + if (fastlocals[m + i] == null) { + fastlocals[m + i] = defs[i]; + } + } + } + } else if (argcount > 0) { + throw Py.TypeError(String.format("%.200s() takes no arguments (%d given)", + co_name, argcount)); + } + + if ((co_flags & CO_GENERATOR) != 0) { + return new PyGenerator(frame, closure); + } + return call(frame, closure); + } + + public String toString() { + return String.format("<code object %.100s at %s, file \"%.300s\", line %d>", + co_name, Py.idstr(this), co_filename, co_firstlineno); + } + + protected PyObject interpret(PyFrame f) { + throw new UnsupportedOperationException("interpret not supported"); + } +} Added: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java (rev 0) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-20 13:56:46 UTC (rev 5949) @@ -0,0 +1,1129 @@ +package org.python.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class PyBytecode extends PyBaseCode { + + // for debugging + static int count = 0; // total number of opcodes run + final static int maxCount = 900; // less than my buffer on iterm + static PyObject opname; + + static synchronized PyObject getOpname() { + if (opname == null) { + opname = __builtin__.__import__("dis").__getattr__("opname"); + } + return opname; + } + // end debugging + + public final char[] co_code; // to avoid sign issues + public final PyObject[] co_consts; + public final String[] co_names; + public final int co_stacksize; // ignored, probably shouldn't be + public final PyObject[] co_lnotab; // ignored + + // follows new.code's interface + public PyBytecode(int argcount, int nlocals, int stacksize, int flags, + String codestring, PyObject[] constants, String[] names, String varnames[], + String filename, String name, int firstlineno, PyObject[] lnotab) { + this(argcount, nlocals, stacksize, flags, codestring, + constants, names, varnames, filename, name, firstlineno, lnotab, + null, null); + } + + public PyBytecode(int argcount, int nlocals, int stacksize, int flags, + String codestring, PyObject[] constants, String[] names, String varnames[], + String filename, String name, int firstlineno, PyObject[] lnotab, + String[] cellvars, String[] freevars) { + co_argcount = nargs = argcount; + co_varnames = varnames; + co_nlocals = nlocals; // maybe assert = varnames.length; + co_filename = filename; + co_firstlineno = firstlineno; + co_cellvars = cellvars; + co_freevars = freevars; + co_name = name; + +// need to look at how this is used, since it's not part of the standard new.code interface +// this.varargs = varargs; +// if (varargs) { +// co_argcount -= 1; +// co_flags |= CO_VARARGS; +// } +// this.varkwargs = varkwargs; +// if (varkwargs) { +// co_argcount -= 1; +// co_flags |= CO_VARKEYWORDS; +// } + co_flags |= flags; + + co_stacksize = stacksize; + co_consts = constants; + co_names = names; + co_code = codestring.toCharArray(); + co_lnotab = lnotab; + } + private static final String[] __members__ = { + "co_name", "co_argcount", + "co_varnames", "co_filename", "co_firstlineno", + "co_flags", "co_cellvars", "co_freevars", "co_nlocals", + "co_code", "co_consts", "co_names", "co_lnotab", "co_stacksize" + }; + + public PyObject __dir__() { + PyString members[] = new PyString[__members__.length]; + for (int i = 0; i < __members__.length; i++) { + members[i] = new PyString(__members__[i]); + } + return new PyList(members); + } + + private void throwReadonly(String name) { + for (int i = 0; i < __members__.length; i++) { + if (__members__[i] == name) { + throw Py.TypeError("readonly attribute"); + } + } + throw Py.AttributeError(name); + } + + public void __setattr__(String name, PyObject value) { + // no writable attributes + throwReadonly(name); + } + + public void __delattr__(String name) { + throwReadonly(name); + } + + private static PyTuple toPyStringTuple(String[] ar) { + if (ar == null) { + return Py.EmptyTuple; + } + int sz = ar.length; + PyString[] pystr = new PyString[sz]; + for (int i = 0; i < sz; i++) { + pystr[i] = new PyString(ar[i]); + } + return new PyTuple(pystr); + } + + public PyObject __findattr_ex__(String name) { + // have to craft co_varnames specially + if (name == "co_varnames") { + return toPyStringTuple(co_varnames); + } + if (name == "co_cellvars") { + return toPyStringTuple(co_cellvars); + } + if (name == "co_freevars") { + return toPyStringTuple(co_freevars); + } + if (name == "co_filename") { + return new PyString(co_filename); + } + if (name == "co_name") { + return new PyString(co_name); + } + return super.__findattr_ex__(name); + } + + enum Why { + + NOT, /* No error */ + EXCEPTION, /* Exception occurred */ + RERAISE, /* Exception re-raised by 'finally' */ + RETURN, /* 'return' statement */ + BREAK, /* 'break' statement */ + CONTINUE, /* 'continue' statement */ + YIELD /* 'yield' operator */ + + }; + + private Why do_raise() { + throw new UnsupportedOperationException("Not yet implemented"); + } + + private Why do_raise(PyObject type) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + private Why do_raise(PyObject type, PyObject value) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + private Why do_raise(PyObject type, PyObject value, PyObject traceback) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + protected PyObject interpret(PyFrame f) { + final PyStack stack = new PyStack(); + int next_instr = -1; + int opcode; /* Current opcode */ + int oparg = 0; /* Current opcode argument, if any */ + Why why = Why.NOT; + PyObject retval = null; + + while (count < maxCount) { // XXX - replace with while(true) + + f.f_lasti = next_instr++; // should have no worries about needing co_lnotab, just keep this current + opcode = co_code[next_instr]; + if (opcode > Opcode.HAVE_ARGUMENT) { + next_instr += 2; + oparg = (co_code[next_instr] << 8) + co_code[next_instr - 1]; + System.err.println(count + "," + next_instr + "> opcode: " + getOpname().__getitem__(Py.newInteger(opcode)) + ", oparg: " + oparg + ", stack: " + stack.toString()); + } else { + System.err.println(count + "," + next_instr + "> opcode: " + getOpname().__getitem__(Py.newInteger(opcode)) + ", stack: " + stack.toString()); + } + count += 1; + + try { + switch (opcode) { + case Opcode.NOP: + break; + + case Opcode.LOAD_FAST: + stack.push(f.getlocal(oparg)); + break; + + case Opcode.LOAD_CONST: + stack.push(co_consts[oparg]); + break; + + case Opcode.STORE_FAST: + f.setlocal(oparg, stack.pop()); + break; + + case Opcode.POP_TOP: + stack.pop(); + break; + + case Opcode.ROT_TWO: + stack.rotN(2); + break; + + case Opcode.ROT_THREE: + stack.rotN(3); + break; + + case Opcode.ROT_FOUR: + stack.rotN(4); + break; + + case Opcode.DUP_TOP: + stack.dup(); + break; + + case Opcode.DUP_TOPX: + if (oparg == 2 || oparg == 3) { + stack.dupN(oparg); + } else { + throw Py.RuntimeError("invalid argument to DUP_TOPX" + + " (bytecode corruption?)"); + } + break; + + case Opcode.UNARY_POSITIVE: + stack.push(stack.pop().__pos__()); + break; + + case Opcode.UNARY_NEGATIVE: + stack.push(stack.pop().__neg__()); + break; + + case Opcode.UNARY_NOT: + stack.push(stack.pop().__not__()); + break; + + case Opcode.UNARY_CONVERT: + stack.push(stack.pop().__repr__()); + break; + + case Opcode.UNARY_INVERT: + stack.push(stack.pop().__invert__()); + break; + + case Opcode.BINARY_POWER: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__pow__(b)); + break; + } + + case Opcode.BINARY_MULTIPLY: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__mul__(b)); + break; + } + + case Opcode.BINARY_DIVIDE: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + + if ((co_flags & CO_FUTUREDIVISION) == 0) { + stack.push(a.__div__(b)); + } else { + stack.push(a.__truediv__(b)); + } + break; + } + + case Opcode.BINARY_TRUE_DIVIDE: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__truediv__(b)); + break; + } + + case Opcode.BINARY_FLOOR_DIVIDE: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__floordiv__(b)); + break; + } + + case Opcode.BINARY_MODULO: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__mod__(b)); + break; + } + + case Opcode.BINARY_ADD: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__add__(b)); + break; + } + + case Opcode.BINARY_SUBTRACT: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__sub__(b)); + break; + } + + case Opcode.BINARY_SUBSCR: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__getitem__(b)); + break; + } + + case Opcode.BINARY_LSHIFT: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__lshift__(b)); + break; + } + + case Opcode.BINARY_RSHIFT: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__rshift__(b)); + break; + } + + case Opcode.BINARY_AND: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__and__(b)); + break; + } + + + case Opcode.BINARY_XOR: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__xor__(b)); + break; + } + + case Opcode.BINARY_OR: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__or__(b)); + break; + } + + case Opcode.LIST_APPEND: { + PyObject b = stack.pop(); + PyList a = (PyList) (stack.pop()); + a.append(b); + break; + } + + case Opcode.INPLACE_POWER: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__ipow__(b)); + break; + } + + case Opcode.INPLACE_MULTIPLY: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__imul__(b)); + break; + } + + case Opcode.INPLACE_DIVIDE: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + if ((co_flags & CO_FUTUREDIVISION) == 0) { + stack.push(a.__idiv__(b)); + } else { + stack.push(a.__itruediv__(b)); + } + break; + } + + case Opcode.INPLACE_TRUE_DIVIDE: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__itruediv__(b)); + break; + } + + case Opcode.INPLACE_FLOOR_DIVIDE: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__ifloordiv__(b)); + break; + } + + case Opcode.INPLACE_MODULO: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__imod__(b)); + break; + } + + case Opcode.INPLACE_ADD: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__iadd__(b)); + break; + } + + case Opcode.INPLACE_SUBTRACT: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__isub__(b)); + break; + } + + case Opcode.INPLACE_LSHIFT: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__ilshift__(b)); + break; + } + + case Opcode.INPLACE_RSHIFT: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__irshift__(b)); + break; + } + + case Opcode.INPLACE_AND: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__iand__(b)); + break; + } + + case Opcode.INPLACE_XOR: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__ixor__(b)); + break; + } + + case Opcode.INPLACE_OR: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + stack.push(a.__ior__(b)); + break; + } + +// +// case SLICE+0: +// case SLICE+1: +// case SLICE+2: +// case SLICE+3: +// if ((opcode-SLICE) & 2) +// w = POP(); +// else +// w = NULL; +// if ((opcode-SLICE) & 1) +// v = POP(); +// else +// v = NULL; +// u = TOP(); +// x = apply_slice(u, v, w); +// Py_DECREF(u); +// Py_XDECREF(v); +// Py_XDECREF(w); +// SET_TOP(x); +// if (x != NULL) continue; +// break; +// +// case Opcode.STORE_SLICE+0: +// case Opcode.STORE_SLICE+1: +// case Opcode.STORE_SLICE+2: +// case Opcode.STORE_SLICE+3: +// if (((opcode - Opcode.STORE_SLICE) & 2) !=0) { +// +// } +// w = POP(); +// else +// w = NULL; +// if ((opcode-STORE_SLICE) & 1) +// v = POP(); +// else +// v = NULL; +// u = POP(); +// t = POP(); +// err = assign_slice(u, v, w, t); /* u[v:w] = t */ +// Py_DECREF(t); +// Py_DECREF(u); +// Py_XDECREF(v); +// Py_XDECREF(w); +// if (err == 0) continue; +// break; +// +// case DELETE_SLICE+0: +// case DELETE_SLICE+1: +// case DELETE_SLICE+2: +// case DELETE_SLICE+3: +// if ((opcode-DELETE_SLICE) & 2) +// w = POP(); +// else +// w = NULL; +// if ((opcode-DELETE_SLICE) & 1) +// v = POP(); +// else +// v = NULL; +// u = POP(); +// err = assign_slice(u, v, w, (PyObject *)NULL); +// /* del u[v:w] */ +// Py_DECREF(u); +// Py_XDECREF(v); +// Py_XDECREF(w); +// if (err == 0) continue; +// break; +// + case Opcode.STORE_SUBSCR: { + PyObject key = stack.pop(); + PyObject obj = stack.pop(); + PyObject value = stack.pop(); + obj.__setitem__(key, value); + break; + } + + case Opcode.DELETE_SUBSCR: { + PyObject key = stack.pop(); + PyObject obj = stack.pop(); + obj.__delitem__(key); + break; + } + + case Opcode.PRINT_EXPR: + PySystemState.displayhook(stack.pop()); + break; + + case Opcode.PRINT_ITEM_TO: + Py.printComma(stack.pop(), stack.pop()); + break; + + case Opcode.PRINT_ITEM: + Py.printComma(stack.pop()); + break; + + case Opcode.PRINT_NEWLINE_TO: + Py.printlnv(stack.pop()); + break; + + case Opcode.PRINT_NEWLINE: + Py.println(); + break; + + case Opcode.RAISE_VARARGS: + + switch (oparg) { + case 3: { + PyObject tb = stack.pop(); + PyObject value = stack.pop(); + PyObject type = stack.pop(); + why = do_raise(type, value, tb); + break; + } + case 2: { + PyObject value = stack.pop(); + PyObject type = stack.pop(); + why = do_raise(type, value); + break; + } + case 1: { + PyObject type = stack.pop(); + why = do_raise(type); + break; + } + case 0: + why = do_raise(); + break; + default: + throw Py.SystemError("bad RAISE_VARARGS oparg"); + } + break; + + case Opcode.LOAD_LOCALS: + stack.push(f.f_locals); + break; + + case Opcode.RETURN_VALUE: + retval = stack.pop(); + why = Why.RETURN; + break; + + case Opcode.YIELD_VALUE: + retval = stack.pop(); + why = Why.YIELD; + break; + + case Opcode.EXEC_STMT: { + PyObject locals = stack.pop(); + PyObject globals = stack.pop(); + PyObject code = stack.pop(); + + if ((locals == null || locals == Py.None) && + (globals == null || globals == Py.None)) { + throw Py.SystemError("globals and locals cannot be NULL"); + } + Py.exec(code, globals, locals); + + if (!(globals.__finditem__("__builtins__").__nonzero__())) { + globals.__setitem__("__builtins__", f.f_builtins); + } + break; + } + +// case POP_BLOCK: +// { +// PyTryBlock *b = PyFrame_BlockPop(f); +// while (STACK_LEVEL() > b->b_level) { +// v = POP(); +// Py_DECREF(v); +// } +// } +// continue; +// +// case END_FINALLY: +// v = POP(); +// if (PyInt_Check(v)) { +// why = (enum why_code) PyInt_AS_LONG(v); +// assert(why != WHY_YIELD); +// if (why == WHY_RETURN || +// why == WHY_CONTINUE) +// retval = POP(); +// } +// else if (PyExceptionClass_Check(v) || PyString_Check(v)) { +// w = POP(); +// u = POP(); +// PyErr_Restore(v, w, u); +// why = WHY_RERAISE; +// break; +// } +// else if (v != Py_None) { +// PyErr_SetString(PyExc_SystemError, +// "'finally' pops bad exception"); +// why = WHY_EXCEPTION; +// } +// Py_DECREF(v); +// break; +// + case Opcode.BUILD_CLASS: { + PyObject methods = stack.pop(); + PyObject bases[] = (new PyTuple(stack.pop())).getArray(); + String name = stack.pop().toString(); + stack.push(Py.makeClass(name, bases, methods)); + break; + } + + case Opcode.STORE_NAME: + f.setlocal(oparg, stack.pop()); + break; + + case Opcode.DELETE_NAME: + f.dellocal(oparg); + break; + + case Opcode.UNPACK_SEQUENCE: { + PyObject v = stack.pop(); + int i = 0; + PyObject items[] = new PyObject[oparg]; + for (PyObject item : v.asIterable()) { + items[i++] = item; + if (i > oparg) { + break; + } + } + for (i = i - 1; i >= 0; i--) { + stack.push(items[i]); + } + break; + } + + case Opcode.STORE_ATTR: { + PyObject obj = stack.pop(); + PyObject v = stack.pop(); + obj.__setattr__(co_names[oparg], v); + break; + } + + case Opcode.DELETE_ATTR: + stack.pop().__delattr__(co_names[oparg]); + break; + + case Opcode.STORE_GLOBAL: + f.setglobal(co_names[oparg], stack.pop()); + break; + + case Opcode.DELETE_GLOBAL: + f.delglobal(co_names[oparg]); + break; + + case Opcode.LOAD_NAME: + stack.push(f.getname(co_names[oparg])); + break; + + case Opcode.LOAD_GLOBAL: + stack.push(f.getglobal(co_names[oparg])); + break; + + case Opcode.DELETE_FAST: + f.dellocal(oparg); + break; + + case Opcode.LOAD_CLOSURE: + stack.push(f.getclosure(oparg)); + break; + + case Opcode.LOAD_DEREF: + stack.push(f.getderef(oparg)); + break; + + case Opcode.STORE_DEREF: + f.setderef(oparg, stack.pop()); + break; + + case Opcode.BUILD_TUPLE: + stack.push(new PyTuple(stack.popN(oparg))); + break; + + case Opcode.BUILD_LIST: + stack.push(new PyList(stack.popN(oparg))); + break; + + case Opcode.BUILD_MAP: + stack.push(new PyDictionary()); + + case Opcode.LOAD_ATTR: + stack.push(stack.pop().__getattr__(co_names[oparg])); + break; + + case Opcode.COMPARE_OP: { + PyObject b = stack.pop(); + PyObject a = stack.pop(); + + switch (oparg) { + + case Opcode.PyCmp_LT: + stack.push(a._lt(b)); + break; + case Opcode.PyCmp_LE: + stack.push(a._le(b)); + break; + case Opcode.PyCmp_EQ: + stack.push(a._eq(b)); + break; + case Opcode.PyCmp_NE: + stack.push(a._ne(b)); + break; + case Opcode.PyCmp_GT: + stack.push(a._gt(b)); + break; + case Opcode.PyCmp_GE: + stack.push(a._ge(b)); + break; + case Opcode.PyCmp_IN: + stack.push(a._in(b)); + break; + case Opcode.PyCmp_NOT_IN: + stack.push(a._notin(b)); + break; + case Opcode.PyCmp_IS: + stack.push(a._is(b)); + break; + case Opcode.PyCmp_IS_NOT: + stack.push(a._isnot(b)); + break; + case Opcode.PyCmp_EXC_MATCH: + stack.push(Py.newBoolean(Py.matchException(new PyException(a), b))); + break; + + } + break; + } + + case Opcode.IMPORT_NAME: { + PyObject __import__ = f.f_builtins.__finditem__("__import__"); + if (__import__ == null) { + throw Py.ImportError("__import__ not found"); + } + PyString name = Py.newString(co_names[oparg]); + PyObject fromlist = stack.pop(); + PyObject level = stack.pop(); + + if (level.asInt() != -1) { + stack.push(__import__.__call__(new PyObject[]{name, f.f_globals, f.f_locals, fromlist, level})); + } else { + stack.push(__import__.__call__(new PyObject[]{name, f.f_globals, f.f_locals, fromlist})); + } + break; + } + + case Opcode.IMPORT_STAR: { + String module = stack.pop().toString(); + imp.importAll(module, f); + break; + } + + case Opcode.IMPORT_FROM: + String name = co_names[oparg]; + try { + stack.push(stack.pop().__getattr__(name)); + + } catch (PyException pye) { + if (Py.matchException(pye, Py.AttributeError)) { + throw Py.ImportError(String.format("cannot import name %.230s", name)); + } else { + throw pye; + } + } + break; + + case Opcode.JUMP_FORWARD: + next_instr += oparg; + break; + + case Opcode.JUMP_IF_FALSE: + if (!stack.top().__nonzero__()) { + next_instr += oparg; + } + break; + + case Opcode.JUMP_IF_TRUE: + if (stack.top().__nonzero__()) { + next_instr += oparg; + } + break; + + case Opcode.JUMP_ABSOLUTE: + next_instr = oparg; + break; + + case Opcode.GET_ITER: { + PyObject it = stack.top().__iter__(); + if (it != null) { + stack.set_top(it); + } + break; + } + + case Opcode.FOR_ITER: { + PyObject it = stack.pop(); + try { + PyObject x = it.__iternext__(); + if (x != null) { + stack.push(x); + } + } catch (PyException pye) { + if (!Py.matchException(pye, Py.StopIteration)) { + throw pye; + } + } + next_instr += oparg; + break; + } + + case Opcode.BREAK_LOOP: + why = Why.BREAK; + break; + + case Opcode.CONTINUE_LOOP: + retval = Py.newInteger(oparg); + if (retval.__nonzero__()) { + why = Why.CONTINUE; + } + break; +// +// case SETUP_LOOP: +// case SETUP_EXCEPT: +// case SETUP_FINALLY: +// /* NOTE: If you add any new block-setup opcodes that are not try/except/finally +// handlers, you may need to update the PyGen_NeedsFinalizing() function. */ +// +// PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg, +// STACK_LEVEL()); +// continue; +// +// case WITH_CLEANUP: +// { +// /* TOP is the context.__exit__ bound method. +// Below that are 1-3 values indicating how/why +// we entered the finally clause: +// - SECOND = None +// - (SECOND, THIRD) = (WHY_{RETURN,CONTINUE}), retval +// - SECOND = WHY_*; no retval below it +// - (SECOND, THIRD, FOURTH) = exc_info() +// In the last case, we must call +// TOP(SECOND, THIRD, FOURTH) +// otherwise we must call +// TOP(None, None, None) +// +// In addition, if the stack represents an exception, +// *and* the function call returns a 'true' value, we +// "zap" this information, to prevent END_FINALLY from +// re-raising the exception. (But non-local gotos +// should still be resumed.) +// */ +// +// x = TOP(); +// u = SECOND(); +// if (PyInt_Check(u) || u == Py_None) { +// u = v = w = Py_None; +// } +// else { +// v = THIRD(); +// w = FOURTH(); +// } +// /* XXX Not the fastest way to call it... */ +// x = PyObject_CallFunctionObjArgs(x, u, v, w, NULL); +// if (x == NULL) +// break; /* Go to error exit */ +// if (u != Py_None && PyObject_IsTrue(x)) { +// /* There was an exception and a true return */ +// Py_DECREF(x); +// x = TOP(); /* Again */ +// STACKADJ(-3); +// Py_INCREF(Py_None); +// SET_TOP(Py_None); +// Py_DECREF(x); +// Py_DECREF(u); +// Py_DECREF(v); +// Py_DECREF(w); +// } else { +// /* Let END_FINALLY do its thing */ +// Py_DECREF(x); +// x = POP(); +// Py_DECREF(x); +// } +// break; +// } +// + case Opcode.CALL_FUNCTION: { + int na = oparg & 0xff; + int nk = (oparg >> 8) & 0xff; + int n = na + 2 * nk; + + PyObject args[] = stack.popN(na); + PyObject callable = stack.pop(); + System.err.println("__call__:" + callable + "," + Arrays.toString(args)); + stack.push(callable.__call__(args)); + break; + } + +// +// case CALL_FUNCTION_VAR: +// case CALL_FUNCTION_KW: +// case CALL_FUNCTION_VAR_KW: +// { +// int na = oparg & 0xff; +// int nk = (oparg>>8) & 0xff; +// int flags = (opcode - CALL_FUNCTION) & 3; +// int n = na + 2 * nk; +// PyObject **pfunc, *func, **sp; +// PCALL(PCALL_ALL); +// if (flags & CALL_FLAG_VAR) +// n++; +// if (flags & CALL_FLAG_KW) +// n++; +// pfunc = stack_pointer - n - 1; +// func = *pfunc; +// +// if (PyMethod_Check(func) +// && PyMethod_GET_SELF(func) != NULL) { +// PyObject *self = PyMethod_GET_SELF(func); +// Py_INCREF(self); +// func = PyMethod_GET_FUNCTION(func); +// Py_INCREF(func); +// Py_DECREF(*pfunc); +// *pfunc = self; +// na++; +// n++; +// } else +// Py_INCREF(func); +// sp = stack_pointer; +// READ_TIMESTAMP(intr0); +// x = ext_do_call(func, &sp, flags, na, nk); +// READ_TIMESTAMP(intr1); +// stack_pointer = sp; +// Py_DECREF(func); +// +// while (stack_pointer > pfunc) { +// w = POP(); +// Py_DECREF(w); +// } +// PUSH(x); +// if (x != NULL) +// continue; +// break; +// } +// + case Opcode.MAKE_FUNCTION: { + PyCode code = (PyCode) stack.pop(); + PyObject[] defaults = stack.popN(oparg); + PyFunction func = new PyFunction(f.f_globals, defaults, code); + stack.push(func); + break; + } + + case Opcode.MAKE_CLOSURE: { + PyCode code = (PyCode) stack.pop(); + PyObject[] closure_cells = new PyTuple(stack.pop()).getArray(); + PyObject[] defaults = stack.popN(oparg); + PyFunction func = new PyFunction(f.f_globals, defaults, code, closure_cells); + stack.push(func); + break; + } + +// case BUILD_SLICE: +// if (oparg == 3) +// w = POP(); +// else +// w = NULL; +// v = POP(); +// u = TOP(); +// x = PySlice_New(u, v, w); +// Py_DECREF(u); +// Py_DECREF(v); +// Py_XDECREF(w); +// SET_TOP(x); +// if (x != NULL) continue; +// break; +// + case Opcode.EXTENDED_ARG: + opcode = co_code[next_instr++]; + next_instr += 2; + oparg = oparg << 16 | ((co_code[next_instr - 1] << 8) + (co_code[next_instr - 2])); + break; + + default: + Py.print(Py.getSystemState().stderr, + Py.newString( + String.format("XXX lineno: %d, opcode: %d\n", + f.f_lasti, opcode))); + throw Py.SystemError("unknown opcode"); + + + } // end switch + } // end try + catch (Throwable t) { + // wrap so we can consume with our try block handling + PyException pye = Py.JavaError(t); + // XXX - but since that hasn't been written, for now just rethrow in wrapped form + throw pye; + } + + + // process why, blocks + switch (why) { + case RETURN: + return retval; + default: + break; + } + } // end while + return Py.None; // should never get here, just for debugging + } + + // XXX - perhaps add support for max stack size (presumably from co_stacksize) + // and capacity hints + class PyStack { + + final List<PyObject> stack; + + PyStack() { + stack = new ArrayList<PyObject>(); + } + + PyObject top() { + return stack.get(stack.size() - 1); + } + + PyObject pop() { + return stack.remove(stack.size() - 1); + } + + void push(PyObject v) { + stack.add(v); + } + + void set_top(PyObject v) { + stack.set(stack.size() - 1, v); + } + + void dup() { + stack.add(top()); + } + + void dupN(int n) { + PyObject v = top(); + for (int i = 0; i < n; i++) { + stack.add(v); + } + } + + PyObject[] popN(int n) { + int end = stack.size(); // exclusive + PyObject ret[] = new PyObject[n]; + List<PyObject> lastN = stack.subList(end - n, end); + lastN.toArray(ret); + lastN.clear(); + return ret; + } + + void rotN(int n) { + int end = stack.size(); + List<PyObject> lastN = stack.subList(end - n, end); + Collections.rotate(lastN, n); + } + + @Override + public String toString() { + return stack.toString(); + } + } +} + + Modified: branches/pbcvm/src/org/python/core/PyFrame.java =================================================================== --- branches/pbcvm/src/org/python/core/PyFrame.java 2009-01-20 13:47:20 UTC (rev 5948) +++ branches/pbcvm/src/org/python/core/PyFrame.java 2009-01-20 13:56:46 UTC (rev 5949) @@ -8,7 +8,7 @@ { public PyFrame f_... [truncated message content] |
From: <zy...@us...> - 2009-01-20 13:47:24
|
Revision: 5948 http://jython.svn.sourceforge.net/jython/?rev=5948&view=rev Author: zyasoft Date: 2009-01-20 13:47:20 +0000 (Tue, 20 Jan 2009) Log Message: ----------- Python Bytecode VM branch Added Paths: ----------- branches/pbcvm/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2009-01-19 22:23:18
|
Revision: 5947 http://jython.svn.sourceforge.net/jython/?rev=5947&view=rev Author: otmarhumbel Date: 2009-01-19 21:43:36 +0000 (Mon, 19 Jan 2009) Log Message: ----------- add xercesImpl as zipfileset to jarjar again: without this, there are no org.python.apache.* packages in jython.jar Modified Paths: -------------- trunk/jython/build.xml Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-01-18 13:46:12 UTC (rev 5946) +++ trunk/jython/build.xml 2009-01-19 21:43:36 UTC (rev 5947) @@ -522,6 +522,7 @@ <rule pattern="org.jruby.ext.posix.**" result="org.python.posix.@1"/> <zipfileset src="extlibs/constantine-0.4.jar"/> <rule pattern="com.kenai.constantine.**" result="org.python.constantine.@1"/> + <zipfileset src="extlibs/xercesImpl-2.9.1.jar"/> <rule pattern="org.apache.xml.**" result="org.python.apache.xml.@1"/> <rule pattern="org.apache.xerces.**" result="org.python.apache.xerces.@1"/> <rule pattern="org.apache.wml.**" result="org.python.apache.wml.@1"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |