+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.
$(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)
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;
}
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;
/* 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 *);
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);
}
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);
if (info->decl != decl)
abort ();
+ if (! really)
+ return;
ptr[0] = NULL;
if (wide)
{
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,
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
{
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);
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;
}
}
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);
}
}
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))
{
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);
#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));
--- /dev/null
+/* 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 */