summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1991-06-04 19:39:42 (GMT)
committerGuido van Rossum <guido@python.org>1991-06-04 19:39:42 (GMT)
commitc405b7b2fa2b18aa8f3fc62ca422cdee90138583 (patch)
treeed16fe6b23aeed630f1ee7e2ba7a7d3707478cc4 /Python
parent2cfd356f0ac72b982b63eeda0384fe21320d8637 (diff)
downloadcpython-c405b7b2fa2b18aa8f3fc62ca422cdee90138583.zip
cpython-c405b7b2fa2b18aa8f3fc62ca422cdee90138583.tar.gz
cpython-c405b7b2fa2b18aa8f3fc62ca422cdee90138583.tar.bz2
Support ".pyc" files: cached compilation results.
(Similar to Emacs ".elc" files.)
Diffstat (limited to 'Python')
-rw-r--r--Python/import.c77
1 files changed, 72 insertions, 5 deletions
diff --git a/Python/import.c b/Python/import.c
index 67cd31e..a4995ea 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -33,6 +33,13 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "errcode.h"
#include "sysmodule.h"
#include "pythonrun.h"
+#include "marshal.h"
+#include "compile.h"
+#include "ceval.h"
+
+#ifdef THINK_C
+#define macintosh
+#endif
/* Define pathname separator used in file names */
@@ -130,11 +137,15 @@ get_module(m, name, m_ret)
char *name;
object **m_ret;
{
- object *d;
- FILE *fp;
+ codeobject *co = NULL;
+ object *v, *d;
+ FILE *fp, *fpc;
node *n;
int err;
- char namebuf[256];
+ char namebuf[258];
+ int namelen;
+ long mtime;
+ extern long getmtime();
fp = open_module(name, ".py", namebuf);
if (fp == NULL) {
@@ -144,7 +155,33 @@ get_module(m, name, m_ret)
err_setstr(RuntimeError, "no module source file");
return NULL;
}
- err = parse_file(fp, namebuf, file_input, &n);
+ /* Get mtime -- always useful */
+ mtime = getmtime(namebuf);
+ /* Check ".pyc" file first */
+ namelen = strlen(namebuf);
+ namebuf[namelen] = 'c';
+ namebuf[namelen+1] = '\0';
+ fpc = fopen(namebuf, "rb");
+ if (fpc != NULL) {
+ long pyc_mtime;
+ (void) rd_long(fpc); /* Reserved for magic word */
+ pyc_mtime = rd_long(fpc);
+ if (pyc_mtime != 0 && pyc_mtime != -1 && pyc_mtime == mtime) {
+ v = rd_object(fpc);
+ if (v == NULL || err_occurred() || !is_codeobject(v)) {
+ err_clear();
+ XDECREF(v);
+ }
+ else
+ co = (codeobject *)v;
+ }
+ fclose(fpc);
+ }
+ namebuf[namelen] = '\0';
+ if (co == NULL)
+ err = parse_file(fp, namebuf, file_input, &n);
+ else
+ err = E_DONE;
fclose(fp);
if (err != E_DONE) {
err_input(err);
@@ -159,7 +196,37 @@ get_module(m, name, m_ret)
*m_ret = m;
}
d = getmoduledict(m);
- return run_node(n, namebuf, d, d);
+ if (co == NULL) {
+ co = compile(n, namebuf);
+ freetree(n);
+ if (co == NULL)
+ return NULL;
+ /* Now write the code object to the ".pyc" file */
+ namebuf[namelen] = 'c';
+ namebuf[namelen+1] = '\0';
+ fpc = fopen(namebuf, "wb");
+ if (fpc != NULL) {
+ wr_long(0L, fpc); /* Reserved for magic word */
+ /* First write a 0 for mtime */
+ wr_long(0L, fpc);
+ wr_object((object *)co, fpc);
+ if (ferror(fpc)) {
+ /* Don't keep partial file */
+ fclose(fpc);
+ (void) unlink(namebuf);
+ }
+ else {
+ /* Now write the true mtime */
+ fseek(fpc, 4L, 0);
+ wr_long(mtime, fpc);
+ fflush(fpc);
+ fclose(fpc);
+ }
+ }
+ }
+ v = eval_code(co, d, d, (object *)NULL);
+ DECREF(co);
+ return v;
}
static object *