summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2003-04-10 18:24:42 +0000
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2003-04-10 18:24:42 +0000
commita1b2d596c5e1b82621145fadb4714ec4d6a56701 (patch)
tree98f513bd1a000a4d78b65f788485eb0f3dd32eeb /gcc
parentd2cfc12473c22b1289f6326d978474cc5700589e (diff)
downloadgcc-a1b2d596c5e1b82621145fadb4714ec4d6a56701.tar.gz
2003-03-16 Mohan Embar <gnustuff@thisiscool.com>
* Make-lang.in: added win32-host.c * jcf.h: defined macro JCF_OPEN_EXACT_CASE which resolves to open() on non-Win32 platforms and Win32-specific jcf_open_exact_case() on Win32 * jcf-io.c (find_class): use JCF_OPEN_EXACT_CASE when trying .java and .class files * win32-host.c: added to repository. Defines Win32-specific jcf_open_exact_case() 2003-04-10 Andrew Haley <aph@redhat.com> * jcf-write.c (struct jcf_partial): num_jsrs: new field. (maybe_free_localvar): Renamed from localvar_free. Add new arg, really. (generate_bytecode_insns): Set new variable, jsrs. Only free local vars if no jsr insns have been emittted. Call maybe_free_localvar, not localvar_free. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@65430 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/java/ChangeLog20
-rw-r--r--gcc/java/Make-lang.in1
-rw-r--r--gcc/java/jcf-io.c4
-rw-r--r--gcc/java/jcf-write.c25
-rw-r--r--gcc/java/jcf.h18
-rw-r--r--gcc/java/win32-host.c85
6 files changed, 143 insertions, 10 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index c141615b6b0..85a30a987e2 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,23 @@
+2003-03-16 Mohan Embar <gnustuff@thisiscool.com>
+
+ * Make-lang.in: added win32-host.c
+ * jcf.h: defined macro JCF_OPEN_EXACT_CASE which
+ resolves to open() on non-Win32 platforms and
+ Win32-specific jcf_open_exact_case() on Win32
+ * jcf-io.c (find_class): use JCF_OPEN_EXACT_CASE
+ when trying .java and .class files
+ * win32-host.c: added to repository. Defines
+ Win32-specific jcf_open_exact_case()
+
+2003-04-10 Andrew Haley <aph@redhat.com>
+
+ * jcf-write.c (struct jcf_partial): num_jsrs: new field.
+ (maybe_free_localvar): Renamed from localvar_free.
+ Add new arg, really.
+ (generate_bytecode_insns): Set new variable, jsrs.
+ Only free local vars if no jsr insns have been emittted.
+ Call maybe_free_localvar, not localvar_free.
+
2003-03-30 Joseph S. Myers <jsm@polyomino.org.uk>
* gcj.texi: Remove @ at start of file.
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index 9a97da57c43..5d747142127 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -334,6 +334,7 @@ java/resource.o: java/resource.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) function.h gt-java-resource.h
java/typeck.o: java/typeck.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
java/convert.h toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) real.h
+java/win32-host.o: java/win32-host.c $(CONFIG_H) $(SYSTEM_H) java/jcf.h
java/verify.o: java/verify.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
java/javaop.h java/java-opcodes.h java/java-except.h toplev.h $(SYSTEM_H) \
coretypes.h $(TM_H)
diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c
index c280f1f5546..d673ec8c7cc 100644
--- a/gcc/java/jcf-io.c
+++ b/gcc/java/jcf-io.c
@@ -544,7 +544,7 @@ find_class (const char *classname, int classname_length, JCF *jcf,
classname+classname_length-
(classname_length <= 30 ?
classname_length : 30)));
- fd = open (buffer, O_RDONLY | O_BINARY);
+ fd = JCF_OPEN_EXACT_CASE (buffer, O_RDONLY | O_BINARY);
if (fd >= 0)
goto found;
}
@@ -556,7 +556,7 @@ find_class (const char *classname, int classname_length, JCF *jcf,
classname+classname_length-
(classname_length <= 30 ?
classname_length : 30)));
- fd = open (buffer, O_RDONLY);
+ fd = JCF_OPEN_EXACT_CASE (buffer, O_RDONLY);
if (fd >= 0)
{
jcf->java_source = 1;
diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c
index d9fc6508259..9c05a5ae831 100644
--- a/gcc/java/jcf-write.c
+++ b/gcc/java/jcf-write.c
@@ -279,6 +279,9 @@ struct jcf_partial
/* Information about the current switch statement. */
struct jcf_switch_state *sw_state;
+
+ /* The count of jsr instructions that have been emmitted. */
+ long num_jsrs;
};
static void generate_bytecode_insns (tree, int, struct jcf_partial *);
@@ -293,7 +296,7 @@ static void define_jcf_label (struct jcf_block *, struct jcf_partial *);
static struct jcf_block * get_jcf_label_here (struct jcf_partial *);
static void put_linenumber (int, struct jcf_partial *);
static void localvar_alloc (tree, struct jcf_partial *);
-static void localvar_free (tree, struct jcf_partial *);
+static void maybe_free_localvar (tree, struct jcf_partial *, int);
static int get_access_flags (tree);
static void write_chunks (FILE *, struct chunk *);
static int adjust_typed_op (tree, int);
@@ -601,7 +604,7 @@ localvar_alloc (tree decl, struct jcf_partial *state)
}
static void
-localvar_free (tree decl, struct jcf_partial *state)
+maybe_free_localvar (tree decl, struct jcf_partial *state, int really)
{
struct jcf_block *end_label = get_jcf_label_here (state);
int index = DECL_LOCAL_INDEX (decl);
@@ -613,6 +616,8 @@ localvar_free (tree decl, struct jcf_partial *state)
if (info->decl != decl)
abort ();
+ if (! really)
+ return;
ptr[0] = NULL;
if (wide)
{
@@ -1066,6 +1071,7 @@ emit_jsr (struct jcf_block *target, struct jcf_partial *state)
OP1 (OPCODE_jsr);
/* Value is 1 byte from reloc back to start of instruction. */
emit_reloc (RELOCATION_VALUE_1, OPCODE_jsr_w, target, state);
+ state->num_jsrs++;
}
/* Generate code to evaluate EXP. If the result is true,
@@ -1347,7 +1353,7 @@ generate_bytecode_return (tree exp, struct jcf_partial *state)
emit_store (state->return_value_decl, state);
call_cleanups (NULL, state);
emit_load (state->return_value_decl, state);
- /* If we call localvar_free (state->return_value_decl, state),
+ /* If we call maybe_free_localvar (state->return_value_decl, state, 1),
then we risk the save decl erroneously re-used in the
finalizer. Instead, we keep the state->return_value_decl
allocated through the rest of the method. This is not
@@ -1384,6 +1390,7 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state)
{
tree local;
tree body = BLOCK_EXPR_BODY (exp);
+ long jsrs = state->num_jsrs;
for (local = BLOCK_EXPR_DECLS (exp); local; )
{
tree next = TREE_CHAIN (local);
@@ -1397,10 +1404,11 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state)
body = TREE_OPERAND (body, 1);
}
generate_bytecode_insns (body, target, state);
+
for (local = BLOCK_EXPR_DECLS (exp); local; )
{
tree next = TREE_CHAIN (local);
- localvar_free (local, state);
+ maybe_free_localvar (local, state, state->num_jsrs <= jsrs);
local = next;
}
}
@@ -2354,8 +2362,8 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state)
if (CAN_COMPLETE_NORMALLY (finally))
{
maybe_wide (OPCODE_ret, DECL_LOCAL_INDEX (return_link), state);
- localvar_free (exception_decl, state);
- localvar_free (return_link, state);
+ maybe_free_localvar (exception_decl, state, 1);
+ maybe_free_localvar (return_link, state, 1);
define_jcf_label (finished_label, state);
}
}
@@ -2960,6 +2968,7 @@ generate_classfile (tree clas, struct jcf_partial *state)
get_jcf_label_here (state); /* Force a first block. */
for (t = DECL_ARGUMENTS (part); t != NULL_TREE; t = TREE_CHAIN (t))
localvar_alloc (t, state);
+ state->num_jsrs = 0;
generate_bytecode_insns (body, IGNORE_TARGET, state);
if (CAN_COMPLETE_NORMALLY (body))
{
@@ -2969,9 +2978,9 @@ generate_classfile (tree clas, struct jcf_partial *state)
OP1 (OPCODE_return);
}
for (t = DECL_ARGUMENTS (part); t != NULL_TREE; t = TREE_CHAIN (t))
- localvar_free (t, state);
+ maybe_free_localvar (t, state, 1);
if (state->return_value_decl != NULL_TREE)
- localvar_free (state->return_value_decl, state);
+ maybe_free_localvar (state->return_value_decl, state, 1);
finish_jcf_block (state);
perform_relocations (state);
diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h
index 96809748692..5a28735c061 100644
--- a/gcc/java/jcf.h
+++ b/gcc/java/jcf.h
@@ -63,6 +63,24 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#define COMPARE_FILENAMES(X, Y) strcmp ((X), (Y))
#endif
+/* On case-insensitive file systems, we need to ensure that a request
+ to open a .java or .class file is honored only if the file to be
+ opened is of the exact case we are asking for. In other words, we
+ want to override the inherent case insensitivity of the underlying
+ file system. On other platforms, this macro becomes the vanilla
+ open() call.
+
+ If you want to add another host, add your define to the list below
+ (i.e. defined(WIN32) || defined(YOUR_HOST)) and add an host-specific
+ .c file to Make-lang.in similar to win32-host.c */
+#if defined(WIN32)
+extern int
+jcf_open_exact_case (const char* filename, int oflag);
+#define JCF_OPEN_EXACT_CASE(X, Y) jcf_open_exact_case (X, Y)
+#else
+#define JCF_OPEN_EXACT_CASE open
+#endif /* WIN32 */
+
struct JCF;
typedef int (*jcf_filbuf_t) PARAMS ((struct JCF*, int needed));
diff --git a/gcc/java/win32-host.c b/gcc/java/win32-host.c
new file mode 100644
index 00000000000..7ab8fa53f96
--- /dev/null
+++ b/gcc/java/win32-host.c
@@ -0,0 +1,85 @@
+/* Platform-Specific Win32 Functions
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Java and all Java-based marks are trademarks or registered trademarks
+of Sun Microsystems, Inc. in the United States and other countries.
+The Free Software Foundation is independent of Sun Microsystems, Inc. */
+
+/* Written by Mohan Embar <gnustuff@thisiscool.com>, March 2003. */
+
+#ifdef WIN32
+
+#include "config.h"
+#include "system.h"
+
+#include "jcf.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+/* Simulate an open() failure with ENOENT */
+static int
+file_not_found (void);
+
+static int
+file_not_found (void)
+{
+ errno = ENOENT;
+ return -1;
+}
+
+int
+jcf_open_exact_case (const char *filename, int oflag)
+{
+ int filename_len = strlen (filename);
+ int found_file_len;
+ HANDLE found_file_handle;
+ WIN32_FIND_DATA fd;
+
+ /* See if we can find this file. */
+ found_file_handle = FindFirstFile (filename, &fd);
+ if (found_file_handle == INVALID_HANDLE_VALUE)
+ return file_not_found ();
+ FindClose (found_file_handle);
+
+ found_file_len = strlen (fd.cFileName);
+
+ /* This should never happen. */
+ if (found_file_len > filename_len)
+ return file_not_found ();
+
+ /* Here, we're only actually comparing the filename and not
+ checking the case of any containing directory components.
+ Although we're not fully obeying our contract, checking
+ all directory components would be tedious and time-consuming
+ and it's a pretty safe assumption that mixed-case package
+ names are a fringe case.... */
+ if (strcmp (filename + filename_len - found_file_len, fd.cFileName))
+ {
+ /* Reject this because it is not a perfect-case match. */
+ /* printf("************\nRejected:\n%s\n%s\n************\n\n", filename, fd.cFileName); */
+ return file_not_found ();
+ }
+ else
+ {
+ return open (filename, oflag);
+ }
+}
+
+#endif /* WIN32 */